[libshumate] tests: Add ShumateNetworkTileSource tests
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] tests: Add ShumateNetworkTileSource tests
- Date: Tue, 6 Apr 2021 21:11:29 +0000 (UTC)
commit 006dbe774c6e16eb944cdb2aa2428cd79951efd7
Author: James Westman <james jwestman net>
Date: Fri Mar 26 22:23:15 2021 -0500
tests: Add ShumateNetworkTileSource tests
tests/network-tile-source.c | 143 +++++++++++++++++++++++++++++++++++++++++++-
tests/test-tile-server.c | 111 ++++++++++++++++++++++++----------
tests/test-tile-server.h | 5 +-
3 files changed, 224 insertions(+), 35 deletions(-)
---
diff --git a/tests/network-tile-source.c b/tests/network-tile-source.c
index fce9eeb..bceca25 100644
--- a/tests/network-tile-source.c
+++ b/tests/network-tile-source.c
@@ -1,4 +1,5 @@
#include <gtk/gtk.h>
+#include <libsoup/soup.h>
#include <shumate/shumate.h>
#include "test-tile-server.h"
@@ -10,9 +11,11 @@ create_tile_source (const char *uri)
// source
g_autofree char *template = g_strdup_printf ("%s/#X#/#Y#/#Z#", uri);
+ g_autofree char *r = g_uuid_string_random ();
+ g_autofree char *id = g_strdup_printf ("test_%s", r);
return SHUMATE_MAP_SOURCE (
- shumate_network_tile_source_new_full ("testsrc",
+ shumate_network_tile_source_new_full (id,
"Test Source",
NULL, NULL,
0, 20,
@@ -51,8 +54,140 @@ test_network_tile_source_tile (void)
g_main_loop_run (loop);
g_assert_nonnull (shumate_tile_get_texture (tile));
+ test_tile_server_assert_requests (server, 1);
}
+/* Test that once a tile is requested, future requests go to the cache */
+static void
+test_network_tile_cache_hit (void)
+{
+ g_autoptr(TestTileServer) server = test_tile_server_new ();
+ g_autofree char *uri = test_tile_server_start (server);
+ g_autoptr(ShumateMapSource) source = create_tile_source (uri);
+ g_autoptr(ShumateTile) tile = shumate_tile_new_full (0, 0, 256, 1);
+ g_autoptr(GMainLoop) loop = NULL;
+
+ g_object_ref_sink (tile);
+
+ /* Fill the tile */
+ loop = g_main_loop_new (NULL, TRUE);
+ shumate_map_source_fill_tile_async (source, tile, NULL, on_tile_filled, loop);
+ g_main_loop_run (loop);
+
+ g_assert_nonnull (shumate_tile_get_texture (tile));
+
+ shumate_tile_set_texture (tile, NULL);
+
+ test_tile_server_assert_requests (server, 1);
+ loop = g_main_loop_new (NULL, TRUE);
+ shumate_map_source_fill_tile_async (source, tile, NULL, on_tile_filled, loop);
+ g_main_loop_run (loop);
+
+ g_assert_nonnull (shumate_tile_get_texture (tile));
+ test_tile_server_assert_requests (server, 0);
+}
+
+
+static void
+on_filled_invalid_url (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+ GMainLoop *loop = user_data;
+
+ shumate_map_source_fill_tile_finish ((ShumateMapSource *) object, res, &error);
+ g_assert_error (error, SHUMATE_NETWORK_SOURCE_ERROR, SHUMATE_NETWORK_SOURCE_ERROR_MALFORMED_URL);
+
+ g_main_loop_quit (loop);
+}
+
+/* Test that the proper error is thrown when the URL is invalid */
+static void
+test_network_tile_invalid_url (void)
+{
+ char *uri = "this isn't a valid url";
+ g_autoptr(ShumateMapSource) source = create_tile_source (uri);
+ g_autoptr(ShumateTile) tile = shumate_tile_new_full (0, 0, 256, 1);
+ g_autoptr(GMainLoop) loop = NULL;
+
+ g_object_ref_sink (tile);
+
+ /* Fill the tile */
+ loop = g_main_loop_new (NULL, TRUE);
+ shumate_map_source_fill_tile_async (source, tile, NULL, on_filled_invalid_url, loop);
+ g_main_loop_run (loop);
+
+ g_assert_null (shumate_tile_get_texture (tile));
+}
+
+
+static void
+on_filled_bad_response (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+ GMainLoop *loop = user_data;
+
+ shumate_map_source_fill_tile_finish ((ShumateMapSource *) object, res, &error);
+ g_assert_error (error, SHUMATE_NETWORK_SOURCE_ERROR, SHUMATE_NETWORK_SOURCE_ERROR_BAD_RESPONSE);
+
+ g_main_loop_quit (loop);
+}
+
+/* Test that the proper error is thrown when a bad response is returned */
+static void
+test_network_tile_bad_response (void)
+{
+ g_autoptr(TestTileServer) server = test_tile_server_new ();
+ g_autofree char *uri = test_tile_server_start (server);
+ g_autoptr(ShumateMapSource) source = create_tile_source (uri);
+ g_autoptr(ShumateTile) tile = shumate_tile_new_full (0, 0, 256, 1);
+ g_autoptr(GMainLoop) loop = NULL;
+
+ g_object_ref_sink (tile);
+ test_tile_server_set_status (server, 404);
+
+ /* Fill the tile */
+ loop = g_main_loop_new (NULL, TRUE);
+ shumate_map_source_fill_tile_async (source, tile, NULL, on_filled_bad_response, loop);
+ g_main_loop_run (loop);
+
+ g_assert_null (shumate_tile_get_texture (tile));
+}
+
+
+static void
+on_filled_invalid_data (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+ GMainLoop *loop = user_data;
+
+ shumate_map_source_fill_tile_finish ((ShumateMapSource *) object, res, &error);
+ g_assert_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_UNKNOWN_TYPE);
+
+ g_main_loop_quit (loop);
+}
+
+/* Test that the proper error is thrown when invalid data is returned */
+static void
+test_network_tile_invalid_data (void)
+{
+ g_autoptr(TestTileServer) server = test_tile_server_new ();
+ g_autofree char *uri = test_tile_server_start (server);
+ g_autoptr(ShumateMapSource) source = create_tile_source (uri);
+ g_autoptr(ShumateTile) tile = shumate_tile_new_full (0, 0, 256, 1);
+ g_autoptr(GMainLoop) loop = NULL;
+
+ g_object_ref_sink (tile);
+ test_tile_server_set_data (server, "this is not an image file");
+
+ /* Fill the tile */
+ loop = g_main_loop_new (NULL, TRUE);
+ shumate_map_source_fill_tile_async (source, tile, NULL, on_filled_invalid_data, loop);
+ g_main_loop_run (loop);
+
+ g_assert_null (shumate_tile_get_texture (tile));
+}
+
+
int
main (int argc, char *argv[])
{
@@ -60,6 +195,12 @@ main (int argc, char *argv[])
gtk_init ();
g_test_add_func ("/network-tile-source/tile", test_network_tile_source_tile);
+ /* shumate_network_source_fill_tile_async doesn't wait for the cache
+ * operation to finish, so this is unreliable */
+ /* g_test_add_func ("/network-tile-source/cache-hit", test_network_tile_cache_hit); */
+ g_test_add_func ("/network-tile-source/invalid-url", test_network_tile_invalid_url);
+ g_test_add_func ("/network-tile-source/bad-response", test_network_tile_bad_response);
+ g_test_add_func ("/network-tile-source/invalid-data", test_network_tile_invalid_data);
return g_test_run ();
}
diff --git a/tests/test-tile-server.c b/tests/test-tile-server.c
index 719be56..6820bc4 100644
--- a/tests/test-tile-server.c
+++ b/tests/test-tile-server.c
@@ -11,11 +11,43 @@ struct _TestTileServer
{
GObject parent_instance;
SoupServer *server;
+ GBytes *bytes;
+ int requests;
+ int status;
+ char *etag;
};
G_DEFINE_TYPE (TestTileServer, test_tile_server, G_TYPE_OBJECT)
+static cairo_status_t
+write_func (void *bytearray, const unsigned char *data, unsigned int length)
+{
+ g_byte_array_append ((GByteArray *) bytearray, data, length);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static GBytes *
+generate_image ()
+{
+ GByteArray *bytearray = g_byte_array_new ();
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256, 256);
+
+ cr = cairo_create (surface);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_write_to_png_stream (surface, write_func, bytearray);
+ cairo_surface_destroy (surface);
+
+ return g_byte_array_free_to_bytes (bytearray);
+}
+
+
TestTileServer *
test_tile_server_new (void)
{
@@ -28,6 +60,8 @@ test_tile_server_finalize (GObject *object)
TestTileServer *self = (TestTileServer *)object;
g_clear_object (&self->server);
+ g_clear_pointer (&self->bytes, g_bytes_unref);
+ g_clear_pointer (&self->etag, g_free);
G_OBJECT_CLASS (test_tile_server_parent_class)->finalize (object);
}
@@ -44,35 +78,8 @@ static void
test_tile_server_init (TestTileServer *self)
{
self->server = soup_server_new (NULL, NULL);
-}
-
-
-static cairo_status_t
-write_func (void *bytearray, const unsigned char *data, unsigned int length)
-{
- g_byte_array_append ((GByteArray *) bytearray, data, length);
- return CAIRO_STATUS_SUCCESS;
-}
-
-
-static GBytes *
-generate_image ()
-{
- GByteArray *bytearray = g_byte_array_new ();
- cairo_surface_t *surface;
- cairo_t *cr;
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256, 256);
-
- cr = cairo_create (surface);
- cairo_set_source_rgb (cr, 1, 0, 0);
- cairo_paint (cr);
- cairo_destroy (cr);
-
- cairo_surface_write_to_png_stream (surface, write_func, bytearray);
- cairo_surface_destroy (surface);
-
- return g_byte_array_free_to_bytes (bytearray);
+ self->bytes = generate_image ();
+ self->status = 200;
}
@@ -84,11 +91,19 @@ server_callback (SoupServer *server,
SoupClientContext *client,
gpointer user_data)
{
+ TestTileServer *self = user_data;
gsize data_size;
- const char *data = g_bytes_get_data ((GBytes *) user_data, &data_size);
+ const char *data = NULL;
+
+ self->requests ++;
+
+ if (self->bytes)
+ {
+ data = g_bytes_get_data (self->bytes, &data_size);
+ soup_message_set_response (msg, "image/png", SOUP_MEMORY_STATIC, data, data_size);
+ }
- soup_message_set_response (msg, "image/png", SOUP_MEMORY_STATIC, data, data_size);
- soup_message_set_status (msg, 200);
+ soup_message_set_status (msg, self->status);
}
@@ -97,7 +112,7 @@ test_tile_server_start (TestTileServer *self)
{
g_autoptr(GError) error = NULL;
g_autoptr(GSList) uris = NULL;
- soup_server_add_handler (self->server, NULL, server_callback, generate_image (), (GDestroyNotify)
g_bytes_unref);
+ soup_server_add_handler (self->server, NULL, server_callback, self, NULL);
soup_server_listen_local (self->server, 0, 0, &error);
g_assert_no_error (error);
@@ -106,3 +121,33 @@ test_tile_server_start (TestTileServer *self)
g_assert_true (g_slist_length (uris) >= 1);
return soup_uri_to_string (uris->data, FALSE);
}
+
+void
+test_tile_server_assert_requests (TestTileServer *self, int times)
+{
+ g_assert_cmpint (self->requests, ==, times);
+ self->requests = 0;
+}
+
+void
+test_tile_server_set_status (TestTileServer *self, int status)
+{
+ self->status = status;
+}
+
+void
+test_tile_server_set_data (TestTileServer *self, const char *data)
+{
+ g_bytes_unref (self->bytes);
+ if (data)
+ self->bytes = g_bytes_new (data, strlen (data));
+ else
+ self->bytes = NULL;
+}
+
+void
+test_tile_server_set_etag (TestTileServer *self, const char *etag)
+{
+ g_clear_pointer (&self->etag, g_free);
+ self->etag = g_strdup (etag);
+}
diff --git a/tests/test-tile-server.h b/tests/test-tile-server.h
index fe2d802..98e24f3 100644
--- a/tests/test-tile-server.h
+++ b/tests/test-tile-server.h
@@ -12,6 +12,9 @@ G_DECLARE_FINAL_TYPE (TestTileServer, test_tile_server, TEST, TILE_SERVER, GObje
TestTileServer *test_tile_server_new (void);
char *test_tile_server_start (TestTileServer *self);
-
+void test_tile_server_assert_requests (TestTileServer *self, int times);
+void test_tile_server_set_status (TestTileServer *self, int status);
+void test_tile_server_set_data (TestTileServer *self, const char *data);
+void test_tile_server_set_etag (TestTileServer *self, const char *etag);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]