return conn;
}
-MOCKABLE_FOR_TESTS
int dbus_subscribe(void (*signal_handler)(GDBusConnection *,
const gchar *,
const gchar *,
subscription_id = 0;
}
-MOCKABLE_FOR_TESTS
int dbus_get_file_from_report(const char *report_path, const int entry, int *fd)
{
GDBusConnection *conn = dbus_connect();
#include <gio/gunixfdlist.h>
#include <glib.h>
-#ifdef UNIT_TEST
-#define MOCKABLE_FOR_TESTS __attribute__((weak))
-#else
-#define MOCKABLE_FOR_TESTS
-#endif
-
struct dbus_signal_s {
gchar *sender_name;
gchar *object_path;
ADD_DEPENDENCIES(ctest test_${name})
endfunction(add_mocked_test)
-add_mocked_test(diagnostics_set_notification_cb "-Wl,--wrap=system_info_get_platform_bool,--wrap=dbus_subscribe")
-add_mocked_test(diagnostics_unset_notification_cb "-Wl,--wrap=system_info_get_platform_bool")
+add_mocked_test(diagnostics_common "-Wl,--wrap=calloc,--wrap=system_info_get_platform_bool,--wrap=dumpsys_dump,--wrap=poll,--wrap=read,--wrap=g_bus_get_sync,--wrap=g_dbus_connection_send_message_with_reply_sync")
+add_mocked_test(diagnostics_set_notification_cb "-Wl,--wrap=system_info_get_platform_bool,--wrap=g_bus_get_sync,--wrap=g_dbus_connection_signal_subscribe")
+add_mocked_test(diagnostics_unset_notification_cb "-Wl,--wrap=system_info_get_platform_bool,--wrap=g_bus_get_sync,--wrap=g_dbus_connection_signal_subscribe,--wrap=g_dbus_connection_signal_unsubscribe")
add_mocked_test(diagnostics_request_client_data "-Wl,--wrap=system_info_get_platform_bool,--wrap=dumpsys_dump")
add_mocked_test(diagnostics_get_client_id "-Wl,--wrap=system_info_get_platform_bool")
add_mocked_test(diagnostics_get_report_path "")
-add_mocked_test(diagnostics_get_data "-Wl,--wrap=system_info_get_platform_bool,--wrap=dbus_get_file_from_report")
+add_mocked_test(diagnostics_get_data "-Wl,--wrap=system_info_get_platform_bool,--wrap=g_bus_get_sync,--wrap=g_dbus_connection_send_message_with_reply_sync")
add_mocked_test(diagnostics_data_read "-Wl,--wrap=system_info_get_platform_bool,--wrap=poll,--wrap=read")
add_mocked_test(diagnostics_create "")
add_mocked_test(diagnostics_data_create "")
return (int)mock();
}
-int __wrap_dbus_get_file_from_report(const char *report_path, const int entry, int *fd)
+GDBusConnection *__wrap_g_bus_get_sync(GBusType bus_type, GCancellable *cancellable, GError **error)
{
- (void) report_path;
- (void) entry;
- *fd = 1;
+ GDBusConnection *conn = mock_ptr_type(GDBusConnection *);
+ if (!conn && error)
+ *error = g_error_new_literal(1, 1, "");
- return (int)mock();
+ return conn;
+}
+
+guint __wrap_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)
+{
+ return (guint)mock();
+}
+
+void __wrap_g_dbus_connection_signal_unsubscribe(GDBusConnection *connection, guint subscription_id)
+{
+ (void) connection;
+ return;
+}
+
+GDBusMessage *__wrap_g_dbus_connection_send_message_with_reply_sync(GDBusConnection *connection,
+ GDBusMessage *message,
+ GDBusSendMessageFlags flags,
+ gint timeout_msec,
+ volatile guint32 *out_serial,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GDBusMessage *reply = mock_ptr_type(GDBusMessage *);
+ if (!reply && error) {
+ *error = g_error_new_literal(1, 1, "");
+ reply = g_dbus_message_new();
+ g_dbus_message_set_message_type(reply, G_DBUS_MESSAGE_TYPE_ERROR);
+ }
+
+ return reply;
}
int __wrap_poll(struct pollfd *__fds, nfds_t __nfds, int __timeout)
(void) __fds;
(void) __nfds;
(void) __timeout;
+ int mode = (int)mock();
- __fds->revents = POLLIN;
+ if (mode <= 0)
+ return mode;
- return (int)mock();
+ __fds->revents = mode;
+
+ return 1;
}
ssize_t __wrap_read(int fd, void *buf, size_t nbytes)
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stddef.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "diagnostics.h"
+#include <gio/gio.h>
+#include <glib.h>
+
+#include <stdio.h>
+
+#include "test_diagnostics.h"
+#include "test_diagnostics_add_function_defs.h"
+
+struct _diagnostics_cb_info_s {
+ diagnostics_notification_cb cb;
+ void *user_data;
+};
+
+struct _diagnostics_ctx_s *ctx = NULL;
+
+void signal_callback(void *_ctx, void *user_data)
+{
+ ctx = _ctx;
+
+ assert_ptr_equal(user_data, NULL);
+}
+
+void *__real_calloc(size_t nmemb, size_t size);
+void *__wrap_calloc(size_t nmemb, size_t size)
+{
+ int fake = (int) mock();
+ if (fake)
+ return NULL;
+
+ return __real_calloc(nmemb, size);
+}
+
+static void test_diagnostics_common_n1(void **state)
+{
+ (void) state;
+ GVariant *parameters = build_signal_parameters_crash();
+
+ cb_info.cb = signal_callback;
+ cb_info.user_data = NULL;
+
+ will_return(__wrap_calloc, 1);
+
+ signal_handler(NULL, DBUS_SENDER_CRASH, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, DBUS_MEMBER_CRASH, parameters, NULL);
+ assert_null(ctx);
+
+ g_variant_unref(parameters);
+}
+
+static void test_diagnostics_common_n2(void **state)
+{
+ (void) state;
+ struct dbus_signal_s *signal;
+ struct _diagnostics_ctx_s *ctx;
+
+ will_return(__wrap_calloc, 0);
+ will_return(__wrap_calloc, 1);
+
+ signal = dbus_signal_create(DBUS_SENDER_CRASH, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, DBUS_MEMBER_CRASH, build_signal_parameters_crash());
+ assert_non_null(signal);
+
+ ctx = diagnostics_create(signal);
+ assert_null(ctx);
+
+ dbus_signal_cleanup(signal);
+}
+
+static void test_diagnostics_common_n3(void **state)
+{
+ (void) state;
+ int fd = 0;
+
+ will_return(__wrap_calloc, 1);
+ assert_null(diagnostics_data_create(fd));
+}
+
+static void test_diagnostics_common_n4(void **state)
+{
+ (void) state;
+ const char *client_id = "";
+ int params_size = 3;
+ const char *params[] = {"a", "b", "c"};
+ struct _diagnostics_data_s *data = NULL;
+ int ret;
+
+ will_return(__wrap_dumpsys_dump, DIAGNOSTICS_ERROR_NONE);
+ will_return(__wrap_calloc, 1);
+
+ ret = diagnostics_request_client_data(client_id, params, params_size, (void**)&data);
+
+ assert_int_equal(ret, DIAGNOSTICS_ERROR_OUT_OF_MEMORY);
+ assert_null(data);
+}
+
+static void test_diagnostics_common_n5(void **state)
+{
+ (void) state;
+ struct _diagnostics_ctx_s *ctx = NULL;
+ struct _diagnostics_data_s *data = NULL;
+ const char *params[] = {"cs_full"};
+ static int dummy = 1;
+ GDBusConnection *conn = (GDBusConnection *)&dummy;
+ GDBusMessage *reply;
+ GUnixFDList *fd_list;
+ int fd = 1;
+ int ret;
+
+ will_return_count(__wrap_calloc, 0, 2);
+
+ ctx = build_ctx_crash();
+ reply = g_dbus_message_new();
+ fd_list = g_unix_fd_list_new_from_array(&fd, 1);
+ g_dbus_message_set_message_type(reply, G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ g_dbus_message_set_unix_fd_list(reply, fd_list);
+
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_send_message_with_reply_sync, reply);
+ will_return(__wrap_calloc, 1);
+
+ ret = diagnostics_get_data(ctx, params, 1, (void**)&data);
+
+ assert_int_equal(ret, DIAGNOSTICS_ERROR_OUT_OF_MEMORY);
+ assert_null(data);
+
+ destroy_ctx(ctx);
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_diagnostics_common_n1),
+ cmocka_unit_test(test_diagnostics_common_n2),
+ cmocka_unit_test(test_diagnostics_common_n3),
+ cmocka_unit_test(test_diagnostics_common_n4),
+ cmocka_unit_test(test_diagnostics_common_n5),
+ };
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
\ No newline at end of file
static void test_diagnostics_create_n2(void **state)
{
(void) state;
- struct _diagnostics_ctx_s *ctx = build_ctx_crash();
- free(ctx->signal->signal_name);
- ctx->signal->signal_name = g_strdup("non dbus member crash");
- struct _diagnostics_ctx_s *result = diagnostics_create(ctx->signal);
+ struct dbus_signal_s *signal;
+ struct _diagnostics_ctx_s *ctx;
- assert_null(result);
+ signal = dbus_signal_create(DBUS_SENDER_CRASH, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, "", build_signal_parameters_crash());
+ assert_non_null(signal);
- destroy_ctx(ctx);
-}
-
-static void test_diagnostics_create_n3(void **state)
-{
- (void) state;
- struct _diagnostics_ctx_s *ctx = build_ctx_crash();
- free(ctx->signal->signal_name);
- ctx->signal->signal_name = NULL;
- struct _diagnostics_ctx_s *result = diagnostics_create(ctx->signal);
-
- assert_null(result);
+ ctx = diagnostics_create(signal);
+ assert_null(ctx);
- destroy_ctx(ctx);
+ dbus_signal_cleanup(signal);
}
static void test_diagnostics_create_p1(void **state)
{
(void) state;
- struct _diagnostics_ctx_s *ctx = build_ctx_crash();
- struct _diagnostics_ctx_s *result = diagnostics_create(ctx->signal);
+ struct dbus_signal_s *signal;
+ struct _diagnostics_ctx_s *ctx;
+
+ signal = dbus_signal_create(DBUS_SENDER_CRASH, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, DBUS_MEMBER_CRASH, build_signal_parameters_crash());
+ assert_non_null(signal);
- assert_non_null(result);
- assert_string_equal(result->client_id, DBUS_SENDER_CRASH);
- assert_ptr_equal(result->signal, ctx->signal);
- assert_int_equal(result->signal_type, SIG_TYPE_CRASH);
+ ctx = diagnostics_create(signal);
+ assert_non_null(ctx);
+ assert_string_equal(ctx->client_id, DBUS_SENDER_CRASH);
+ assert_ptr_equal(ctx->signal, ctx->signal);
+ assert_int_equal(ctx->signal_type, SIG_TYPE_CRASH);
- destroy_ctx(ctx);
- free(result);
+ dbus_signal_cleanup(signal);
+ free(ctx);
}
int main(void)
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_diagnostics_create_n1),
cmocka_unit_test(test_diagnostics_create_n2),
- cmocka_unit_test(test_diagnostics_create_n3),
cmocka_unit_test(test_diagnostics_create_p1),
};
return cmocka_run_group_tests(tests, NULL, NULL);
assert_int_equal(diagnostics_data_read(&data, buf, count, timeout, &bytes_read), DIAGNOSTICS_ERROR_IO_ERROR);
}
+static void test_diagnostics_data_read_n7(void **state)
+{
+ (void) state;
+ struct _diagnostics_data_s data;
+ data.fd = 0;
+ char buf[256];
+ size_t count = sizeof(buf);
+ int timeout = 100;
+ size_t bytes_read = 0;
+
+ will_return(__wrap_poll, POLLIN);
+ will_return(__wrap_read, -1);
+
+ assert_int_equal(diagnostics_data_read(&data, buf, count, timeout, &bytes_read), DIAGNOSTICS_ERROR_IO_ERROR);
+ assert_int_equal(bytes_read, 0);
+}
+
+static void test_diagnostics_data_read_n8(void **state)
+{
+ (void) state;
+ struct _diagnostics_data_s data;
+ data.fd = 0;
+ char buf[256];
+ size_t count = sizeof(buf);
+ int timeout = 100;
+ size_t bytes_read = 0;
+
+ will_return(__wrap_poll, POLLERR);
+
+ assert_int_equal(diagnostics_data_read(&data, buf, count, timeout, &bytes_read), DIAGNOSTICS_ERROR_IO_ERROR);
+ assert_int_equal(bytes_read, 0);
+}
+
static void test_diagnostics_data_read_p1(void **state)
{
(void) state;
int timeout = 100;
size_t bytes_read = 0;
- will_return(__wrap_poll, 1);
+ will_return(__wrap_poll, POLLIN);
will_return(__wrap_read, 2);
assert_int_equal(diagnostics_data_read(&data, buf, count, timeout, &bytes_read), DIAGNOSTICS_ERROR_NONE);
assert_int_equal(bytes_read, 2);
}
+static void test_diagnostics_data_read_p2(void **state)
+{
+ (void) state;
+ struct _diagnostics_data_s data;
+ data.fd = 0;
+ char buf[256];
+ size_t count = sizeof(buf);
+ int timeout = 100;
+ size_t bytes_read = 0;
+
+ will_return(__wrap_poll, POLLHUP);
+
+ assert_int_equal(diagnostics_data_read(&data, buf, count, timeout, &bytes_read), DIAGNOSTICS_ERROR_NONE);
+ assert_int_equal(bytes_read, 0);
+}
+
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_diagnostics_data_read_n4),
cmocka_unit_test(test_diagnostics_data_read_n5),
cmocka_unit_test(test_diagnostics_data_read_n6),
+ cmocka_unit_test(test_diagnostics_data_read_n7),
+ cmocka_unit_test(test_diagnostics_data_read_n8),
cmocka_unit_test(test_diagnostics_data_read_p1),
+ cmocka_unit_test(test_diagnostics_data_read_p2),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
#include "dbus.h"
#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "test_diagnostics.h"
+static int dummy = 1;
+GDBusConnection *conn = (GDBusConnection *)&dummy;
+
static void test_diagnostics_get_data_n1(void **state)
{
(void) state;
struct _diagnostics_data_s *data = NULL;
const char *params[] = {"cs_foo"};
- int result = diagnostics_get_data(ctx, params, 1, (void**)&data);
+ assert_int_equal(diagnostics_get_data(ctx, params, 1, (void**)&data), DIAGNOSTICS_ERROR_NOT_SUPPORTED);
+ assert_null(data);
+
+ destroy_ctx(ctx);
+}
+
+static void test_diagnostics_get_data_n5(void **state)
+{
+ (void) state;
+ struct _diagnostics_ctx_s *ctx = build_ctx_crash();
+ struct _diagnostics_data_s *data = NULL;
+ const char *params[] = {"cs_full"};
+ GDBusConnection *conn = NULL;
+
+ will_return(__wrap_g_bus_get_sync, conn);
+
+ assert_int_equal(diagnostics_get_data(ctx, params, 1, (void**)&data), DIAGNOSTICS_ERROR_IO_ERROR);
+ assert_null(data);
+
+ destroy_ctx(ctx);
+}
+
+static void test_diagnostics_get_data_n6(void **state)
+{
+ (void) state;
+ struct _diagnostics_ctx_s *ctx = build_ctx_crash();
+ struct _diagnostics_data_s *data = NULL;
+ const char *params[] = {"cs_full"};
+ GDBusMessage *reply = NULL;
+
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_send_message_with_reply_sync, reply);
+
+ assert_int_equal(diagnostics_get_data(ctx, params, 1, (void**)&data), DIAGNOSTICS_ERROR_IO_ERROR);
+ assert_null(data);
+
+ destroy_ctx(ctx);
+}
+
+static void test_diagnostics_get_data_n7(void **state)
+{
+ (void) state;
+ struct _diagnostics_ctx_s *ctx = build_ctx_crash();
+ struct _diagnostics_data_s *data = NULL;
+ const char *params[] = {"cs_full"};
+ GDBusMessage *reply = g_dbus_message_new();
+
+ g_dbus_message_set_message_type(reply, G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
+
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_send_message_with_reply_sync, reply);
+
+ assert_int_equal(diagnostics_get_data(ctx, params, 1, (void**)&data), DIAGNOSTICS_ERROR_IO_ERROR);
+ assert_null(data);
+
+ destroy_ctx(ctx);
+}
+
+static void test_diagnostics_get_data_n8(void **state)
+{
+ (void) state;
+ struct _diagnostics_ctx_s *ctx = build_ctx_crash();
+ struct _diagnostics_data_s *data = NULL;
+ const char *params[] = {"cs_full"};
+ GDBusMessage *reply = g_dbus_message_new();
+ GUnixFDList *fd_list = g_unix_fd_list_new();
+
+ g_dbus_message_set_message_type(reply, G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ g_dbus_message_set_unix_fd_list(reply, fd_list);
+
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_send_message_with_reply_sync, reply);
- assert_int_equal(result, DIAGNOSTICS_ERROR_NOT_SUPPORTED);
+ assert_int_equal(diagnostics_get_data(ctx, params, 1, (void**)&data), DIAGNOSTICS_ERROR_IO_ERROR);
assert_null(data);
destroy_ctx(ctx);
struct _diagnostics_ctx_s *ctx = build_ctx_crash();
struct _diagnostics_data_s *data = NULL;
const char *params[] = {"cs_full"};
+ int fd = 1;
+ GDBusMessage *reply = g_dbus_message_new();
+ GUnixFDList *fd_list = g_unix_fd_list_new_from_array(&fd, 1);
- will_return(__wrap_dbus_get_file_from_report, 0);
+ g_dbus_message_set_message_type(reply, G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ g_dbus_message_set_unix_fd_list(reply, fd_list);
- int result = diagnostics_get_data(ctx, params, 1, (void**)&data);
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_send_message_with_reply_sync, reply);
- assert_int_equal(result, DIAGNOSTICS_ERROR_NONE);
+ assert_int_equal(diagnostics_get_data(ctx, params, 1, (void**)&data), DIAGNOSTICS_ERROR_NONE);
assert_non_null(data);
- assert_int_equal(data->fd, 1);
destroy_ctx(ctx);
}
cmocka_unit_test(test_diagnostics_get_data_n2),
cmocka_unit_test(test_diagnostics_get_data_n3),
cmocka_unit_test(test_diagnostics_get_data_n4),
+ cmocka_unit_test(test_diagnostics_get_data_n5),
+ cmocka_unit_test(test_diagnostics_get_data_n6),
+ cmocka_unit_test(test_diagnostics_get_data_n7),
+ cmocka_unit_test(test_diagnostics_get_data_n8),
cmocka_unit_test(test_diagnostics_get_data_p1),
};
return cmocka_run_group_tests(tests, NULL, NULL);
void *user_data;
};
+static int dummy = 1;
+GDBusConnection *conn = (GDBusConnection *)&dummy;
+
void callback(void *ctx, void *user_data)
{
(void)ctx;
}
static void test_diagnostics_set_notification_cb_n2(void **state)
+{
+ (void) state;
+ GDBusConnection *conn = NULL;
+
+ will_return(__wrap_g_bus_get_sync, conn);
+
+ assert_int_equal(diagnostics_set_notification_cb(callback, NULL), DIAGNOSTICS_ERROR_IO_ERROR);
+}
+
+static void test_diagnostics_set_notification_cb_n3(void **state)
{
(void) state;
- will_return(__wrap_dbus_subscribe, -1);
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_signal_subscribe, 0);
assert_int_equal(diagnostics_set_notification_cb(callback, NULL), DIAGNOSTICS_ERROR_IO_ERROR);
}
{
(void) state;
- will_return(__wrap_dbus_subscribe, DIAGNOSTICS_ERROR_NONE);
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_signal_subscribe, 1);
assert_int_equal(diagnostics_set_notification_cb(callback, NULL), DIAGNOSTICS_ERROR_NONE);
assert_ptr_equal(cb_info.cb, callback);
{
(void) state;
- will_return(__wrap_dbus_subscribe, DIAGNOSTICS_ERROR_NONE);
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_signal_subscribe, 1);
assert_int_equal(diagnostics_set_notification_cb(callback, NULL), DIAGNOSTICS_ERROR_NONE);
assert_int_equal(diagnostics_set_notification_cb(callback, NULL), DIAGNOSTICS_ERROR_RESOURCE_BUSY);
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_diagnostics_set_notification_cb_n1),
cmocka_unit_test(test_diagnostics_set_notification_cb_n2),
+ cmocka_unit_test(test_diagnostics_set_notification_cb_n3),
cmocka_unit_test(test_diagnostics_set_notification_cb_p1),
cmocka_unit_test(test_diagnostics_set_notification_cb_p2),
};
#include "test_diagnostics.h"
+static int dummy = 1;
+GDBusConnection *conn = (GDBusConnection *)&dummy;
+
+void callback(void *ctx, void *user_data)
+{
+ (void)ctx;
+ (void)user_data;
+}
+
static void test_diagnostics_unset_notification_cb_p1(void **state)
{
(void) state;
+ will_return(__wrap_g_bus_get_sync, conn);
+ will_return(__wrap_g_dbus_connection_signal_subscribe, 1);
+
+ assert_int_equal(diagnostics_set_notification_cb(callback, NULL), DIAGNOSTICS_ERROR_NONE);
+
+ will_return(__wrap_g_bus_get_sync, conn);
assert_int_equal(diagnostics_unset_notification_cb(), DIAGNOSTICS_ERROR_NONE);
}