Launch dbus session for docker unit tests
Fix for openbmc/openbmc#1137
Change-Id: I9e8a41820c6b85bff3625af4ab7b488a66b39c65
Signed-off-by: Leonel Gonzalez <lgonzalez@us.ibm.com>
diff --git a/build-unit-test-docker.sh b/build-unit-test-docker.sh
index cc1d887..61b5430 100755
--- a/build-unit-test-docker.sh
+++ b/build-unit-test-docker.sh
@@ -63,7 +63,8 @@
libssl-dev \
sudo \
wget \
- git
+ git \
+ dbus
RUN easy_install pip
RUN pip install inflection
diff --git a/run-unit-test-docker.sh b/run-unit-test-docker.sh
index 7ebb0a9..283017b 100755
--- a/run-unit-test-docker.sh
+++ b/run-unit-test-docker.sh
@@ -4,6 +4,7 @@
#
# It uses a few variables which are part of Jenkins build job matrix:
# distro = fedora|ubuntu|ubuntu:14.04|ubuntu:16.04
+# dbus_sys_config_file = <path of the dbus config file>
# WORKSPACE = <location of unit test execution script>
# Trace bash processing. Set -e so when a step fails, we fail the build
@@ -16,6 +17,8 @@
OBMC_BUILD_SCRIPTS="openbmc-build-scripts"
UNIT_TEST_PY_DIR="scripts"
UNIT_TEST_PY="unit-test.py"
+DBUS_UNIT_TEST_PY="dbus-unit-test.py"
+DBUS_SYS_CONFIG_FILE=${dbus_sys_config_file:-"/usr/share/dbus-1/system.conf"}
# Timestamp for job
echo "Unit test build started, $(date)"
@@ -47,17 +50,27 @@
${WORKSPACE}/${UNIT_TEST_PY}
chmod a+x ${WORKSPACE}/${UNIT_TEST_PY}
+# Copy dbus unit test script into workspace
+cp ${WORKSPACE}/${OBMC_BUILD_SCRIPTS}/${UNIT_TEST_PY_DIR}/${DBUS_UNIT_TEST_PY} \
+${WORKSPACE}/${DBUS_UNIT_TEST_PY}
+chmod a+x ${WORKSPACE}/${DBUS_UNIT_TEST_PY}
+
# Configure docker build
cd ${WORKSPACE}/${OBMC_BUILD_SCRIPTS}
echo "Building docker image with build-unit-test-docker.sh"
./build-unit-test-docker.sh ${DOCKER_IMG_NAME} ${DISTRO}
+# Unit test and parameters
+UNIT_TEST="${WORKSPACE}/${UNIT_TEST_PY},-w,${WORKSPACE},-p,${UNIT_TEST_PKG},-v"
+
# Run the docker unit test container with the unit test execution script
echo "Executing docker image"
docker run --cap-add=sys_admin --rm=true \
+ --privileged=true \
-w "${WORKSPACE}" -v "${WORKSPACE}":"${WORKSPACE}" \
-t ${DOCKER_IMG_NAME} \
- ${WORKSPACE}/${UNIT_TEST_PY} -w ${WORKSPACE} -p ${UNIT_TEST_PKG} -v
+ ${WORKSPACE}/${DBUS_UNIT_TEST_PY} -u ${UNIT_TEST} \
+ -f ${DBUS_SYS_CONFIG_FILE}
# Timestamp for build
echo "Unit test build completed, $(date)"
diff --git a/scripts/dbus-unit-test.py b/scripts/dbus-unit-test.py
new file mode 100755
index 0000000..a6ccb72
--- /dev/null
+++ b/scripts/dbus-unit-test.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+"""
+This script launches a dbus session, sets the DBUS_SESSION_BUS_ADDRESS
+and DBUS_STARTER_BUS_TYPE Eenvironment variables and puts the generated files
+in the dbus dir location passed as a paramter. It then runs the unit test
+script, and then cleans up the generated dbus files.
+"""
+
+from subprocess import check_call, check_output
+import os
+import sys
+import argparse
+import re
+import tempfile
+
+def launch_session_dbus(dbus_dir, dbus_config_file):
+ """
+ Launches a session debus using a modified config file and
+ sets the DBUS_SESSION_BUS_ADDRESS environment variable
+
+ Parameter descriptions:
+ dbus_dir Directory location for generated files
+ dbus_config_file File location of dbus sys config file
+ """
+ dbus_pid = os.path.join(dbus_dir,'pid')
+ dbus_socket = os.path.join(dbus_dir,'system_bus_socket')
+ dbus_local_conf = os.path.join(dbus_dir,'system-local.conf')
+ if os.path.isfile(dbus_pid):
+ os.remove(dbus_pid)
+ with open(dbus_config_file) as infile, \
+ open(dbus_local_conf, 'w') as outfile:
+ for line in infile:
+ line = re.sub('<type>.*</type>','<type>session</type>', \
+ line, flags=re.DOTALL)
+ line = re.sub('<pidfile>.*</pidfile>', \
+ '<pidfile>%s</pidfile>' % dbus_pid, \
+ line, flags=re.DOTALL)
+ line = re.sub('<listen>.*</listen>', \
+ '<listen>unix:path=%s</listen>' % dbus_socket, \
+ line, flags=re.DOTALL)
+ line = re.sub('<deny','<allow', line)
+ outfile.write(line)
+ infile.close()
+ outfile.close()
+ command = ['dbus-daemon', '--config-file=%s' % dbus_local_conf, \
+ '--print-address']
+ out = check_output(command).splitlines()
+ os.environ['DBUS_SESSION_BUS_ADDRESS'] = out[0]
+ os.environ['DBUS_STARTER_BUS_TYPE'] = 'session'
+
+def dbus_cleanup(dbus_dir):
+ """
+ Kills the dbus session started by launch_session_dbus
+ and removes the generated files.
+
+ Parameter descriptions:
+ dbus_dir Directory location of generated files
+ """
+
+ dbus_pid = os.path.join(dbus_dir,'pid')
+ dbus_socket = os.path.join(dbus_dir,'system_bus_socket')
+ dbus_local_conf = os.path.join(dbus_dir,'system-local.conf')
+ if os.path.isfile(dbus_pid):
+ dbus_pid = open(dbus_pid,'r').read().replace('\n','')
+ check_call(['kill', dbus_pid])
+ if os.path.isfile(dbus_local_conf):
+ os.remove(dbus_local_conf)
+ if os.path.exists(dbus_socket):
+ os.remove(dbus_socket)
+
+
+if __name__ == '__main__':
+
+ # Set command line arguments
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument("-f", "--dbussysconfigfile",
+ dest="DBUS_SYS_CONFIG_FILE",
+ required=True, help="Dbus sys config file location")
+ parser.add_argument("-u", "--unittestandparams",
+ dest="UNIT_TEST",
+ required=True, help="Unit test script and params \
+ as comma delimited string")
+ args = parser.parse_args(sys.argv[1:])
+ DBUS_DIR = tempfile.mkdtemp()
+ DBUS_SYS_CONFIG_FILE = args.DBUS_SYS_CONFIG_FILE
+ UNIT_TEST = args.UNIT_TEST
+
+ launch_session_dbus(DBUS_DIR, DBUS_SYS_CONFIG_FILE)
+ check_call(UNIT_TEST.split(','), env=os.environ)
+ dbus_cleanup(DBUS_DIR)