diff --git a/debian/control b/debian/control
index 73f78ac811c0a5155a39093ccb46a53203e2439a..a6d229ae3b742047e751baf568270430b8edb829 100644
--- a/debian/control
+++ b/debian/control
@@ -86,6 +86,7 @@ Section: misc
 Depends:
  ${misc:Depends},
  ${shlibs:Depends},
+ zlib1g,
 Description:
  The Steam Runtime is the library stack used to run the Steam client
  on Linux. The Steam Runtime Tools utility library contains open-source
diff --git a/steam-runtime-tools/architecture-internal.h b/steam-runtime-tools/architecture-internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..06825aad7859341b3c85105ecb545f9bb364090e
--- /dev/null
+++ b/steam-runtime-tools/architecture-internal.h
@@ -0,0 +1,31 @@
+/*<private_header>*/
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <glib.h>
+
+G_GNUC_INTERNAL gboolean _srt_architecture_can_run (const char *multiarch);
diff --git a/steam-runtime-tools/architecture.c b/steam-runtime-tools/architecture.c
index e8a5f4390f34524bb440d39ec03c756440fda93c..44616d4d4c646a55aee1ca47dd51b7782d0454db 100644
--- a/steam-runtime-tools/architecture.c
+++ b/steam-runtime-tools/architecture.c
@@ -24,6 +24,7 @@
  */
 
 #include "steam-runtime-tools/architecture.h"
+#include "steam-runtime-tools/architecture-internal.h"
 
 #include "steam-runtime-tools/utils-internal.h"
 
@@ -38,7 +39,7 @@
  * operating system.
  */
 
-static gboolean
+gboolean
 _srt_architecture_can_run (const char *multiarch)
 {
   gchar *helper = NULL;
diff --git a/steam-runtime-tools/glib-compat.h b/steam-runtime-tools/glib-compat.h
index e41c71b4ae80518f1549ab7e7de31958d5fe7c33..51e3b08825a2d8ce3ac23c54b77c9a2daddf298f 100644
--- a/steam-runtime-tools/glib-compat.h
+++ b/steam-runtime-tools/glib-compat.h
@@ -42,7 +42,8 @@ _srt_steal_pointer (gpointer pointer_to_pointer)
 #endif
 
 #if !GLIB_CHECK_VERSION(2, 34, 0)
-#define g_clear_pointer(x, destroy) _srt_clear_pointer (x, destroy)
+#define g_clear_pointer(x, destroy) \
+  _srt_clear_pointer (x, (GDestroyNotify) (void (*)(void)) destroy)
 /* A simplified version of g_clear_pointer without type-safety. */
 static inline void
 _srt_clear_pointer (gpointer pointer_to_pointer,
diff --git a/steam-runtime-tools/meson.build b/steam-runtime-tools/meson.build
index 7431fef406310bce5c1c2d0a9c53797cc537c2bc..1211aebc96a0134578611dec3caa341dfba1d525 100644
--- a/steam-runtime-tools/meson.build
+++ b/steam-runtime-tools/meson.build
@@ -22,9 +22,11 @@
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 libsteamrt_sources = [
+    'architecture-internal.h',
     'architecture.c',
     'library-internal.h',
     'library.c',
+    'system-info.c',
     'utils-internal.h',
     'utils.c',
 ]
@@ -33,6 +35,7 @@ libsteamrt_public_headers = [
     'architecture.h',
     'library.h',
     'steam-runtime-tools.h',
+    'system-info.h',
 ]
 
 enums = gnome.mkenums_simple(
diff --git a/steam-runtime-tools/steam-runtime-tools.h b/steam-runtime-tools/steam-runtime-tools.h
index 844d550df34944668e29e68018d91f6e5d098b01..e7313d07bcf9f72676c70466ed54bb8367b2e334 100644
--- a/steam-runtime-tools/steam-runtime-tools.h
+++ b/steam-runtime-tools/steam-runtime-tools.h
@@ -30,5 +30,6 @@
 #include <steam-runtime-tools/architecture.h>
 #include <steam-runtime-tools/enums.h>
 #include <steam-runtime-tools/library.h>
+#include <steam-runtime-tools/system-info.h>
 
 #undef _SRT_IN_SINGLE_HEADER
diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c
new file mode 100644
index 0000000000000000000000000000000000000000..4a6ae3f062b5b1169073d91f8fb72f91ea3dd45c
--- /dev/null
+++ b/steam-runtime-tools/system-info.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "steam-runtime-tools/system-info.h"
+
+#include "steam-runtime-tools/architecture.h"
+#include "steam-runtime-tools/architecture-internal.h"
+#include "steam-runtime-tools/glib-compat.h"
+#include "steam-runtime-tools/utils-internal.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/**
+ * SECTION:system-info
+ * @title: System information
+ * @short_description: Cached information about the system
+ * @include: steam-runtime-tools/steam-runtime-tools.h
+ *
+ * #SrtSystemInfo is an opaque object representing information about
+ * the system. Information is retrieved "lazily"; when it has been
+ * retrieved, it is cached until the #SrtSystemInfo is destroyed.
+ *
+ * This is a reference-counted object: use g_object_ref() and
+ * g_object_unref() to manage its lifecycle.
+ */
+
+typedef enum
+{
+  TRI_NO = FALSE,
+  TRI_YES = TRUE,
+  TRI_MAYBE = -1
+} Tristate;
+
+struct _SrtSystemInfo
+{
+  /*< private >*/
+  GObject parent;
+  gchar *expectations;
+  Tristate can_write_uinput;
+  /* (element-type Abi) */
+  GPtrArray *abis;
+};
+
+struct _SrtSystemInfoClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+};
+
+enum {
+  PROP_0,
+  PROP_EXPECTATIONS,
+  N_PROPERTIES
+};
+
+G_DEFINE_TYPE (SrtSystemInfo, srt_system_info, G_TYPE_OBJECT)
+
+typedef struct
+{
+  GQuark multiarch_tuple;
+  Tristate can_run;
+} Abi;
+
+static Abi *
+ensure_abi (SrtSystemInfo *self,
+            const char *multiarch_tuple)
+{
+  GQuark quark;
+  guint i;
+  Abi *abi = NULL;
+
+  quark = g_quark_from_string (multiarch_tuple);
+
+  for (i = 0; i < self->abis->len; i++)
+    {
+      abi = g_ptr_array_index (self->abis, i);
+
+      if (abi->multiarch_tuple == quark)
+        return abi;
+    }
+
+  abi = g_slice_new0 (Abi);
+  abi->multiarch_tuple = quark;
+  abi->can_run = TRI_MAYBE;
+  /* transfer ownership to self->abis */
+  g_ptr_array_add (self->abis, abi);
+  return abi;
+}
+
+static void
+abi_free (gpointer self)
+{
+  g_slice_free (Abi, self);
+}
+
+static void
+srt_system_info_init (SrtSystemInfo *self)
+{
+  self->can_write_uinput = TRI_MAYBE;
+
+  /* Assume that in practice we will usually add two ABIs: amd64 and i386 */
+  self->abis = g_ptr_array_new_full (2, abi_free);
+}
+
+static void
+srt_system_info_get_property (GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+  SrtSystemInfo *self = SRT_SYSTEM_INFO (object);
+
+  switch (prop_id)
+    {
+      case PROP_EXPECTATIONS:
+        g_value_set_string (value, self->expectations);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+srt_system_info_set_property (GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+  SrtSystemInfo *self = SRT_SYSTEM_INFO (object);
+
+  switch (prop_id)
+    {
+      case PROP_EXPECTATIONS:
+        /* Construct-only */
+        g_return_if_fail (self->expectations == NULL);
+        self->expectations = g_value_dup_string (value);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+srt_system_info_finalize (GObject *object)
+{
+  SrtSystemInfo *self = SRT_SYSTEM_INFO (object);
+
+  g_clear_pointer (&self->abis, g_ptr_array_unref);
+  g_free (self->expectations);
+
+  G_OBJECT_CLASS (srt_system_info_parent_class)->finalize (object);
+}
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL };
+
+static void
+srt_system_info_class_init (SrtSystemInfoClass *cls)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (cls);
+
+  object_class->get_property = srt_system_info_get_property;
+  object_class->set_property = srt_system_info_set_property;
+  object_class->finalize = srt_system_info_finalize;
+
+  properties[PROP_EXPECTATIONS] =
+    g_param_spec_string ("expectations", "Expectations",
+                         "Path to a directory containing information "
+                         "about the properties we expect the system "
+                         "to have, or NULL if unknown",
+                         NULL,
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+}
+
+SrtSystemInfo *
+srt_system_info_new (const char *expectations)
+{
+  g_return_val_if_fail ((expectations == NULL ||
+                         g_file_test (expectations, G_FILE_TEST_IS_DIR)),
+                        NULL);
+  return g_object_new (SRT_TYPE_SYSTEM_INFO,
+                       "expectations", expectations,
+                       NULL);
+}
+
+gboolean
+srt_system_info_can_run (SrtSystemInfo *self,
+                         const char *multiarch_tuple)
+{
+  Abi *abi = NULL;
+
+  g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), FALSE);
+  g_return_val_if_fail (multiarch_tuple != NULL, FALSE);
+
+  abi = ensure_abi (self, multiarch_tuple);
+
+  if (abi->can_run == TRI_MAYBE)
+    {
+      if (_srt_architecture_can_run (multiarch_tuple))
+        abi->can_run = TRI_YES;
+      else
+        abi->can_run = TRI_NO;
+    }
+
+  return (abi->can_run == TRI_YES);
+}
+
+gboolean
+srt_system_info_can_write_to_uinput (SrtSystemInfo *self)
+{
+  g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), FALSE);
+
+  if (self->can_write_uinput == TRI_MAYBE)
+    {
+      int fd = open ("/dev/uinput", O_WRONLY | O_NONBLOCK);
+
+      if (fd >= 0)
+        {
+          g_debug ("Successfully opened /dev/uinput for writing");
+          self->can_write_uinput = TRI_YES;
+          close (fd);
+        }
+      else
+        {
+          g_debug ("Failed to open /dev/uinput for writing: %s",
+                   g_strerror (errno));
+          self->can_write_uinput = TRI_NO;
+        }
+    }
+
+  return (self->can_write_uinput == TRI_YES);
+}
diff --git a/steam-runtime-tools/system-info.h b/steam-runtime-tools/system-info.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc1f72b29c6772843558492c49383b0171e9e3ee
--- /dev/null
+++ b/steam-runtime-tools/system-info.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#if !defined(_SRT_IN_SINGLE_HEADER) && !defined(_SRT_COMPILATION)
+#error "Do not include directly, use <steam-runtime-tools/steam-runtime-tools.h>"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <steam-runtime-tools/library.h>
+
+typedef struct _SrtSystemInfo SrtSystemInfo;
+typedef struct _SrtSystemInfoClass SrtSystemInfoClass;
+
+#define SRT_TYPE_SYSTEM_INFO srt_system_info_get_type ()
+#define SRT_SYSTEM_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SRT_TYPE_SYSTEM_INFO, SrtSystemInfo))
+#define SRT_SYSTEM_INFO_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST ((cls), SRT_TYPE_SYSTEM_INFO, SrtSystemInfoClass))
+#define SRT_IS_SYSTEM_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SRT_TYPE_SYSTEM_INFO))
+#define SRT_IS_SYSTEM_INFO_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE ((cls), SRT_TYPE_SYSTEM_INFO))
+#define SRT_SYSTEM_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SRT_TYPE_SYSTEM_INFO, SrtSystemInfoClass)
+
+GType srt_system_info_get_type (void);
+
+SrtSystemInfo *srt_system_info_new (const char *expectations);
+
+gboolean srt_system_info_can_run (SrtSystemInfo *self,
+                                  const char *multiarch_tuple);
+gboolean srt_system_info_can_write_to_uinput (SrtSystemInfo *self);
diff --git a/tests/expectations/i386-linux-gnu/zlib1g.symbols b/tests/expectations/i386-linux-gnu/zlib1g.symbols
new file mode 100644
index 0000000000000000000000000000000000000000..63be790e3612555c3aae70b905be7b349964ee34
--- /dev/null
+++ b/tests/expectations/i386-linux-gnu/zlib1g.symbols
@@ -0,0 +1,4 @@
+# Cut-down version of zlib1g:amd64.symbols, to illustrate what we expect
+# to find here
+libz.so.1 zlib1g #MINVER#
+ adler32@Base 1:1.1.4
diff --git a/tests/expectations/x86_64-linux-gnu/zlib1g.symbols b/tests/expectations/x86_64-linux-gnu/zlib1g.symbols
new file mode 100644
index 0000000000000000000000000000000000000000..63be790e3612555c3aae70b905be7b349964ee34
--- /dev/null
+++ b/tests/expectations/x86_64-linux-gnu/zlib1g.symbols
@@ -0,0 +1,4 @@
+# Cut-down version of zlib1g:amd64.symbols, to illustrate what we expect
+# to find here
+libz.so.1 zlib1g #MINVER#
+ adler32@Base 1:1.1.4
diff --git a/tests/meson.build b/tests/meson.build
index 9f92740023fb106046b7045ccaa72b203f531023..d763b615b85c18a1893750a135745a06d822e7ec 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -29,6 +29,7 @@ test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'he
 tests = [
   'architecture',
   'library',
+  'system-info',
 ]
 
 tests_dir = join_paths(
@@ -42,6 +43,8 @@ tests_metadir = join_paths(
   meson.project_name() + '-' + api_major,
 )
 
+install_subdir('expectations', install_dir : tests_dir)
+
 foreach test_name : tests
   exe = executable(
     'test-' + test_name,
diff --git a/tests/system-info.c b/tests/system-info.c
new file mode 100644
index 0000000000000000000000000000000000000000..451253c5889500ccc4c662525d4c0baca2333bb4
--- /dev/null
+++ b/tests/system-info.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2019 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <steam-runtime-tools/steam-runtime-tools.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "test-utils.h"
+
+static const char *argv0;
+
+typedef struct
+{
+  gchar *srcdir;
+  gchar *builddir;
+} Fixture;
+
+typedef struct
+{
+  int unused;
+} Config;
+
+static void
+setup (Fixture *f,
+       gconstpointer context)
+{
+  G_GNUC_UNUSED const Config *config = context;
+
+  f->srcdir = g_strdup (g_getenv ("G_TEST_SRCDIR"));
+  f->builddir = g_strdup (g_getenv ("G_TEST_BUILDDIR"));
+
+  if (f->srcdir == NULL)
+    f->srcdir = g_path_get_dirname (argv0);
+
+  if (f->builddir == NULL)
+    f->builddir = g_path_get_dirname (argv0);
+}
+
+static void
+teardown (Fixture *f,
+          gconstpointer context)
+{
+  G_GNUC_UNUSED const Config *config = context;
+
+  g_free (f->srcdir);
+  g_free (f->builddir);
+}
+
+/*
+ * Test basic functionality of the SrtSystemInfo object.
+ */
+static void
+test_object (Fixture *f,
+             gconstpointer context)
+{
+  SrtSystemInfo *info;
+  gchar *expectations_in = NULL;
+  gchar *expectations = NULL;
+  int fd;
+
+  info = srt_system_info_new (NULL);
+  g_assert_nonnull (info);
+  g_object_get (info,
+                "expectations", &expectations,
+                NULL);
+  g_assert_cmpstr (expectations, ==, NULL);
+
+  /* We try it twice, to exercise the cached and non-cached cases */
+#if defined(__x86_64__) && defined(__LP64__)
+  g_assert_true (srt_system_info_can_run (info, SRT_ABI_X86_64));
+  g_assert_true (srt_system_info_can_run (info, SRT_ABI_X86_64));
+#endif
+
+#if defined(__i386__)
+  g_assert_true (srt_system_info_can_run (info, SRT_ABI_I386));
+  g_assert_true (srt_system_info_can_run (info, SRT_ABI_I386));
+#endif
+
+  g_assert_false (srt_system_info_can_run (info, "hal9000-linux-gnu"));
+  g_assert_false (srt_system_info_can_run (info, "hal9000-linux-gnu"));
+
+  /* This is a little bit tautologous - we're using the same check
+   * that the production code does. */
+  fd = open ("/dev/uinput", O_WRONLY | O_NONBLOCK);
+
+  if (fd >= 0)
+    {
+      g_assert_true (srt_system_info_can_write_to_uinput (info));
+      g_assert_true (srt_system_info_can_write_to_uinput (info));
+      close (fd);
+    }
+  else
+    {
+      g_assert_false (srt_system_info_can_write_to_uinput (info));
+      g_assert_false (srt_system_info_can_write_to_uinput (info));
+    }
+
+  g_object_unref (info);
+
+  expectations_in = g_build_filename (f->srcdir, "expectations", NULL);
+  info = srt_system_info_new (expectations_in);
+  g_assert_nonnull (info);
+  g_object_get (info,
+                "expectations", &expectations,
+                NULL);
+  g_assert_cmpstr (expectations, ==, expectations_in);
+  g_free (expectations_in);
+  g_free (expectations);
+  g_object_unref (info);
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  argv0 = argv[0];
+
+  g_test_init (&argc, &argv, NULL);
+  g_test_add ("/system-info/object", Fixture, NULL,
+              setup, test_object, teardown);
+
+  return g_test_run ();
+}