summaryrefslogtreecommitdiff
path: root/libgweather/tests
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2021-11-19 15:34:38 +0000
committerEmmanuele Bassi <ebassi@gmail.com>2021-11-19 18:25:44 +0000
commit6bfad6d01f9ab3216af935faba67fb5003f3ea96 (patch)
treecb41ab2565cfa48cc9052f021a0135d25a454b10 /libgweather/tests
parent549bc5e5bc3a68e159f92300dafb26d5b9a8005a (diff)
downloadlibgweather-6bfad6d01f9ab3216af935faba67fb5003f3ea96.tar.gz
tests: Move duplicate units into their own suite
The duplicate tests modify the environment, and impose ordering on the general test suite. Instead of modifying the environment inside the tests—which comes with its own set of threading issues—we can split the tests into a separate binary, and set up the environment when executing the test.
Diffstat (limited to 'libgweather/tests')
-rw-r--r--libgweather/tests/duplicates.c242
-rw-r--r--libgweather/tests/meson.build62
-rw-r--r--libgweather/tests/test_libgweather.c137
3 files changed, 284 insertions, 157 deletions
diff --git a/libgweather/tests/duplicates.c b/libgweather/tests/duplicates.c
new file mode 100644
index 0000000..40204de
--- /dev/null
+++ b/libgweather/tests/duplicates.c
@@ -0,0 +1,242 @@
+/* duplicates.c: Check for duplicates in the locations database
+ *
+ * SPDX-FileCopyrightText: 2017 Bastien Nocera <hadess@hadess.net>
+ * SPDX-FileCopyrightText: 2021 Emmanuele Bassi
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <libsoup/soup.h>
+#include <locale.h>
+#include <string.h>
+
+#include <libgweather/gweather-version.h>
+
+/* We use internal API */
+#include "gweather-private.h"
+
+extern void
+_gweather_location_reset_world (void);
+
+/* Set up the temporary directory with the GSettings schemas */
+static char *
+setup_gsettings (void)
+{
+ char *tmpdir, *schema_text, *dest, *cmdline;
+ int result;
+
+ /* Create the installed schemas directory */
+ GError *error = NULL;
+ tmpdir = g_dir_make_tmp ("libgweather-test-XXXXXX", &error);
+ g_assert_no_error (error);
+
+ g_test_message ("Using temporary directory: %s", tmpdir);
+
+ /* Copy the schemas files */
+ g_assert_true (g_file_get_contents (SCHEMAS_BUILDDIR "/org.gnome.GWeather4.enums.xml", &schema_text, NULL, NULL));
+ dest = g_build_filename (tmpdir, "org.gnome.GWeather4.enums.xml", NULL);
+ g_assert_true (g_file_set_contents (dest, schema_text, -1, NULL));
+ g_free (dest);
+ g_free (schema_text);
+
+ g_assert_true (g_file_get_contents (SCHEMASDIR "/org.gnome.GWeather4.gschema.xml", &schema_text, NULL, NULL));
+ dest = g_build_filename (tmpdir, "org.gnome.GWeather4.gschema.xml", NULL);
+ g_assert_true (g_file_set_contents (dest, schema_text, -1, NULL));
+ g_free (dest);
+ g_free (schema_text);
+
+ /* Compile the schemas */
+ cmdline = g_strdup_printf ("glib-compile-schemas --targetdir=%s "
+ "--schema-file=%s/org.gnome.GWeather4.enums.xml "
+ "--schema-file=%s/org.gnome.GWeather4.gschema.xml",
+ tmpdir,
+ SCHEMAS_BUILDDIR,
+ SCHEMASDIR);
+ g_assert_true (g_spawn_command_line_sync (cmdline, NULL, NULL, &result, NULL));
+ g_assert_cmpint (result, ==, 0);
+ g_free (cmdline);
+
+ /* Set envvar */
+ g_setenv ("GSETTINGS_SCHEMA_DIR", tmpdir, TRUE);
+
+ return tmpdir;
+}
+
+/* Tear down the temporary directory with the GSettings schemas */
+static void
+teardown_gsettings (const char *schemas_dir)
+{
+ char *dest = NULL;
+
+ dest = g_build_filename (schemas_dir, "org.gnome.GWeather4.enums.xml", NULL);
+ g_assert_no_errno (g_unlink (dest));
+ g_free (dest);
+
+ dest = g_build_filename (schemas_dir, "org.gnome.GWeather4.gschema.xml", NULL);
+ g_assert_no_errno (g_unlink (dest));
+ g_free (dest);
+
+ dest = g_build_filename (schemas_dir, "gschemas.compiled", NULL);
+ g_assert_no_errno (g_unlink (dest));
+ g_free (dest);
+
+ g_assert_no_errno (g_rmdir (schemas_dir));
+}
+
+static void
+check_bad_duplicate_weather_stations (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GPtrArray *stations = value;
+ GHashTable *dedup;
+ guint i;
+
+ if (stations->len == 1)
+ goto out;
+
+ dedup = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ for (i = 0; i < stations->len; i++) {
+ GWeatherLocation *location = g_ptr_array_index (stations, i);
+
+ double latitude, longitude;
+ gweather_location_get_coords (location, &latitude, &longitude);
+
+ char *coords = g_strdup_printf ("%.10lf %.10lf", latitude, longitude);
+ g_hash_table_insert (dedup, coords, GUINT_TO_POINTER (1));
+ }
+
+ if (g_hash_table_size (dedup) > 1) {
+ g_test_message ("Airport '%s' is defined %u times in different ways\n",
+ (const char *) key,
+ stations->len);
+ g_test_fail ();
+ }
+
+ g_hash_table_destroy (dedup);
+
+out:
+ g_ptr_array_free (stations, TRUE);
+}
+
+static void
+test_bad_duplicate_weather_stations_children (GWeatherLocation *location,
+ GHashTable *stations_ht)
+{
+ g_autoptr (GWeatherLocation) child = NULL;
+ while ((child = gweather_location_next_child (location, child)) != NULL) {
+ if (gweather_location_get_level (child) == GWEATHER_LOCATION_WEATHER_STATION) {
+ GPtrArray *stations;
+ const char *code;
+
+ code = gweather_location_get_code (child);
+
+ stations = g_hash_table_lookup (stations_ht, code);
+ if (!stations) {
+ stations = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ g_hash_table_insert (stations_ht, g_strdup (code), stations);
+ }
+ g_ptr_array_add (stations, g_object_ref (child));
+ } else {
+ test_bad_duplicate_weather_stations_children (child, stations_ht);
+ }
+ }
+}
+
+static void
+test_bad_duplicate_weather_stations (void)
+{
+ g_autoptr (GWeatherLocation) world = NULL;
+ GHashTable *stations_ht;
+
+ world = gweather_location_get_world ();
+ g_assert_nonnull (world);
+
+ stations_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) NULL);
+ test_bad_duplicate_weather_stations_children (world, stations_ht);
+
+ g_hash_table_foreach (stations_ht, check_bad_duplicate_weather_stations, NULL);
+
+ g_hash_table_unref (stations_ht);
+
+ g_clear_object (&world);
+ _gweather_location_reset_world ();
+}
+
+static void
+test_duplicate_weather_stations_children (GWeatherLocation *location)
+{
+ g_autoptr (GHashTable) stations_ht = NULL;
+
+ g_autoptr (GWeatherLocation) child = NULL;
+ while ((child = gweather_location_next_child (location, child)) != NULL) {
+ if (gweather_location_get_level (child) == GWEATHER_LOCATION_WEATHER_STATION) {
+ const char *code;
+
+ code = gweather_location_get_code (child);
+ if (stations_ht == NULL) {
+ stations_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) NULL);
+ } else {
+ gboolean exists;
+
+ exists = GPOINTER_TO_INT (g_hash_table_lookup (stations_ht, code));
+ if (exists) {
+ GWeatherLocationLevel parent_level;
+
+ parent_level = gweather_location_get_level (location);
+ g_test_message ("Duplicate weather station '%s' in %s (level '%s')\n",
+ code,
+ gweather_location_get_name (location),
+ gweather_location_level_to_string (parent_level));
+ g_test_fail ();
+ return;
+ }
+ }
+
+ g_hash_table_insert (stations_ht, g_strdup (code), GINT_TO_POINTER (1));
+ } else {
+ test_duplicate_weather_stations_children (child);
+ }
+ }
+}
+
+static void
+test_duplicate_weather_stations (void)
+{
+ g_autoptr (GWeatherLocation) world = NULL;
+
+ world = gweather_location_get_world ();
+ g_assert_nonnull (world);
+
+ test_duplicate_weather_stations_children (world);
+
+ g_clear_object (&world);
+ _gweather_location_reset_world ();
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ setlocale (LC_ALL, "");
+
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("http://gitlab.gnome.org/GNOME/libgweather/issues/");
+
+ char *schemas_dir = setup_gsettings ();
+
+ /* Modifies environment, so needs to run last */
+ g_test_add_func ("/weather/bad_duplicate_weather_stations", test_bad_duplicate_weather_stations);
+ g_test_add_func ("/weather/duplicate_weather_stations", test_duplicate_weather_stations);
+
+ int res = g_test_run ();
+
+ teardown_gsettings (schemas_dir);
+
+ g_free (schemas_dir);
+
+ return res;
+}
diff --git a/libgweather/tests/meson.build b/libgweather/tests/meson.build
index 5018326..4ed6a3d 100644
--- a/libgweather/tests/meson.build
+++ b/libgweather/tests/meson.build
@@ -1,26 +1,48 @@
-test_cargs = [
+gweather_test_cargs = [
'-DTEST_LOCATIONS="@0@"'.format(locations_bin.full_path()),
'-DSCHEMASDIR="@0@/schemas"'.format(meson.source_root()),
'-DSCHEMAS_BUILDDIR="@0@/schemas"'.format(meson.build_root()),
]
-test_env = environment()
-test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
-test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
-test_env.set('GIO_USE_VFS', 'local')
-test_env.set('GSETTINGS_BACKED', 'memory')
-test_env.set('G_ENABLE_DIAGNOSTIC', '0')
-test_env.set('LIBGWEATHER_LOCATIONS_PATH', locations_bin.full_path())
+gweather_test_env = environment()
+gweather_test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
+gweather_test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
+gweather_test_env.set('GIO_USE_VFS', 'local')
+gweather_test_env.set('GSETTINGS_BACKED', 'memory')
+gweather_test_env.set('G_ENABLE_DIAGNOSTIC', '0')
+gweather_test_env.set('LIBGWEATHER_LOCATIONS_PATH', locations_bin.full_path())
-test('test_libgweather',
- executable('test_libgweather',
- sources: ['test_libgweather.c'],
- c_args: test_cargs,
- dependencies: libgweather_static_dep,
- install: false,
- ),
- args: ['--tap', '-k'],
- protocol: 'tap',
- env: test_env,
- depends: [locations_bin],
-)
+gweather_tests = [
+ { 'name': 'test_libgweather' },
+ {
+ 'name': 'duplicates',
+ 'env': {
+ 'LIBGWEATHER_LOCATIONS_NO_NEAREST': '1',
+ },
+ },
+]
+
+foreach t: gweather_tests
+ test_name = t['name']
+ test_sources = [test_name + '.c'] + t.get('sources', [])
+ test_c_args = gweather_test_cargs + t.get('c_args', [])
+ test_env = gweather_test_env
+
+ extra_env = t.get('env', {})
+ foreach var, value: extra_env
+ test_env.set(var, value)
+ endforeach
+
+ test(test_name,
+ executable(test_name,
+ sources: test_sources,
+ c_args: test_c_args,
+ dependencies: libgweather_static_dep,
+ install: false,
+ ),
+ args: ['--tap', '-k'],
+ protocol: 'tap',
+ env: test_env,
+ depends: [locations_bin],
+ )
+endforeach
diff --git a/libgweather/tests/test_libgweather.c b/libgweather/tests/test_libgweather.c
index c7d07a9..7fa4408 100644
--- a/libgweather/tests/test_libgweather.c
+++ b/libgweather/tests/test_libgweather.c
@@ -554,141 +554,6 @@ test_utc_sunset (void)
}
static void
-check_bad_duplicate_weather_stations (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- GPtrArray *stations = value;
- GHashTable *dedup;
- guint i;
-
- if (stations->len == 1)
- goto out;
-
- dedup = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- for (i = 0; i < stations->len; i++) {
- GWeatherLocation *location = g_ptr_array_index (stations, i);
-
- double latitude, longitude;
- gweather_location_get_coords (location, &latitude, &longitude);
-
- char *coords = g_strdup_printf ("%.10lf %.10lf", latitude, longitude);
- g_hash_table_insert (dedup, coords, GUINT_TO_POINTER (1));
- }
-
- if (g_hash_table_size (dedup) > 1) {
- g_test_message ("Airport '%s' is defined %u times in different ways\n",
- (const char *) key,
- stations->len);
- g_test_fail ();
- }
-
- g_hash_table_destroy (dedup);
-
-out:
- g_ptr_array_free (stations, TRUE);
-}
-
-static void
-test_bad_duplicate_weather_stations_children (GWeatherLocation *location,
- GHashTable *stations_ht)
-{
- g_autoptr (GWeatherLocation) child = NULL;
- while ((child = gweather_location_next_child (location, child)) != NULL) {
- if (gweather_location_get_level (child) == GWEATHER_LOCATION_WEATHER_STATION) {
- GPtrArray *stations;
- const char *code;
-
- code = gweather_location_get_code (child);
-
- stations = g_hash_table_lookup (stations_ht, code);
- if (!stations) {
- stations = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
- g_hash_table_insert (stations_ht, g_strdup (code), stations);
- }
- g_ptr_array_add (stations, g_object_ref (child));
- } else {
- test_bad_duplicate_weather_stations_children (child, stations_ht);
- }
- }
-}
-
-static void
-test_bad_duplicate_weather_stations (void)
-{
- g_autoptr (GWeatherLocation) world = NULL;
- GHashTable *stations_ht;
-
- g_setenv ("LIBGWEATHER_LOCATIONS_NO_NEAREST", "1", TRUE);
- world = gweather_location_get_world ();
- g_assert_nonnull (world);
-
- stations_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) NULL);
- test_bad_duplicate_weather_stations_children (world, stations_ht);
-
- g_hash_table_foreach (stations_ht, check_bad_duplicate_weather_stations, NULL);
-
- g_hash_table_unref (stations_ht);
-
- g_unsetenv ("LIBGWEATHER_LOCATIONS_NO_NEAREST");
- g_clear_object (&world);
- _gweather_location_reset_world ();
-}
-
-static void
-test_duplicate_weather_stations_children (GWeatherLocation *location)
-{
- g_autoptr (GHashTable) stations_ht = NULL;
-
- g_autoptr (GWeatherLocation) child = NULL;
- while ((child = gweather_location_next_child (location, child)) != NULL) {
- if (gweather_location_get_level (child) == GWEATHER_LOCATION_WEATHER_STATION) {
- const char *code;
-
- code = gweather_location_get_code (child);
- if (stations_ht == NULL) {
- stations_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) NULL);
- } else {
- gboolean exists;
-
- exists = GPOINTER_TO_INT (g_hash_table_lookup (stations_ht, code));
- if (exists) {
- GWeatherLocationLevel parent_level;
-
- parent_level = gweather_location_get_level (location);
- g_test_message ("Duplicate weather station '%s' in %s (level '%s')\n",
- code,
- gweather_location_get_name (location),
- gweather_location_level_to_string (parent_level));
- g_test_fail ();
- return;
- }
- }
-
- g_hash_table_insert (stations_ht, g_strdup (code), GINT_TO_POINTER (1));
- } else {
- test_duplicate_weather_stations_children (child);
- }
- }
-}
-
-static void
-test_duplicate_weather_stations (void)
-{
- g_autoptr (GWeatherLocation) world = NULL;
-
- g_setenv ("LIBGWEATHER_LOCATIONS_NO_NEAREST", "1", TRUE);
- world = gweather_location_get_world ();
- g_assert_nonnull (world);
-
- test_duplicate_weather_stations_children (world);
-
- g_unsetenv ("LIBGWEATHER_LOCATIONS_NO_NEAREST");
- g_clear_object (&world);
- _gweather_location_reset_world ();
-}
-
-static void
test_location_names (void)
{
g_autoptr (GWeatherLocation) world = NULL;
@@ -904,8 +769,6 @@ main (int argc, char *argv[])
g_test_add_func ("/weather/utc_sunset", test_utc_sunset);
g_test_add_func ("/weather/weather-loop-use-after-free", test_weather_loop_use_after_free);
/* Modifies environment, so needs to run last */
- g_test_add_func ("/weather/bad_duplicate_weather_stations", test_bad_duplicate_weather_stations);
- g_test_add_func ("/weather/duplicate_weather_stations", test_duplicate_weather_stations);
g_test_add_func ("/weather/location-names", test_location_names);
g_test_add_func ("/weather/walk_world", test_walk_world);