The idea behind this framework is to support building and testing on different platforms without the knowledge about the different behaviors.
Writing build scripts and test should be very easy and one should not have to know where the current installation is or if one should check /var/log/syslog or /var/adm/message.
The framework depend on two environment variables that Jenkins sets before executing.
- WORKSPACE - The path to the checked out code configured for the Jenkins job being executed.
- INSTALL_TAG - Specify an tag for the installation being made, this is used to separate the different branches.
To use the framework inside a build or test script (bash) you include it by using source and then initialize it.
To run the framework manually for testing or debugging:
These are the important environment variables used by the framework, more about Jenkins environment variables can be read here: .
The workspace path set by Jenkins or manually.
This must be set.
The workspace root path set by init().
The install tag set manually.
This must be set if INSTALL_ROOT is not set.
The install root path set by init().
This must be set if INSTALL_TAG is not set.
The SVN revision of the checked out source configured in the Jenkins job, set by Jenkins if there is only one SVN configured.
This must be set.
The SVN revision of the checked out source configured in the Jenkins job, set by Jenkins if there is more then one SVN configured. Number is the order configured starting with 1.
The framework will detect if this is set and concat the revisions into SVN_REVISION.
This is set by the framework to the distribution running on the host currently executing the framework. It can be used to maintain different configurations based on distribution.
<Current Working Directory>/._log.BUILD_TAG.<log name>.stdout
<Current Working Directory>/._log.BUILD_TAG.<log name>.stderr
Logs produced by log_this().
<Current Working Directory>/._syslog.BUILD_TAG
Logs produced by syslog_trace().
This can be set to a shell script function that will be called before a test. See more on run_tests().
This can be set to a shell script function that will be called after a test. See more on run_test().
Contains the PID of the background syslog trace.
Is set if test lock needs to be cleaned up.
Files and Paths
These files and paths are important to the framework.
This is the root directory that contains all INSTALL_ROOT's.
This is the INSTALL_ROOT directory if INSTALL_ROOT was not set prior of init().
This directory is a cache for fetched files.
This file contains the SVN_REVISION of the latest successful build of <name tag>.
Used by: check_if_built() start_build() set_build_ok() require()
This file exists if <name tag> has been built successfully.
Used by: start_build() set_build_ok() require()
This file contains the SVN_REVISION of the latest successful test of <name tag>.
Used by: check_if_tested() start_test() set_test_ok()
This file exists if <name tag> has been tested successfully.
Used by: start_test() set_test_ok()
These are the test locks, .testing is a symlink to .testing.<pid> and .testing.<pid> also contains the pid of the process currently running tests.
Append path to PATH, checks if path exists and that its not already added to PATH.
Prepend path to PATH, checks if path exists and that its not already added to PATH.
Append flags to CFLAGS, checks if flags is already in CFLAGS and won't add if they are.
Append flags to CPPFLAGS, checks if flags is already in CPPFLAGS and won't add if they are.
Append flags to LDFLAGS, checks if flags is already in LDFLAGS and won't add if they are.
Append path to LD_LIBRARY_PATH, checks if path exists and that its not already added to PATH.
Locates the workspace root directory and sets WORKSPACE_ROOT.
Locates program and returns the full path to it.
Locate variants of make and set MAKE to the first usable.
Locate variants of m4 and set M4 to the first usable.
Locate variants of md5sum and set MD5SUM to the first usable.
Locate variants of sha1sum and set SHA1SUM to the first usable.
Locate variants of sha256sum and set SHA256SUM to the first usable.
Locate variants of wget and set WGET to the first usable.
Locate variants of ccache and set CCACHE to the first usable.
Locate variants of cc and set CC to the first usable.
Locate variants of cxx and set CXX to the first usable.
Locate variants of tee and set TEE to the first usable.
Locate variants of date and set DATE to the first usable.
Locate variants of tail and set TAIL to the first usable and sets TAIL_FOLLOW to the distributions specific tail command to follow a file that will be able to handle log rotation.
Set up the installation root based on INSTALL_TAG or INSTALL_ROOT. If only INSTALL_TAG is set it will set INSTALL_ROOT.
Detects the distribution on the host currently running the framework.
Initialize the framework.
This must be done prior of using the framework.
check_if_built <name tag>
Check if <name tag> has been built successfully. It is based on SVN_REVISION currently set.
This is to support periodically Jenkins job and not build them if they are already built and the source has not changed.
start_build <name tag>
Tell the framework your starting the build of <name tag>.
set_build_ok <name tag>
Tell the framework the build of <name tag> was successful.
check_if_tested <name tag>
Check if <name tag> has been tested successfully. It is based on the SVN_REVISION currently set.
This is to support periodically Jenkins job and not test them if they are already tested and the source has not changed.
start_test <name tag>
Tell the framework your starting the tests of <name tag>. This will also lock the workspace before running test so that tests are not running at the same time to prevent problems with listening on the same port etc. There is a timeout of one hour waiting for the lock.
set_test_ok <name tag>
Tell the framework the tests of <name tag> was successful.
require <name tag>
Require <name tag> that may have been built by another Jenkins job. This will check that it exists and was built successfully.
check_hash <filename> <type> <hash>
Check a file if the hash is correct.
Type can be: md5 sha1 sha256
fetch_src <url> <filename> <type> <hash>
Fetch a file with wget and place it in a named file. After retrieving check the hash of the file with check_hash().
log_this <log name> <command> [...]
Runs a command and logs stdout and stderr to a named log file to later be used with log_grep().
log_grep <log name> <grep string ...>
Grep from the <log name> after using log_this().
Clean up logs made by log_this(), should only be used after a successful build/test so if it fails logs are still there for analysis.
run_tests <test directory>
This function runs tests inside a directory in a rc.d/run-parts fashion.
A test in the <test directory> must be a directory which name must start with a number and inside that directory there must be a test.sh file. To turn off test you can rename the directory so that it ends with '.off' or you can put a file named 'off' inside the directory.
Before running the test run_tests() will change directory into the test directory so that log_this() and syslog_trace() stores logs related to the test inside the test directory for later analysis if the test fails. It will also start a syslog_trace() and do both log_cleanup() and syslog_cleanup() if the test was successful.
run_tests() will call two callback function if they are set. The environment variable PRE_TEST will be called after changing into the test directory but before running it, it will get the test directory name as first parameter. The environment variable POST_TEST will be called after the test but before any cleanup have started, it will get the test directory name as first parameter and the test exit status as the second parameter.
Starts a background trace of the syslog.
Stops the background trace of the syslog.
syslog_waitfor <timeout in seconds> <grep string ...>
Greps in the syslog after the <grep string>, returns successfully if it find the string within the timeout otherwise returns failure.
syslog_grep <grep string ...>
Grep from the syslog.
Clean up syslog files made by syslog_trace(), should only be used after a successful build/test so if it fails logs are still there for analysis.