summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2022-01-17 12:34:29 +0000
committerSimon McVittie <smcv@debian.org>2022-01-18 16:35:28 +0000
commita16efca8ec2ee3b1d4f66254356c6dfd1e5351cf (patch)
treec914c5693ef96ec6529c8fdaf1c55e202d4ea1b7
parent0e2e9a55832082354d707468a03f95243b3db1fc (diff)
downloadflatpak-a16efca8ec2ee3b1d4f66254356c6dfd1e5351cf.tar.gz
test-context: Exercise some corner cases for merging filesystems
Signed-off-by: Simon McVittie <smcv@collabora.com> Co-authored-by: Alexander Larsson <alexl@redhat.com> (cherry picked from commit fab0f8ed7c52fc58e6c550d123ede9621c760ca7)
-rw-r--r--tests/test-context.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/tests/test-context.c b/tests/test-context.c
index b4626288..b13a2a4d 100644
--- a/tests/test-context.c
+++ b/tests/test-context.c
@@ -17,12 +17,24 @@
#include "config.h"
+#include <stdarg.h>
+
#include <glib.h>
#include "flatpak.h"
#include "flatpak-context-private.h"
+#include "flatpak-run-private.h"
+#include "flatpak-utils-private.h"
#include "tests/testlib.h"
+/* g_str_has_prefix as a GEqualFunc */
+static gboolean
+str_has_prefix (gconstpointer candidate,
+ gconstpointer pattern)
+{
+ return g_str_has_prefix (candidate, pattern);
+}
+
static void
test_context_env (void)
{
@@ -116,6 +128,305 @@ test_context_env_fd (void)
g_clear_error (&error);
}
+static void context_parse_args (FlatpakContext *context,
+ ...) G_GNUC_NULL_TERMINATED;
+
+static void
+context_parse_args (FlatpakContext *context,
+ ...)
+{
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(GOptionContext) oc = NULL;
+ g_autoptr(GOptionGroup) group = NULL;
+ g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
+ g_auto(GStrv) argv = NULL;
+ const char *arg;
+ va_list ap;
+
+ g_ptr_array_add (args, g_strdup ("argv[0]"));
+
+ va_start (ap, context);
+
+ while ((arg = va_arg (ap, const char *)) != NULL)
+ g_ptr_array_add (args, g_strdup (arg));
+
+ va_end (ap);
+
+ g_ptr_array_add (args, NULL);
+ argv = (GStrv) g_ptr_array_free (g_steal_pointer (&args), FALSE);
+
+ oc = g_option_context_new ("");
+ group = flatpak_context_get_options (context);
+ g_option_context_add_group (oc, group);
+ g_option_context_parse_strv (oc, &argv, &local_error);
+ g_assert_no_error (local_error);
+}
+
+static void
+test_context_merge_fs (void)
+{
+ /*
+ * We want to arrive at the same result regardless of whether we:
+ * - start from lowest precedence, and successively merge higher
+ * precedences into it, discarding them when done;
+ * - successively merge highest precedence into second-highest, and
+ * then discard highest
+ */
+ enum { LOWEST_FIRST, HIGHEST_FIRST, INVALID } merge_order;
+
+ for (merge_order = LOWEST_FIRST; merge_order < INVALID; merge_order++)
+ {
+ g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
+ g_autoptr(FlatpakContext) middle = flatpak_context_new ();
+ g_autoptr(FlatpakContext) highest = flatpak_context_new ();
+ gpointer value;
+
+ context_parse_args (lowest,
+ "--filesystem=/one",
+ NULL);
+ context_parse_args (middle,
+ "--nofilesystem=host:reset",
+ "--filesystem=/two",
+ NULL);
+ context_parse_args (highest,
+ "--nofilesystem=host",
+ "--filesystem=/three",
+ NULL);
+
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/three", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/two", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ if (merge_order == LOWEST_FIRST)
+ {
+ flatpak_context_merge (lowest, middle);
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+
+ flatpak_context_merge (lowest, highest);
+ }
+ else
+ {
+ flatpak_context_merge (middle, highest);
+
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_merge (lowest, middle);
+ }
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ }
+
+ for (merge_order = LOWEST_FIRST; merge_order < INVALID; merge_order++)
+ {
+ g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
+ g_autoptr(FlatpakContext) mid_low = flatpak_context_new ();
+ g_autoptr(FlatpakContext) mid_high = flatpak_context_new ();
+ g_autoptr(FlatpakContext) highest = flatpak_context_new ();
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(GKeyFile) metakey = g_key_file_new ();
+ g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
+ g_autofree char *filesystems = NULL;
+ gpointer value;
+
+ context_parse_args (lowest,
+ "--filesystem=/one",
+ NULL);
+ context_parse_args (mid_low,
+ "--nofilesystem=host:reset",
+ "--filesystem=/two",
+ NULL);
+ context_parse_args (mid_high,
+ "--filesystem=host",
+ "--filesystem=/three",
+ NULL);
+ context_parse_args (highest,
+ "--nofilesystem=host",
+ "--filesystem=/four",
+ NULL);
+
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/three", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/four", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/two", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/four", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/two", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/three", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ if (merge_order == LOWEST_FIRST)
+ {
+ flatpak_context_merge (lowest, mid_low);
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));
+
+ flatpak_context_merge (lowest, mid_high);
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));
+
+ flatpak_context_merge (lowest, highest);
+ }
+ else
+ {
+ flatpak_context_merge (mid_high, highest);
+
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/two", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_merge (mid_low, mid_high);
+
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_merge (lowest, mid_low);
+ }
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_save_metadata (lowest, FALSE, metakey);
+ filesystems = g_key_file_get_value (metakey,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_FILESYSTEMS,
+ &local_error);
+ g_assert_no_error (local_error);
+ g_test_message ("%s=%s", FLATPAK_METADATA_KEY_FILESYSTEMS, filesystems);
+ /* !host:reset is serialized first */
+ g_assert_true (g_str_has_prefix (filesystems, "!host:reset;"));
+ /* The rest are serialized in arbitrary order */
+ g_assert_nonnull (strstr (filesystems, ";!host;"));
+ g_assert_null (strstr (filesystems, "/one"));
+ g_assert_nonnull (strstr (filesystems, ";/two;"));
+ g_assert_nonnull (strstr (filesystems, ";/three;"));
+ g_assert_nonnull (strstr (filesystems, ";/four;"));
+
+ flatpak_context_to_args (lowest, args);
+ /* !host:reset is serialized first */
+ g_assert_cmpuint (args->len, >, 0);
+ g_assert_cmpstr (g_ptr_array_index (args, 0), ==,
+ "--nofilesystem=host:reset");
+ /* The rest are serialized in arbitrary order */
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--nofilesystem=host", g_str_equal, NULL));
+ g_assert_false (g_ptr_array_find_with_equal_func (args, "--filesystem=/one", str_has_prefix, NULL));
+ g_assert_false (g_ptr_array_find_with_equal_func (args, "--nofilesystem=/one", str_has_prefix, NULL));
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/two", g_str_equal, NULL));
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/three", g_str_equal, NULL));
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/four", g_str_equal, NULL));
+ }
+}
+
int
main (int argc, char *argv[])
{
@@ -123,6 +434,7 @@ main (int argc, char *argv[])
g_test_add_func ("/context/env", test_context_env);
g_test_add_func ("/context/env-fd", test_context_env_fd);
+ g_test_add_func ("/context/merge-fs", test_context_merge_fs);
return g_test_run ();
}