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;
#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);
}
}
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);
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
#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;
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"));
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,
}
};
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);
}
}
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
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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
#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;
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)
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