From 985b010a84e5c49165657b96495c77e894539111 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 19 Nov 2021 17:41:46 +0000 Subject: tests: Move METAR test to its own suite This allows us to remove the libsoup include from the shared test utilities header. --- libgweather/tests/gweather-test-utils.h | 1 - libgweather/tests/meson.build | 1 + libgweather/tests/metar.c | 191 ++++++++++++++++++++++++++++++++ libgweather/tests/test_libgweather.c | 162 --------------------------- 4 files changed, 192 insertions(+), 163 deletions(-) create mode 100644 libgweather/tests/metar.c diff --git a/libgweather/tests/gweather-test-utils.h b/libgweather/tests/gweather-test-utils.h index c899e9b..f94014e 100644 --- a/libgweather/tests/gweather-test-utils.h +++ b/libgweather/tests/gweather-test-utils.h @@ -8,7 +8,6 @@ #include #include -#include #include #include diff --git a/libgweather/tests/meson.build b/libgweather/tests/meson.build index 6baddd7..5ff528f 100644 --- a/libgweather/tests/meson.build +++ b/libgweather/tests/meson.build @@ -20,6 +20,7 @@ gweather_tests = [ }, }, { 'name': 'timezones' }, + { 'name': 'metar' }, ] foreach t: gweather_tests diff --git a/libgweather/tests/metar.c b/libgweather/tests/metar.c new file mode 100644 index 0000000..7d6c7c0 --- /dev/null +++ b/libgweather/tests/metar.c @@ -0,0 +1,191 @@ +/* metar.c: METAR tests + * + * SPDX-FileCopyrightText: 2021 Emmanuele Bassi + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include "gweather-test-utils.h" + +#include + +/* For test_metar_weather_stations */ +#define METAR_SOURCES "https://www.aviationweather.gov/docs/metar/stations.txt" + +static GHashTable * +parse_metar_stations (const char *contents) +{ + GHashTable *stations_ht; + char **lines; + guint i, num_stations; + + stations_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + num_stations = 0; + lines = g_strsplit (contents, "\n", -1); + + for (i = 0; lines[i] != NULL; i++) { + char *line = lines[i]; + char *station; + + if (line[0] == '!') + continue; + + if (strlen (line) != 83) + continue; + + station = g_strndup (line + 20, 4); + /* Skip stations with no ICAO code */ + if (g_str_equal (station, " ")) { + g_free (station); + continue; + } + + if (g_hash_table_lookup (stations_ht, station)) { + const char * const known_duplicates[] = { + "VOGO", + "KHQG", + "KOEL", + "KTQK", + "KX26", + NULL + }; + if (g_strv_contains (known_duplicates, station)) { + g_free (station); + continue; + } + g_test_message ("Weather station '%s' already defined\n", station); + } + + g_hash_table_insert (stations_ht, station, g_strdup (line)); + num_stations++; + } + + g_strfreev (lines); + + /* Duplicates? */ + g_assert_cmpuint (num_stations, ==, g_hash_table_size (stations_ht)); + + g_test_message ("Parsed %u weather stations", num_stations); + + return stations_ht; +} + +static void +test_metar_weather_station (GWeatherLocation *location, + GHashTable *stations_ht) +{ + const char *code, *line; + + code = gweather_location_get_code (location); + g_assert_nonnull (code); + + line = g_hash_table_lookup (stations_ht, code); + if (!line) { + g_test_message ("Could not find airport for '%s' in " METAR_SOURCES "\n", code); + g_test_fail (); + } else { + char *has_metar; + + has_metar = g_strndup (line + 62, 1); + if (*has_metar == 'Z') { + g_test_message ("Airport weather station '%s' is obsolete\n", code); + g_test_fail (); + } else if (*has_metar == ' ') { + g_test_message ("Could not find weather station for '%s' in " METAR_SOURCES "\n", code); + g_test_fail (); + } + g_free (has_metar); + } +} + +static void +test_metar_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) + test_metar_weather_station (child, stations_ht); + else + test_metar_weather_stations_children (child, stations_ht); + } +} + +static void +test_metar_weather_stations (void) +{ + g_autoptr (GWeatherLocation) world = NULL; + SoupMessage *msg; + SoupSession *session; + GHashTable *stations_ht; + char *contents; +#if SOUP_CHECK_VERSION(2, 99, 2) + GBytes *body; + GError *error = NULL; + gsize bsize; +#endif + + world = gweather_location_get_world (); + g_assert_nonnull (world); + + msg = soup_message_new ("GET", METAR_SOURCES); + session = soup_session_new (); +#if SOUP_CHECK_VERSION(2, 99, 2) + body = soup_session_send_and_read (session, msg, NULL, &error); + if (error && error->domain == G_TLS_ERROR) { +#else + soup_session_send_message (session, msg); + if (msg->status_code == SOUP_STATUS_SSL_FAILED) { +#endif + g_test_message ("SSL/TLS failure, please check your glib-networking installation"); + g_test_failed (); + return; + } +#if SOUP_CHECK_VERSION(2, 99, 2) + g_assert_no_error (error); + g_assert_cmpint (soup_message_get_status (msg), >=, 200); + g_assert_cmpint (soup_message_get_status (msg), <, 300); + g_assert_nonnull (body); + contents = g_bytes_unref_to_data (body, &bsize); +#else + g_assert_cmpint (msg->status_code, >=, 200); + g_assert_cmpint (msg->status_code, <, 300); + g_assert_nonnull (msg->response_body); + contents = g_strndup (msg->response_body->data, msg->response_body->length); +#endif + g_object_unref (session); + g_object_unref (msg); + + stations_ht = parse_metar_stations (contents); + g_assert_nonnull (stations_ht); + g_free (contents); + + test_metar_weather_stations_children (world, stations_ht); + + g_hash_table_unref (stations_ht); + + g_clear_object (&world); + + gweather_test_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/"); + + g_autofree char *schemas_dir = gweather_test_setup_gsettings (); + + g_test_add_func ("/weather/metar_weather_stations", test_metar_weather_stations); + + int res = g_test_run (); + + gweather_test_teardown_gsettings (schemas_dir); + + return res; +} diff --git a/libgweather/tests/test_libgweather.c b/libgweather/tests/test_libgweather.c index 47f2389..6cfef2e 100644 --- a/libgweather/tests/test_libgweather.c +++ b/libgweather/tests/test_libgweather.c @@ -18,9 +18,6 @@ #include "gweather-private.h" -/* For test_metar_weather_stations */ -#define METAR_SOURCES "https://www.aviationweather.gov/docs/metar/stations.txt" - /* Maximum for test_airport_distance_sanity() */ #define TOO_FAR 100.0 static double max_distance = 0.0; @@ -113,164 +110,6 @@ test_airport_distance_sanity (void) gweather_test_reset_world (); } -static GHashTable * -parse_metar_stations (const char *contents) -{ - GHashTable *stations_ht; - char **lines; - guint i, num_stations; - - stations_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - num_stations = 0; - lines = g_strsplit (contents, "\n", -1); - - for (i = 0; lines[i] != NULL; i++) { - char *line = lines[i]; - char *station; - - if (line[0] == '!') - continue; - - if (strlen (line) != 83) - continue; - - station = g_strndup (line + 20, 4); - /* Skip stations with no ICAO code */ - if (g_str_equal (station, " ")) { - g_free (station); - continue; - } - - if (g_hash_table_lookup (stations_ht, station)) { - const char * const known_duplicates[] = { - "VOGO", - "KHQG", - "KOEL", - "KTQK", - "KX26", - NULL - }; - if (g_strv_contains (known_duplicates, station)) { - g_free (station); - continue; - } - g_test_message ("Weather station '%s' already defined\n", station); - } - - g_hash_table_insert (stations_ht, station, g_strdup (line)); - num_stations++; - } - - g_strfreev (lines); - - /* Duplicates? */ - g_assert_cmpuint (num_stations, ==, g_hash_table_size (stations_ht)); - - g_test_message ("Parsed %u weather stations", num_stations); - - return stations_ht; -} - -static void -test_metar_weather_station (GWeatherLocation *location, - GHashTable *stations_ht) -{ - const char *code, *line; - - code = gweather_location_get_code (location); - g_assert_nonnull (code); - - line = g_hash_table_lookup (stations_ht, code); - if (!line) { - g_test_message ("Could not find airport for '%s' in " METAR_SOURCES "\n", code); - g_test_fail (); - } else { - char *has_metar; - - has_metar = g_strndup (line + 62, 1); - if (*has_metar == 'Z') { - g_test_message ("Airport weather station '%s' is obsolete\n", code); - g_test_fail (); - } else if (*has_metar == ' ') { - g_test_message ("Could not find weather station for '%s' in " METAR_SOURCES "\n", code); - g_test_fail (); - } - g_free (has_metar); - } -} - -static void -test_metar_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) - test_metar_weather_station (child, stations_ht); - else - test_metar_weather_stations_children (child, stations_ht); - } -} - -static void -test_metar_weather_stations (void) -{ - g_autoptr (GWeatherLocation) world = NULL; - SoupMessage *msg; - SoupSession *session; - GHashTable *stations_ht; - char *contents; -#if SOUP_CHECK_VERSION(2, 99, 2) - GBytes *body; - GError *error = NULL; - gsize bsize; -#endif - - world = gweather_location_get_world (); - g_assert_nonnull (world); - - msg = soup_message_new ("GET", METAR_SOURCES); - session = soup_session_new (); -#if SOUP_CHECK_VERSION(2, 99, 2) - body = soup_session_send_and_read (session, msg, NULL, &error); - if (error && error->domain == G_TLS_ERROR) { -#else - soup_session_send_message (session, msg); - if (msg->status_code == SOUP_STATUS_SSL_FAILED) { -#endif - g_test_message ("SSL/TLS failure, please check your glib-networking installation"); - g_test_failed (); - return; - } -#if SOUP_CHECK_VERSION(2, 99, 2) - g_assert_no_error (error); - g_assert_cmpint (soup_message_get_status (msg), >=, 200); - g_assert_cmpint (soup_message_get_status (msg), <, 300); - g_assert_nonnull (body); - contents = g_bytes_unref_to_data (body, &bsize); -#else - g_assert_cmpint (msg->status_code, >=, 200); - g_assert_cmpint (msg->status_code, <, 300); - g_assert_nonnull (msg->response_body); - contents = g_strndup (msg->response_body->data, msg->response_body->length); -#endif - g_object_unref (session); - g_object_unref (msg); - - stations_ht = parse_metar_stations (contents); - g_assert_nonnull (stations_ht); - g_free (contents); - - test_metar_weather_stations_children (world, stations_ht); - - g_hash_table_unref (stations_ht); - - g_clear_object (&world); - - gweather_test_reset_world (); -} - static void test_utc_sunset (void) { @@ -515,7 +354,6 @@ main (int argc, char *argv[]) g_test_add_func ("/weather/radians-to-degrees_str", test_radians_to_degrees_str); g_test_add_func ("/weather/no-code-serialize", test_no_code_serialize); g_test_add_func ("/weather/airport_distance_sanity", test_airport_distance_sanity); - g_test_add_func ("/weather/metar_weather_stations", test_metar_weather_stations); 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); g_test_add_func ("/weather/location-names", test_location_names); -- cgit v1.2.1