summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Playfair Cal <daniel.playfair.cal@gmail.com>2019-02-12 22:17:20 +0000
committerDaniel Playfair Cal <daniel.playfair.cal@gmail.com>2019-02-12 22:17:20 +0000
commitb62ce371159be9f518657ec907b668d91287e7c8 (patch)
tree1e8171e23490d3cca27c18494454b344724e3bc8
parent0740fd9c28f5cb2cfab634ebdd3c6f4893e2d296 (diff)
parent8cbaee1c341b97d81fc597a4571b459baaac5c11 (diff)
downloaddconf-b62ce371159be9f518657ec907b668d91287e7c8.tar.gz
Merge branch 'fix-shm-test-modules' into 'master'
Tests: remove bug prone usage of dlsym and RTDL_NEXT See merge request GNOME/dconf!37
-rw-r--r--engine/dconf-engine-mockable.c39
-rw-r--r--engine/dconf-engine-mockable.h30
-rw-r--r--engine/dconf-engine-profile.c9
-rw-r--r--engine/meson.build20
-rw-r--r--shm/dconf-shm-mockable.c40
-rw-r--r--shm/dconf-shm-mockable.h31
-rw-r--r--shm/dconf-shm.c5
-rw-r--r--shm/meson.build22
-rw-r--r--tests/engine.c9
-rw-r--r--tests/meson.build4
-rw-r--r--tests/shm.c10
11 files changed, 196 insertions, 23 deletions
diff --git a/engine/dconf-engine-mockable.c b/engine/dconf-engine-mockable.c
new file mode 100644
index 0000000..dce2f43
--- /dev/null
+++ b/engine/dconf-engine-mockable.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2019 Daniel Playfair Cal
+ *
+ * This library 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 of the licence, 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/>.
+ *
+ * Author: Daniel Playfair Cal <daniel.playfair.cal@gmail.com>
+ */
+
+/**
+ * This module contains the production implementations of methods used in
+ * dconf_shm that need to be mocked out for tests.
+ *
+ * In some cases, external methods are wrapped with a different name. This is
+ * done so that it is not necessary to redefine the external functions in
+ * unit tests in order to mock them out, and therefore easy to also call the
+ * non mocked versions in tests if necessary.
+ */
+
+#include "config.h"
+
+#include "dconf-engine-mockable.h"
+
+
+FILE *
+dconf_engine_fopen (const char *pathname, const char *mode)
+{
+ return fopen (pathname, mode);
+}
diff --git a/engine/dconf-engine-mockable.h b/engine/dconf-engine-mockable.h
new file mode 100644
index 0000000..091f6d3
--- /dev/null
+++ b/engine/dconf-engine-mockable.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2019 Daniel Playfair Cal
+ *
+ * This library 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 of the licence, 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/>.
+ *
+ * Author: Daniel Playfair Cal <daniel.playfair.cal@gmail.com>
+ */
+
+#ifndef __dconf_engine_mockable_h__
+#define __dconf_engine_mockable_h__
+
+#include <gio/gio.h>
+#include <stdio.h>
+
+G_GNUC_INTERNAL
+FILE *dconf_engine_fopen (const char *pathname,
+ const char *mode);
+
+#endif
diff --git a/engine/dconf-engine-profile.c b/engine/dconf-engine-profile.c
index b204bb4..6474248 100644
--- a/engine/dconf-engine-profile.c
+++ b/engine/dconf-engine-profile.c
@@ -21,6 +21,7 @@
#include "config.h"
#include "dconf-engine-profile.h"
+#include "dconf-engine-mockable.h"
#include <string.h>
#include <stdio.h>
@@ -207,7 +208,7 @@ dconf_engine_open_profile_file (const gchar *profile)
gchar *filename;
filename = g_build_filename (prefix, "dconf/profile", profile, NULL);
- fp = fopen (filename, "r");
+ fp = dconf_engine_fopen (filename, "r");
/* If it wasn't ENOENT then we don't want to continue on to check
* other paths. Fail immediately.
@@ -236,7 +237,7 @@ dconf_engine_open_mandatory_profile (void)
memcpy (path, MANDATORY_DIR, mdlen);
snprintf (path + mdlen, 20, "%u", (guint) getuid ());
- return fopen (path, "r");
+ return dconf_engine_fopen (path, "r");
}
static FILE *
@@ -253,7 +254,7 @@ dconf_engine_open_runtime_profile (void)
memcpy (path, runtime_dir, rdlen);
memcpy (path + rdlen, RUNTIME_PROFILE, sizeof RUNTIME_PROFILE);
- return fopen (path, "r");
+ return dconf_engine_fopen (path, "r");
}
DConfEngineSource **
@@ -311,7 +312,7 @@ dconf_engine_profile_open (const gchar *profile,
if (profile[0] != '/')
file = dconf_engine_open_profile_file (profile);
else
- file = fopen (profile, "r");
+ file = dconf_engine_fopen (profile, "r");
}
if (file != NULL)
diff --git a/engine/meson.build b/engine/meson.build
index d1a959d..ca46b60 100644
--- a/engine/meson.build
+++ b/engine/meson.build
@@ -1,4 +1,4 @@
-sources = files(
+testable_sources = files(
'dconf-engine.c',
'dconf-engine-profile.c',
'dconf-engine-source.c',
@@ -8,6 +8,10 @@ sources = files(
'dconf-engine-source-system.c',
)
+sources = testable_sources + files(
+ 'dconf-engine-mockable.c',
+)
+
engine_deps = [
libdconf_common_dep,
libgvdb_dep,
@@ -26,3 +30,17 @@ libdconf_engine_dep = declare_dependency(
dependencies: engine_deps,
link_with: libdconf_engine,
)
+
+libdconf_engine_test = static_library(
+ 'dconf-engine-test',
+ sources: testable_sources,
+ include_directories: top_inc,
+ dependencies: engine_deps + [libdconf_shm_dep],
+ c_args: dconf_c_args,
+ pic: true,
+)
+
+libdconf_engine_test_dep = declare_dependency(
+ dependencies: engine_deps,
+ link_with: libdconf_engine_test,
+)
diff --git a/shm/dconf-shm-mockable.c b/shm/dconf-shm-mockable.c
new file mode 100644
index 0000000..6adf7d5
--- /dev/null
+++ b/shm/dconf-shm-mockable.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2019 Daniel Playfair Cal
+ *
+ * This library 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 of the licence, 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/>.
+ *
+ * Author: Daniel Playfair Cal <daniel.playfair.cal@gmail.com>
+ */
+
+/**
+ * This module contains the production implementations of methods used in
+ * dconf_shm that need to be mocked out for tests.
+ *
+ * In some cases, external methods are wrapped with a different name. This is
+ * done so that it is not necessary to redefine the external functions in
+ * unit tests in order to mock them out, and therefore easy to also call the
+ * non mocked versions in tests if necessary.
+ */
+
+#include "config.h"
+
+#include "dconf-shm-mockable.h"
+
+#include <unistd.h>
+
+ssize_t
+dconf_shm_pwrite (int fd, const void *buf, size_t count, off_t offset)
+{
+ return pwrite (fd, buf, count, offset);
+}
diff --git a/shm/dconf-shm-mockable.h b/shm/dconf-shm-mockable.h
new file mode 100644
index 0000000..98ff33f
--- /dev/null
+++ b/shm/dconf-shm-mockable.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2019 Daniel Playfair Cal
+ *
+ * This library 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 of the licence, 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/>.
+ *
+ * Author: Daniel Playfair Cal <daniel.playfair.cal@gmail.com>
+ */
+
+#ifndef __dconf_shm_mockable_h__
+#define __dconf_shm_mockable_h__
+
+#include <glib.h>
+
+G_GNUC_INTERNAL
+ssize_t dconf_shm_pwrite (int fd,
+ const void *buf,
+ size_t count,
+ off_t offset);
+
+#endif /* __dconf_shm_mockable_h__ */
diff --git a/shm/dconf-shm.c b/shm/dconf-shm.c
index ae8c1c7..dbde759 100644
--- a/shm/dconf-shm.c
+++ b/shm/dconf-shm.c
@@ -21,6 +21,7 @@
#include "config.h"
#include "dconf-shm.h"
+#include "dconf-shm-mockable.h"
#include <sys/mman.h>
#include <unistd.h>
@@ -82,7 +83,7 @@ dconf_shm_open (const gchar *name)
* By writing to the second byte in the file we ensure we don't
* overwrite the first byte (which is the one we care about).
*/
- if (pwrite (fd, "", 1, 1) != 1)
+ if (dconf_shm_pwrite (fd, "", 1, 1) != 1)
{
g_critical ("failed to allocate file '%s': %s. dconf will not work properly.", filename, g_strerror (errno));
goto out;
@@ -124,7 +125,7 @@ dconf_shm_flag (const gchar *name)
* If this fails then it will probably fail for the client too.
* If it doesn't then there's not really much we can do...
*/
- if (pwrite (fd, "", 1, 1) == 1)
+ if (dconf_shm_pwrite (fd, "", 1, 1) == 1)
{
guint8 *shm;
diff --git a/shm/meson.build b/shm/meson.build
index 5fb9fe2..07f77d0 100644
--- a/shm/meson.build
+++ b/shm/meson.build
@@ -1,6 +1,11 @@
+sources = files(
+ 'dconf-shm.c',
+ 'dconf-shm-mockable.c',
+)
+
libdconf_shm = static_library(
'dconf-shm',
- sources: 'dconf-shm.c',
+ sources: sources,
include_directories: top_inc,
dependencies: glib_dep,
c_args: dconf_c_args,
@@ -11,3 +16,18 @@ libdconf_shm_dep = declare_dependency(
dependencies: glib_dep,
link_with: libdconf_shm,
)
+
+
+libdconf_shm_test = static_library(
+ 'dconf-shm-test',
+ sources: 'dconf-shm.c',
+ include_directories: top_inc,
+ dependencies: glib_dep,
+ c_args: dconf_c_args,
+ pic: true,
+)
+
+libdconf_shm_test_dep = declare_dependency(
+ dependencies: glib_dep,
+ link_with: libdconf_shm,
+)
diff --git a/tests/engine.c b/tests/engine.c
index 7f2a748..fd2a348 100644
--- a/tests/engine.c
+++ b/tests/engine.c
@@ -2,6 +2,7 @@
#include "../engine/dconf-engine.h"
#include "../engine/dconf-engine-profile.h"
+#include "../engine/dconf-engine-mockable.h"
#include "../common/dconf-enums.h"
#include "dconf-mock.h"
@@ -17,13 +18,9 @@ static const gchar *filename_to_replace;
static const gchar *filename_to_replace_it_with;
FILE *
-fopen (const char *filename,
+dconf_engine_fopen (const char *filename,
const char *mode)
{
- static FILE * (*real_fopen) (const char *, const char *);
-
- if (!real_fopen)
- real_fopen = dlsym (RTLD_NEXT, "fopen");
if (filename_to_replace && g_str_equal (filename, filename_to_replace))
{
@@ -32,7 +29,7 @@ fopen (const char *filename,
filename = filename_to_replace_it_with;
}
- return (* real_fopen) (filename, mode);
+ return fopen (filename, mode);
}
static void assert_no_messages (void);
diff --git a/tests/meson.build b/tests/meson.build
index 247ad76..8aa5837 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -24,11 +24,11 @@ unit_tests = [
# [name, sources, c_args, dependencies, link_with]
['paths', 'paths.c', [], libdconf_common_dep, []],
['changeset', 'changeset.c', [], libdconf_common_dep, []],
- ['shm', ['shm.c', 'tmpdir.c'], [], [dl_dep, libdconf_common_dep, libdconf_shm_dep], []],
+ ['shm', ['shm.c', 'tmpdir.c'], [], [dl_dep, libdconf_common_dep, libdconf_shm_test_dep], []],
['gvdb', 'gvdb.c', '-DSRCDIR="@0@"'.format(test_dir), libgvdb_dep, []],
['gdbus-thread', 'dbus.c', '-DDBUS_BACKEND="/gdbus/thread"', libdconf_gdbus_thread_dep, []],
['gdbus-filter', 'dbus.c', '-DDBUS_BACKEND="/gdbus/filter"', libdconf_gdbus_filter_dep, []],
- ['engine', 'engine.c', '-DSRCDIR="@0@"'.format(test_dir), [dl_dep, libdconf_engine_dep, m_dep], libdconf_mock],
+ ['engine', 'engine.c', '-DSRCDIR="@0@"'.format(test_dir), [dl_dep, libdconf_engine_test_dep, m_dep], libdconf_mock],
['client', 'client.c', '-DSRCDIR="@0@"'.format(test_dir), [libdconf_client_dep, libdconf_engine_dep], libdconf_mock],
['writer', 'writer.c', '-DSRCDIR="@0@"'.format(test_dir), [glib_dep, dl_dep, m_dep, libdconf_service_dep], [libdconf_mock]],
]
diff --git a/tests/shm.c b/tests/shm.c
index a0cf67e..69d683f 100644
--- a/tests/shm.c
+++ b/tests/shm.c
@@ -10,6 +10,7 @@
#include <dlfcn.h>
#include "../shm/dconf-shm.h"
+#include "../shm/dconf-shm-mockable.h"
#include "tmpdir.h"
static void
@@ -90,20 +91,15 @@ test_flag_nonexistent (void)
static gboolean should_fail_pwrite;
/* interpose */
ssize_t
-pwrite (int fd, const void *buf, size_t count, off_t offset)
+dconf_shm_pwrite (int fd, const void *buf, size_t count, off_t offset)
{
- static ssize_t (* real_pwrite) (int, const void *, size_t, off_t);
-
- if (!real_pwrite)
- real_pwrite = dlsym (RTLD_NEXT, "pwrite");
-
if (should_fail_pwrite)
{
errno = ENOSPC;
return -1;
}
- return (* real_pwrite) (fd, buf, count, offset);
+ return pwrite (fd, buf, count, offset);
}
static void