Table of contents
Writing Unit tests for plugins
Risu uses unit testing for the main python wrappers (risu.py
and magui.py
), but tests are mostly written in bash
so no UT is performed.
As a workaround and to detect issues in your code you can:
- Test the code as part of functional testing (like we do for each test we develop)
- Consider creating unit tests for it
Creating the tests
Tests require two things:
- Script that setups a fake folder with relevant contents to either
pass
,skipped
orfail
a test - The actual
unittest
thattox
executes viapy.test
For example, for bugzilla_httpd_bug_1406417
we create:
tests/plugins-unit-tests/setup/bugzilla/httpd_bug_1406417.sh
tests/plugins-unit-tests/test_bugzilla_httpd_bug_1406417.py
First file (in the setup/
folder) does the proper setup of the fake root:
# The way we're executed, $1 is the script name, $2 is the mode and $3 is the folder
FOLDER=$3
case $2 in
pass)
# Create required files for test to pass
mkdir -p $FOLDER
# Touch the systemctl command we check
mkdir -p "$FOLDER/var/log/httpd/"
echo "" > "$FOLDER/var/log/httpd/error_log"
;;
fail)
# Create required files for test to fail
mkdir -p $FOLDER
# Touch the systemctl command we check
mkdir -p "$FOLDER/var/log/httpd/"
echo "MaxRequestWorkers" > "$FOLDER/var/log/httpd/error_log"
;;
skip)
# Do nothing, the folder will be empty and test should be skipped
;;
esac
You'll need to adapt above code or use it as template for creating your own setup
script.
Once done, the actual unittest
should be checked, for example (note that test is named test\_\$PLUGINNAME
):
import os
import subprocess
from unittest import TestCase
import tempfile
import shutil
from risu import risu
# To create your own test, update NAME with plugin name and copy this file to test_$NAME.py
NAME = "httpd_bug_1406417"
testplugins = os.path.join(risu.risudir, "plugins", "test")
plugins = os.path.join(risu.risudir, "plugins")
folder = os.path.join(os.path.abspath(os.path.dirname(__file__)), "setup")
uttest = risu.findplugins(folders=[folder], include=[NAME])[0]
us = os.path.basename(uttest)
citplugs = risu.findplugins(folders=[plugins], include=[us])
# Setup commands and expected return codes
rcs = {
"pass": risu.RC_OKAY,
"fail": risu.RC_FAILED,
"skipped": risu.RC_SKIPPED,
"info": risu.RC_INFO,
}
def runtest(testtype="False"):
# testtype will be 'pass', 'fail', 'skipped'
# We're iterating against the different UT tests defined in UT-tests folder
tmpdir = tempfile.mkdtemp(prefix="risu-tmp")
# Setup test for 'testtype'
subprocess.call([uttest, uttest, testtype, tmpdir])
# Run test against it
res = risu.dorisu(path=tmpdir, plugins=citplugs)
# Get Return code
rc = res[0]["result"]["rc"]
# Remove tmp folder
shutil.rmtree(tmpdir)
# Check if it passed
return rc
class RisuTest(TestCase):
def test_pass(self):
# testtype will be 'pass', 'fail', 'skipped'
testtype = "pass"
assert runtest(testtype="fail") == rcs[testtype]
def test_fail(self):
# testtype will be 'pass', 'fail', 'skipped'
testtype = "fail"
assert runtest(testtype=testtype) == rcs[testtype]
def test_skip(self):
# testtype will be 'pass', 'fail', 'skipped'
testtype = "skipped"
assert runtest(testtype=testtype) == rcs[testtype]
Briefing
For a new plugin and test you'll then require:
risu/risuclient/plugins/core/path-to-your-plugin/$NAME.sh
tests/plugins-unit-tests/setup/bugzilla/$NAME.sh
tests/plugins-unit-tests/test_$NAME.py
You'll still have to code your plugin and the setup, and for the test, copy one of the provided test\_.py
like test_pacemaker_stonith_enabled.py
and edit the 'NAME' variable inside the python file to match your plugin.
tox
should now pick it up and report status.
Let us know if you face any issue while creating them.