PMC:QA:optimizing integration of hudson and adempiere
optimizing integration of hudson and adempiere
AdempiereQA job integration include Adempiere source code update,database update,junit test,adempiere installation.
First update adempiere source code(source code in hudson job workspace),then compile source code,update database,do junit test.last install adempiere(extract install package to install directory -> CI/current,and install)
configuration
AdempiereQA configuration include follow options:
* Adempiere source code management * Build Triggers * setup environment * database backup * source code compilation * database migration * junit test * adempiere installation * save variables
Source Code Management
hudson -> AdempiereQA -> configure -> Source Code Management
Explanation:
we use Mercurial to manage adempiere source code.
- Repository URL - Specify the repository to track
- Branch - Specify the branch name if you'd like to track a specific branch in a repository. Leave this field empty otherwise, to track the "default" branch. Here we specify the branch name "development".
Build Triggers
AdempiereQA -> configure -> Build Triggers
Thus AdempiereQA job will build at 4:06 every Monday and Wednesday
Set environment
AdempiereQA -> configure -> Build
add Execute shell
# Setup Envoronment # make sure you make a symlink of /opt/sun-jdk to current # system jdk you configured with java-config-2 cd /opt/sun-jdk # check if directory /CI exist. cd /CI # import current deployed version into building variables, . /CI/current/version_current VERSION_OLD=$VERSION echo "VERSION_OLD='$VERSION'" > /CI/version_building REVISION_OLD=$REVISION echo "REVISION_OLD='$REVISION'" >> /CI/version_building # check building files and directories md5sum -c /CI/checkfiles [[ -d /CI/db-backup ]] && echo "Directory /CI/db-backup found." || mkdir /CI/db-backup [[ -d /CI/logs ]] && echo "Directory /CI/logs found." || mkdir /CI/logs # import current building version into building variables # and set timestamp cd ${WORKSPACE} [[ -d ./trunk ]] && echo "Directory ./trunk found." || ln -sf release trunk #cd trunk VERSION=$(grep -i "env.ADEMPIERE_VERSION_FILE" utils_dev/build.properties | cut -f2 -d"=") VERSION=$(echo "${VERSION}" | cut -b 1-$((${#VERSION} - 1))) echo "Got current version number: $VERSION" REVISION=$(hg tip| grep -i "changeset" |cut -b 14-17) #REVISION=$(hg log| grep -i "revision" |cut -f2 -d "") #REVISION=$(hg tip| grep -i "changeset" |cut -b 19-30) echo "Got current trunk revision ID: $REVISION" if [[ "$REVISION" == "$REVISION_OLD" ]] then echo "SAME REVISION" exit 1 else echo "NOT SAME REVISION" echo "VERSION='$VERSION'" >> /CI/version_building echo "REVISION='$REVISION'" >> /CI/version_building echo "DATETIME='$(date +%s)'" >> /CI/version_building exit 0 fi
Explanation
get and output the old version,revision to /CI/version_building
# import current deployed version into building variables, . /CI/current/version_current VERSION_OLD=$VERSION echo "VERSION_OLD='$VERSION'" > /CI/version_building REVISION_OLD=$REVISION echo "REVISION_OLD='$REVISION'" >> /CI/version_building
get the new version and revision
VERSION=$(grep -i "env.ADEMPIERE_VERSION_FILE" utils_dev/build.properties | cut -f2 -d"=") VERSION=$(echo "${VERSION}" | cut -b 1-$((${#VERSION} - 1))) echo "Got current version number: $VERSION" REVISION=$(hg tip| grep -i "changeset" |cut -b 14-17) echo "Got current trunk revision ID: $REVISION"
Adempiere changeset judgment
if [[ "$REVISION" == "$REVISION_OLD" ]] then echo "SAME REVISION" exit 1 else echo "NOT SAME REVISION" echo "VERSION='$VERSION'" >> /CI/version_building echo "REVISION='$REVISION'" >> /CI/version_building echo "DATETIME='$(date +%s)'" >> /CI/version_building exit 0 fi
1. If there is no new revision of source code, needn't to integrate and compile it again 2. If there is a new version of the tests,output new version,revision and date time to /CI/version_building.Next compile source code and deploy adempiere ...
Backup database
# backup database . /CI/version_building FILENAME="db-backup.Adempiere.${VERSION_OLD}.${REVISION_OLD}" DB_NAME=$(grep -i "postgresql.database" /CI/postgresql.properties | cut -f2 -d"=") DB_NAME=$(echo "${DB_NAME}" | cut -b 1-$((${#DB_NAME} - 1))) DB_USER=$(grep -i "postgresql.user" /CI/postgresql.properties | cut -f2 -d"=") DB_USER=$(echo "${DB_USER}" | cut -b 1-$((${#DB_USER} - 1))) DB_PASS=$(grep -i "postgresql.password" /CI/postgresql.properties | cut -f2 -d"=") DB_PASS=$(echo "${DB_PASS}" | cut -b 1-$((${#DB_PASS} - 1))) DB_HOST=$(grep -i "postgresql.host" /CI/postgresql.properties | cut -f2 -d"=") DB_HOST=$(echo "${DB_HOST}" | cut -b 1-$((${#DB_HOST} - 1))) DB_PORT=$(grep -i "postgresql.port" /CI/postgresql.properties | cut -f2 -d"=") DB_PORT=$(echo "${DB_PORT}" | cut -b 1-$((${#DB_PORT} - 1))) echo ${DB_HOST}:${DB_PORT}:${DB_NAME}:${DB_USER}:${DB_PASS} > ~/.pgpass chmod 0600 ~/.pgpass cd /CI/db-backup # pg_dump command syntax based on pg_dump in postgresql 8.4.2 pg_dump -U ${DB_USER} -h ${DB_HOST} -p ${DB_PORT} ${DB_NAME} > ${DATETIME}_${FILENAME}.sql tar -czf ${DATETIME}_${FILENAME}.tar.gz ${DATETIME}_${FILENAME}.sql --remove-files
Compilation
add a Invoke Ant
- Targets -Specify a list of Ant targets to be invoked
- Build file - specify build file(ps:here is compilation build file in adempiere_source/utils_dev)
migrate database
Add Execute shell to migrate/update database
# migrate database . /CI/version_building cd ${WORKSPACE}/migration/ cp -f /CI/postgresql.properties ./postgresql.properties cp -f /CI/migrate2trunk.sh ./migrate2trunk.sh ./migrate2trunk.sh $DATETIME $VERSION_OLD $VERSION
migrate2trunk.sh use for judging the database need to migrate or not,if need update database,then excute build file in adempiere_source/migration/version-release/postgresql.
Junit test
test.properties file
First junit test need to use test.properties file ,test.properties is a properties file,how to create it please refer to adempiere_source_code/extend/testTemplate.properties test.properties sample:
#AdempiereProperties=/CI/current/Adempiere.properties AdempiereProperties=/opt/Adempiere.properties isClient=Y AD_Client_ID=11 AD_User_ID=0
Note:
"Adempiere.properties" file generated when adempiere install.
"Adempiere.properties",you can specify it:
- the one which in the last install application
- or your backup file
configuration in hudson:
copy a test.properties file to Adempiere_source/extend/
build file
To run junit test via invoking target "functionaltest" which in Adempiere_source/workspace/extend/build.xml.
functiontest target
<target name="functionaltest" depends="dist"> <junit> <classpath refid="class.path.test" /> <formatter type="brief" usefile="false" /> <test name="test.functional.MUserTest" /> <test name="test.functional.MLocationTest" /> <test name="test.functional.MBPartnerTest" /> <test name="test.functional.MBPGroupTest" /> <test name="test.functional.MBPartnerLocationTest" /> <test name="test.functional.MSessionTest" /> <test name="test.functional.PackOutTest" /> <test name="test.functional.MWFNodePlaceHolderTest" /> <test name="test.functional.XMLValidateTest" /> <!-- test name="test.functional.XMLImportStructureTest" / --> <!-- test name="test.functional.BPMigrationTest" / --> </junit> </target>
above script defined "<formatter type="brief" usefile="false" />",the test result output in console
But we want to display the test result in hudson(need to get results from xml file)
So need to modify adempiere_source_code/extend/build.xml
create a build file "adempiere_junit_test.xml". The diff with adempiere_source_code/extend/build.xml as following:
<property name="test.xml" value="/opt/hudson/jobs/AdempiereQA/workspace/junittest"/> <property name="test.report" value="/opt/hudson/jobs/AdempiereQA/workspace/junitreport"/> <!--Note:please set test result out dir to hudson job workspace,thus next we can publish junit report in hudson--> <target name="functionaltest" depends="dist"> <junit> <classpath refid="class.path.test" /> <formatter type="xml"/> <test name="test.functional.MUserTest" todir="${test.xml}"/> <test name="test.functional.MLocationTest" todir="${test.xml}"/> <test name="test.functional.MBPartnerTest" todir="${test.xml}"/> <test name="test.functional.MBPGroupTest" todir="${test.xml}"/> <test name="test.functional.MBPartnerLocationTest" todir="${test.xml}"/> <test name="test.functional.MSessionTest" todir="${test.xml}"/> <test name="test.functional.PackOutTest" todir="${test.xml}"/> <!-- <test name="test.functional.MWFNodePlaceHolderTest" todir="${test.xml}"/> <test name="test.functional.XMLValidateTest" todir="${test.xml}"/>--> </junit> <junitreport todir="${test.xml}"> <fileset dir="${test.xml}"> <include name="TEST-*.xml"/> </fileset> <report format="frames" todir="${test.report}"/> </junitreport> </target>
- modify output formatter to be "xml"
- add output dir
- add report
- "<test name="test.functional.MWFNodePlaceHolderTest" todir="${test.xml}"/> <test name="test.functional.XMLValidateTest" todir="${test.xml}"/>"
these two tests can't pass test,because of class not found exception,take them out.
hudson configuration
Publish JUnit test result report
First you need to create junit test output dir in hudson AdempiereQA worksapce(eg,hudson/jobs/AdempiereQA/workspace/junittest).
Other Note
- junit test use Extend.jar,and Extend.jar generated when adempiere source code compilation,so junit test must after compilation build.
- junit test need adempiere database is starting
Installation
Add execute shell
# install ADempiere . /CI/version_building rm /CI/Adempiere -Rf tar -xzf ${WORKSPACE}/install/build/Adempiere_$VERSION.tar.gz -C /CI rm /CI/*Adempiere.$VERSION.$REVISION -Rf mv /CI/Adempiere /CI/${DATETIME}_Adempiere.$VERSION.$REVISION rm /CI/lastbuild -Rf [[ -d /CI/current ]] && mv /CI/current /CI/lastbuild ln -sf /CI/${DATETIME}_Adempiere.$VERSION.$REVISION /CI/current cd /CI/current cp -f /CI/AdempiereEnv.properties ./ chmod +x *.sh ./RUN_silentsetup.sh | grep "BUILD SUCCESSFUL"
Adempiere installation need "AdempiereEnv.properties" file,install via invoke command "/RUN_silentsetup.sh"
Save variables
# finish, save variables . /CI/version_building echo "VERSION='$VERSION'" > /CI/current/version_current echo "REVISION='$REVISION'" >> /CI/current/version_current echo "TIME_DEPLOYED='$DATETIME'" >> /CI/current/version_current rm /CI/version_building -Rf
output current version,revision and time deployed to /CI/current/version_current
Links
* Go back to PMC:QA