summaryrefslogtreecommitdiff
path: root/tst/nhm-main-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tst/nhm-main-test.c')
-rw-r--r--tst/nhm-main-test.c1110
1 files changed, 1110 insertions, 0 deletions
diff --git a/tst/nhm-main-test.c b/tst/nhm-main-test.c
new file mode 100644
index 0000000..25a62ce
--- /dev/null
+++ b/tst/nhm-main-test.c
@@ -0,0 +1,1110 @@
+/* NHM - NodeHealthMonitor
+ *
+ * Copyright (C) 2013 Continental Automotive Systems, Inc.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Author: Jean-Pierre Bogler <Jean-Pierre.Bogler@continental-corporation.com>
+ */
+
+/**
+ * SECTION:nhm-unit-test
+ * @title: NodeHealthMonitor (NHM) unit test
+ * @short_description: Unit test for an automatic check of the NHM
+ *
+ * The unit test will stimulate the NHM and check for the expected reactions.
+ */
+
+/*******************************************************************************
+*
+* Header includes
+*
+*******************************************************************************/
+
+/* Include glib to use gtypes */
+#include <glib-2.0/glib.h>
+#include <stdlib.h>
+
+/* Include the stubbed main file of the NHM. Its functions will be tested! */
+#include "nhm-main-test.h"
+
+
+/*******************************************************************************
+*
+* Local variables and constants
+*
+*******************************************************************************/
+
+/* There are no local variables, define or constants */
+
+
+/*******************************************************************************
+*
+* Prototypes for file local functions (see implementation for description)
+*
+*******************************************************************************/
+
+static gint nhm_test_main (void);
+static gint nhm_test_load_config (void);
+static gint nhm_test_connect_to_nsm (void);
+static gint nhm_test_nhm_bus_callbacks (void);
+static gint nhm_test_register_app_status (void);
+static gint nhm_test_read_statistics (void);
+static gint nhm_test_userland_check (void);
+static gint nhm_test_watchdog (void);
+static gint nhm_test_handle_lc_request (void);
+static gint nhm_test_app_restart_request (void);
+static gint nhm_test_is_dbus_alive (void);
+static gint nhm_test_on_sigterm (void);
+
+
+/*******************************************************************************
+*
+* Local (static) functions
+*
+*******************************************************************************/
+
+/**
+ * nhm_test_handle_lc_request:
+ *
+ * Test reaction of NHM on LC request.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint nhm_test_app_restart_request(void)
+{
+ gint retval = 0;
+ gchar* my_no_restart_apps[] = {"App1", "App2", NULL};
+
+ no_restart_apps = my_no_restart_apps;
+
+ /* Check 1: Request from App3 (not on black list) */
+ nsm_dbus_lc_control_call_request_node_restart_sync_stub_set_error = FALSE;
+ nsm_dbus_lc_control_call_request_node_restart_sync_stub_out_ErrorCode = NsmErrorStatus_Ok;
+ nhm_dbus_info_complete_request_node_restart_stub_ErrorStatus = NsmErrorStatus_NotSet;
+ nhm_main_request_node_restart_cb(NULL, NULL, "App3", NULL);
+ retval = ( nhm_dbus_info_complete_request_node_restart_stub_ErrorStatus
+ == NhmErrorStatus_Ok) ? 0 : -1;
+
+ /* Check 2: Request from App1 (on black list) */
+ if(retval == 0)
+ {
+ nhm_dbus_info_complete_request_node_restart_stub_ErrorStatus = NsmErrorStatus_NotSet;
+ nhm_main_request_node_restart_cb(NULL, NULL, "App1", NULL);
+ retval = ( nhm_dbus_info_complete_request_node_restart_stub_ErrorStatus
+ == NhmErrorStatus_RestartNotPossible) ? 0 : -1;
+ }
+
+ no_restart_apps = NULL;
+
+ return retval;
+}
+
+/**
+ * nhm_test_handle_lc_request:
+ *
+ * Test reaction of NHM on LC request.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint nhm_test_handle_lc_request(void)
+{
+ gint retval = 0;
+
+ /* Check 1: Successful write of shutdown flag at "shutdown" request */
+ pclKeyWriteData_stub_return = sizeof(NhmNodeState);
+ pclKeyWriteData_stub_WriteVal = 0;
+ nhm_main_lc_request_cb(NULL, NULL, NSM_SHUTDOWNTYPE_FAST, 0, NULL);
+
+ /* Check that NHM wrote 'NHM_NODESTATE_SHUTDOWN' to persistence */
+ if( ((NhmNodeState) pclKeyWriteData_stub_WriteVal
+ != NHM_NODESTATE_SHUTDOWN)
+ || ((NsmErrorStatus_e) nsm_dbus_lc_consumer_complete_lifecycle_request_stub_ErrorCode
+ != NsmErrorStatus_Ok))
+ {
+ retval = -1;
+ }
+
+ /* Check 2: Unsuccessful write of shutdown flag at "shutdown" request */
+ if(retval == 0)
+ {
+ pclKeyWriteData_stub_return = -1;
+ pclKeyWriteData_stub_WriteVal = 0;
+ nhm_main_lc_request_cb(NULL, NULL, NSM_SHUTDOWNTYPE_NORMAL, 0, NULL);
+
+ /* Check that NHM wrote 'NHM_NODESTATE_SHUTDOWN' to persistence */
+ if( ((NhmNodeState) pclKeyWriteData_stub_WriteVal
+ != NHM_NODESTATE_SHUTDOWN)
+ || ((NsmErrorStatus_e) nsm_dbus_lc_consumer_complete_lifecycle_request_stub_ErrorCode
+ != NsmErrorStatus_Error))
+ {
+ retval = -1;
+ }
+ }
+
+ /* Check 3: Successful write of shutdown flag at "runup" request */
+ if(retval == 0)
+ {
+ pclKeyWriteData_stub_return = sizeof(NhmNodeState);
+ pclKeyWriteData_stub_WriteVal = 0;
+ nhm_main_lc_request_cb(NULL, NULL, NSM_SHUTDOWNTYPE_RUNUP, 0, NULL);
+
+ /* Check that NHM wrote 'NHM_NODESTATE_SHUTDOWN' to persistence */
+ if( ((NhmNodeState) pclKeyWriteData_stub_WriteVal
+ != NHM_NODESTATE_STARTED)
+ || ((NsmErrorStatus_e) nsm_dbus_lc_consumer_complete_lifecycle_request_stub_ErrorCode
+ != NsmErrorStatus_Ok))
+ {
+ retval = -1;
+ }
+ }
+
+ /* Check 4: Unsuccessful write of shutdown flag at "runup" request */
+ if(retval == 0)
+ {
+ pclKeyWriteData_stub_return = -1;
+ pclKeyWriteData_stub_WriteVal = 0;
+ nhm_main_lc_request_cb(NULL, NULL, NSM_SHUTDOWNTYPE_RUNUP, 0, NULL);
+
+ /* Check that NHM wrote 'NHM_NODESTATE_SHUTDOWN' to persistence */
+ if( ((NhmNodeState) pclKeyWriteData_stub_WriteVal
+ != NHM_NODESTATE_STARTED)
+ || ((NsmErrorStatus_e) nsm_dbus_lc_consumer_complete_lifecycle_request_stub_ErrorCode
+ != NsmErrorStatus_Error))
+ {
+ retval = -1;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * nhm_test_watchdog:
+ *
+ * Tests the WDOG triggering of the NHM
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint nhm_test_watchdog(void)
+{
+ gint retval = 0;
+
+ sd_notify_stub_called = FALSE;
+ nhm_main_timer_wdog_cb(NULL);
+ retval = (sd_notify_stub_called == TRUE) ? 0 : -1;
+
+ return retval;
+}
+
+
+static gint nhm_test_is_dbus_alive(void)
+{
+ gint retval = 0;
+ NhmCheckedDbus *checked_dbus = g_new(NhmCheckedDbus, 1);
+ GdbusConnectionCallSyncStubCalls g_dbus_connection_call_sync_stub_calls[1];
+
+ /* Check 1: No conn. obtained. Conn. can't be obtained. Call fails. */
+ checked_dbus->bus_addr = NULL;
+ checked_dbus->bus_conn = NULL;
+ g_dbus_connection_new_for_address_sync_stub_set_error = TRUE;
+
+ g_dbus_connection_call_sync_stub_control.count = 1;
+ g_dbus_connection_call_sync_stub_calls[0].method = "GetId";
+ g_dbus_connection_call_sync_stub_calls[0].rval = NULL;
+ g_dbus_connection_call_sync_stub_control.calls = g_dbus_connection_call_sync_stub_calls;
+
+ retval = nhm_main_is_dbus_alive(checked_dbus) == FALSE ? 0 : -1;
+
+ /* Check 2: No conn. obtained. Conn. can be obtained. Call fails. */
+ if(retval == 0)
+ {
+ checked_dbus->bus_addr = NULL;
+ checked_dbus->bus_conn = NULL;
+ g_dbus_connection_new_for_address_sync_stub_set_error = FALSE;
+
+ g_dbus_connection_call_sync_stub_control.count = 1;
+ g_dbus_connection_call_sync_stub_calls[0].method = "GetId";
+ g_dbus_connection_call_sync_stub_calls[0].rval = NULL;
+ g_dbus_connection_call_sync_stub_control.calls = g_dbus_connection_call_sync_stub_calls;
+
+ retval = nhm_main_is_dbus_alive(checked_dbus) == FALSE ? 0 : -1;
+ }
+
+ /* Check 3: No conn. obtained. Conn. can be obtained. Call succeeds. */
+ if(retval == 0)
+ {
+ checked_dbus->bus_addr = NULL;
+ checked_dbus->bus_conn = NULL;
+ g_dbus_connection_new_for_address_sync_stub_set_error = FALSE;
+
+ g_dbus_connection_call_sync_stub_control.count = 1;
+ g_dbus_connection_call_sync_stub_calls[0].method = "GetId";
+ g_dbus_connection_call_sync_stub_calls[0].rval = g_variant_new("()");
+ g_dbus_connection_call_sync_stub_control.calls = g_dbus_connection_call_sync_stub_calls;
+
+ retval = nhm_main_is_dbus_alive(checked_dbus) == TRUE ? 0 : -1;
+ }
+
+ /* Check 4: Conn. obtained. Call succeeds. */
+ if(retval == 0)
+ {
+ checked_dbus->bus_addr = NULL;
+ checked_dbus->bus_conn = g_object_new(G_TYPE_DBUS_CONNECTION, NULL);
+
+ g_dbus_connection_new_for_address_sync_stub_set_error = FALSE;
+
+ g_dbus_connection_call_sync_stub_control.count = 1;
+ g_dbus_connection_call_sync_stub_calls[0].method = "GetId";
+ g_dbus_connection_call_sync_stub_calls[0].rval = g_variant_new("()");
+ g_dbus_connection_call_sync_stub_control.calls = g_dbus_connection_call_sync_stub_calls;
+
+ retval = nhm_main_is_dbus_alive(checked_dbus) == TRUE ? 0 : -1;
+
+ g_object_unref(checked_dbus->bus_conn);
+ checked_dbus->bus_conn = NULL;
+ }
+
+ /* Check 5: Conn. obtained. Call fails. */
+ if(retval == 0)
+ {
+ checked_dbus->bus_addr = NULL;
+ checked_dbus->bus_conn = g_object_new(G_TYPE_DBUS_CONNECTION, NULL);
+
+ g_dbus_connection_new_for_address_sync_stub_set_error = FALSE;
+
+ g_dbus_connection_call_sync_stub_control.count = 1;
+ g_dbus_connection_call_sync_stub_calls[0].method = "GetId";
+ g_dbus_connection_call_sync_stub_calls[0].rval = NULL;
+ g_dbus_connection_call_sync_stub_control.calls = g_dbus_connection_call_sync_stub_calls;
+
+ retval = nhm_main_is_dbus_alive(checked_dbus) == FALSE ? 0 : -1;
+
+ g_object_unref(checked_dbus->bus_conn);
+ checked_dbus->bus_conn = NULL;
+ }
+
+ nhm_main_free_checked_dbus(checked_dbus);
+
+ return retval;
+}
+
+
+/**
+ * nhm_test_userland_check:
+ *
+ * Tests the userland check functionality of the NHM.
+ *
+ * Returns always 0, because NHM shows no reaction yet.
+ */
+static gint nhm_test_userland_check(void)
+{
+ gchar *my_monitored_files[] = {"missing_file", NULL};
+ gchar *my_monitored_progs[] = {"invalid_prog", NULL};
+ gchar *my_monitored_procs[] = {"/usr/bin/invalid_proc", NULL};
+ NhmCheckedDbus my_checked_dbus = {NULL, NULL};
+
+ /* Check 1: No monitored files. No monitored progs. No monitored procs. No monitored dbus */
+ monitored_files = NULL;
+ monitored_progs = NULL;
+ monitored_procs = NULL;
+ checked_dbusses = NULL;
+
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 2: No monitored files. No monitored progs. Monitored procs. nok. No monitored dbus. */
+ monitored_files = NULL;
+ monitored_progs = NULL;
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = NULL;
+
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 3: No monitored files. No monitored progs. Monitored procs. ok. No monitored dbus. */
+ monitored_files = NULL;
+ monitored_progs = NULL;
+ my_monitored_procs[0] = "valid_proc";
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = NULL;
+
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 4: No monitored files. monitored progs nok. Monitored procs. ok. No monitored dbus. */
+ monitored_files = NULL;
+ monitored_progs = g_strdupv(my_monitored_progs);
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = NULL;
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 5: No monitored files. monitored progs ok. Monitored procs. ok. No monitored dbus. */
+ monitored_files = NULL;
+ my_monitored_progs[0] = "/usr/bin/valid_prog1";
+ monitored_progs = g_strdupv(my_monitored_progs);
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = NULL;
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 6: monitored files nok. monitored progs ok. Monitored procs. ok. No monitored dbus. */
+ monitored_files = g_strdupv(my_monitored_files);
+ monitored_progs = g_strdupv(my_monitored_progs);
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = NULL;
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 7: monitored files ok. monitored progs ok. Monitored procs. ok. No monitored dbus. */
+ my_monitored_files[0] = "valid_file";
+ monitored_files = g_strdupv(my_monitored_files);
+ monitored_progs = g_strdupv(my_monitored_progs);
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = NULL;
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 8: monitored files ok. monitored progs ok. Monitored procs. ok. Monitored dbus nok */
+ monitored_files = g_strdupv(my_monitored_files);
+ monitored_progs = g_strdupv(my_monitored_progs);
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = g_ptr_array_new();
+
+ g_ptr_array_add(checked_dbusses, (gpointer) &my_checked_dbus);
+ g_dbus_connection_new_for_address_sync_stub_set_error = TRUE;
+ g_dbus_connection_new_for_address_sync_stub_set_error = TRUE;
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ /* Check 9: monitored files ok. monitored progs ok. Monitored procs. ok. Monitored dbus ok */
+ monitored_files = g_strdupv(my_monitored_files);
+ monitored_progs = g_strdupv(my_monitored_progs);
+ monitored_procs = g_strdupv(my_monitored_procs);
+ checked_dbusses = g_ptr_array_new();
+
+ g_ptr_array_add(checked_dbusses, (gpointer) &my_checked_dbus);
+ g_dbus_connection_new_for_address_sync_stub_set_error = FALSE;
+ g_dbus_connection_new_for_address_sync_stub_set_error = FALSE;
+ nhm_main_timer_userland_check_cb(NULL);
+
+ nhm_main_free_check_objects();
+ nhm_main_free_config_objects();
+
+ return 0;
+}
+
+
+/**
+ * nhm_test_read_statistics:
+ *
+ * Tests the read statistics dbus interface of the NHM.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint nhm_test_read_statistics(void)
+{
+ guint app_idx = 0;
+ NhmLcInfo *lc_info[3] = {0};
+ NhmFailedApp *lc_apps[5] = {0};
+ NhmCurrentFailedApp *current_failed_app[3] = {0};
+ gint retval = 0;
+
+ /*
+ * Create initial nodeinfo for the test:
+ *
+ * LC1: NHM_NODESTATE_SHUTDOWN. (App1, 3), (App2, 4), (App3, 5)
+ * LC2: NHM_NODESTATE_STARTED. (App1, 4), (App2, 5)
+ * LC3: NHM_NODESTATE_SHUTDOWN. NULL
+ */
+
+ /* Create five apps that will be assigned to the LCs */
+ lc_apps[0] = g_new(NhmFailedApp, 1);
+ lc_apps[0]->name = g_strdup("App1");
+ lc_apps[0]->failcount = 3;
+
+ lc_apps[1] = g_new(NhmFailedApp, 1);
+ lc_apps[1]->name = g_strdup("App2");
+ lc_apps[1]->failcount = 4;
+
+ lc_apps[2] = g_new(NhmFailedApp, 1);
+ lc_apps[2]->name = g_strdup("App3");
+ lc_apps[2]->failcount = 5;
+
+ lc_apps[3] = g_new(NhmFailedApp, 1);
+ lc_apps[3]->name = g_strdup("App1");
+ lc_apps[3]->failcount = 4;
+
+ lc_apps[4] = g_new(NhmFailedApp, 1);
+ lc_apps[4]->name = g_strdup("App2");
+ lc_apps[4]->failcount = 5;
+
+ /* Create three LCs */
+ lc_info[0] = g_new(NhmLcInfo, 1);
+ lc_info[0]->start_state = NHM_NODESTATE_SHUTDOWN;
+ lc_info[0]->failed_apps = NULL;
+
+ lc_info[1] = g_new(NhmLcInfo, 1);
+ lc_info[1]->start_state = NHM_NODESTATE_STARTED;
+ lc_info[1]->failed_apps = NULL;
+
+ lc_info[2] = g_new(NhmLcInfo, 1);
+ lc_info[2]->start_state = NHM_NODESTATE_SHUTDOWN;
+ lc_info[2]->failed_apps = NULL;
+
+ /* Add lc_apps[0], lc_apps[1] and lc_apps[2] to list of LC1 */
+ lc_info[0]->failed_apps = g_slist_append(lc_info[0]->failed_apps, lc_apps[0]);
+ lc_info[0]->failed_apps = g_slist_append(lc_info[0]->failed_apps, lc_apps[1]);
+ lc_info[0]->failed_apps = g_slist_append(lc_info[0]->failed_apps, lc_apps[2]);
+
+ /* Add lc_apps[4] and lc_apps[5] to list of LC2*/
+ lc_info[1]->failed_apps = g_slist_append(lc_info[1]->failed_apps, lc_apps[3]);
+ lc_info[1]->failed_apps = g_slist_append(lc_info[1]->failed_apps, lc_apps[4]);
+
+ /* Create array and add LCs */
+ nodeinfo = g_ptr_array_new_with_free_func(&nhm_main_free_lc_info);
+ g_ptr_array_add(nodeinfo, lc_info[0]);
+ g_ptr_array_add(nodeinfo, lc_info[1]);
+ g_ptr_array_add(nodeinfo, lc_info[2]);
+
+ /*
+ * Create initial list of current failed apps: App1, App2, app3
+ */
+ current_failed_app[0] = g_new(NhmCurrentFailedApp, 1);
+ current_failed_app[0]->name = g_strdup("App1");
+
+ current_failed_app[1] = g_new(NhmCurrentFailedApp, 1);
+ current_failed_app[1]->name = g_strdup("App2");
+
+ current_failed_app[2] = g_new(NhmCurrentFailedApp, 1);
+ current_failed_app[2]->name = g_strdup("App3");
+
+ current_failed_apps = NULL;
+ for(app_idx = 0; app_idx < sizeof(current_failed_app)/sizeof(NhmCurrentFailedApp); app_idx++)
+ {
+ current_failed_apps = g_slist_append(current_failed_apps, current_failed_app[app_idx]);
+ }
+
+ /* Check 1: Request info for "App1" for up to 5 LCs => 3 LCs are delivered */
+ max_lc_count = 5;
+
+ nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalFailures = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles = 0;
+
+ nhm_main_read_statistics_cb(NULL, NULL, "App1", NULL);
+
+ retval = ( (nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount == 3)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalFailures == 7)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles == 3)) ? 0 : -1;
+
+ /* Check 2: Request info for "App1" for up to 1 LCs => 1 LC is delivered */
+ if(retval == 0)
+ {
+ max_lc_count = 0;
+
+ nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalFailures = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles = 0;
+
+ nhm_main_read_statistics_cb(NULL, NULL, "App1", NULL);
+
+ retval = ( (nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount == 3)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalFailures == 3)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles == 1)) ? 0 : -1;
+ }
+
+ /* Check 3: Request node info for up to 5 LCs => 3 LCs are delivered */
+ if(retval == 0)
+ {
+ max_lc_count = 5;
+
+ nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalFailures = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles = 0;
+
+ nhm_main_read_statistics_cb(NULL, NULL, "", NULL);
+
+ retval = ( (nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount == 3)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalFailures == 1)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles == 3)) ? 0 : -1;
+ }
+
+ /* Check 4: Request node info for up to 2 LCs => 2 LCs are delivered */
+ if(retval == 0)
+ {
+ max_lc_count = 1;
+
+ nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalFailures = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles = 0;
+
+ nhm_main_read_statistics_cb(NULL, NULL, "", NULL);
+
+ retval = ( (nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount == 3)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalFailures == 1)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles == 2)) ? 0 : -1;
+ }
+
+ /* Check 5: Request app info for App4 for up to 2 LCs => 2 LCs are delivered */
+ if(retval == 0)
+ {
+ max_lc_count = 1;
+
+ nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalFailures = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles = 0;
+
+ nhm_main_read_statistics_cb(NULL, NULL, "App4", NULL);
+
+ retval = ( (nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount == 0)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalFailures == 0)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles == 2)) ? 0 : -1;
+ }
+
+ /* Check 6: No current failed apps. Request node info for 2 LCs */
+ if(retval == 0)
+ {
+ max_lc_count = 1;
+
+ if(current_failed_apps != NULL)
+ {
+ g_slist_free_full(current_failed_apps, &nhm_main_free_current_failed_app);
+ current_failed_apps = NULL;
+ }
+
+ nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalFailures = 0;
+ nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles = 0;
+
+ nhm_main_read_statistics_cb(NULL, NULL, "", NULL);
+
+ retval = ( (nhm_dbus_info_complete_read_statistics_stub_CurrentFailCount == 0)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalFailures == 1)
+ && (nhm_dbus_info_complete_read_statistics_stub_TotalLifecycles == 2)) ? 0 : -1;
+ }
+
+ /* Clean up objects after test */
+ if(current_failed_apps != NULL)
+ {
+ g_slist_free_full(current_failed_apps, &nhm_main_free_current_failed_app);
+ }
+
+ g_ptr_array_unref(nodeinfo);
+
+ return retval;
+}
+
+/**
+ * nhm_test_register_app_status:
+ *
+ * Tests the register app status dbus interface of the NHM.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint
+nhm_test_register_app_status(void)
+{
+ gint retval = 0;
+ NhmLcInfo *initial_lc_info = g_new(NhmLcInfo, 1);
+ gchar *rmcmd = NULL;
+
+ initial_lc_info->start_state = NHM_NODESTATE_SHUTDOWN;
+ initial_lc_info->failed_apps = NULL;
+
+ nodeinfo = g_ptr_array_new_with_free_func(&nhm_main_free_lc_info);
+ g_ptr_array_add(nodeinfo, initial_lc_info);
+ current_failed_apps = NULL;
+
+ /* Check 1: App1 fails. NSM nok => App1 in current_failed_apps */
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = TRUE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App1", NhmAppStatus_Failed, NULL);
+ retval = (nhm_main_find_current_failed_app("App1") != NULL) ? 0 : -1;
+
+ /* Check 2: App2 fails. NSM ok => App2 in current_failed_apps */
+ if(retval == 0)
+ {
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = FALSE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App2", NhmAppStatus_Failed, NULL);
+ retval = (nhm_main_find_current_failed_app("App2") != NULL) ? 0 : -1;
+ }
+
+ /* Check 3: App1 becomes valid. NSM ok => App1 not in current_failed_apps */
+ if(retval == 0)
+ {
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = FALSE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App1", NhmAppStatus_Ok, NULL);
+ retval = (nhm_main_find_current_failed_app("App1") == NULL) ? 0 : -1;
+ }
+
+ /* Check 4: App2 becomes valid. NSM ok => App2 not in current_failed_apps */
+ if(retval == 0)
+ {
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = FALSE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App2", NhmAppStatus_Ok, NULL);
+ retval = (nhm_main_find_current_failed_app("App2") == NULL) ? 0 : -1;
+ }
+
+ /* Check 5: App1 becomes valid. NSM ok => App1 not in current_failed_apps */
+ if(retval == 0)
+ {
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = FALSE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App1", NhmAppStatus_Ok, NULL);
+ retval = (nhm_main_find_current_failed_app("App1") == NULL) ? 0 : -1;
+ }
+
+ /* Check 6: App1 fails. NSM ok => App1 in current_failed_apps */
+ if(retval == 0)
+ {
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = FALSE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App1", NhmAppStatus_Failed, NULL);
+ retval = (nhm_main_find_current_failed_app("App1") != NULL) ? 0 : -1;
+ }
+
+ /* Check 7: App1 fails. NSM ok => App1 in current_failed_apps */
+ if(retval == 0)
+ {
+ nsm_dbus_lc_control_call_set_app_health_status_sync_stub_set_error = FALSE;
+ nhm_main_register_app_status_cb(NULL, NULL, "App1", NhmAppStatus_Failed, NULL);
+ retval = (nhm_main_find_current_failed_app("App1") != NULL) ? 0 : -1;
+ }
+
+ /* Clean up objects created during the test */
+ if(current_failed_apps != NULL)
+ {
+ g_slist_free_full(current_failed_apps, &nhm_main_free_current_failed_app);
+ }
+
+ g_ptr_array_unref(nodeinfo);
+
+ rmcmd = g_strdup_printf("rm %s", NHM_LC_DATA_FILE);
+ system(rmcmd);
+ g_free(rmcmd);
+
+ return retval;
+}
+
+
+/**
+ * nhm_test_nhm_bus_callbacks:
+ *
+ * Tests the bus connection callbacks for the NHM dbus connection.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint
+nhm_test_nhm_bus_callbacks(void)
+{
+ gint retval = 0;
+ GDBusConnection *busconn = NULL;
+
+ /* Check 1: BusAcquired. Interface export ok => Mainloop should not be quit */
+ busconn = g_object_new(G_TYPE_DBUS_CONNECTION, NULL);
+ g_main_loop_quit_stub_called = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = FALSE;
+ nhm_main_bus_acquired_cb(busconn, NULL, NULL);
+ retval = (g_main_loop_quit_stub_called == FALSE) ? 0 : -1;
+ nhm_main_free_nhm_objects();
+ g_object_unref(busconn);
+
+ /* Check 2: BusAcquired. IF export fails => Mainloop should quit */
+ if(retval == 0)
+ {
+ busconn = g_object_new(G_TYPE_DBUS_CONNECTION, NULL);
+ g_main_loop_quit_stub_called = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = TRUE;
+ nhm_main_bus_acquired_cb(busconn, NULL, NULL);
+ retval = (g_main_loop_quit_stub_called == TRUE) ? 0 : -1;
+ nhm_main_free_nhm_objects();
+ g_object_unref(busconn);
+ }
+
+ /* Check 3: NameAcquired. No UL checks => No timer scheduled */
+ if(retval == 0)
+ {
+ nodeinfo = g_ptr_array_new_with_free_func(&nhm_main_free_lc_info);
+ ul_chk_interval = 0;
+
+ g_timeout_add_seconds_called = FALSE;
+ g_timeout_add_seconds_called_interval = 0;
+
+ nhm_main_name_acquired_cb(NULL, NULL, NULL);
+
+ retval = (g_timeout_add_seconds_called == FALSE) ? 0 : -1;
+ g_ptr_array_unref(nodeinfo);
+ }
+
+ /* Check 4: NameAcquired. UL check enabled => Timer is scheduled */
+ if(retval == 0)
+ {
+ nodeinfo = g_ptr_array_new_with_free_func(&nhm_main_free_lc_info);
+ ul_chk_interval = 10000;
+
+ g_timeout_add_seconds_called = FALSE;
+ g_timeout_add_seconds_called_interval = 0;
+
+ nhm_main_name_acquired_cb(NULL, NULL, NULL);
+
+ retval = ( (g_timeout_add_seconds_called == TRUE )
+ && (g_timeout_add_seconds_called_interval == 10000)) ? 0 : -1;
+ g_ptr_array_unref(nodeinfo);
+ }
+
+ /* Check 5: NameLost. Connection not established => Quit Mainloop */
+ if(retval == 0)
+ {
+ g_main_loop_quit_stub_called = FALSE;
+ nhm_main_name_lost_cb(NULL, NULL, NULL);
+ retval = (g_main_loop_quit_stub_called == TRUE) ? 0 : -1;
+ }
+
+ /* Check 6: NameLost. Name lost => Quit Mainloop */
+ if(retval == 0)
+ {
+ g_main_loop_quit_stub_called = FALSE;
+ nhm_main_name_lost_cb((GDBusConnection*) 0x00000001, NULL, NULL);
+ retval = (g_main_loop_quit_stub_called == TRUE) ? 0 : -1;
+ }
+
+ return retval;
+}
+
+
+/**
+ * nhm_test_connect_to_nsm:
+ *
+ * Will test what happens if there is an error when connecting to the NSM.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint
+nhm_test_connect_to_nsm(void)
+{
+ gint retval = 0;
+
+ /* Check 1: Bus connection fails */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = TRUE;
+ retval = (nhm_main_connect_to_nsm() == FALSE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ /* Check 2: Bus connection: ok. LifecycleControl: nok */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_control_proxy_new_sync_stub_set_error = TRUE;
+ retval = (nhm_main_connect_to_nsm() == FALSE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ /* Check 3: Bus connection: ok. LifecycleControl: ok. NodeStateConsumer: nok */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_control_proxy_new_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_proxy_new_sync_stub_set_error = TRUE;
+ retval = (nhm_main_connect_to_nsm() == FALSE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ /* Check 4: Bus connection: ok. LifecycleControl: ok. NodeStateConsumer: ok. Client reg: ok. IF export: nok */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_control_proxy_new_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_proxy_new_sync_stub_set_error = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = TRUE;
+ retval = (nhm_main_connect_to_nsm() == FALSE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ /* Check 5: Bus connection: ok. LifecycleControl: ok. NodeStateConsumer: ok. Client reg: ok. IF export: ok. Reg: nok I */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_control_proxy_new_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_proxy_new_sync_stub_set_error = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_set_error = TRUE;
+ retval = (nhm_main_connect_to_nsm() == FALSE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ /* Check 6: Bus connection: ok. LifecycleControl: ok. NodeStateConsumer: ok. Client reg: ok. IF export: ok. Reg: nok II */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_control_proxy_new_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_proxy_new_sync_stub_set_error = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_out_ErrorCode = NsmErrorStatus_Error;
+ retval = (nhm_main_connect_to_nsm() == FALSE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ /* Check 7: Bus connection: ok. LifecycleControl: ok. NodeStateConsumer: ok. Client reg: ok. IF export: ok. Reg: ok */
+ if(retval == 0)
+ {
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_control_proxy_new_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_proxy_new_sync_stub_set_error = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_out_ErrorCode = NsmErrorStatus_Ok;
+ retval = (nhm_main_connect_to_nsm() == TRUE) ? 0 : -1;
+ nhm_main_free_nsm_objects();
+ }
+
+ return retval;
+}
+
+
+/**
+ * nhm_test_load_config:
+ *
+ * Will test loading of different formated config files.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint
+nhm_test_load_config(void)
+{
+ gint retval = 0;
+
+ /* Check 1: Check if the default config file is correctly loaded */
+ system("cp ../cfg/node-health-monitor.conf ./");
+
+ nhm_main_load_config();
+
+ retval = (max_lc_count == 5 )
+ && (max_failed_apps == 8 )
+ && (no_restart_apps == NULL)
+ && (ul_chk_interval == 0 )
+ && (monitored_files == NULL)
+ && (monitored_procs == NULL)
+ && (monitored_progs == NULL) ? 0 : -1;
+
+ nhm_main_free_config_objects();
+
+ /* Check 2: Check handling if unsigned setting contains neg. value */
+ if(retval == 0)
+ {
+ system("sed -i 's/historic_lc_count = 5/historic_lc_count = -1/g' node-health-monitor.conf");
+
+ nhm_main_load_config();
+
+ retval = (max_lc_count == 0 )
+ && (max_failed_apps == 8 )
+ && (no_restart_apps == NULL)
+ && (ul_chk_interval == 0 )
+ && (monitored_files == NULL)
+ && (monitored_procs == NULL)
+ && (monitored_progs == NULL) ? 0 : -1;
+
+ nhm_main_free_config_objects();
+ }
+
+ /* Check 3: Check handling of missing unsigned keys */
+ if(retval == 0)
+ {
+ system("sed -i 's/historic_lc_count = -1//g' node-health-monitor.conf");
+
+ nhm_main_load_config();
+
+ retval = (max_lc_count == 0 )
+ && (max_failed_apps == 8 )
+ && (no_restart_apps == NULL)
+ && (ul_chk_interval == 0 )
+ && (monitored_files == NULL)
+ && (monitored_procs == NULL)
+ && (monitored_progs == NULL) ? 0 : -1;
+
+ nhm_main_free_config_objects();
+ }
+
+ /* Check 4: Check handling of missing string keys */
+ if(retval == 0)
+ {
+ system("sed -i 's/no_restart_apps =//g' node-health-monitor.conf");
+
+ nhm_main_load_config();
+
+ retval = (max_lc_count == 0 )
+ && (max_failed_apps == 8 )
+ && (no_restart_apps == NULL)
+ && (ul_chk_interval == 0 )
+ && (monitored_files == NULL)
+ && (monitored_procs == NULL)
+ && (monitored_progs == NULL) ? 0 : -1;
+
+ nhm_main_free_config_objects();
+ }
+
+ /* Check 5: Load some valid values */
+ if(retval == 0)
+ {
+ system("sed -i 's/ul_chk_interval = 0/ul_chk_interval = 10/g' node-health-monitor.conf");
+ system("sed -i 's/monitored_files =/monitored_files = File1;File2/g' node-health-monitor.conf");
+
+ nhm_main_load_config();
+
+ retval = (max_lc_count == 0 )
+ && (max_failed_apps == 8 )
+ && (no_restart_apps == NULL)
+ && (ul_chk_interval == 10 )
+ && (monitored_files != NULL)
+ && (strcmp(monitored_files[0], "File1") == 0 )
+ && (strcmp(monitored_files[1], "File2") == 0 )
+ && (monitored_files[2] == NULL)
+ && (monitored_procs == NULL)
+ && (monitored_progs == NULL) ? 0 : -1;
+
+ nhm_main_free_config_objects();
+ }
+
+ system("rm -rf node-health-monitor.conf");
+
+ return retval;
+}
+
+
+/**
+ * nhm_test_main:
+ *
+ * Will check the main function and its embedded calls to nhm_main_load_config
+ * and nhm_main_nsm_connect.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint
+nhm_test_main(void)
+{
+ gint retval = -1;
+
+ /* Preparation for 'nhm_main_nsm_connect':
+ * Bus connection: ok. LifecycleControl: ok. NodeStateConsumer: ok. Client reg: ok. IF export: ok. Reg: ok
+ * => nhm_main_nsm_connect returns 'TRUE', should nhm_main proceed
+ */
+ g_bus_get_sync_set_error = FALSE;
+ nsm_dbus_lc_consumer_proxy_new_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_proxy_new_sync_stub_set_error = FALSE;
+ g_dbus_interface_skeleton_export_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_set_error = FALSE;
+ nsm_dbus_consumer_call_register_shutdown_client_sync_stub_out_ErrorCode = NsmErrorStatus_Ok;
+
+ /* Call main */
+ retval = (nhm_main() == EXIT_FAILURE) ? 0 : -1;
+
+ /* Preparation for 'nhm_main_nsm_connect':
+ * Bus connection: nok.
+ * => nhm_main_nsm_connect returns 'FALSE', should nhm_main fail
+ */
+ if(retval == 0)
+ {
+ mainreturn = EXIT_SUCCESS;
+ g_bus_get_sync_set_error = TRUE;
+
+ /* Call main */
+ retval = (nhm_main() == EXIT_FAILURE) ? 0 : -1;
+ }
+
+ return retval;
+}
+
+/**
+ * nhm_test_on_sigterm:
+ *
+ * Will check the 'nhm_test_on_sigterm' function.
+ *
+ * Returns 0, if test succeeds. Otherwise, it will return -1.
+ */
+static gint
+nhm_test_on_sigterm(void)
+{
+ g_main_loop_quit_stub_called = FALSE;
+
+ nhm_main_on_sigterm(NULL);
+
+ return ( (g_main_loop_quit_stub_called == TRUE)
+ && (mainreturn == EXIT_SUCCESS )) ? 0 : -1;
+}
+
+
+/*******************************************************************************
+*
+* Interfaces. Exported functions.
+*
+*******************************************************************************/
+
+/**
+ * main:
+ *
+ * Main function of the unit test.
+ *
+ * Return value: 0 if all tests succeeded. Otherwise -1.
+ */
+int
+main(void)
+{
+ int retval = 0;
+
+ /* Test 1: Test the main function of the NHM */
+ retval = (retval == 0) ? nhm_test_main() : -1;
+
+ /* Test 2: Test loading and handling of configuration */
+ retval = (retval == 0) ? nhm_test_load_config() : -1;
+
+ /* Test 3: Test NSM connection */
+ retval = (retval == 0) ? nhm_test_connect_to_nsm() : -1;
+
+ /* Test 4: Test NHM bus connection callbacks */
+ retval = (retval == 0) ? nhm_test_nhm_bus_callbacks() : -1;
+
+ /* Test 5: Test NHM register_app_status dbus interface */
+ retval = (retval == 0) ? nhm_test_register_app_status() : -1;
+
+ /* Test 6: Test NHM read_statistics dbus interface */
+ retval = (retval == 0) ? nhm_test_read_statistics() : -1;
+
+ /* Test 7: Test NHM request node restart dbus interface */
+ retval = (retval == 0) ? nhm_test_app_restart_request() : -1;
+
+ /* Test 8: Test NHM user land check functionality */
+ retval = (retval == 0) ? nhm_test_userland_check() : -1;
+
+ /* Test 9: Test NHM WDOG handling */
+ retval = (retval == 0) ? nhm_test_watchdog() : -1;
+
+ /* Test 10: Test NHM LC request handling */
+ retval = (retval == 0) ? nhm_test_handle_lc_request() : -1;
+
+ /* Test 11: Test dbus alive */
+ retval = (retval == 0) ? nhm_test_is_dbus_alive() : -1;
+
+ /* Test 12: Test SIGTERM */
+ retval = (retval == 0) ? nhm_test_on_sigterm() : -1;
+
+ return retval;
+}