BEAKERLIB(1)
๐ NAME ๐
BeakerLib โ the manual name is BEAKERLIB(1), and bestie, this is a shell-level integration testing library. No cap.
๐ธ DESCRIPTION ๐ธ
BeakerLib is a shell-level integration testing library that gives you convenience functions to simplify writing, running, and analyzing integration and blackbox tests. Itโs giving โmake testing less painfulโ energy, fr fr.
The essential features include:
- Journal โ uniform logging mechanism (logs & results saved in flexible XML format, easy to compare results & generate reports) ๐
- Phases โ logical grouping of test actions, clear separation of setup / test / cleanup (preventing false fails) โจ
- Asserts โ common checks affecting the overall results of the individual phases (checking for exit codes, file existence & content...) ๐ฏ
- Helpers โ convenience functions for common operations such as managing services, backup & restore ๐ ๏ธ
The main script sets the BEAKERLIB variable and sources other scripts where the actual functions are defined. You should source it at the beginning of your test with:
. /usr/share/beakerlib/beakerlib.sh
See the EXAMPLES section for quick start inspiration. ๐
See the BKRDOC section for more information about Automated documentation generator for BeakerLib tests. ๐
๐งฌ Result fingerprint ๐งฌ
Beakerlib provides two types of fingerprint of the test run. The fingerprints are counted at the phase end and journal end. ๐ซถ
The first one is a phases fingerprint which represents a list of the results of all the executed phases in the order of the execution.
The second one is an asserts fingerprint which represents a list of the results of all the executed asserts in the order of the execution.
The lists are then hashed resulting in a 8 letters string. ๐ฅ
Such fingerprint may be used as a reference result of the respective test run in a particular environment. Periodt.
โจ FUNCTIONS โจ
๐ Journalling ๐
๐ซ rlJournalStart
Initialize the journal file.
rlJournalStart
Run on the very beginning of your script to initialize journalling functionality. Like, literally the first thing. ๐
๐ rlJournalEnd
Summarize the test run and upload the journal file.
rlJournalEnd
Run on the very end of your script to print summary of the whole test run, generate OUTPUTFILE and include journal in Beaker logs. ๐
๐จ๏ธ rlJournalPrint
Print the content of the journal in pretty xml format.
rlJournalPrint [type]
- type โ Can be either 'raw' or 'pretty', with the latter as a default. Raw: xml is in raw form, no indentation etc. Pretty: xml is pretty printed, indented, with one record per line.
Example:
<?xml version="1.0"?>
<BEAKER_TEST>
<test_id>debugging</test_id>
<package>setup</package>
<pkgdetails>setup-2.8.9-1.fc12.noarch</pkgdetails>
<starttime>2010-02-08 15:17:47</starttime>
<endtime>2010-02-08 15:17:47</endtime>
<testname>/examples/beakerlib/Sanity/simple</testname>
<release>Fedora release 12 (Constantine)</release>
<hostname>localhost</hostname>
<arch>i686</arch>
<purpose>PURPOSE of /examples/beakerlib/Sanity/simple
Description: Minimal BeakerLib sanity test
Author: Petr Splichal <psplicha@redhat.com>
This is a minimal sanity test for BeakerLib. It contains a single
phase with a couple of asserts. We Just check that the "setup"
package is installed and that there is a sane /etc/passwd file.
</purpose>
<log>
<phase endtime="2010-02-08 15:17:47" name="Test" result="PASS"
score="0" starttime="2010-02-08 15:17:47" type="FAIL">
<test message="Checking for the presence of setup rpm">PASS</test>
<test message="File /etc/passwd should exist">PASS</test>
<test message="File '/etc/passwd' should contain 'root'">PASS</test>
</phase>
</log>
</BEAKER_TEST>
๐ rlJournalPrintText
Print the content of the journal in pretty text format.
rlJournalPrintText [--full-journal]
--full-journalโ The option is now deprecated, has no effect and will be removed in a future version. ๐ซ
Example:
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ LOG ] :: TEST PROTOCOL
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ LOG ] :: Test run ID : debugging
:: [ LOG ] :: Package : debugging
:: [ LOG ] :: Test started : 2010-02-08 14:45:57
:: [ LOG ] :: Test finished : 2010-02-08 14:45:58
:: [ LOG ] :: Test name :
:: [ LOG ] :: Distro: : Fedora release 12 (Constantine)
:: [ LOG ] :: Hostname : localhost
:: [ LOG ] :: Architecture : i686
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ LOG ] :: Test description
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
PURPOSE of /examples/beakerlib/Sanity/simple
Description: Minimal BeakerLib sanity test
Author: Petr Splichal <psplicha@redhat.com>
This is a minimal sanity test for BeakerLib. It contains a single
phase with a couple of asserts. We Just check that the "setup"
package is installed and that there is a sane /etc/passwd file.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ LOG ] :: Test
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ PASS ] :: Checking for the presence of setup rpm
:: [ PASS ] :: File /etc/passwd should exist
:: [ PASS ] :: File '/etc/passwd' should contain 'root'
:: [ LOG ] :: Duration: 1s
:: [ LOG ] :: Assertions: 3 good, 0 bad
:: [ PASS ] :: RESULT: Test
๐ rlGetTestState
Returns number of failed asserts so far, or 255 if there are more than 255 failures. The variable ECODE is set to the precise number.
rlGetTestState
๐ rlGetPhaseState
Returns number of failed asserts in the current phase so far, or 255 if there are more than 255 failures. The variable ECODE is set to the precise number.
rlGetPhaseState
๐ชต Logging ๐ชต
๐ rlLog, rlLogDebug, rlLogInfo, rlLogWarning, rlLogError, rlLogFatal
Create a time/priority-labelled message in the log. There is a bunch of aliases which can create messages formated as DEBUG/INFO/WARNING/ERROR or FATAL (but you would probably want to use rlDie instead of the last one). ๐
rlLog message [logfile] [priority] [label]
- message โ Message you want to show (use quotes when invoking).
- logfile โ Log file. If not supplied, OUTPUTFILE is assumed.
- priority โ Priority of the log.
- label โ Print this text instead of time in log label.
๐ rlDie
Create a time-labelled message in the log, report test result, upload logs, close unfinished phase and terminate the test. Dramatic exit, but make it useful. ๐ญ
rlDie message [file...]
- message โ Message you want to show (use quotes when invoking) โ this option is mandatory.
- file โ Files (logs) you want to upload as well.
rlBundleLogswill be used for it. Files which are not readable will be excluded before callingrlBundleLogs, so it is safe to call even with possibly nonexistent logs and it will succeed. ๐ซถ
๐ฆ rlBundleLogs
Create a tarball of files (e.g. logs) and attach them to the test result.
rlBundleLogs package file [file...]
- package โ Name of the package. Will be used as part of the tarball name.
- file โ File(s) to be packed and submitted.
Returns result of submitting the tarball.
๐ค rlFileSubmit
Resolves absolute path to the file, replaces / with - and uploads this renamed file using rhts-submit-log. It also allows you to specify your custom name for the uploaded file.
rlFileSubmit [-s sep] path_to_file [required_name]
-ssep โ Sets separator (i.e. the replacement of the /) to sep.- path_to_file โ Either absolute or relative path to file. Relative path is converted to absolute.
- required_name โ Default behavior renames file to full_path_to_file with / replaced for -, if this does not suit your needs, you can specify the name using this option.
Examples:
rlFileSubmit logfile.txt -> logfile.txt cd /etc; rlFileSubmit
./passwd -> etc-passwd rlFileSubmit /etc/passwd -> etc-passwd
rlFileSubmit /etc/passwd my-top-secret_file -> my-top-secret-file
rlFileSubmit -s '_' /etc/passwd -> etc_passwd
โน๏ธ Info โน๏ธ
๐ท๏ธ rlShowPackageVersion
Shows a message about version of packages.
rlShowPackageVersion package [package...]
- package โ Name of a package(s) you want to log.
๐๏ธ rlGetArch
Sanitize architecture for simplier matching.
Return base arch for the current system (good when you need base arch on a multilib system).
rlGetArch
On any 32-bit Intel (i386, i486, i586, ...) system you will get i386. ๐
๐ฅ rlGetPrimaryArch
Return primary arch for the current system (good when you need base arch on a multilib system).
rlGetPrimaryArch
On non-RHEL systems if the primary/secondary sedicision fails a fallback to rlGetArch is done.
๐ฅ rlGetSecondaryArch
Return base arch for the current system (good when you need base arch on a multilib system).
rlGetSecondaryArch
๐ง rlGetDistroRelease, rlGetDistroVariant
Return release or variant of the distribution on the system.
rlGetDistroRelease
rlGetDistroVariant
For example on the RHEL-4-AS you will get release 4 and variant AS, on the RHEL-5-Client you will get release 5 and variant Client. ๐
๐ฅ๏ธ rlShowRunningKernel
Log a message with version of the currently running kernel.
rlShowRunningKernel
๐ญ Phases ๐ญ
๐ rlPhaseStart
Starts a phase of a specific type. The final phase result is based on all asserts included in the phase. Do not forget to end phase with rlPhaseEnd when you are done. ๐ซก
rlPhaseStart type [name]
- type โ Type of the phase, one of the following:
- FAIL โ When assert fails here, phase will report a FAIL.
- WARN โ When assert fails here, phase will report a WARN.
- name โ Optional name of the phase (if not provided, one will be generated).
If all asserts included in the phase pass, phase reports PASS. โจ
๐ rlPhaseEnd
End current phase, summarize asserts included and report phase result.
rlPhaseEnd
Final phase result is based on included asserts and phase type.
๐งฐ rlPhaseStartSetup, rlPhaseStartTest, rlPhaseStartCleanup
Start a phase of the specified type: Setup -> WARN, Test -> FAIL, Cleanup -> WARN.
rlPhaseStartSetup [name]
rlPhaseStartTest [name]
rlPhaseStartCleanup [name]
nameโ an optional name for the phase. If you don't pass one, the defaultsSetup/Test/Cleanupget used.
And if you're not feeling the shortcuts, bestie? Just use the plain rlPhaseStart function. It's right there. ๐ซถ
๐ Reboot
Okay so this one is important โ a controlled reboot must not be executed inside of an open phase. Otherwise it's possible the Overall result of the test will be reported incorrectly. Not the vibe. ๐
๐ Metric
rlLogMetricLow
Logs a metric that should be as low as possible to the journal. Think: memory consumption, run time. Lower = slay.
rlLogMetricLow name value [tolerance]
nameโ name of the metric. It has to be unique in a phase. No dupes, periodt.valueโ the value of the metric.toleranceโ used when comparing viarcw. It means how larger the second value can be to not trigger a FAIL. Default is0.2.
When comparing FIRST and SECOND, then:
FIRST >= SECOND means PASS
FIRST+FIRST*tolerance >= SECOND means WARN
FIRST+FIRST*tolerance < SECOND means FAIL
Example: a simple benchmark is compared via this metric type in rcw. It has a tolerance of 0.2. First run had 1 second. So:
For PASS, second run has to be better or equal to first.
So any value of second or less is a PASS.
For WARN, second run can be a little worse than first.
Tolerance is 0.2, so anything lower than 1.2 means WARN.
For FAIL, anything worse than 1.2 means FAIL.
rlLogMetricHigh
Logs a metric that should be as high as possible to the journal. Think: number of executions per second. Higher = iconic. ๐
rlLogMetricHigh name value [tolerance]
nameโ name of the metric. It has to be unique in a phase.valueโ the value of the metric.toleranceโ used when comparing viarcw. It means how lower the second value can be to not trigger a FAIL. Default is0.2.
When comparing FIRST and SECOND, then:
FIRST <= SECOND means PASS
FIRST+FIRST*tolerance <= SECOND means WARN
FIRST+FIRST*tolerance > SECOND means FAIL
โ Manual Asserts
rlPass
A manual assertion โ it asserts and logs PASS. Literally manifesting success. โจ
rlPass comment
commentโ short test summary.
Returns 0 and asserts PASS.
rlFail
A manual assertion โ it asserts and logs FAIL. Sometimes you gotta call it like you see it. ๐ญ
rlFail comment
commentโ short test summary.
Returns 1 and asserts FAIL.
๐งฎ Arithmetic Asserts
rlAssert0
Assertion checking for the equality of the parameter to zero.
rlAssert0 comment value
commentโ short test summary, e.g."Test if compilation ended successfully".valueโ integer value (usually the return code of a command).
Returns 0 and asserts PASS when "value == 0".
rlAssertEquals
Assertion checking for the equality of two parameters.
rlAssertEquals comment value1 value2
commentโ short test summary, e.g."Test if all 3 packages have been downloaded".value1โ first parameter to compare, can be a number or a string.value2โ second parameter to compare, can be a number or a string.
Returns 0 and asserts PASS when "value1 == value2".
rlAssertNotEquals
Assertion checking for the non-equality of two parameters.
rlAssertNotEquals comment value1 value2
commentโ short test summary, e.g."Test if return code is not 139".value1โ first parameter to compare, can be a number or a string.value2โ second parameter to compare, can be a number or a string.
Returns 0 and asserts PASS when "value1 != value2".
rlAssertGreater
Assertion checking whether the first parameter is greater than the second one.
rlAssertGreater comment value1 value2
commentโ short test summary, e.g."Test whether there are running more instances of program."value1โ integer value.value2โ integer value.
Returns 0 and asserts PASS when "value1 > value2".
rlAssertGreaterOrEqual
Assertion checking whether the first parameter is greater or equal to the second one.
rlAssertGreaterOrEqual comment value1 value2
commentโ short test summary (e.g."There should present at least one...")value1โ integer value.value2โ integer value.
Returns 0 and asserts PASS when "value1 X= value2". (yup, that's literally what the page says โ copying it exactly, don't come for me ๐)
rlAssertLesser
Assertion checking whether the first parameter is lesser than the second one.
rlAssertLesser comment value1 value2
commentโ short test summary, e.g."Test whether there are running more instances of program."value1โ integer value.value2โ integer value.
Returns 0 and asserts PASS when "value1 < value2".
rlAssertLesserOrEqual
Assertion checking whether the first parameter is lesser or equal to the second one.
rlAssertLesserOrEqual comment value1 value2
commentโ short test summary (e.g."There should present at least one...")value1โ integer value.value2โ integer value.
Returns 0 and asserts PASS when "value1 X= value2". (same energy as above, keeping it 100% verbatim ๐
)
๐ File Asserts
rlAssertExists
Assertion checking for the existence of a file or a directory.
rlAssertExists file|directory
file|directoryโ path to the file or directory.
Returns 0 and asserts PASS when "file" exists. It's giving "found it, bestie". ๐ฆ
rlAssertNotExists
Assertion checking for the non-existence of a file or a directory.
rlAssertNotExists file|directory
file|directoryโ path to the file or directory.
Returns 0 and asserts PASS when "file" does not exist.
rlAssertGrep
Assertion checking if the file contains a pattern.
rlAssertGrep pattern file [options]
patternโ regular expression to be searched for.fileโ path to the file.optionsโ optional parameters to be passed togrep, default is"-q". Can be used to perform case insensitive matches (-i), or using extended (-E) or perl (-P) regular expressions.
Returns 0 and asserts PASS when "file" exists and contains the given "pattern". ๐
rlAssertNotGrep
Assertion checking that the file does not contain a pattern.
rlAssertNotGrep pattern file [options]
patternโ regular expression to be searched for.fileโ path to the file.optionsโ optional parameters to be passed togrep, default is"-q". Can be used to perform case insensitive matches (-i), or using extended (-E) or perl (-P) regular expressions.
Returns 0 and asserts PASS when "file" exists and does not contain the given "pattern".
rlAssertDiffer
Assertion checking that two files differ (are not identical).
rlAssertDiffer file1 file2
file1โ path to firstfile1file2โ path to second file
Returns 0 and asserts PASS when "file1" and "file2" differs.
rlAssertNotDiffer
Assertion checking that two files do not differ (are identical).
rlAssertNotDiffer file1 file2
file1โ path to firstfile1file2โ path to second file
Returns 0 and asserts PASS when "file1" and "file2" do not differ.
๐ Run, Watch, Report
rlRun
Runs a command with an optional comment and makes sure its exit code matches expectations. This is the main character of the whole page, ngl. ๐
rlRun [-t] [-l] [-c] [-s] command [status[,status...] [comment]]
-tโ if specified, stdout and stderr of the command output will be tagged with the strings'STDOUT: 'and'STDERR: '.-lโ if specified, output of the command (tagged, if-twas specified) is logged using therlLogfunction. This is intended for short outputs, and therefore only the last 50 lines are logged this way. Longer outputs should be analysed separately, or uploaded viarlFileSubmitorrlBundleLogs.-cโ same as"-l", but only log the command output if it failed.-sโ store stdout and stderr to a file (mixed together, as the user would see it on a terminal) and set$rlRun_LOGvariable to the name of the file.$rlRun_LOGis now actually an array where the first index holds the last reference to the file. Thus its behavior is not changed if used without an index. The array is consumed by therlJournalEndfunction to remove the leftover files, so no manual file removal is needed anymore. Note that if you need to use such a file after calling therlJournalEndfunction you need to create your own copy of the respective file. When the-toption is used, the content of the file becomes tagged too.
If the -s option is not used, $rlRun_LOG is not modified and keeps its content from the last "rlRun -s".
commandโ command to run.statusโ expected exit code(s). Optional, default0. If you expect more exit codes, separate them with a comma (e.g."0,1"when both0and1are OK and expected), or use from-to notation (i.e."2-5"for"2,3,4,5"), or combine them (e.g."2-4,26"for"2,3,4,26").commentโ short summary describing the action (optional, but recommended โ explain what you are doing here).
Returns the exit code of the command run. Asserts PASS when the command's exit status is in the list of expected exit codes.
Note:
- The output of
rlRunis buffered when using"-t","-l"or"-s"option (they use unix pipes, which are buffered by nature). If you need an unbuffered output just make sure that"expect"package is installed on your system (its"unbuffer"tool will automatically be used to produce unbuffered output). - Be aware that there are some variables which can collide with your code executed within
rlRun. You should avoid using__INTERNAL_rlRun_*variables. ๐ซฃ - When any of
"-t""-l","-c", or"-s"option is used, special file descriptors111and112are used to avoid the issue with incomplete log file,bz1361246. As there might be an indefinite loop, there's a timeout of two minutes implemented as a fix forbz1416796. Also an error message is issued to signal the possibility of running a subprocess which keeps the file descriptors open.
Do not use these options if you expect process forking and continuous run. Try your own appropriate solution instead.
โ ๏ธ Warning: using the"unbuffer"tool is now disabled because of bug547686. Yeah. We don't talk about it. ๐
rlWatchdog
Run "command". If it does not finish in the specified time, then kill it using "signal". Note that the command is executed in a sub-shell so modified environment (e.g. set variables) is not reflected in the test environment. Important detail, bestie โ don't get caught out. ๐โ๐ฆบ
rlWatchdog command timeout [signal] [callback]
commandโ command to run.timeoutโ timeout to wait, in seconds.signalโ signal to use (optional, defaultKILL).callbackโ optional callback function called before the signal is sent. Default is none, bestie. It gets exactly one argument available: thePGIDof the process group. ๐
Returns 0 if the command ends normally, without needing to be killed. That's the return vibe, fr fr.
๐ฌ rlReport ๐ฌ
Report the test result to the test harness. The command used for reporting is set by the respective plugin. You can also use the $BEAKERLIB_COMMAND_REPORT_RESULT variable to use your custom command. โจ
rlReport name result [score] [log]
nameโ name of the test result.resultโ result, one ofPASS,WARN,FAIL,SKIP. If called with something else, it will useWARN.scoreโ test score (optional).logโ optional log file to be submitted instead of default"OUTPUTFILE".
๐ฆ rlCmpVersion ๐ฆ
Compare two given versions composed by numbers and letters divided by dot (.), underscore (_), or dash (-).
rlCmpVersion ver1 ver2
- If
ver1 = ver2, the sign'='is printed to stdout and0is returned. - If
ver1 > ver2, the sign'>'is printed to stdout and1is returned. - If
ver1 < ver2, the sign'<'is printed to stdout and2is returned.
๐ธ rlTestVersion ๐ธ
Test the relation between two given versions based on the given operator.
rlTestVersion ver1 op ver2
opโ operator defining the logical expression. It can be'=','==','!=','<','<=','=<','>','>=', or'=>'.
Returns 0 if the expression ver1 op ver2 is true; 1 if the expression is false; and 2 if something went wrong.
๐ฟ Release Info ๐ฟ
You can use the environment variable BEAKERLIB_OS_RELEASE for alternative os-release information. You can either supply a file path (recognised by starting with /) or directly as a list of environment variables. ๐ซถ
Example:
BEAKERLIB_OS_RELEASE="ID=rhel VERSION_ID=42" rlIsRHEL 42
๐ rlIsRHEL ๐
rlIsRHEL [VERSION_SPEC]...
VERSION_SPECโ argument specifies the version of the particular RHEL distribution, eg.8,8.4,">8.4".
For more details see description of rlIsOSVersion.
Returns 0 when we're running on RHEL. With the given version specification in arguments, returns 0 if the particular RHEL version is running.
Prototype:
rlIsRHEL
Returns 0 if we are running on RHEL.
rlIsRHEL 7 '>=8.5'
Returns 0 if we are running any RHEL 7 or RHEL 8.5 and higher.
๐ rlIsFedora ๐
rlIsFedora [VERSION_SPEC]...
VERSION_SPECโ argument specifies the version of the particular Fedora distribution, eg.30,">30".
For more details see description of rlIsOSVersion.
Returns 0 when we're running on Fedora. With the given version specification in arguments, returns 0 if the particular Fedora version is running.
Prototype:
rlIsFedora
Returns 0 if we are running on Fedora.
rlIsFedora 30 32
Returns 0 if we are running Fedora 30 or 32.
๐ง rlIsCentOS ๐ง
rlIsCentOS [VERSION_SPEC]...
VERSION_SPECโ argument specifies the version of the particular CentOS distribution, eg.7,">7".
For more details see description of rlIsOSVersion.
Returns 0 when we're running on CentOS. With the given version specification in arguments, returns 0 if the particular CentOS version is running.
Prototype:
rlIsCentOS
Returns 0 if we are running on CentOS.
rlIsCentOS 7.1 6
Returns 0 if we are running CentOS 7.1 or any CentOS 6.
โญ rlIsOS โญ
rlIsOS ID
IDโ argument is based on contents of/etc/os-release. Possible options ofIDare e.g.fedora,rhel,centos,ol.
Returns 0 when we're running on a system with the respective ID. Returns 1 when the parameter does not match with ID in os-release. Returns 2 when there is no ID defined. Returns 3 when no argument is given.
Prototype:
rlIsOS rhel
Returns 0 if we are running on RHEL.
๐ rlIsOSLike ๐
rlIsOSLike ID_LIKE
ID_LIKEโ argument is based on contents of/etc/os-release. Possible options ofID_LIKEare e.g.fedora,rhel.
Returns 0 when we're running on a system with the requested ID_LIKE. Returns 1 when the parameter does not match with ID nor ID_LIKE in os-release. Returns 2 when there is no ID or ID_LIKE defined. Returns 3 when no argument is given.
Prototype:
rlIsOSLike rhel
Returns 0 if we are running on RHEL, CentOS, Rocky Linux, etc..
rlIsOSLike fedora
Returns 0 if we are running on Fedora, RHEL, CentOS, Oracle Linux, etc..
๐ rlIsOSVersion ๐
rlIsOsVersion VERSION_SPEC...
VERSION_SPECโ parameter is based onVERSION_IDin/etc/os-release. It consists of either"major"or"major"."minor"referring to a particular release.
It accepts multiple arguments separated by space (8.1 8.2 8.3 9).
To specify a group of distributions, an optional operator can be passed in the argument together with the version number as one string ('>8.5'). Operator can be '<', '<=', '=<', '=', '>', '>=' matching whether the currently installed version is lesser, lesser or equal, equal, equal or greater, greater than the version number supplied as the second half of the argument.
โ ๏ธ Note that when using>/<operators you have to either put the argument in quotes or escape the operators to avoid them being interpreted as a bash redirection operator. No cap.
Returns 0 when we're running a distribution of the particular version requested by the argument.
It usually follows after rlIsOS and rlIsOSLike.
Be cautious when using together with rlIsOSLike, as different distributions may use different versioning schema.
Prototype:
rlIsOSVersion 6 7 9
Returns 0 if we are running a distribution with VERSION_ID 6, 7 or 9.
rlIsOSVersion 7.8 8
Returns 0 if we are running distribution 7.8 or any 8.
rlIsOSVersion ">=7.5" or rlIsOSVersion \>=7.5
Returns 0 if we are running distribution 7.5 or higher (both minors or majors).
Note:
rlIsOSVersion '<7.5' || rlIsOSVersion '<8.5'
would also cover 7.9 as it is less than 8.5, which is not what you want. So if you want to construct a condition for a distribution <7.5 within the major 7 or a distribution <8.5 within the major 8, you actually need to use the following construct:
rlIsOSVersion 7 && rlIsOSVersion '<7.5' || rlIsOSVersion 8 && rlIsOSVersion '<8.5'
This returns 0 when running distribution less than 7.5 and less then 8.5, but not 7.9 (nor 6.9).
๐ rlIsRHELLike ๐
rlIsRHELLike [VERSION_SPEC]...
VERSION_SPECโ argument specifies the version of the particular RHEL distribution, eg.8,8.4,">8.4".
For more details see description of rlIsOSVersion.
Returns 0 when we're running on a RHEL-like distribution. These are considered to be RHEL, CentOS, Rocky Linux, etc.. With the given version specification in arguments, returns 0 if the particular version of the RHEL-like distribution is running.
Prototype:
rlIsRHELLike
Returns 0 if we are running on a RHEL-like system.
rlIsRHELLike ">=6"
Returns 0 if we are running on a RHEL-like distribution of version 6.0 or higher.
๐ฆ Rpm Handling ๐ฆ
๐ฅ rlCheckRpm ๐ฅ
Check whether a package is installed.
rlCheckRpm name [version] [release] [arch]
nameโ package name like"kernel".versionโ package version like2.6.25.6.releaseโ package release like"55.fc9".archโ package architecture like"i386".
Returns 0 if the specified package is installed.
๐ rlAssertRpm ๐
Assertion making sure that a package is installed.
rlAssertRpm name [version] [release] [arch]>
rlAssertRpm --all
nameโ package name like"kernel".versionโ package version like2.6.25.6.releaseโ package release like"55.fc9".archโ package architecture like"i386".--allโ assert all packages listed in the$PACKAGES,$REQUIRES, and$COLLECTIONSenvironment variables.
Returns 0 and asserts PASS if the specified package is installed.
๐ฆ rlAssertNotRpm ๐ฆ
Assertion making sure that a package is not installed. This is just the inverse of rlAssertRpm.
rlAssertNotRpm name [version] [release] [arch]>
nameโ package name like"kernel".versionโ package version like2.6.25.6.releaseโ package release like"55.fc9".archโ package architecture like"i386".
Returns 0 and asserts PASS if the specified package is not installed.
๐ Example ๐
The function rlAssertRpm is useful especially in the prepare phase, where it causes an abort if a package is missing, while rlCheckRpm is handy when doing something like:
if ! rlCheckRpm package; then
yum install package
rlAssertRpm package
fi
๐ซง rlAssertBinaryOrigin ๐ซง
Assertion making sure that the given binary is owned by (one of) the given package(s).
rlAssertBinaryOrigin binary package [package2 [...]]
PACKAGES=... rlAssertBinaryOrigin binary
binaryโ binary name like"ksh"or"/bin/ksh".packageโ list of packages like"ksh mksh". The parameter is optional. If missing, contents of the environment variable$PACKAGESare taken into account.
Returns 0 and asserts PASS if the specified binary belongs to (one of) the given package(s). Returns 1 and asserts FAIL if the specified binary does not belong to (any of) the given package(s). Returns 2 and asserts FAIL if the specified binary is not found. Returns 3 and asserts FAIL if no packages are given. Returns 100 and asserts FAIL if invoked with no parameters.
๐บ Example ๐บ
The function rlAssertBinaryOrigin is useful especially in the prepare phase, where it causes an abort if a binary is missing or is owned by a different package:
PACKAGES=mksh rlAssertBinaryOrigin ksh
or
rlAssertBinaryOrigin ksh mksh
Returns true if ksh is owned by the mksh package (in this case: /bin/ksh is a symlink pointing to /bin/mksh).
๐งพ rlGetMakefileRequires ๐งพ
Prints a space-separated list of requirements defined in the Makefile using the 'Requires' attribute.
Return 0 if success.
๐ง rlGetYAMLdeps ๐ง
Prints a space-separated list of requirements defined in metadata.yaml using the 'require' and / or 'recommend' attribute.
Full fmf ids and library references are to be ignored.
rlGetYAMLdeps DEP_TYPE [array_var_name]
DEP_TYPEโ dependency type defined as a regexp. Expected values are'require','recommend', or'require|recommend'. The matching attribute values are then processed. Defaults to'require'.array_var_nameโ name of the variable to put the output to in a form of an array. This can hold also dependencies with a specific version. If used, the output to stdout is suppressed.
Return 0 if success.
๐งพ rlCheckRequirements
Okay so rlCheckRequirements is the vibe check for your requirements: it checks that every requirement you pass is covered either by an installed package, by a binary available in your PATHs, or by something a package provides.
rlRun "rlCheckRequirements REQ..."
REQโ the requirement to check. It can be a package name, a provides string, or a binary name. You can even write it the same way asRequirein a spec file, version spec included, e.g."bash >= 4.4". The comparison operator can be any of the ones supported byrlTestVersion()โ see its manual.
Returns the number of unsatisfied requirements.
โจ rlCheckMakefileRequires โจ
Checks whether the required packages / binaries defined in metadata.yaml (provided by tmt) or in the testโs Makefile are present.
It also checks recommended packages / binaries defined in metadata.yaml provided by tmt. Those do not participate in the return code โ theyโre just informative. Lowkey just there for the info, fr fr.
Example:
rlRun "rlCheckMakefileRequires"
Returns 255 if requirements could not be retrieved, 0 if all requirements are satisfied, or the number of unsatisfied requirements.
๐ rlGetRequired & rlGetRecommended ๐
These two pull a list of required or recommended packages / binaries defined in metadata.yaml provided by tmt or in a Makefile of the test.
rlGetRequired [ARRAY_VAR_NAME]
rlGetRecommended [ARRAY_VAR_NAME]
ARRAY_VAR_NAMEโ if provided, the variable is populated as an array with the respective dependencies. Otherwise the dependencies are printed out to theSTDOUT.
Returns 255 if requirements could not be retrieved, 0 otherwise.
๐ rlCheckRequired, rlCheckRecommended, & rlCheckDependencies ๐
These check the presence of required, recommended, or both packages / binaries defined in metadata.yaml provided by tmt or in a Makefile of the test.
Example:
rlRun "rlCheckRequired"
rlRun "rlCheckRecommended"
rlRun "rlCheckDependencies"
Returns 255 if requirements could not be retrieved, 0 if all requirements are satisfied, or the number of unsatisfied requirements.
๐ rlAssertRequired ๐
Ensures that all required packages provided in either metadata.yaml or Makefile are installed.
rlAssertRequired
Prints out a verbose list of installed/missing packages during operation.
Returns 0 if all required packages are installed, 1 if one or more packages are missing or if no Makefile is present.
๐ฅ Getting RPMs ๐ฅ
๐ Download methods ๐
Functions handling rpm downloading/installing can use more methods for the actual download of the rpm.
Currently there are two download methods available:
directโ use direct download from the build system (brew).yumโ useyumdownloaderordnf download.
The methods and their order are defined by the BEAKERLIB_RPM_DOWNLOAD_METHODS variable as a space-separated list. By default it is 'direct yum'. This can be overridden by the user. There may also be additions or changes done to the original value, e.g.:
BEAKERLIB_RPM_DOWNLOAD_METHODS='yum ${BEAKERLIB_RPM_DOWNLOAD_METHODS/yum/}'
Beakerlib is prepared for more Koji-based sources of packages while using the direct download method. By default packages are fetched from Koji, specifically from https://kojipkgs.fedoraproject.org/packages.
โจ rlRpmInstall โจ
Tries to install the specified package from local Red Hat sources.
rlRpmInstall [--quiet] package version release arch
--quietโ make the download and the install process be quiet.packageโ package name like"kernel".versionโ package version like2.6.25.6.releaseโ package release like"55.fc9".archโ package arch like"i386".
Returns 0 if the specified package was installed successfully.
๐ rlRpmDownload ๐
Tries to download the specified package.
rlRpmDownload [--quiet] {package version release arch|N-V-R.A}
rlRpmDownload [--quiet] --source {package version release|N-V-R}
--quietโ make the download process be quiet.packageโ package name like"kernel".versionโ package version like2.6.25.6.releaseโ package release like"55.fc9".archโ package arch like"i386".
Returns 0 if the specified package was downloaded successfully.
๐ฆ rlFetchSrcForInstalled ๐ฆ
Tries various ways to download the source rpm for the specified installed rpm.
rlFetchSrcForInstalled [--quiet] package
--quietโ make the download process be quiet.packageโ installed package name like"kernel". It accepts in-direct names. E.g. for the package name"krb5-libs"the function will download the"krb5"source rpm.
Returns 0 if the source package was successfully downloaded.
๐ง Mounting ๐ง
๐ rlMount ๐
Creates the mount point (if necessary) and mounts an NFS share.
rlMount [-o MOUNT_OPTS] server share mountpoint
serverโ NFS server hostname.shareโ shared directory name.mountpointโ local mount point.MOUNT_OPTSโ mount options.
Returns 0 if mounting the share was successful.
๐ rlCheckMount ๐
Checks if a directory is a mountpoint, if it is a mountpoint to a specific server, or if it is a mountpoint to a specific export on a specific server โ and whether it uses specific mount options.
rlCheckMount [-o MOUNT_OPTS] mountpoint
rlCheckMount [-o MOUNT_OPTS] server mountpoint
rlCheckMount [-o MOUNT_OPTS] server share mountpoint
mountpointโ local mount point.serverโ NFS server hostname.shareโ shared directory name.MOUNT_OPTSโ mount options to check (comma-separated list).
With one parameter, returns 0 when the specified directory exists and is a mountpoint. With two parameters, returns 0 when the specific directory exists, is a mountpoint, and an export from the specific server is mounted there. With three parameters, returns 0 if a specific shared directory is mounted on a given server on a given mountpoint.
If the -o option is provided, returns 0 if the mountpoint uses all the given options, 2 otherwise.
๐ rlAssertMount ๐
Assertion making sure that the given directory is a mount point, if it is a mountpoint to a specific server, or if it is a mountpoint to a specific export on a specific server โ and if it uses specific mount options.
rlAssertMount [-o MOUNT_OPTS] mountpoint
rlAssertMount [-o MOUNT_OPTS] server mountpoint
rlAssertMount [-o MOUNT_OPTS] server share mountpoint
mountpointโ local mount point.serverโ NFS server hostname.shareโ shared directory name.MOUNT_OPTSโ mount options to check (comma-separated list).
With one parameter, returns 0 when the specified directory exists and is a mountpoint. With two parameters, returns 0 when the specific directory exists, is a mountpoint, and an export from the specific server is mounted there. With three parameters, returns 0 if a specific shared directory is mounted on a given server on a given mountpoint. Asserts PASS when the condition is true.
If the -o option is provided, asserts PASS if the above conditions are met and the mountpoint uses all the given options.
๐ rlHash, rlUnhash ๐
Hashes/Unhashes the given string and prints the result to stdout.
rlHash [--decode] [--algorithm HASH_ALG] --stdin|STRING
rlUnhash [--algorithm HASH_ALG] --stdin|STRING
--decodeโ unhash the given string.--algorithmโ use the given hash algorithm. Currently supported algorithms:base64base64_โ this is standard base64 where=is replaced by_hex
Defaults to hex. The default algorithm can be overridden using the global variable rlHashAlgorithm.
--stdinโ get the string from stdin.STRINGโ string to be hashed/unhashed.
Returns 0 if success.
๐ Backup and Restore ๐
๐ฆ rlFileBackup ๐ฆ
Creates a backup of files or directories (recursive). Can be used multiple times to add more files to backup. Backing up an already backed up file overwrites the original backup.
rlFileBackup [--clean] [--namespace name] [--missing-ok|--no-missing-ok] file [file...]
You can use rlRun for asserting the result but keep in mind the meaning of exit codes, especially exit code 8, if using without the --clean option.
--cleanโ if this option is provided (it has to be the first option of the command), then the file/dir backed up using this command (provided in the next options) will be (recursively) removed before we restore it. This option implies--missing-ok, which can be overridden by--no-missing-ok.--namespace nameโ specifies the namespace to use. Namespaces can be used to separate backups and their restoration.--missing-okโ do not raise an error in case of a missing file to backup.--no-missing-okโ do raise an error in case of a missing file to backup. This is useful with--clean. This behaviour can be globally set by the global variableBEAKERLIB_FILEBACKUP_MISSING_OK=false.fileโ files and/or directories to be backed up.
Returns 0 if the backup was successful. Returns 1 if parsing of parameters was not successful. Returns 2 if no files specification was provided. Returns 3 if the BEAKERLIB_DIR variable is not set, e.g. rlJournalStart was not executed. Returns 4 if creating the main backup destination directories was not successful. Returns 5 if creating the file-specific backup destination directories was not successful. Returns 6 if the copy of backed up files was not successful. Returns 7 if attributes of backed up files were not successfully copied. Returns 8 if backed up files do not exist. This can be suppressed based on other options.
Example with --clean:
touch cleandir/aaa
rlRun "rlFileBackup --clean cleandir/"
touch cleandir/bbb
ls cleandir/
aaa bbb
rlRun "rlFileRestore"
ls cleandir/
aaa
๐ธ rlFileRestore ๐ธ
Restores backed up files to their original location. rlFileRestore does not remove new files appearing after the backup has been made. If you donโt want to leave anything behind, just remove the whole original tree before running rlFileRestore, or see the --clean option of rlFileBackup.
rlFileRestore [--namespace name]
You can use rlRun for asserting the result.
--namespace nameโ specifies the namespace to use. Namespaces can be used to separate backups and their restoration.
Returns 0 if the backup dir is found and files are restored successfully.
Return code bits meaning:
XXXXX
|||||
||||\_ error parsing parameters
|||\__ could not find backup directory
||\___ files cleanup failed
|\____ files restore failed
\_____ no files were restored nor cleaned
๐ ๏ธ Services ๐ ๏ธ
Okay so these routines are the comfy way to start and stop system services, and the whole point is that you can put them back exactly how they were after your testing is done. Restore-and-chill, basically. ๐
rlServiceStart
Makes sure the service you named is running with fresh config โ like, it starts it if it's stopped and restarts it if it's already running. And here's the cute part: the first time you call it, it saves the current state, so the service can be put back to its original state when your testing wraps up. See rlServiceRestore. โจ
rlServiceStart service [service...]
- service โ name of the service(s) to start.
Returns the number of services that failed to start/restart, so zero means everything is OK. Zero = slay. ๐
rlServiceStop
Makes sure the service is stopped. Stop it if it's running, do literally nothing if it's already stopped. Same vibe as above: the first call saves the current state so it can be restored later via rlServiceRestore. ๐ฆ
rlServiceStop service [service...]
- service โ name of the service(s) to stop.
Returns the number of services that failed to become stopped; zero when everything is OK. ๐
rlServiceRestore
Puts the service back into its original state โ meaning the state it was in before the first rlServiceStart or rlServiceStop call. Fun detail: if rlServiceStart was called on a service that was already running, then rlServiceRestore will restart the service when it's restoring that state. ๐ญ
rlServiceRestore [service...]
- service โ name of the service(s) to restore to original state. If you pass no service name at all, all services get restored in reverse order.
Returns the number of services that failed to get back to their original state; zero when everything is OK. ๐ซถ
rlServiceStatus
Prints the status of the SERVICE you gave it โ specifically the output of service SERVICE status or systemctl status SERVICE. ๐
rlServiceStatus SERVICE [SERVICE...]
- SERVICE โ the service to get the status of.
Returns the service status return code of the last SERVICE you provided. ๐
rlServiceEnable
Enables the selected services if they need it, or does nothing at all if they're already enabled. And yup โ first call saves the current state so it can be restored later, see rlServiceRestore. ๐ธ
rlServiceEnable service [service...]
- service โ name of the service(s) to enable.
Returns the number of services that failed enablement; zero when everything is OK. โญ
rlServiceDisable
Disables the selected services if needed, or does nothing if they're already disabled. First call saves the current state for later restore, see rlServiceRestore. ๐ง
rlServiceDisable service [service...]
- service โ name of the service(s) to disable.
Returns the number of services that failed disablement; zero when everything is OK. ๐
๐ Sockets ๐
Same comfy deal, but for system sockets โ start/stop them, then put them back the way they were after testing. No cap, it's the exact same energy. โจ
rlSocketStart
Makes sure the socket is running. Starts it if it's stopped, leaves it alone if it's already running. First call saves the current state so it can be restored later, see rlSocketRestore. ๐ซ
rlSocketStart socket [socket...]
- socket โ name of the socket(s) to start.
Returns the number of sockets that failed to start/restart; zero when everything is OK. ๐ฅ
rlSocketStop
Makes sure the socket is stopped. Stops it if it's running, does nothing if it's already stopped. First call saves the current state for later restore, see rlSocketRestore. ๐
rlSocketStop socket [socket...]
- socket โ name of the socket(s) to stop.
Returns the number of sockets that failed to become stopped; zero when everything is OK. ๐
rlSocketRestore
Restores the given socket into its original state โ the state it was in before the first rlSocketStart or rlSocketStop call. ๐ฆ
Warning !!! The Xinetd process is NOT restored โ even though it might have been used. It's recommended to call rlServiceRestore xinetd as well. Like, actually do it, bestie. ๐ญ
rlSocketRestore socket [socket...]
- socket โ name of the socket(s) to restore to original state.
Returns the number of sockets that failed to get back to their original state; zero when everything is OK. ๐ซถ
๐งน Cleanup management ๐งน
Okay so cleanup management works with a so-called cleanup buffer, which is a temporary representation of what should be run at cleanup time, plus a final cleanup script (executable) that gets generated from that buffer and wraps it using BeakerLib essentials (journal initialization, cleanup phase, and so on...). The cleanup script must always be updated on an atomic basis (filesystem-wise) so that a third party โ ie. the test watcher โ can execute it asynchronously. โก
Using the test watcher is mandatory for the cleanup management system to work properly, because the test watcher is the thing that actually executes the cleanup script. There is a limited, catastrophe-avoiding mechanism in place even when the test isn't run in the test watcher, but treat that as a backup and avoid that situation whenever you possibly can. ๐
The cleanup script shares all environment โ variables, exported or not, and functions โ with the test itself. The cleanup append/prepend functions sample or snapshot the environment at the moment of their call, IOW any changes to the test environment are synchronized to the cleanup script only upon calling append/prepend. And when the append/prepend functions are called inside a function that has local variables, those will show up as global in the cleanup. ๐
The cleanup script does receive $PWD from the test, but its working dir is set to the initial test execution dir even if $PWD contains something else. Also, you can't reliably use relative paths inside cleanup โ certain parts of the cleanup might have been added under different current directories (CWDs). So always use absolute paths in append/prepend cleanup, or make sure you never cd anywhere else (ie. to a TmpDir). ๐
rlCleanupAppend
Appends a string to the cleanup buffer and recreates the cleanup script. ๐
rlCleanupAppend string
Returns 0 if the operation was successful, 1 otherwise. โญ
rlCleanupPrepend
Prepends a string to the cleanup buffer and recreates the cleanup script. ๐
rlCleanupPrepend string
Returns 0 if the operation was successful, 1 otherwise. โญ
โฑ๏ธ Time Performance โฑ๏ธ
rlPerfTime_RunsInTime
Measures how many runs of some commands can be done in a specified amount of time. This approach is suitable for short-time running tasks (up to a few seconds), where averaging a few runs isn't precise. It does the thing several times and the final result is the average of all runs. It prints the number on stdout, so you gotta capture it. ๐ฅ
rlPerfTime_RunsInTime command [time] [runs]
- command โ command to run.
- time โ time in seconds (optional, default=
30). - runs โ number of averaged runs (optional, default=
3).
rlPerfTime_AvgFromRuns
Measures the average time of running some task. This approach is suitable for long-time running tasks (tens of seconds and more), where it's precise enough. The measured runs can be preceded by a dry run which is not measured โ its whole purpose is to warm up various caches. It prints the number on stdout, so it has to be captured. Or, the result is then stored in the special rl_retval variable. ๐
rlPerfTime_AvgFromRuns command [count] [warmup]
- command โ command to run.
- count โ times to run (optional, default=
3). - warmup โ warm-up run, run if this option is not
"warmup"(optional, default="warmup").
๐ Analyze ๐
rlDejaSum
TODO description ๐ญ (yes bestie, the manpage literally says that, I'm not making it up)
rlDejaSum par1 par2
- par1 โ TODO description
- par2 โ TODO description
Return 0 if... TODO
rlImport
Imports code provided by one or more libraries into the test namespace. The library search mechanism is based on the Beaker test hierarchy system, i.e.: ๐๏ธ
/component/type/test-name/test-file
When test-file calls rlImport with 'foo/bar' as the parameter, the libraries are searched in the following locations โ these are the possible path prefixes: ๐
- colon-separated paths from
$BEAKERLIB_LIBRARY_PATH /mnt/tests/usr/share/beakerlib-libraries
The next component of the path is one of the following: ๐
/foo/Library/bar/foo/bar/libs/foo/bar/*/foo/Library/bar/*/foo/bar/libs/*/foo/Library/bar/libs/*/foo/bar
The directory path is then constructed as prefix/path/lib.sh. If the library is still not found, an upwards directory traversal is used, and a check for the presence of the library in the above-mentioned possible paths gets performed. Which means: this function needs to be called from the test hierarchy, not from, like, the /tmp directory. ๐
Once the library is found, it's sourced and a verifier function is called. The verifier function is constructed by composing the library prefix and LibraryLoaded. The library prefix must be defined in the library itself โ it should be part of the lib.sh header in this format: '# library-prefix = <PREFIX>'. If the verifier passes, the library is ready to use. Also, the variable <PREFIX>LibraryDir is created and it points to the library folder. ๐
Usage:
rlImport --all
rlImport LIBRARY [LIBRARY2...]
--allโ read$BEAKERLIB_DIR/metadata.yamlor./Makefile, pick up the library requirements and import them all. ๐ฆ- LIBRARY โ must have
'[component/]path'or'.'format. Identifies the library to import. The dot (.) is a special case where thelib.shfrom the current directory is used. ๐
Returns 0 if the import of all libraries was successful. Returns non-zero if one or more libraries failed to import. ๐
๐งต Process Synchronisation ๐งต
rlWaitForCmd
Pauses script execution until the command exit status is the expected value. It logs a WARNING and returns 1 if the command didn't exit successfully before the timeout elapsed, or if a maximum number of invocations has been reached. โณ
rlWaitForCmd command [-p PID] [-t time] [-m count] [-d delay] [-r retval]
- command โ command that will be executed until its return code is equal to
0or the value specified as option to-r. -t timeโ timeout, in seconds, default120. If the command doesn't return0before the clock runs out, the command gets killed. no survivors ๐-p PIDโ the PID of a process that should also be running. If that process bails before the command exits with the expected exit code, the return code gets set to1.-m countโ max number ofcommandexecutions before it just continues anyway. Default is infinite (as in, no cap, go off forever). Returns1if the maximum was actually reached.-d delayโ delay betweencommandinvocations. Default1.-r retvalโ the expected return value of the command. Default0.
๐ค rlWaitForFile
Pauses script execution until the specified file or directory starts existing. Returns 0 if the file started existing, 1 if the timeout was reached or the PID exited. Return code is greater than 1 in case of error.
rlWaitForFile path [-p PID] [-t time] [-d delay]
- path โ path to the file that should start existing.
-t timeโ timeout in seconds (optional, default120). If the file isn't opened before the time elapses, the command returns1.-p PIDโ PID of the process that should also be running. If the process exits before the file is created, the command returns with status code1.-d delayโ delay between subsequent checks for existence of the file. Default1.
๐ rlWaitForSocket
Pauses script execution until a local socket starts listening. Returns 0 if the socket started listening, 1 if the timeout was reached or the PID exited. Return code is greater than 1 in case of error.
rlWaitForSocket {port|path} [-p PID] [-t time] [-d delay] [--close] [--remote]
- port|path โ network port to wait for opening, or a path to a UNIX socket. Regular expressions are supported too, bestie โจ
-t timeโ timeout in seconds (optional, default120). If the socket isn't opened before the time elapses, the command returns1.-p PIDโ PID of the process that should also be running. If the process exits before the socket is opened, the command returns with status code1.-d delayโ delay between subsequent checks for availability of the socket. Default1.--closeโ wait for the socket to stop listening. flip the script ๐ฆ--remoteโ wait for the remote socket to start listening instead of the local one.
โณ rlWait
Wrapper around the bash builtin wait command. See bash_builtins(1) man page. Kills the process and all its children if the timeout elapses.
rlWait [n ...] [-s SIGNAL] [-t time]
- n โ list of PIDs to wait for. They need to be background tasks of the current shell. See the
bash_builtins(1)section for thewaitcommand. -t timeโ timeout in seconds (optional, default30). If the wait isn't successful before the time elapses, then all specified tasks are killed.-s SIGNALโ signal used to kill the process, optional,SIGTERMby default.
๐ฅ๏ธ Virtual X Server
Functions providing a simple way how to start and stop a virtual X server. so cozy, so convenient ๐
rlVirtualXStart
Start a virtual X server on the first free display. Only tries the first N displays, so yeah โ you can run out of them ๐ญ
rlVirtualXStart name [N]
- name โ string identifying the X server.
- N โ maximum number of displays to try. Defaults to
3.
Returns 0 when the server is started successfully.
rlVirtualXGetDisplay
Get the DISPLAY variable for the specified virtual X server.
rlVirtualXGetDisplay name
- name โ string identifying the X server.
Displays the number of the display where the specified virtual X server is running to standard output. Returns 0 on success.
rlVirtualXStop
Kill the specified X server. bye bestie ๐
rlVirtualXStop name
- name โ string identifying the X server.
Returns 0 when the server is stopped successfully.
๐ธ Example
Below is a simple example of usage. Note that a lot of useful debugging information is reported on the DEBUG level, so you can run your test with DEBUG=1 make run to get them.
rlVirtualXStart $TEST
rlAssert0 "Virtual X server started" $?
export DISPLAY="$( rlVirtualXGetDisplay $TEST )"
# ...your test which needs X...
rlVirtualXStop $TEST
rlAssert0 "Virtual X server killed" $?
These are Requires lines for your scripts โ note the different package names for different RHEL versions:
@echo "Requires: xorg-x11-server-Xvfb" >> $(METADATA) # RHEL-5
@echo "Requires: xorg-x11-Xvfb" >> $(METADATA) # RHEL-4
@echo "Requires: XFree86-Xvfb" >> $(METADATA) # RHEL-3
๐ง rlYash_parse
Parse yaml data to an associative array. very demure, very mindful ๐
rlYash_parse VAR_NAME YAML_DATA
- VAR_NAME โ name of the variable to which the yaml structure will be saved. Note that the variable needs to be predeclared as an associative array. (predeclare it or it's not gonna work, iykyk)
- YAML_DATA โ the actual yaml data.
๐ฅ Beakerlib Profiling
Enable profiling
Set the environment variable BEAKERLIB_PROFILING=1
BEAKERLIB_PROFILING=1 make run
A file /dev/shm/beakerlib_profile will be created for later processing.
Process the profile
/usr/share/beakerlib/profiling.sh process > profile.csv
๐ OUTPUT FILES ๐
Location of test results related output files can be configured by setting the BEAKERLIB_DIR variable before running the test. If it's not set, a temporary directory is created. set it, bestie, it's giving organized ๐
๐ journal.txt
Journal in human readable form. iconic, readable, we love her.
๐ journal.xml
Journal in XML format โ requires python. This dependency can be avoided if the test is run with the variable BEAKERLIB_JOURNAL set to 0, in which case journal.xml is not created.
๐ฆ XSLT
The XML journal can be transformed through an XSLT template. Which template is used is configurable by setting the BEAKERLIB_JOURNAL variable. The value can be either a filename โ in which case beakerlib will try to use $INSTALL_DIR/xslt-template/$filename (e.g.: /usr/share/beakerlib/xstl-templates/xunit.xsl) โ or it can be a path to a template anywhere on the system.
๐ TestResults
Overall results of the test in a sourceable form. Each line contains a pair VAR=VALUE. All variable names have the TESTRESULT_ prefix.
List of variables:
TESTRESULT_STATEโ current state of the test run; possible values:started,incompleteandcomplete.startedis set after a Journal is opened.incompleteis set after a Phase is closed.completeis set after a Journal is closed.
TESTRESULT_RESULT_STRINGโ result of the test in a string, e.g.:PASS,FAIL,WARN.TESTRESULT_RESULT_ECODEโ result of the test as an integer,0equals toPASS.TESTRESULT_PHASES_PASSEDโ number of phases that ended withPASS.TESTRESULT_PHASES_FAILEDโ number of phases that ended with a non-PASSresult.TESTRESULT_PHASES_SKIPPEDโ number of skipped phases.TESTRESULT_ASSERTS_FAILEDโ number of asserts that ended with a non-PASSresult in the whole test.TESTRESULT_STARTTIMEโ time when the test started in seconds since epoch.TESTRESULT_ENDTIMEโ time when the test ended in seconds since epoch.TESTRESULT_DURATIONโ duration of the test run in seconds.TESTRESULT_BEAKERLIB_DIRโ directory with test results files.TESTRESULT_PHASES_FINGERPRINTโ a hash of all phases results which may serve as a reference result in a specific environment.TESTRESULT_ASSERTS_FINGERPRINTโ a hash of all asserts results which may serve as a reference result in a specific environment.
๐ธ EXAMPLES ๐ธ
โจ Simple
Okay bestie, here's the most minimal BeakerLib test that's still a whole entire vibe:
. /usr/share/beakerlib/beakerlib.sh
rlJournalStart
rlPhaseStartTest
rlAssertRpm "setup"
rlAssertExists "/etc/passwd"
rlAssertGrep "root" "/etc/passwd"
rlPhaseEnd
rlJournalEnd
Like, that's it. That's the whole test. Iconic behavior honestly ๐
๐ Phases
Now THIS one's a little more interesting โ a test that sets all the recommended variables and actually uses the phases like a good little main character:
# Include the BeakerLib environment
. /usr/share/beakerlib/beakerlib.sh
# Set the full test name
TEST="/examples/beakerlib/Sanity/phases"
# Package being tested
PACKAGE="coreutils"
rlJournalStart
# Setup phase: Prepare test directory
rlPhaseStartSetup
rlAssertRpm $PACKAGE
rlRun 'TmpDir=$(mktemp -d)' 0 'Creating tmp directory' # no-reboot
rlRun "pushd $TmpDir"
rlPhaseEnd
# Test phase: Testing touch, ls and rm commands
rlPhaseStartTest
rlRun "touch foo" 0 "Creating the foo test file"
rlAssertExists "foo"
rlRun "ls -l foo" 0 "Listing the foo test file"
rlRun "rm foo" 0 "Removing the foo test file"
rlAssertNotExists "foo"
rlRun "ls -l foo" 2 "Listing foo should now report an error"
rlPhaseEnd
# Cleanup phase: Remove test directory
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalEnd
# Print the test report
rlJournalPrintText
And the output of the rlJournalPrintText command? It would produce something similar to this (yes, all of it, we're reading the whole menu):
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: TEST PROTOCOL
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Package : coreutils
Installed : coreutils-8.27-19.fc27.x86_64
beakerlib RPM : beakerlib-1.17-6.fc27.noarch
Test started : 2018-02-08 15:43:03 CET
Test finished : 2018-02-08 15:43:04 CET
Test duration : 1 seconds
Test name : /examples/beakerlib/Sanity/phases
Distro : Fedora release 27 (Twenty Seven)
Hostname : localhost
Architecture : x86_64
CPUs : 4 x Intel Core Processor (Skylake)
RAM size : 1992 MB
HDD size : 17.55 GB
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Test description
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
PURPOSE of /examples/beakerlib/Sanity/phases
Description: Testing BeakerLib phases
Author: Petr Splichal <psplicha@redhat.com>
This example shows how the phases work in the BeakerLib on a
trivial smoke test for the "touch", "ls" and "rm" commands from
the coreutils package.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Setup
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ 15:43:03 ] :: [ PASS ] :: Checking for the presence of coreutils rpm
:: [ 15:43:03 ] :: [ LOG ] :: Package versions:
:: [ 15:43:03 ] :: [ LOG ] :: coreutils-8.27-19.fc27.x86_64
:: [ 15:43:03 ] :: [ PASS ] :: Creating tmp directory (Expected 0, got 0)
:: [ 15:43:03 ] :: [ PASS ] :: Command 'pushd /tmp/tmp.MMQf7dj9QV' (Expected 0, got 0)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Duration: 1s
:: Assertions: 3 good, 0 bad
:: RESULT: PASS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Test
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ 15:43:04 ] :: [ PASS ] :: Creating the foo test file (Expected 0, got 0)
:: [ 15:43:04 ] :: [ PASS ] :: File foo should exist
:: [ 15:43:04 ] :: [ PASS ] :: Listing the foo test file (Expected 0, got 0)
:: [ 15:43:04 ] :: [ PASS ] :: Removing the foo test file (Expected 0, got 0)
:: [ 15:43:04 ] :: [ PASS ] :: File foo should not exist
:: [ 15:43:04 ] :: [ PASS ] :: Listing foo should now report an error (Expected 2, got 2)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Duration: 0s
:: Assertions: 6 good, 0 bad
:: RESULT: PASS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Cleanup
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ 15:43:04 ] :: [ PASS ] :: Command 'popd' (Expected 0, got 0)
:: [ 15:43:04 ] :: [ PASS ] :: Removing tmp directory (Expected 0, got 0)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Duration: 0s
:: Assertions: 2 good, 0 bad
:: RESULT: PASS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: /examples/beakerlib/Sanity/phases
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: [ 15:43:04 ] :: [ LOG ] :: Phases fingerprint: ZmU1NmJ
:: [ 15:43:04 ] :: [ LOG ] :: Asserts fingerprint: YTBiZDE
:: [ 15:43:04 ] :: [ LOG ] :: JOURNAL XML: /var/tmp/beakerlib-pRiJfWE/journal.xml
:: [ 15:43:04 ] :: [ LOG ] :: JOURNAL TXT: /var/tmp/beakerlib-pRiJfWE/journal.txt
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Duration: 1s
:: Phases: 3 good, 0 bad
:: OVERALL RESULT: PASS
Heads up bestie: that detailed test description is read from a separate file called PURPOSE, placed in the same directory as the test itself. Don't come for me, that's just how it works ๐
A lot of useful debugging info gets reported on the DEBUG level โ you can run your test with DEBUG=1 make run to get all of it.
Verbosity of the test logging can also be changed by setting the LOG_LEVEL variable. Possible values are "ERROR", "WARNING", "INFO" and "DEBUG". You'll see messages like the ones below ๐ซถ
:: [ WARNING ] :: rlGetArch: Update test to use rlGetPrimaryArch/rlGetSecondaryArch
:: [ DEBUG ] :: rlGetArch: This is architecture 'x86_64'
:: [ ERROR ] :: this function was dropped as its development is completely moved to the beaker library
:: [ INFO ] :: if you realy on this function and you really need to have it present in core beakerlib, file a RFE, please
Setting LOG_LEVEL="DEBUG" is equivalent to DEBUG=1. Same vibe, different outfit โจ
Set DEBUG_TO_CONSOLE_ONLY=1 in conjuction with DEBUG=1 to avoid storing debug messages in the journal. This also speeds up the execution in debug mode, since those messages are not fully processed than. (Faster test, fewer notes in the diary, yk?)
๐ง BKRDOC ๐ง
Description
Bkrdoc is a documentation generator, and it works off tests written using the BeakerLib library. This generator makes documentation from test code with and also without any documentation markup. Versatile queen ๐
What it's good for
For fast, brief and reliable documentation creation. It`s good for a quick start with an unknown BeakerLib test. The created documentation provides information about the documentation credibility. Also, the created documentation shows environmental variables and helps the reader run the test script from which the documentation was created. Literally everything you need to not be lost ๐ฆ
Bkrdoc project page
https://github.com/rh-lab-q/bkrdoc
๐ LINKS ๐
Project Page
https://github.com/beakerlib/beakerlib
Manual
https://github.com/beakerlib/beakerlib/wiki/man
Issues list
https://github.com/beakerlib/beakerlib/issues
Reporting issues
https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=beakerlib
https://github.com/beakerlib/beakerlib/issues/new
๐ AUTHORS ๐
The actual legends who built this:
- Petr Muller
<pmuller@redhat.com> - Ondrej Hudlicky
<ohudlick@redhat.com> - Jan Hutar
<jhutar@redhat.com> - Petr Splichal
<psplicha@redhat.com> - Ales Zelinka
<azelinka@redhat.com> - Dalibor Pospisil
<dapospis@redhat.com> - Martin Kyral
<mkyral@redhat.com> - Jakub Prokes
<jprokes@redhat.com> - Jakub Heger
<jheger@redhat.com>
And that's a wrap on the whole page, bestie!! ๐ This edition was served up by perl v5.32.1, dated 2026-04-07, and it's the BEAKERLIB(1) page โ go forth and write slay little tests ๐
โจ
๐ฆ where this page comes from
- epel 9: beakerlib 1.33.3-1.el9 ยท GPL-2.0-only
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms