aboutsummaryrefslogtreecommitdiffstats
path: root/src/libqmi-glib/test/test-fixture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libqmi-glib/test/test-fixture.c')
-rw-r--r--src/libqmi-glib/test/test-fixture.c324
1 files changed, 324 insertions, 0 deletions
diff --git a/src/libqmi-glib/test/test-fixture.c b/src/libqmi-glib/test/test-fixture.c
new file mode 100644
index 0000000..376707f
--- /dev/null
+++ b/src/libqmi-glib/test/test-fixture.c
@@ -0,0 +1,324 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details:
+ *
+ * Copyright (C) 2014 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#include <string.h>
+#include "test-fixture.h"
+
+#define VIRTUAL_SOCKET_PATH "virtual-socket-path"
+
+static const QmiService services [] = {
+ QMI_SERVICE_DMS,
+ QMI_SERVICE_NAS,
+ QMI_SERVICE_WDS,
+ QMI_SERVICE_PDS
+};
+
+static void
+device_allocate_client_ready (QmiDevice *device,
+ GAsyncResult *res,
+ TestFixture *fixture)
+{
+ GError *error = NULL;
+ QmiClient *client;
+ QmiService service;
+
+ client = qmi_device_allocate_client_finish (device, res, &error);
+ g_assert_no_error (error);
+ g_assert (QMI_IS_CLIENT (client));
+
+ service = qmi_client_get_service (client);
+ g_assert (service > QMI_SERVICE_CTL);
+ fixture->service_info[service].client = client;
+ fixture->service_info[service].transaction_id = 0x0001;
+ test_fixture_loop_stop (fixture);
+}
+
+static void
+device_open_ready (QmiDevice *device,
+ GAsyncResult *res,
+ TestFixture *fixture)
+{
+ GError *error = NULL;
+ gboolean ret;
+
+ ret = qmi_device_open_finish (device, res, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ test_fixture_loop_stop (fixture);
+}
+
+static void
+device_virtual_new_ready (GObject *source,
+ GAsyncResult *res,
+ TestFixture *fixture)
+{
+ GError *error = NULL;
+
+ fixture->device = qmi_device_new_finish (res, &error);
+ g_assert_no_error (error);
+ g_assert (QMI_IS_DEVICE (fixture->device));
+ test_fixture_loop_stop (fixture);
+}
+
+void
+test_fixture_setup (TestFixture *fixture)
+{
+ GFile *file;
+ guint i;
+ static guint32 num = 0;
+
+ g_debug ("[%lu,%p] fixture setup", (gulong) pthread_self (), g_main_context_get_thread_default ());
+
+ qmi_utils_set_traces_enabled (TRUE);
+
+ fixture->path = g_strdup_printf ("/dev/virtual/qmi%04u", num++);
+ fixture->service_info[QMI_SERVICE_CTL].transaction_id = 0x0001;
+ fixture->ctx = test_port_context_new (fixture->path);
+ test_port_context_start (fixture->ctx);
+
+ /* Create device */
+ file = g_file_new_for_path (fixture->path);
+ g_async_initable_new_async (QMI_TYPE_DEVICE,
+ G_PRIORITY_DEFAULT,
+ NULL,
+ (GAsyncReadyCallback) device_virtual_new_ready,
+ fixture,
+ QMI_DEVICE_FILE, file,
+ QMI_DEVICE_NO_FILE_CHECK, TRUE,
+ QMI_DEVICE_PROXY_PATH, fixture->path,
+ NULL);
+ g_object_unref (file);
+ test_fixture_loop_run (fixture);
+
+ /* Open device */
+ {
+ guint8 expected[] = {
+ 0x01, /* marker */
+ /* QMUX */
+ 0x22, 0x00, /* length */
+ 0x00, /* flags */
+ 0x00, /* service CTL */
+ 0x00, /* client */
+ /* QMI header */
+ 0x00, /* flags */
+ 0xFF, /* transaction */
+ 0x00, 0xFF, /* message: Internal proxy open */
+ 0x17, 0x00, /* tlv length */
+ /* TLV */
+ 0x01, /* type */
+ 0x14, 0x00, /* length */
+ 0x2F, 0x64, 0x65, 0x76, 0x2F, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6C, 0x2F, 0x71, 0x6D, 0x69, 0x00, 0x00, 0x00, 0x00
+ };
+ guint8 response[] = {
+ 0x01, /* marker */
+ /* QMUX */
+ 0x12, 0x00, /* length */
+ 0x00, /* flags */
+ 0x00, /* service CTL */
+ 0x00, /* client */
+ /* QMI header */
+ 0x01, /* flags */
+ 0xFF, /* transaction */
+ 0x00, 0xFF, /* message: Internal proxy open */
+ 0x07, 0x00, /* tlv length */
+ /* TLV */
+ 0x02, /* type: Result */
+ 0x04, 0x00, /* length */
+ 0x00, 0x00, /* error status */
+ 0x00, 0x00, /* error code */
+ };
+
+ g_assert_cmpuint (strlen (fixture->path), ==, 20);
+ memcpy (&expected[15], fixture->path, strlen (fixture->path));
+
+ test_port_context_set_command (fixture->ctx,
+ expected, G_N_ELEMENTS (expected),
+ response, G_N_ELEMENTS (response),
+ fixture->service_info[QMI_SERVICE_CTL].transaction_id++);
+ }
+ qmi_device_open (fixture->device, QMI_DEVICE_OPEN_FLAGS_PROXY, 1, NULL,
+ (GAsyncReadyCallback) device_open_ready,
+ fixture);
+ test_fixture_loop_run (fixture);
+
+ /* Allocate clients */
+ for (i = 0; i < G_N_ELEMENTS (services); i++) {
+ guint8 expected[] = {
+ 0x01, /* marker */
+ /* QMUX */
+ 0x0F, 0x00, /* length */
+ 0x00, /* flags */
+ 0x00, /* service CTL */
+ 0x00, /* client */
+ /* QMI header */
+ 0x00, /* flags */
+ 0xFF, /* transaction */
+ 0x22, 0x00, /* message: Allocate CID */
+ 0x04, 0x00, /* tlv length */
+ /* TLV */
+ 0x01, /* type */
+ 0x01, 0x00, /* length */
+ 0xFF /* UPDATE: service */
+ };
+ guint8 response[] = {
+ 0x01, /* marker */
+ /* QMUX */
+ 0x17, 0x00, /* length */
+ 0x00, /* flags */
+ 0x00, /* service */
+ 0x00, /* client */
+ /* QMI header */
+ 0x01, /* flags: Response */
+ 0xFF, /* transaction */
+ 0x22, 0x00, /* message */
+ 0x0C, 0x00, /* tlv length */
+ /* TLV */
+ 0x02, /* type: Result */
+ 0x04, 0x00, /* length */
+ 0x00, 0x00, /* error status */
+ 0x00, 0x00, /* error code */
+ /* TLV */
+ 0x01, /* type: Allocation info */
+ 0x02, 0x00, /* length */
+ 0xFF, /* UPDATE: service */
+ 0x01, /* cid: 1 */
+ };
+
+ expected[15] = services[i];
+ response[22] = services[i];
+
+ test_port_context_set_command (fixture->ctx,
+ expected, G_N_ELEMENTS (expected),
+ response, G_N_ELEMENTS (response),
+ fixture->service_info[QMI_SERVICE_CTL].transaction_id++);
+ qmi_device_allocate_client (fixture->device, services[i], QMI_CID_NONE, 10, NULL,
+ (GAsyncReadyCallback) device_allocate_client_ready,
+ fixture);
+ test_fixture_loop_run (fixture);
+ }
+}
+
+static void
+device_release_client_ready (QmiDevice *device,
+ GAsyncResult *res,
+ TestFixture *fixture)
+{
+ GError *error = NULL;
+ gboolean st;
+
+ st = qmi_device_release_client_finish (device, res, &error);
+ g_assert_no_error (error);
+ g_assert (st);
+ test_fixture_loop_stop (fixture);
+}
+
+void
+test_fixture_teardown (TestFixture *fixture)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (services); i++) {
+ guint8 expected[] = {
+ 0x01, /* marker */
+ /* QMUX */
+ 0x10, 0x00, /* length */
+ 0x00, /* flags */
+ 0x00, /* service CTL */
+ 0x00, /* client */
+ /* QMI header */
+ 0x00, /* flags */
+ 0xFF, /* transaction */
+ 0x23, 0x00, /* message: Release CID */
+ 0x05, 0x00, /* tlv length: 5 bytes */
+ /* TLV */
+ 0x01, /* type */
+ 0x02, 0x00, /* length */
+ 0xFF, /* UPDATE: service */
+ 0x01
+ };
+ guint8 response[] = {
+ 0x01, /* marker */
+ /* QMUX */
+ 0x17, 0x00, /* length */
+ 0x00, /* flags */
+ 0x00, /* service */
+ 0x00, /* client */
+ /* QMI header */
+ 0x01, /* flags: Response */
+ 0xFF, /* transaction */
+ 0x23, 0x00, /* message */
+ 0x0C, 0x00, /* tlv length */
+ /* TLV */
+ 0x02, /* type: Result*/
+ 0x04, 0x00, /* length */
+ 0x00, 0x00, /* error status */
+ 0x00, 0x00, /* error code */
+ /* TLV */
+ 0x01, /* type: Allocation Info */
+ 0x02, 0x00, /* length */
+ 0xFF, /* UPDATE: service */
+ 0x01, /* cid: 1 */
+ };
+
+ expected[15] = services[i];
+ response[22] = services[i];
+ test_port_context_set_command (fixture->ctx,
+ expected, G_N_ELEMENTS (expected),
+ response, G_N_ELEMENTS (response),
+ fixture->service_info[QMI_SERVICE_CTL].transaction_id++);
+
+ qmi_device_release_client (fixture->device, fixture->service_info[services[i]].client, QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID, 10, NULL,
+ (GAsyncReadyCallback) device_release_client_ready,
+ fixture);
+
+ test_fixture_loop_run (fixture);
+
+ g_clear_object (&fixture->service_info[services[i]].client);
+ fixture->service_info[services[i]].transaction_id = 0x0000;
+ }
+
+ if (fixture->device) {
+ GError *error = NULL;
+ gboolean ret;
+
+ ret = qmi_device_close (fixture->device, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_object_unref (fixture->device);
+ }
+
+ g_free (fixture->path);
+
+ /* Stop port context */
+ test_port_context_stop (fixture->ctx);
+ test_port_context_free (fixture->ctx);
+}
+
+void
+test_fixture_loop_stop (TestFixture *fixture)
+{
+ g_assert (fixture->loop);
+ g_main_loop_quit (fixture->loop);
+}
+
+void
+test_fixture_loop_run (TestFixture *fixture)
+{
+ g_assert (!fixture->loop);
+ fixture->loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
+ g_main_loop_run (fixture->loop);
+ g_main_loop_unref (fixture->loop);
+ fixture->loop = NULL;
+}