[libsoup/autobahn-integration-new: 14/23] autobahn: Various improvements:
- From: Diego Pino <dpino src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/autobahn-integration-new: 14/23] autobahn: Various improvements:
- Date: Fri, 12 Mar 2021 02:34:08 +0000 (UTC)
commit 0047575adf9018e45f86e2d95f6d5d86424f4f7b
Author: Patrick Griffis <pgriffis igalia com>
Date: Fri Feb 5 12:47:45 2021 -0600
autobahn: Various improvements:
- build: change autobahn into a auto-detected feature
- build: Remove duplication from existing test build file
- Avoid using __FILE__ and use GLibs test file utils
- Change indentation to be consistent with project
- Remove duplicate args to list number of tests or run specific tests
glib provides this already
- In each test case run mainloop to completion to properly track case status
- Generate a report every run
- Output reports into the meson-logs directory, not the CWD of source
- Actually run the server until it is listening rather than sleep()
.gitlab-ci.yml | 2 +-
meson.build | 8 +-
meson_options.txt | 6 +-
tests/autobahn/autobahn-server.json.in | 8 +
tests/autobahn/autobahn-server.sh | 9 +-
tests/autobahn/autobahn-test.c | 260 ++++++++++++++++++++++++
tests/autobahn/fuzzingserver.json | 8 -
tests/autobahn/meson.build | 39 ++--
tests/autobahn/soup-autobahn-test-client.c | 304 -----------------------------
tests/meson.build | 4 +
10 files changed, 297 insertions(+), 351 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 18de3d45..c0b9c547 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -42,7 +42,7 @@ fedora-autobahn:
- "tests/autobahn"
artifacts:
paths:
- - "_build/tests/autobahn/autobahn-report"
+ - "_build/meson-logs/autobahn-report"
fedora-scan:
extends: .build
diff --git a/meson.build b/meson.build
index 92db547b..c0eda487 100644
--- a/meson.build
+++ b/meson.build
@@ -281,7 +281,9 @@ if have_apache
endif
endif
-if not have_apache
+have_autobahn = find_program('wstest', required: get_option('autobahn')).found()
+
+if not have_apache or not have_autobahn
warning('Some regression tests will not be compiled due to missing libraries or modules. Please check the
logs for more details.')
endif
@@ -411,7 +413,3 @@ summary({
},
section : 'Testing'
)
-
-if get_option('autobahn')
- subdir('tests/autobahn')
-endif
diff --git a/meson_options.txt b/meson_options.txt
index 6462fa9f..778e5d34 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -60,9 +60,9 @@ option('tests',
)
option('autobahn',
- type: 'boolean',
- value: 'true',
- description: 'Enable autobahn client compilation'
+ type: 'feature',
+ value: 'auto',
+ description: 'Enable autobahn test suite'
)
option('installed_tests',
diff --git a/tests/autobahn/autobahn-server.json.in b/tests/autobahn/autobahn-server.json.in
new file mode 100644
index 00000000..02f86501
--- /dev/null
+++ b/tests/autobahn/autobahn-server.json.in
@@ -0,0 +1,8 @@
+
+{
+ "url": "ws://127.0.0.1:9001",
+ "outdir": "@MESON_BUILD_ROOT@/meson-logs/autobahn-reports",
+ "cases": ["*"],
+ "exclude-cases": [],
+ "exclude-agent-cases": {}
+}
diff --git a/tests/autobahn/autobahn-server.sh b/tests/autobahn/autobahn-server.sh
index 9596e72b..74046e75 100755
--- a/tests/autobahn/autobahn-server.sh
+++ b/tests/autobahn/autobahn-server.sh
@@ -2,12 +2,6 @@
# set -x
-REPORTS_DIR="${PWD}/reports"
-
-cd "$(dirname "$0")"
-
-[ ! -d "${REPORTS_DIR}" ] && mkdir "${REPORTS_DIR}"
-
ACTION=${1:---start}
PORT=${2:-9001}
@@ -38,8 +32,7 @@ autobahn_start() {
--name fuzzingserver \
crossbario/autobahn-testsuite
else
- virtualenv ~/wstest
- wstest -m fuzzingserver &> autobahn-server.log
+ wstest -m fuzzingserver -s 'autobahn-server.json'
fi
}
diff --git a/tests/autobahn/autobahn-test.c b/tests/autobahn/autobahn-test.c
new file mode 100644
index 00000000..406b76fc
--- /dev/null
+++ b/tests/autobahn/autobahn-test.c
@@ -0,0 +1,260 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-autobahn-test-client.c
+ *
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ */
+
+#include "test-utils.h"
+
+#include <libsoup/soup.h>
+
+static char *address = "ws://localhost:9001";
+static char *agent = "libsoup";
+
+typedef void (*ConnectionFunc) (SoupWebsocketConnection *socket_connection,
+ gint type,
+ GBytes *message,
+ gpointer data);
+
+typedef struct {
+ ConnectionFunc method;
+ gpointer data;
+ gboolean done;
+} ConnectionContext;
+
+typedef struct {
+ SoupSession *session;
+ unsigned int num_test_case;
+ char *path;
+} TestBundle;
+
+static void
+test_bundle_free (TestBundle *bundle)
+{
+ g_free (bundle->path);
+ g_free (bundle);
+}
+
+static void
+on_message_received (SoupWebsocketConnection *socket_connection,
+ gint type, GBytes *message,
+ gpointer data)
+{
+ ConnectionContext *ctx = (ConnectionContext *)data;
+
+ g_test_message ("Message recieved");
+
+ if (ctx && ctx->method)
+ ctx->method (socket_connection, type, message, ctx->data);
+}
+
+static void
+on_connection_closed (SoupWebsocketConnection *socket_connection,
+ gpointer data)
+{
+ ConnectionContext *ctx = (ConnectionContext *)data;
+
+ g_test_message ("Connection closed");
+
+ g_object_unref (socket_connection);
+
+ ctx->done = TRUE;
+}
+
+static void
+on_connect (GObject *session,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ ConnectionContext *ctx = user_data;
+ GError *error = NULL;
+ SoupWebsocketConnection *socket_connection = soup_session_websocket_connect_finish (SOUP_SESSION
(session), res, &error);
+ if (!socket_connection) {
+ g_test_message ("Connection failed: %s", error->message);
+ g_error_free (error);
+ ctx->done = TRUE;
+ return;
+ }
+
+ /* The performance tests increase the size of the payload up to 16 MB, let's disable
+ the limit to see what happens. */
+ soup_websocket_connection_set_max_incoming_payload_size (socket_connection, 0);
+
+ g_test_message ("Connected");
+ g_signal_connect (socket_connection, "message", G_CALLBACK (on_message_received), ctx);
+ g_signal_connect (socket_connection, "closed", G_CALLBACK (on_connection_closed), ctx);
+}
+
+static void
+connect_and_run (SoupSession *session, char *path, ConnectionFunc method, gpointer data)
+{
+ char *uri = g_strconcat (address, path, NULL);
+ SoupMessage *message = soup_message_new (SOUP_METHOD_GET, uri);
+ ConnectionContext *ctx = g_new0 (ConnectionContext, 1);
+ GMainContext *async_context = g_main_context_ref_thread_default ();
+
+ ctx->method = method;
+ ctx->data = data;
+ ctx->done = FALSE;
+
+ g_test_message ("Connecting to %s", uri);
+ soup_session_websocket_connect_async (session, message, NULL, NULL, G_PRIORITY_DEFAULT, NULL,
on_connect, ctx);
+
+ while (!ctx->done)
+ g_main_context_iteration (async_context, TRUE);
+
+ g_object_unref (message);
+ g_free (uri);
+ g_free (ctx);
+ g_main_context_unref (async_context);
+}
+
+static void
+test_case_message_received (SoupWebsocketConnection *socket_connection,
+ gint type,
+ GBytes *message,
+ gpointer data)
+{
+ /* Cannot send messages if we're not in an open state. */
+ if (soup_websocket_connection_get_state (socket_connection) != SOUP_WEBSOCKET_STATE_OPEN)
+ return;
+
+ g_test_message ("Sending message");
+
+ soup_websocket_connection_send_message (socket_connection, type, message);
+}
+
+static void
+test_case (gconstpointer data)
+{
+ TestBundle *bundle = (TestBundle *)data;
+
+ connect_and_run (bundle->session, bundle->path, test_case_message_received, bundle);
+}
+
+static void
+update_reports (SoupSession *session)
+{
+ char *path = g_strdup_printf ("/updateReports?agent=%s", agent);
+ g_test_message ("Updating reports...");
+ connect_and_run (session, path, NULL, NULL);
+ g_free (path);
+}
+
+static gboolean
+autobahn_server (const char *action, guint64 *num_cases_out)
+{
+ GSubprocessLauncher *launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
+ GSubprocess *proc;
+ GError *error = NULL;
+ char *build_dir;
+ char *autobahn_script;
+
+ autobahn_script = g_test_build_filename (G_TEST_DIST, "autobahn", "autobahn-server.sh", NULL);
+ build_dir = g_test_build_filename (G_TEST_BUILT, "autobahn", NULL);
+
+ g_subprocess_launcher_set_cwd (launcher, build_dir);
+ proc = g_subprocess_launcher_spawn (launcher, &error, autobahn_script, action, NULL);
+
+ g_free (autobahn_script);
+ g_free (build_dir);
+ g_object_unref (launcher);
+
+ if (error) {
+ debug_printf (1, "Error running autobahn script: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ /* We are done if we are stopping the server */
+ if (strcmp (action, "--start"))
+ return TRUE;
+
+ GDataInputStream *stdout = g_data_input_stream_new (g_subprocess_get_stdout_pipe (proc));
+ GRegex *re = g_regex_new ("Ok, will run (\\d+) test cases", 0, 0, NULL);
+ char *line = NULL;
+ gboolean ret = FALSE;
+
+ /* Read the process output until we know its listening successfully */
+ while (TRUE) {
+ line = g_data_input_stream_read_line_utf8 (stdout, NULL, NULL, NULL);
+ if (!line)
+ goto done;
+
+ GMatchInfo *match;
+ if (g_regex_match (re, line, 0, &match)) {
+ char *matched_number = g_match_info_fetch (match, 1);
+ *num_cases_out = g_ascii_strtoull (matched_number, NULL, 10);
+
+ ret = TRUE;
+ g_free (matched_number);
+ g_match_info_unref (match);
+ goto done;
+ }
+
+ g_clear_pointer (&line, g_free);
+ }
+
+done:
+ g_free (line);
+ g_object_unref (stdout);
+ g_object_unref (proc);
+ g_regex_unref (re);
+
+ return ret;
+}
+
+int main (int argc, char *argv[])
+{
+ int ret = 0;
+ guint64 num_cases;
+ SoupSession *session;
+
+ test_init (argc, argv, NULL);
+
+ if (!autobahn_server ("--start", &num_cases))
+ exit (1);
+
+ session = soup_session_new ();
+ soup_session_add_feature_by_type (session, SOUP_TYPE_WEBSOCKET_EXTENSION_MANAGER);
+
+ for (int i = 0; i < num_cases; i++) {
+ char *test_path = g_strdup_printf ("/autobahn/%u", i);
+
+ TestBundle *bundle = g_new0 (TestBundle, 1);
+ bundle->session = session;
+ bundle->num_test_case = i;
+ bundle->path = g_strdup_printf ("/runCase?case=%u&agent=%s", i, agent);
+
+ g_test_add_data_func_full (test_path, bundle, test_case, (GDestroyNotify)test_bundle_free);
+
+ g_free (test_path);
+ }
+
+ ret = g_test_run ();
+
+ update_reports (session);
+
+ g_object_unref (session);
+
+ autobahn_server ("--stop", NULL);
+ test_cleanup ();
+
+ return ret;
+}
diff --git a/tests/autobahn/meson.build b/tests/autobahn/meson.build
index 9c158ad2..c4598bd4 100644
--- a/tests/autobahn/meson.build
+++ b/tests/autobahn/meson.build
@@ -1,26 +1,21 @@
-test_utils_name = 'test-utils'
-installed_tests_execdir = join_paths(get_option('libexecdir'), 'installed-tests', libsoup_api_name)
-installed_tests_enabled = get_option('installed_tests')
-abs_installed_tests_execdir = join_paths(prefix, installed_tests_execdir)
+autobahn_conf = configuration_data()
+autobahn_conf.set('MESON_BUILD_ROOT', meson.build_root())
-if cc.get_id() == 'msvc'
- test_utils = static_library(test_utils_name, '../' + test_utils_name + '.c',
- dependencies : libsoup_static_dep)
-else
- test_utils = library(test_utils_name, '../' + test_utils_name + '.c',
- dependencies : libsoup_static_dep,
- install : installed_tests_enabled,
- install_dir : installed_tests_execdir,
- )
-endif
+configure_file(
+ input : 'autobahn-server.json.in',
+ output : 'autobahn-server.json',
+ configuration : autobahn_conf,
+)
-deps = [
- glib_deps,
- libsoup_dep
-]
+client = executable('autobahn-test', 'autobahn-test.c',
+ link_with : test_utils,
+ dependencies : libsoup_static_dep,
+ include_directories : include_directories('..'),
+)
-client = executable('soup-autobahn-test-client', 'soup-autobahn-test-client.c',
- dependencies: deps,
- link_with : test_utils
+test('autobahn-test', client,
+ suite : 'autobahn',
+ env : env,
+ timeout : 3600,
+ protocol : 'tap',
)
-test('soup-autobahn-test-client', client, suite: 'autobahn', timeout: 3600)
diff --git a/tests/meson.build b/tests/meson.build
index c847a254..0892cccf 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -137,6 +137,10 @@ env.set('MALLOC_CHECK_', '2')
# This is set by Meson if empty
env.set('MALLOC_PERTURB_', '')
+if have_autobahn
+ subdir('autobahn')
+endif
+
foreach test: tests
test_name = '@0@-test'.format(test[0])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]