summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2020-08-26 17:07:28 +0100
committerAlexander Larsson <alexander.larsson@gmail.com>2020-08-27 17:48:50 +0200
commitc0faab35fabb469e3945ad99c32f041d2d7a0dab (patch)
tree8426a16257ee7a86e36ad8c52cee09fe717eb23e
parent55b27b1393a3880b79dfe108b6f13f1a2fa1888b (diff)
downloadflatpak-c0faab35fabb469e3945ad99c32f041d2d7a0dab.tar.gz
tests: Add basic unit tests for FlatpakExports, FlatpakContext
There's a limit to how many assertions we can make here right now, because what we do here is very dependent on the "shape" of the host filesystem. This could be extended in future by using a mock home directory whose contents we control. Signed-off-by: Simon McVittie <smcv@collabora.com>
-rw-r--r--tests/Makefile.am.inc6
-rw-r--r--tests/test-exports.c481
2 files changed, 486 insertions, 1 deletions
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
index cefd9822..e43e8972 100644
--- a/tests/Makefile.am.inc
+++ b/tests/Makefile.am.inc
@@ -60,6 +60,10 @@ testcommon_LDADD = \
$(NULL)
testcommon_SOURCES = tests/testcommon.c
+test_exports_CFLAGS = $(testcommon_CFLAGS)
+test_exports_LDADD = $(testcommon_LDADD)
+test_exports_SOURCES = tests/test-exports.c
+
tests_httpcache_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) $(JSON_CFLAGS) $(APPSTREAM_GLIB_CFLAGS) \
-DFLATPAK_COMPILATION \
-DLOCALEDIR=\"$(localedir)\"
@@ -216,7 +220,7 @@ test_scripts = ${TEST_MATRIX}
dist_test_scripts = ${TEST_MATRIX_DIST}
dist_installed_test_extra_scripts += ${TEST_MATRIX_EXTRA_DIST}
-test_programs = testlibrary testcommon
+test_programs = testlibrary testcommon test-exports
test_extra_programs = tests/httpcache tests/test-update-portal tests/test-portal-impl tests/test-authenticator
@VALGRIND_CHECK_RULES@
diff --git a/tests/test-exports.c b/tests/test-exports.c
new file mode 100644
index 00000000..21d8329e
--- /dev/null
+++ b/tests/test-exports.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright © 2020 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include "flatpak.h"
+#include "flatpak-bwrap-private.h"
+#include "flatpak-context-private.h"
+#include "flatpak-exports-private.h"
+#include "flatpak-run-private.h"
+
+/* This differs from g_file_test (path, G_FILE_TEST_IS_DIR) which
+ returns true if the path is a symlink to a dir */
+static gboolean
+path_is_dir (const char *path)
+{
+ struct stat s;
+
+ if (lstat (path, &s) != 0)
+ return FALSE;
+
+ return S_ISDIR (s.st_mode);
+}
+
+/*
+ * Assert that the next few arguments starting from @i are setting up
+ * /run/host/os-release. Return the next argument that hasn't been used.
+ */
+G_GNUC_WARN_UNUSED_RESULT static gsize
+assert_next_is_os_release (FlatpakBwrap *bwrap,
+ gsize i)
+{
+ if (g_file_test ("/etc/os-release", G_FILE_TEST_EXISTS))
+ {
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--ro-bind");
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/etc/os-release");
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/run/host/os-release");
+ }
+ else if (g_file_test ("/usr/lib/os-release", G_FILE_TEST_EXISTS))
+ {
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--ro-bind");
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/usr/lib/os-release");
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "/run/host/os-release");
+ }
+
+ return i;
+}
+
+/* Assert that arguments starting from @i are --dir @dir.
+ * Return the new @i. */
+G_GNUC_WARN_UNUSED_RESULT static gsize
+assert_next_is_dir (FlatpakBwrap *bwrap,
+ gsize i,
+ const char *dir)
+{
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--dir");
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, dir);
+ return i;
+}
+
+/* Assert that arguments starting from @i are --tmpfs @dir.
+ * Return the new @i. */
+G_GNUC_WARN_UNUSED_RESULT static gsize
+assert_next_is_tmpfs (FlatpakBwrap *bwrap,
+ gsize i,
+ const char *dir)
+{
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "--tmpfs");
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, dir);
+ return i;
+}
+
+/* Assert that arguments starting from @i are @how @path @path.
+ * Return the new @i. */
+G_GNUC_WARN_UNUSED_RESULT static gsize
+assert_next_is_bind (FlatpakBwrap *bwrap,
+ gsize i,
+ const char *how,
+ const char *path)
+{
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, how);
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, path);
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, path);
+ return i;
+}
+
+/* Print the arguments of a call to bwrap. */
+static void
+print_bwrap (FlatpakBwrap *bwrap)
+{
+ guint i;
+
+ for (i = 0; i < bwrap->argv->len && bwrap->argv->pdata[i] != NULL; i++)
+ g_test_message ("%s", (const char *) bwrap->argv->pdata[i]);
+
+ g_test_message ("--");
+}
+
+static void
+test_empty_context (void)
+{
+ g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
+ g_autoptr(FlatpakContext) context = flatpak_context_new ();
+ g_autoptr(FlatpakExports) exports = NULL;
+
+ g_assert_cmpuint (g_hash_table_size (context->env_vars), ==, 0);
+ g_assert_cmpuint (g_hash_table_size (context->persistent), ==, 0);
+ g_assert_cmpuint (g_hash_table_size (context->filesystems), ==, 0);
+ g_assert_cmpuint (g_hash_table_size (context->session_bus_policy), ==, 0);
+ g_assert_cmpuint (g_hash_table_size (context->system_bus_policy), ==, 0);
+ g_assert_cmpuint (g_hash_table_size (context->generic_policy), ==, 0);
+ g_assert_cmpuint (context->shares, ==, 0);
+ g_assert_cmpuint (context->shares_valid, ==, 0);
+ g_assert_cmpuint (context->sockets, ==, 0);
+ g_assert_cmpuint (context->sockets_valid, ==, 0);
+ g_assert_cmpuint (context->devices, ==, 0);
+ g_assert_cmpuint (context->devices_valid, ==, 0);
+ g_assert_cmpuint (context->features, ==, 0);
+ g_assert_cmpuint (context->features_valid, ==, 0);
+ g_assert_cmpuint (flatpak_context_get_run_flags (context), ==, 0);
+
+ exports = flatpak_context_get_exports (context, "com.example.App");
+ g_assert_nonnull (exports);
+
+ g_clear_pointer (&exports, flatpak_exports_free);
+ flatpak_context_append_bwrap_filesystem (context, bwrap,
+ "com.example.App",
+ NULL,
+ NULL,
+ &exports);
+ print_bwrap (bwrap);
+ g_assert_nonnull (exports);
+}
+
+static void
+test_full_context (void)
+{
+ g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
+ g_autoptr(FlatpakContext) context = flatpak_context_new ();
+ g_autoptr(FlatpakExports) exports = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GKeyFile) keyfile = g_key_file_new ();
+
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_SHARED,
+ "network;ipc;");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_SOCKETS,
+ "x11;wayland;pulseaudio;session-bus;system-bus;"
+ "fallback-x11;ssh-auth;pcsc;cups;");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_DEVICES,
+ "dri;all;kvm;shm;");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_FEATURES,
+ "devel;multiarch;bluetooth;canbus;");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_FILESYSTEMS,
+ "host;/home;");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_PERSISTENT,
+ ".openarena;");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY,
+ "org.example.SessionService",
+ "own");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_SYSTEM_BUS_POLICY,
+ "net.example.SystemService",
+ "talk");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_ENVIRONMENT,
+ "HYPOTHETICAL_PATH", "/foo:/bar");
+ g_key_file_set_value (keyfile,
+ FLATPAK_METADATA_GROUP_PREFIX_POLICY "MyPolicy",
+ "Colours", "blue;green;");
+
+ flatpak_context_load_metadata (context, keyfile, &error);
+ g_assert_no_error (error);
+
+ g_assert_cmpuint (context->shares, ==,
+ (FLATPAK_CONTEXT_SHARED_NETWORK |
+ FLATPAK_CONTEXT_SHARED_IPC));
+ g_assert_cmpuint (context->shares_valid, ==, context->shares);
+ g_assert_cmpuint (context->devices, ==,
+ (FLATPAK_CONTEXT_DEVICE_DRI |
+ FLATPAK_CONTEXT_DEVICE_ALL |
+ FLATPAK_CONTEXT_DEVICE_KVM |
+ FLATPAK_CONTEXT_DEVICE_SHM));
+ g_assert_cmpuint (context->devices_valid, ==, context->devices);
+ g_assert_cmpuint (context->sockets, ==,
+ (FLATPAK_CONTEXT_SOCKET_X11 |
+ FLATPAK_CONTEXT_SOCKET_WAYLAND |
+ FLATPAK_CONTEXT_SOCKET_PULSEAUDIO |
+ FLATPAK_CONTEXT_SOCKET_SESSION_BUS |
+ FLATPAK_CONTEXT_SOCKET_SYSTEM_BUS |
+ FLATPAK_CONTEXT_SOCKET_FALLBACK_X11 |
+ FLATPAK_CONTEXT_SOCKET_SSH_AUTH |
+ FLATPAK_CONTEXT_SOCKET_PCSC |
+ FLATPAK_CONTEXT_SOCKET_CUPS));
+ g_assert_cmpuint (context->sockets_valid, ==, context->sockets);
+ g_assert_cmpuint (context->features, ==,
+ (FLATPAK_CONTEXT_FEATURE_DEVEL |
+ FLATPAK_CONTEXT_FEATURE_MULTIARCH |
+ FLATPAK_CONTEXT_FEATURE_BLUETOOTH |
+ FLATPAK_CONTEXT_FEATURE_CANBUS));
+ g_assert_cmpuint (context->features_valid, ==, context->features);
+
+ g_assert_cmpuint (flatpak_context_get_run_flags (context), ==,
+ (FLATPAK_RUN_FLAG_DEVEL |
+ FLATPAK_RUN_FLAG_MULTIARCH |
+ FLATPAK_RUN_FLAG_BLUETOOTH |
+ FLATPAK_RUN_FLAG_CANBUS));
+
+ exports = flatpak_context_get_exports (context, "com.example.App");
+ g_assert_nonnull (exports);
+
+ g_clear_pointer (&exports, flatpak_exports_free);
+ flatpak_context_append_bwrap_filesystem (context, bwrap,
+ "com.example.App",
+ NULL,
+ NULL,
+ &exports);
+ print_bwrap (bwrap);
+ g_assert_nonnull (exports);
+}
+
+typedef struct
+{
+ const char *input;
+ GOptionError code;
+} NotFilesystem;
+
+static const NotFilesystem not_filesystems[] =
+{
+ { "homework", G_OPTION_ERROR_FAILED },
+ { "xdg-run", G_OPTION_ERROR_FAILED },
+};
+
+typedef struct
+{
+ const char *input;
+ FlatpakFilesystemMode mode;
+ const char *fs;
+} Filesystem;
+
+static const Filesystem filesystems[] =
+{
+ { "home", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "host", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "host-etc", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "host-os", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "host:ro", FLATPAK_FILESYSTEM_MODE_READ_ONLY, "host" },
+ { "home:rw", FLATPAK_FILESYSTEM_MODE_READ_WRITE, "home" },
+ { "~/Music", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "/srv/obs/debian\\:sid\\:main:create", FLATPAK_FILESYSTEM_MODE_CREATE,
+ "/srv/obs/debian:sid:main" },
+ { "/srv/c\\:\\\\Program Files\\\\Steam", FLATPAK_FILESYSTEM_MODE_READ_WRITE,
+ "/srv/c:\\Program Files\\Steam" },
+ { "/srv/escaped\\unnecessarily", FLATPAK_FILESYSTEM_MODE_READ_WRITE,
+ "/srv/escapedunnecessarily" },
+ { "xdg-desktop", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-desktop/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-documents", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-documents/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-download", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-download/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-music", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-music/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-pictures", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-pictures/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-public-share", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-public-share/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-templates", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-templates/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-videos", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-videos/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-data", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-data/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-cache", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-cache/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-config", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-config/Stuff", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+ { "xdg-run/dbus", FLATPAK_FILESYSTEM_MODE_READ_WRITE },
+};
+
+static void
+test_filesystems (void)
+{
+ gsize i;
+
+ for (i = 0; i < G_N_ELEMENTS (filesystems); i++)
+ {
+ const Filesystem *fs = &filesystems[i];
+ g_autoptr(GError) error = NULL;
+ g_autofree char *normalized;
+ FlatpakFilesystemMode mode;
+ gboolean ret;
+
+ g_test_message ("%s", fs->input);
+ ret = flatpak_context_parse_filesystem (fs->input, &normalized, &mode,
+ &error);
+ g_assert_no_error (error);
+ g_assert_true (ret);
+
+ if (fs->fs == NULL)
+ g_assert_cmpstr (normalized, ==, fs->input);
+ else
+ g_assert_cmpstr (normalized, ==, fs->fs);
+
+ g_assert_cmpuint (mode, ==, fs->mode);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (not_filesystems); i++)
+ {
+ const NotFilesystem *not = &not_filesystems[i];
+ g_autoptr(GError) error = NULL;
+ char *normalized = NULL;
+ FlatpakFilesystemMode mode;
+ gboolean ret;
+
+ g_test_message ("%s", not->input);
+ ret = flatpak_context_parse_filesystem (not->input, &normalized, &mode,
+ &error);
+ g_test_message ("-> %s", error ? error->message : "(no error)");
+ g_assert_error (error, G_OPTION_ERROR, not->code);
+ g_assert_false (ret);
+ g_assert_null (normalized);
+ }
+}
+
+static void
+test_empty (void)
+{
+ g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
+ g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
+ gsize i;
+
+ g_assert_false (flatpak_exports_path_is_visible (exports, "/run"));
+ g_assert_cmpint (flatpak_exports_path_get_mode (exports, "/tmp"), ==,
+ FLATPAK_FILESYSTEM_MODE_NONE);
+
+ flatpak_bwrap_add_arg (bwrap, "bwrap");
+ flatpak_exports_append_bwrap_args (exports, bwrap);
+ flatpak_bwrap_finish (bwrap);
+ print_bwrap (bwrap);
+
+ i = 0;
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");
+
+ i = assert_next_is_os_release (bwrap, i);
+
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
+ g_assert_cmpuint (i, ==, bwrap->argv->len);
+}
+
+static void
+test_full (void)
+{
+ g_autoptr(FlatpakBwrap) bwrap = flatpak_bwrap_new (NULL);
+ g_autoptr(FlatpakExports) exports = flatpak_exports_new ();
+ gsize i;
+
+ flatpak_exports_add_host_etc_expose (exports,
+ FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ flatpak_exports_add_host_os_expose (exports,
+ FLATPAK_FILESYSTEM_MODE_READ_ONLY);
+ flatpak_exports_add_path_expose (exports,
+ FLATPAK_FILESYSTEM_MODE_READ_WRITE,
+ "/tmp");
+ flatpak_exports_add_path_expose (exports,
+ FLATPAK_FILESYSTEM_MODE_READ_ONLY,
+ "/var");
+ flatpak_exports_add_path_tmpfs (exports, "/var/tmp");
+ flatpak_exports_add_path_expose_or_hide (exports,
+ FLATPAK_FILESYSTEM_MODE_NONE,
+ "/home");
+ flatpak_exports_add_path_expose_or_hide (exports,
+ FLATPAK_FILESYSTEM_MODE_READ_ONLY,
+ "/srv");
+
+ flatpak_bwrap_add_arg (bwrap, "bwrap");
+ flatpak_exports_append_bwrap_args (exports, bwrap);
+ flatpak_bwrap_finish (bwrap);
+ print_bwrap (bwrap);
+
+ i = 0;
+ g_assert_cmpuint (i, <, bwrap->argv->len);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, "bwrap");
+
+ /* Hiding /home just uses --dir because / is not exposed. */
+ if (path_is_dir ("/home"))
+ i = assert_next_is_dir (bwrap, i, "/home");
+
+ if (path_is_dir ("/srv"))
+ i = assert_next_is_bind (bwrap, i, "--ro-bind", "/srv");
+
+ if (path_is_dir ("/tmp"))
+ i = assert_next_is_bind (bwrap, i, "--bind", "/tmp");
+
+ if (path_is_dir ("/var"))
+ i = assert_next_is_bind (bwrap, i, "--ro-bind", "/var");
+
+ /* We don't create a FAKE_MODE_TMPFS in the container unless there is
+ * a directory on the host to mount it on.
+ * Hiding /var/tmp has to use --tmpfs because /var *is* exposed. */
+ if (path_is_dir ("/var") && path_is_dir ("/var/tmp"))
+ i = assert_next_is_tmpfs (bwrap, i, "/var/tmp");
+
+ while (i < bwrap->argv->len && bwrap->argv->pdata[i] != NULL)
+ {
+ /* An unknown number of --bind, --ro-bind and --symlink,
+ * depending how your /usr and /etc are set up.
+ * About the only thing we can say is that they are in threes. */
+ g_assert_cmpuint (i++, <, bwrap->argv->len);
+ g_assert_cmpuint (i++, <, bwrap->argv->len);
+ g_assert_cmpuint (i++, <, bwrap->argv->len);
+ }
+
+ g_assert_cmpuint (i, ==, bwrap->argv->len - 1);
+ g_assert_cmpstr (bwrap->argv->pdata[i++], ==, NULL);
+ g_assert_cmpuint (i, ==, bwrap->argv->len);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int res;
+
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/context/empty", test_empty_context);
+ g_test_add_func ("/context/filesystems", test_filesystems);
+ g_test_add_func ("/context/full", test_full_context);
+ g_test_add_func ("/exports/empty", test_empty);
+ g_test_add_func ("/exports/full", test_full);
+
+ res = g_test_run ();
+
+ return res;
+}