]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: use ${builddir}/systemd-runtest.env to set $SYSTEMD_TEST_DATA
authorFilipe Brandenburger <filbranden@google.com>
Wed, 12 Sep 2018 06:55:02 +0000 (23:55 -0700)
committerFilipe Brandenburger <filbranden@google.com>
Wed, 12 Sep 2018 16:49:03 +0000 (09:49 -0700)
This simplifies get_testdata_dir() to simply checking for an environment
variable, with an additional function to locate a systemd-runtest.env file in
the same directory as the test binary and reading environment variable
assignments from that file if it exists.

This makes it possible to:
- Run `ninja test` from the build dir and have it use ${srcdir}/test for
  test unit definitions.
- Run a test directly, such as `build/test-execute` and have it locate
  them correctly.
- Run installed tests (from systemd-tests package) and locate the test
  units in the installed location (/usr/lib/systemd/tests/testdata), in
  which case the absence of the systemd-runtest.env file will have
  get_testdata_dir() use the installed location hardcoded into the
  binaries.

Explicit setting of $SYSTEMD_TEST_DATA still overrides the contents of
systemd-runtest.env.

meson.build
src/shared/tests.c

index d4d6f013771bde1f15dd796ee7332ad777778caf..ed91d1a4dbf895b028c76209358e9ae82c1e8d91 100644 (file)
@@ -206,6 +206,7 @@ conf.set_quoted('SYSTEM_SHUTDOWN_PATH',                       systemshutdowndir)
 conf.set_quoted('SYSTEM_SLEEP_PATH',                          systemsleepdir)
 conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      join_paths(pkgdatadir, 'kbd-model-map'))
 conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              join_paths(pkgdatadir, 'language-fallback-map'))
+conf.set_quoted('SYSTEMD_TEST_DATA',                          join_paths(testsdir, 'testdata'))
 conf.set_quoted('UDEVLIBEXECDIR',                             udevlibexecdir)
 conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   join_paths(bindir, 'pkttyagent'))
 conf.set_quoted('LIBDIR',                                     libdir)
@@ -222,7 +223,6 @@ conf.set('MEMORY_ACCOUNTING_DEFAULT',                         memory_accounting_
 conf.set_quoted('MEMORY_ACCOUNTING_DEFAULT_YES_NO',           memory_accounting_default ? 'yes' : 'no')
 
 conf.set_quoted('ABS_BUILD_DIR',                              meson.build_root())
-conf.set_quoted('ABS_SRC_DIR',                                meson.source_root())
 
 substs.set('prefix',                                          prefixdir)
 substs.set('exec_prefix',                                     prefixdir)
@@ -2607,6 +2607,14 @@ executable('systemd-sulogin-shell',
 
 ############################################################
 
+custom_target(
+        'systemd-runtest.env',
+        output : 'systemd-runtest.env',
+        command : ['sh', '-c', '{ ' +
+                   'echo SYSTEMD_TEST_DATA=@0@; '.format(join_paths(meson.current_source_dir(), 'test')) +
+                   '} >@OUTPUT@'],
+        build_by_default : true)
+
 foreach tuple : tests
         sources = tuple[0]
         link_with = tuple[1].length() > 0 ? tuple[1] : [libshared]
index a002260439030197de8dd3846562646377f9dc49..ac11f5191be3c3a3304e3e9dcf5e07a80786f6fb 100644 (file)
@@ -6,8 +6,11 @@
 #include <stdlib.h>
 #include <util.h>
 
-#include "tests.h"
+#include "alloc-util.h"
+#include "fileio.h"
 #include "path-util.h"
+#include "strv.h"
+#include "tests.h"
 
 char* setup_fake_runtime_dir(void) {
         char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
@@ -19,53 +22,47 @@ char* setup_fake_runtime_dir(void) {
         return p;
 }
 
-bool test_is_running_from_builddir(char **exedir) {
+static void load_testdata_env(void) {
+        static bool called = false;
         _cleanup_free_ char *s = NULL;
-        bool r;
+        _cleanup_free_ char *envpath = NULL;
+        _cleanup_strv_free_ char **pairs = NULL;
+        char **k, **v;
 
-        /* Check if we're running from the builddir. Optionally, this returns
-         * the path to the directory where the binary is located. */
+        if (called)
+                return;
+        called = true;
 
         assert_se(readlink_and_make_absolute("/proc/self/exe", &s) >= 0);
-        r = path_startswith(s, ABS_BUILD_DIR);
+        dirname(s);
 
-        if (exedir) {
-                dirname(s);
-                *exedir = TAKE_PTR(s);
-        }
+        envpath = path_join(NULL, s, "systemd-runtest.env");
+        if (load_env_file_pairs(NULL, envpath, NULL, &pairs) < 0)
+                return;
 
-        return r;
+        STRV_FOREACH_PAIR(k, v, pairs)
+                setenv(*k, *v, 0);
+}
+
+bool test_is_running_from_builddir(char **exedir) {
+        load_testdata_env();
+
+        return !!getenv("SYSTEMD_TEST_DATA");
 }
 
 const char* get_testdata_dir(void) {
         const char *env;
-        /* convenience: caller does not need to free result */
-        static char testdir[PATH_MAX];
+
+        load_testdata_env();
 
         /* if the env var is set, use that */
         env = getenv("SYSTEMD_TEST_DATA");
-        testdir[sizeof(testdir) - 1] = '\0';
-        if (env) {
-                if (access(env, F_OK) < 0) {
-                        fputs("ERROR: $SYSTEMD_TEST_DATA directory does not exist\n", stderr);
-                        exit(EXIT_FAILURE);
-                }
-                strncpy(testdir, env, sizeof(testdir) - 1);
-        } else {
-                _cleanup_free_ char *exedir = NULL;
-
-                /* Check if we're running from the builddir. If so, use the compiled in path. */
-                if (test_is_running_from_builddir(&exedir))
-                        assert_se(snprintf(testdir, sizeof(testdir), "%s/test", ABS_SRC_DIR) > 0);
-                else
-                        /* Try relative path, according to the install-test layout */
-                        assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", exedir) > 0);
-
-                if (access(testdir, F_OK) < 0) {
-                        fputs("ERROR: Cannot find testdata directory, set $SYSTEMD_TEST_DATA\n", stderr);
-                        exit(EXIT_FAILURE);
-                }
+        if (!env)
+                env = SYSTEMD_TEST_DATA;
+        if (access(env, F_OK) < 0) {
+                fprintf(stderr, "ERROR: $SYSTEMD_TEST_DATA directory [%s] does not exist\n", env);
+                exit(EXIT_FAILURE);
         }
 
-        return testdir;
+        return env;
 }