]>
git.ipfire.org Git - thirdparty/systemd.git/blob - test/integration-test-wrapper.py
2 # SPDX-License-Identifier: LGPL-2.1-or-later
4 '''Test wrapper command for driving integration tests.
6 Note: This is deliberately rough and only intended to drive existing tests
7 with the expectation that as part of formally defining the API it will be tidy.
17 from pathlib
import Path
20 EMERGENCY_EXIT_DROPIN
= """\
22 Wants=emergency-exit.service
26 EMERGENCY_EXIT_SERVICE
= """\
28 DefaultDependencies=no
29 Conflicts=shutdown.target
30 Conflicts=rescue.service
31 Before=shutdown.target
41 if not bool(int(os
.getenv("SYSTEMD_INTEGRATION_TESTS", "0"))):
42 print("SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping", file=sys
.stderr
)
45 parser
= argparse
.ArgumentParser(description
=__doc__
)
46 parser
.add_argument('--meson-source-dir', required
=True, type=Path
)
47 parser
.add_argument('--meson-build-dir', required
=True, type=Path
)
48 parser
.add_argument('--test-name', required
=True)
49 parser
.add_argument('--test-number', required
=True)
50 parser
.add_argument('--storage', required
=True)
51 parser
.add_argument('--firmware', required
=True)
52 parser
.add_argument('mkosi_args', nargs
="*")
53 args
= parser
.parse_args()
55 name
= args
.test_name
+ (f
"-{i}" if (i
:= os
.getenv("MESON_TEST_ITERATION")) else "")
56 test_unit
= f
"testsuite-{args.test_number}.service"
58 dropin
= textwrap
.dedent(
61 After=multi-user.target network.target
62 Requires=multi-user.target
64 SuccessActionExitStatus=123
67 StandardOutput=journal+console
71 if os
.getenv("TEST_MATCH_SUBTEST"):
72 dropin
+= textwrap
.dedent(
75 Environment=TEST_MATCH_SUBTEST={os.environ["TEST_MATCH_SUBTEST"]}
79 if os
.getenv("TEST_MATCH_TESTCASE"):
80 dropin
+= textwrap
.dedent(
83 Environment=TEST_MATCH_TESTCASE={os.environ["TEST_MATCH_TESTCASE"]}
87 if not sys
.stderr
.isatty():
88 dropin
+= textwrap
.dedent(
95 journal_file
= (args
.meson_build_dir
/ (f
"test/journal/{name}.journal")).absolute()
96 journal_file
.unlink(missing_ok
=True)
102 '--directory', os
.fspath(args
.meson_source_dir
),
103 '--output-dir', os
.fspath(args
.meson_build_dir
/ 'mkosi.output'),
104 '--extra-search-path', os
.fspath(args
.meson_build_dir
),
107 *(['--forward-journal', journal_file
] if journal_file
else []),
111 f
"systemd.extra-unit.emergency-exit.service={shlex.quote(EMERGENCY_EXIT_SERVICE)}",
113 f
"systemd.unit-dropin.emergency.target={shlex.quote(EMERGENCY_EXIT_DROPIN)}",
115 if not sys
.stderr
.isatty()
119 f
"systemd.unit-dropin.{test_unit}={shlex.quote(dropin)}",
120 '--runtime-network=none',
121 '--runtime-scratch=no',
123 '--qemu-firmware', args
.firmware
,
124 '--kernel-command-line-extra',
126 'systemd.hostname=H',
127 f
"SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/testsuite-{args.test_number}.units:/usr/lib/systemd/tests/testdata/units:",
128 f
"systemd.unit={test_unit}",
129 'systemd.mask=systemd-networkd-wait-online.service',
132 "systemd.mask=serial-getty@.service",
133 "systemd.show_status=no",
134 "systemd.crash_shell=0",
135 "systemd.crash_action=poweroff",
137 if not sys
.stderr
.isatty()
141 '--credential', f
"journal.storage={'persistent' if sys.stderr.isatty() else args.storage}",
146 result
= subprocess
.run(cmd
)
148 # Return code 123 is the expected success code
149 if result
.returncode
in (123, 77):
150 # Do not keep journal files for tests that don't fail.
152 journal_file
.unlink(missing_ok
=True)
154 exit(0 if result
.returncode
== 123 else 77)
160 '-o', 'short-monotonic',
161 '--file', journal_file
,
165 print("Test failed, relevant logs can be viewed with: \n\n"
166 f
"{shlex.join(str(a) for a in cmd)}\n", file=sys
.stderr
)
168 # 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
169 exit(result
.returncode
or 1)
172 if __name__
== '__main__':