|
|
b1dca6 |
commit 4f79b3e2fb3eba003240ec38a0e68702b9a60b86
|
|
|
b1dca6 |
Author: DJ Delorie <dj@redhat.com>
|
|
|
b1dca6 |
Date: Mon Feb 3 14:49:25 2020 -0500
|
|
|
b1dca6 |
|
|
|
b1dca6 |
test-container: add exec, cwd
|
|
|
b1dca6 |
|
|
|
b1dca6 |
exec <path_to_test_binary> [optional_argv_0]
|
|
|
b1dca6 |
|
|
|
b1dca6 |
copies test binary to specified location and runs it from
|
|
|
b1dca6 |
there. If the second argument is provided, that will
|
|
|
b1dca6 |
be used for argv[0]
|
|
|
b1dca6 |
|
|
|
b1dca6 |
cwd <directory>
|
|
|
b1dca6 |
|
|
|
b1dca6 |
attempts to chdir(directory) before running test
|
|
|
b1dca6 |
|
|
|
b1dca6 |
Note: "cwd" not "cd" as it takes effect just before the
|
|
|
b1dca6 |
test binary runs, not when it's encountered in the script,
|
|
|
b1dca6 |
so it can't be used as a path shortcut like "cd" would imply.
|
|
|
b1dca6 |
|
|
|
b1dca6 |
cleanup: use xstrdup() instead of strdup()
|
|
|
b1dca6 |
|
|
|
b1dca6 |
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
|
|
b1dca6 |
|
|
|
b1dca6 |
diff --git a/support/test-container.c b/support/test-container.c
|
|
|
b1dca6 |
index 6503cea90309b9b0..9488ec7b4a824380 100644
|
|
|
b1dca6 |
--- a/support/test-container.c
|
|
|
b1dca6 |
+++ b/support/test-container.c
|
|
|
b1dca6 |
@@ -95,6 +95,8 @@ int verbose = 0;
|
|
|
b1dca6 |
mv FILE FILE
|
|
|
b1dca6 |
cp FILE FILE
|
|
|
b1dca6 |
rm FILE
|
|
|
b1dca6 |
+ cwd PATH
|
|
|
b1dca6 |
+ exec FILE
|
|
|
b1dca6 |
FILE must start with $B/, $S/, $I/, $L/, or /
|
|
|
b1dca6 |
(expands to build dir, source dir, install dir, library dir
|
|
|
b1dca6 |
(in container), or container's root)
|
|
|
b1dca6 |
@@ -104,6 +106,8 @@ int verbose = 0;
|
|
|
b1dca6 |
- 'mv': A minimal move files command.
|
|
|
b1dca6 |
- 'cp': A minimal copy files command.
|
|
|
b1dca6 |
- 'rm': A minimal remove files command.
|
|
|
b1dca6 |
+ - 'cwd': set test working directory
|
|
|
b1dca6 |
+ - 'exec': change test binary location (may end in /)
|
|
|
b1dca6 |
* mytest.root/postclean.req causes fresh rsync (with delete) after
|
|
|
b1dca6 |
test if present
|
|
|
b1dca6 |
|
|
|
b1dca6 |
@@ -147,7 +151,7 @@ maybe_xmkdir (const char *path, mode_t mode)
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* Temporarily concatenate multiple strings into one. Allows up to 10
|
|
|
b1dca6 |
- temporary results; use strdup () if you need them to be
|
|
|
b1dca6 |
+ temporary results; use xstrdup () if you need them to be
|
|
|
b1dca6 |
permanent. */
|
|
|
b1dca6 |
static char *
|
|
|
b1dca6 |
concat (const char *str, ...)
|
|
|
b1dca6 |
@@ -670,11 +674,13 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
char *new_objdir_path;
|
|
|
b1dca6 |
char *new_srcdir_path;
|
|
|
b1dca6 |
char **new_child_proc;
|
|
|
b1dca6 |
+ char *new_child_exec;
|
|
|
b1dca6 |
char *command_root;
|
|
|
b1dca6 |
char *command_base;
|
|
|
b1dca6 |
char *command_basename;
|
|
|
b1dca6 |
char *so_base;
|
|
|
b1dca6 |
int do_postclean = 0;
|
|
|
b1dca6 |
+ char *change_cwd = NULL;
|
|
|
b1dca6 |
|
|
|
b1dca6 |
int pipes[2];
|
|
|
b1dca6 |
char pid_buf[20];
|
|
|
b1dca6 |
@@ -701,7 +707,7 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
|
|
|
b1dca6 |
if (argc < 2)
|
|
|
b1dca6 |
{
|
|
|
b1dca6 |
- fprintf (stderr, "Usage: containerize <program to run> <args...>\n");
|
|
|
b1dca6 |
+ fprintf (stderr, "Usage: test-container <program to run> <args...>\n");
|
|
|
b1dca6 |
exit (1);
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
|
|
|
b1dca6 |
@@ -746,12 +752,13 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
|
|
|
b1dca6 |
- pristine_root_path = strdup (concat (support_objdir_root,
|
|
|
b1dca6 |
+ pristine_root_path = xstrdup (concat (support_objdir_root,
|
|
|
b1dca6 |
"/testroot.pristine", NULL));
|
|
|
b1dca6 |
- new_root_path = strdup (concat (support_objdir_root,
|
|
|
b1dca6 |
+ new_root_path = xstrdup (concat (support_objdir_root,
|
|
|
b1dca6 |
"/testroot.root", NULL));
|
|
|
b1dca6 |
new_cwd_path = get_current_dir_name ();
|
|
|
b1dca6 |
new_child_proc = argv + 1;
|
|
|
b1dca6 |
+ new_child_exec = argv[1];
|
|
|
b1dca6 |
|
|
|
b1dca6 |
lock_fd = open (concat (pristine_root_path, "/lock.fd", NULL),
|
|
|
b1dca6 |
O_CREAT | O_TRUNC | O_RDWR, 0666);
|
|
|
b1dca6 |
@@ -778,10 +785,10 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
command_root = concat (support_srcdir_root,
|
|
|
b1dca6 |
argv[1] + strlen (support_objdir_root),
|
|
|
b1dca6 |
".root", NULL);
|
|
|
b1dca6 |
- command_root = strdup (command_root);
|
|
|
b1dca6 |
+ command_root = xstrdup (command_root);
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* This cuts off the ".root" we appended above. */
|
|
|
b1dca6 |
- command_base = strdup (command_root);
|
|
|
b1dca6 |
+ command_base = xstrdup (command_root);
|
|
|
b1dca6 |
command_base[strlen (command_base) - 5] = 0;
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* This is the basename of the test we're running. */
|
|
|
b1dca6 |
@@ -792,7 +799,7 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
++command_basename;
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* Shared object base directory. */
|
|
|
b1dca6 |
- so_base = strdup (argv[1]);
|
|
|
b1dca6 |
+ so_base = xstrdup (argv[1]);
|
|
|
b1dca6 |
if (strrchr (so_base, '/') != NULL)
|
|
|
b1dca6 |
strrchr (so_base, '/')[1] = 0;
|
|
|
b1dca6 |
|
|
|
b1dca6 |
@@ -806,9 +813,9 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
&& S_ISDIR (st.st_mode))
|
|
|
b1dca6 |
rsync (command_root, new_root_path, 0);
|
|
|
b1dca6 |
|
|
|
b1dca6 |
- new_objdir_path = strdup (concat (new_root_path,
|
|
|
b1dca6 |
+ new_objdir_path = xstrdup (concat (new_root_path,
|
|
|
b1dca6 |
support_objdir_root, NULL));
|
|
|
b1dca6 |
- new_srcdir_path = strdup (concat (new_root_path,
|
|
|
b1dca6 |
+ new_srcdir_path = xstrdup (concat (new_root_path,
|
|
|
b1dca6 |
support_srcdir_root, NULL));
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* new_cwd_path starts with '/' so no "/" needed between the two. */
|
|
|
b1dca6 |
@@ -868,7 +875,10 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
the_words[i] = concat (new_root_path,
|
|
|
b1dca6 |
support_libdir_prefix,
|
|
|
b1dca6 |
the_words[i] + 2, NULL);
|
|
|
b1dca6 |
- else if (the_words[i][0] == '/')
|
|
|
b1dca6 |
+ /* "exec" and "cwd" use inside-root paths. */
|
|
|
b1dca6 |
+ else if (strcmp (the_words[0], "exec") != 0
|
|
|
b1dca6 |
+ && strcmp (the_words[0], "cwd") != 0
|
|
|
b1dca6 |
+ && the_words[i][0] == '/')
|
|
|
b1dca6 |
the_words[i] = concat (new_root_path,
|
|
|
b1dca6 |
the_words[i], NULL);
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
@@ -912,13 +922,49 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
{
|
|
|
b1dca6 |
maybe_xunlink (the_words[1]);
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
+ else if (nt >= 2 && strcmp (the_words[0], "exec") == 0)
|
|
|
b1dca6 |
+ {
|
|
|
b1dca6 |
+ /* The first argument is the desired location and name
|
|
|
b1dca6 |
+ of the test binary as we wish to exec it; we will
|
|
|
b1dca6 |
+ copy the binary there. The second (optional)
|
|
|
b1dca6 |
+ argument is the value to pass as argv[0], it
|
|
|
b1dca6 |
+ defaults to the same as the first argument. */
|
|
|
b1dca6 |
+ char *new_exec_path = the_words[1];
|
|
|
b1dca6 |
+
|
|
|
b1dca6 |
+ /* If the new exec path ends with a slash, that's the
|
|
|
b1dca6 |
+ * directory, and use the old test base name. */
|
|
|
b1dca6 |
+ if (new_exec_path [strlen(new_exec_path) - 1] == '/')
|
|
|
b1dca6 |
+ new_exec_path = concat (new_exec_path,
|
|
|
b1dca6 |
+ basename (new_child_proc[0]),
|
|
|
b1dca6 |
+ NULL);
|
|
|
b1dca6 |
+
|
|
|
b1dca6 |
+
|
|
|
b1dca6 |
+ /* new_child_proc is in the build tree, so has the
|
|
|
b1dca6 |
+ same path inside the chroot as outside. The new
|
|
|
b1dca6 |
+ exec path is, by definition, relative to the
|
|
|
b1dca6 |
+ chroot. */
|
|
|
b1dca6 |
+ copy_one_file (new_child_proc[0], concat (new_root_path,
|
|
|
b1dca6 |
+ new_exec_path,
|
|
|
b1dca6 |
+ NULL));
|
|
|
b1dca6 |
+
|
|
|
b1dca6 |
+ new_child_exec = xstrdup (new_exec_path);
|
|
|
b1dca6 |
+ if (the_words[2])
|
|
|
b1dca6 |
+ new_child_proc[0] = xstrdup (the_words[2]);
|
|
|
b1dca6 |
+ else
|
|
|
b1dca6 |
+ new_child_proc[0] = new_child_exec;
|
|
|
b1dca6 |
+ }
|
|
|
b1dca6 |
+ else if (nt == 2 && strcmp (the_words[0], "cwd") == 0)
|
|
|
b1dca6 |
+ {
|
|
|
b1dca6 |
+ change_cwd = xstrdup (the_words[1]);
|
|
|
b1dca6 |
+ }
|
|
|
b1dca6 |
else if (nt == 1 && strcmp (the_words[0], "su") == 0)
|
|
|
b1dca6 |
{
|
|
|
b1dca6 |
be_su = 1;
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
else if (nt > 0 && the_words[0][0] != '#')
|
|
|
b1dca6 |
{
|
|
|
b1dca6 |
- printf ("\033[31minvalid [%s]\033[0m\n", the_words[0]);
|
|
|
b1dca6 |
+ fprintf (stderr, "\033[31minvalid [%s]\033[0m\n", the_words[0]);
|
|
|
b1dca6 |
+ exit (1);
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
}
|
|
|
b1dca6 |
fclose (f);
|
|
|
b1dca6 |
@@ -1089,11 +1135,17 @@ main (int argc, char **argv)
|
|
|
b1dca6 |
write (GMAP, tmp, strlen (tmp));
|
|
|
b1dca6 |
xclose (GMAP);
|
|
|
b1dca6 |
|
|
|
b1dca6 |
+ if (change_cwd)
|
|
|
b1dca6 |
+ {
|
|
|
b1dca6 |
+ if (chdir (change_cwd) < 0)
|
|
|
b1dca6 |
+ FAIL_EXIT1 ("Can't cd to %s inside container - ", change_cwd);
|
|
|
b1dca6 |
+ }
|
|
|
b1dca6 |
+
|
|
|
b1dca6 |
/* Now run the child. */
|
|
|
b1dca6 |
- execvp (new_child_proc[0], new_child_proc);
|
|
|
b1dca6 |
+ execvp (new_child_exec, new_child_proc);
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* Or don't run the child? */
|
|
|
b1dca6 |
- FAIL_EXIT1 ("Unable to exec %s\n", new_child_proc[0]);
|
|
|
b1dca6 |
+ FAIL_EXIT1 ("Unable to exec %s\n", new_child_exec);
|
|
|
b1dca6 |
|
|
|
b1dca6 |
/* Because gcc won't know error () never returns... */
|
|
|
b1dca6 |
exit (EXIT_UNSUPPORTED);
|