Add core test case for scan 88/272888/1
authorhyunuk.tak <hyunuk.tak@samsung.com>
Wed, 23 Mar 2022 06:18:14 +0000 (15:18 +0900)
committerhyunuk.tak <hyunuk.tak@samsung.com>
Mon, 28 Mar 2022 01:52:47 +0000 (10:52 +0900)
Change-Id: I22aeb57052fabf469fa78dee72fc5e5d04faf79a
Signed-off-by: hyunuk.tak <hyunuk.tak@samsung.com>
src/thread-util.c
tests/unittest/mocks/thread-mock-dbus.cpp
tests/unittest/mocks/thread-mock-dummy.cpp
tests/unittest/mocks/thread-mock-dummy.h
tests/unittest/mocks/thread-mock-util.cpp [new file with mode: 0644]
tests/unittest/mocks/thread-mock-util.h [new file with mode: 0644]
tests/unittest/thread-unittest-core.cpp

index fc9eebd..81e96bb 100644 (file)
@@ -162,8 +162,8 @@ void __thread_dbus_handle_scan_cb(gboolean res,
        int length = 0;
        uint16_t panid = 0;
        uint16_t joiner_udp_port = 0;
-       uint16_t channel = 0;
-       uint16_t rssi = 0;
+       uint8_t channel = 0;
+       uint8_t rssi = 0;
        uint8_t lqi = 0;
        uint8_t version = 0;
        bool is_native = 0;
index 3342ffb..26da5e4 100644 (file)
 #include "thread-mock-dummy.h"
 
 GDBusConnection *g_bus_get_sync(GBusType bus_type,
-                                                               GCancellable *cancellable, GError **error)
+               GCancellable *cancellable, GError **error)
 {
-       return (GDBusConnection *)GINT_TO_POINTER(0x1234);
+       return (GDBusConnection *)GINT_TO_POINTER(0x1111);
 }
 
 GDBusProxy *g_dbus_proxy_new_for_bus_sync(GBusType bus_type,
-                                                                                 GDBusProxyFlags flags, GDBusInterfaceInfo *info,
-                                                                                 const gchar *name, const gchar *object_path,
-                                                                                 const gchar *interface_name, GCancellable *cancellable,
-                                                                                 GError **error)
+               GDBusProxyFlags flags, GDBusInterfaceInfo *info,
+               const gchar *name, const gchar *object_path,
+               const gchar *interface_name, GCancellable *cancellable,
+               GError **error)
 {
        return (GDBusProxy *)GINT_TO_POINTER(0x1234);
 }
 
 GDBusProxy *g_dbus_proxy_new_sync(GDBusConnection *connection,
-                                                                 GDBusProxyFlags flags, GDBusInterfaceInfo *info,
-                                                                 const gchar *name, const gchar *object_path,
-                                                                 const gchar *interface_name, GCancellable *cancellable,
-                                                                 GError **error)
+               GDBusProxyFlags flags, GDBusInterfaceInfo *info,
+               const gchar *name, const gchar *object_path,
+               const gchar *interface_name, GCancellable *cancellable,
+               GError **error)
 {
        return (GDBusProxy *)GINT_TO_POINTER(0x5678);
 }
 
 guint g_dbus_connection_signal_subscribe(GDBusConnection *connection,
-                                                                                const gchar *sender,
-                                                                                const gchar *interface_name,
-                                                                                const gchar *member,
-                                                                                const gchar *object_path,
-                                                                                const gchar *arg0,
-                                                                                GDBusSignalFlags flags,
-                                                                                GDBusSignalCallback callback,
-                                                                                gpointer user_data,
-                                                                                GDestroyNotify user_data_free_func)
+               const gchar *sender,
+               const gchar *interface_name,
+               const gchar *member,
+               const gchar *object_path,
+               const gchar *arg0,
+               GDBusSignalFlags flags,
+               GDBusSignalCallback callback,
+               gpointer user_data,
+               GDestroyNotify user_data_free_func)
 {
        return _subscribe_signal(interface_name, member, callback, user_data);
 }
@@ -63,12 +63,12 @@ void g_dbus_connection_signal_unsubscribe(GDBusConnection *connection,
 }
 
 GVariant *g_dbus_proxy_call_sync(GDBusProxy *proxy,
-                                 const gchar *method_name,
-                                 GVariant *parameters,
-                                 GDBusCallFlags flags,
-                                 gint timeout_msec,
-                                 GCancellable *cancellable,
-                                 GError **error)
+               const gchar *method_name,
+               GVariant *parameters,
+               GDBusCallFlags flags,
+               gint timeout_msec,
+               GCancellable *cancellable,
+               GError **error)
 {
        retv_if(proxy == nullptr, nullptr);
 
@@ -81,6 +81,28 @@ GVariant *g_dbus_proxy_call_sync(GDBusProxy *proxy,
        return nullptr;
 }
 
+void g_dbus_proxy_call(GDBusProxy *proxy,
+               const gchar *method_name,
+               GVariant *parameters,
+               GDBusCallFlags flags,
+               gint timeout_msec,
+               GCancellable *cancellable,
+               GAsyncReadyCallback callback,
+               gpointer user_data)
+{
+       ret_if(proxy == nullptr);
+
+       if (proxy == GINT_TO_POINTER(0x1234))
+               _handle_async_method(method_name, parameters, callback, user_data);
+}
+
+GVariant *g_dbus_proxy_call_finish(GDBusProxy *proxy,
+               GAsyncResult *res,
+               GError **error)
+{
+       return _get_gdbus_async_result(error);
+}
+
 void g_object_unref(gpointer object)
 {
 }
\ No newline at end of file
index 717dcb4..4a3942b 100644 (file)
 
 #include "thread-private.h"
 #include "thread-dbus-handler.h"
+#include "thread-mock-util.h"
 #include "thread-mock-dummy.h"
 
+typedef struct {
+       GAsyncReadyCallback callback;
+       GVariant *result;
+       gpointer user_data;
+} gdbus_result_data_s;
+
+static gdbus_result_data_s _gdbus_async_result;
+static const int ASYNC_RESULT_DELAY = 5;
+
+static gboolean __reply_async_method(gpointer data)
+{
+       gdbus_result_data_s *gdbus_result = (gdbus_result_data_s *)data;
+       gdbus_result->callback((GObject *)g_object_new(G_TYPE_DBUS_PROXY, NULL),
+                       NULL,
+                       gdbus_result->user_data);
+       return FALSE;
+}
+
 static GVariant * __signal_properties_changed()
 {
        return nullptr;
@@ -33,6 +52,49 @@ static GVariant *__method_factoryreset(GVariant *parameters)
        return g_variant_new("(i)", THREAD_ERROR_NONE);
 }
 
+static GVariant *__make_scan_result()
+{
+       uint64_t ext_address = 0;
+       const char *network_name = "network_name";
+       uint64_t ext_panid = 0;
+       uint16_t panid = 0;
+       uint16_t joiner_udp_port = 0;
+       uint8_t channel = 0;
+       uint8_t rssi = 0;
+       uint8_t lqi = 0;
+       uint8_t version = 0;
+       bool is_native = 0;
+       bool is_joinable = 0;
+
+       GVariantBuilder *scan_results_builder =
+               g_variant_builder_new(G_VARIANT_TYPE("a(tstayqqyyyybb)"));
+
+       GVariantBuilder *steering_data_builder =
+               g_variant_builder_new(G_VARIANT_TYPE("ay"));
+       g_variant_builder_add(steering_data_builder, "y", 1);
+       g_variant_builder_add(steering_data_builder, "y", '\0');
+
+       g_variant_builder_add(scan_results_builder, "(tstayqqyyyybb)",
+               ext_address, network_name, ext_panid, steering_data_builder,
+               panid, joiner_udp_port, channel, rssi, lqi, version,
+               is_native, is_joinable);
+
+       GVariant *scan_results = g_variant_new("(a(tstayqqyyyybb))", scan_results_builder);
+
+       g_variant_builder_unref(scan_results_builder);
+
+       return scan_results;
+}
+
+static void __method_scan(GVariant *parameters,
+               GAsyncReadyCallback callback, gpointer user_data)
+{
+       _gdbus_async_result.callback = callback;
+       _gdbus_async_result.result = __make_scan_result();
+       _gdbus_async_result.user_data = user_data;
+       g_timeout_add(ASYNC_RESULT_DELAY, __reply_async_method, &_gdbus_async_result);
+}
+
 static GVariant *__property_device_role()
 {
        return g_variant_new("(v)", g_variant_new("s", "child"));
@@ -73,19 +135,28 @@ struct {
 
 struct {
        const gchar *method_name;
-       GVariant *(*handler)(GVariant *parameters);
+       GVariant *(*sync_handler)(GVariant *parameters);
+       void(*async_handler)(GVariant *parameters, GAsyncReadyCallback callback, gpointer user_data);
 } thread_gdbus_method_list[] = {
        {
                THREAD_DBUS_RESET_METHOD,
                __method_reset,
+               NULL,
        },
        {
                THREAD_DBUS_FACTORY_RESET_METHOD,
                __method_factoryreset,
+               NULL,
+       },
+       {
+               THREAD_DBUS_SCAN_METHOD,
+               NULL,
+               __method_scan,
        },
        {
                NULL,
                NULL,
+               NULL,
        }
 };
 
@@ -155,7 +226,20 @@ GVariant *_handle_sync_method(const gchar *method_name,
                        return nullptr;
 
                if (__is_same_method(i, method_name))
-                       return thread_gdbus_method_list[i].handler(parameters);
+                       return thread_gdbus_method_list[i].sync_handler(parameters);
+       }
+}
+
+void _handle_async_method(const gchar *method_name,
+               GVariant *parameters, GAsyncReadyCallback callback,
+               gpointer user_data)
+{
+       for (int i = 0; ; ++i) {
+               if (thread_gdbus_method_list[i].method_name == NULL)
+                       return;
+
+               if (__is_same_method(i, method_name))
+                       return thread_gdbus_method_list[i].async_handler(parameters, callback, user_data);
        }
 }
 
@@ -175,4 +259,10 @@ GVariant *_handle_property(const gchar *method_name,
                if (__is_same_property(i, method_name, property_name))
                        return thread_gdbus_property_list[i].handler();
        }
+}
+
+GVariant *_get_gdbus_async_result(GError **error)
+{
+       *error = nullptr;
+       return _gdbus_async_result.result;
 }
\ No newline at end of file
index 491a53e..8d2f35c 100644 (file)
@@ -32,5 +32,11 @@ guint _subscribe_signal(const char *interface_name,
 GVariant *_handle_sync_method(const gchar *method_name,
                GVariant *parameters);
 
+void _handle_async_method(const gchar *method_name,
+               GVariant *parameters, GAsyncReadyCallback callback,
+               gpointer user_data);
+
 GVariant *_handle_property(const gchar *method_name,
-               GVariant *parameters);
\ No newline at end of file
+               GVariant *parameters);
+
+GVariant *_get_gdbus_async_result(GError **error);
\ No newline at end of file
diff --git a/tests/unittest/mocks/thread-mock-util.cpp b/tests/unittest/mocks/thread-mock-util.cpp
new file mode 100644 (file)
index 0000000..84d2aae
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "thread-mock-util.h"
+
+static gboolean _timeoutCallback(gpointer data)
+{
+       GMainLoop *mainLoop = NULL;
+       mainLoop = (GMainLoop *)data;
+       if (mainLoop != NULL)
+               g_main_loop_quit(mainLoop);
+       return FALSE;
+}
+
+void ScanCallback(int result, thread_network_scanning_state_e state,
+               uint64_t ext_address, const char *network_name, uint64_t ext_panidi,
+               const uint8_t *steering_data, int length, uint16_t panid, uint16_t joiner_udp_port, uint16_t channel,
+               uint16_t rssi, uint8_t lqi, uint8_t version, bool is_native, bool is_joinable, void *user_data)
+{
+       if (state == THREAD_SCANNING_FINISHED)
+               QUIT_GMAIN_LOOP;
+}
+
+void ThreadMainLoop::RunMainLoop()
+{
+       mainLoop = g_main_loop_new(NULL, false);
+       timeoutId = g_timeout_add(CALLBACK_TIMEOUT, _timeoutCallback, mainLoop);
+       g_main_loop_run(mainLoop);
+       if (timeoutId > 0)
+               g_source_remove(timeoutId);
+       mainLoop = NULL;
+}
+
+void ThreadMainLoop::QuitMainLoop()
+{
+       if (mainLoop)
+       {
+               g_main_loop_quit(mainLoop);
+               mainLoop = NULL;
+       }
+}
\ No newline at end of file
diff --git a/tests/unittest/mocks/thread-mock-util.h b/tests/unittest/mocks/thread-mock-util.h
new file mode 100644 (file)
index 0000000..2f5fa08
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <glib.h>
+#include "thread-private.h"
+
+#define CALLBACK_TIMEOUT 10
+#define THREAD_MAIN_LOOP ThreadMainLoop::getInstance()
+#define RUN_GMAIN_LOOP THREAD_MAIN_LOOP.RunMainLoop()
+#define QUIT_GMAIN_LOOP THREAD_MAIN_LOOP.QuitMainLoop()
+
+void ScanCallback(int result, thread_network_scanning_state_e state,
+               uint64_t ext_address, const char *network_name, uint64_t ext_panidi,
+               const uint8_t *steering_data, int length, uint16_t panid, uint16_t joiner_udp_port, uint16_t channel,
+               uint16_t rssi, uint8_t lqi, uint8_t version, bool is_native, bool is_joinable, void *user_data);
+
+class ThreadMainLoop
+{
+public:
+       static ThreadMainLoop& getInstance()
+       {
+               static ThreadMainLoop instance;
+               return instance;
+       }
+
+       void RunMainLoop();
+       void QuitMainLoop();
+
+private:
+       ThreadMainLoop() {}
+       ~ThreadMainLoop() = default;
+
+       ThreadMainLoop(const ThreadMainLoop&) = delete;
+       ThreadMainLoop& operator=(const ThreadMainLoop&) = delete;
+
+private:
+       GMainLoop *mainLoop;
+       guint timeoutId;
+};
\ No newline at end of file
index aa3bb37..d2b7ed6 100644 (file)
 #include <gtest/gtest.h>
 
 #include "thread.h"
+#include "mocks/thread-mock-util.h"
 
 class ThreadCoreTest : public ::testing::Test
 {
 public:
+       const int THREAD_DEFAULT_SCAN_TIME = 80;
+
        thread_instance_h instance;
        thread_device_role_e deviceRole;
        thread_device_type_e deviceType;
@@ -223,18 +226,21 @@ TEST_F(ThreadCoreTest, GetDeviceTypeErrorNone)
 TEST_F(ThreadCoreTest, ScanPramCreateNotInitialized)
 {
        EXPECT_EQ(THREAD_ERROR_NONE, thread_deinitialize());
-       EXPECT_EQ(THREAD_ERROR_NOT_INITIALIZED, thread_scan_param_create(instance, 10, &scanParam));
+       EXPECT_EQ(THREAD_ERROR_NOT_INITIALIZED,
+               thread_scan_param_create(instance, THREAD_DEFAULT_SCAN_TIME, &scanParam));
 }
 
 TEST_F(ThreadCoreTest, ScanPramCreateInvalidParameter)
 {
-       EXPECT_EQ(THREAD_ERROR_INVALID_PARAMETER, thread_scan_param_create(instance, 10, &scanParam));
+       EXPECT_EQ(THREAD_ERROR_INVALID_PARAMETER,
+               thread_scan_param_create(instance, THREAD_DEFAULT_SCAN_TIME, &scanParam));
 }
 
 TEST_F(ThreadCoreTest, ScanPramCreateErrorNone)
 {
        EXPECT_EQ(THREAD_ERROR_NONE, thread_enable(&instance));
-       EXPECT_EQ(THREAD_ERROR_NONE, thread_scan_param_create(instance, 10, &scanParam));
+       EXPECT_EQ(THREAD_ERROR_NONE,
+               thread_scan_param_create(instance, THREAD_DEFAULT_SCAN_TIME, &scanParam));
 }
 
 TEST_F(ThreadCoreTest, ScanPramDestroyNotInitialized)
@@ -253,4 +259,28 @@ TEST_F(ThreadCoreTest, ScanPramDestroyErrorNone)
        EXPECT_EQ(THREAD_ERROR_NONE, thread_enable(&instance));
        EXPECT_EQ(THREAD_ERROR_NONE, thread_scan_param_create(instance, 10, &scanParam));
        EXPECT_EQ(THREAD_ERROR_NONE, thread_scan_param_destroy(instance, scanParam));
+}
+
+TEST_F(ThreadCoreTest, ScanNotInitialized)
+{
+       EXPECT_EQ(THREAD_ERROR_NONE, thread_deinitialize());
+       EXPECT_EQ(THREAD_ERROR_NOT_INITIALIZED,
+               thread_scan(instance, scanParam, ScanCallback, nullptr));
+}
+
+TEST_F(ThreadCoreTest, ScanInvalidParameter)
+{
+       EXPECT_EQ(THREAD_ERROR_INVALID_PARAMETER,
+               thread_scan(instance, scanParam, ScanCallback, nullptr));
+}
+
+TEST_F(ThreadCoreTest, ScanErrorNone)
+{
+       EXPECT_EQ(THREAD_ERROR_NONE, thread_enable(&instance));
+       EXPECT_EQ(THREAD_ERROR_NONE,
+               thread_scan_param_create(instance, THREAD_DEFAULT_SCAN_TIME, &scanParam));
+       EXPECT_EQ(THREAD_ERROR_NONE,
+               thread_scan(instance, scanParam, ScanCallback, nullptr));
+
+       RUN_GMAIN_LOOP;
 }
\ No newline at end of file