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