1#!/usr/bin/env python3
2
3"""
4This script launches a dbus session, sets the DBUS_SESSION_BUS_ADDRESS
5and DBUS_STARTER_BUS_TYPE Eenvironment variables and puts the generated files
6in the dbus dir location passed as a parameter. It then runs the unit test
7script, and then cleans up the generated dbus files.
8"""
9
10from subprocess import check_call, check_output
11import os
12import sys
13import argparse
14import re
15import tempfile
16
17def launch_session_dbus(dbus_dir, dbus_config_file):
18    """
19    Launches a session debus using a modified config file and
20    sets the DBUS_SESSION_BUS_ADDRESS environment variable
21
22    Parameter descriptions:
23    dbus_dir            Directory location for generated files
24    dbus_config_file    File location of dbus sys config file
25    """
26    dbus_pid = os.path.join(dbus_dir,'pid')
27    dbus_socket = os.path.join(dbus_dir,'system_bus_socket')
28    dbus_local_conf = os.path.join(dbus_dir,'system-local.conf')
29    if os.path.isfile(dbus_pid):
30        os.remove(dbus_pid)
31    with open(dbus_config_file) as infile, \
32         open(dbus_local_conf, 'w') as outfile:
33        for line in infile:
34            line = re.sub('<type>.*</type>','<type>session</type>', \
35                          line, flags=re.DOTALL)
36            line = re.sub('<pidfile>.*</pidfile>', \
37                          '<pidfile>%s</pidfile>' % dbus_pid, \
38                          line, flags=re.DOTALL)
39            line = re.sub('<listen>.*</listen>', \
40                          '<listen>unix:path=%s</listen>' % dbus_socket, \
41                          line, flags=re.DOTALL)
42            line = re.sub('<deny','<allow', line)
43            outfile.write(line)
44    infile.close()
45    outfile.close()
46    command = ['dbus-daemon', '--config-file=%s' % dbus_local_conf, \
47               '--print-address']
48    out = check_output(command).splitlines()
49    os.environ['DBUS_SESSION_BUS_ADDRESS'] = out[0].decode("utf-8")
50    os.environ['DBUS_STARTER_BUS_TYPE'] = 'session'
51
52def dbus_cleanup(dbus_dir):
53    """
54    Kills the dbus session started by launch_session_dbus
55    and removes the generated files.
56
57    Parameter descriptions:
58    dbus_dir            Directory location of generated files
59    """
60
61    dbus_pid = os.path.join(dbus_dir,'pid')
62    dbus_socket = os.path.join(dbus_dir,'system_bus_socket')
63    dbus_local_conf = os.path.join(dbus_dir,'system-local.conf')
64    if os.path.isfile(dbus_pid):
65        dbus_pid = open(dbus_pid,'r').read().replace('\n','')
66        check_call(['kill', dbus_pid])
67    if os.path.isfile(dbus_local_conf):
68        os.remove(dbus_local_conf)
69    if os.path.exists(dbus_socket):
70        os.remove(dbus_socket)
71
72
73if __name__ == '__main__':
74
75    # Set command line arguments
76    parser = argparse.ArgumentParser()
77
78    parser.add_argument("-f", "--dbussysconfigfile",
79                        dest="DBUS_SYS_CONFIG_FILE",
80                        required=True, help="Dbus sys config file location")
81    parser.add_argument("-u", "--unittestandparams",
82                        dest="UNIT_TEST",
83                        required=True, help="Unit test script and params \
84                        as comma delimited string")
85    args = parser.parse_args(sys.argv[1:])
86    DBUS_DIR = tempfile.mkdtemp()
87    DBUS_SYS_CONFIG_FILE = args.DBUS_SYS_CONFIG_FILE
88    UNIT_TEST = args.UNIT_TEST
89
90    launch_session_dbus(DBUS_DIR, DBUS_SYS_CONFIG_FILE)
91    check_call(UNIT_TEST.split(','), env=os.environ)
92    dbus_cleanup(DBUS_DIR)
93