/autom4te.cache
/aclocal.m4
/aminclude.am
+/ar-lib
/compile
/configure
/depcomp
git log > ChangeLog
astyle:
- astyle --options=.astylerc -nQ src/*.[ch] src/ed25519/e*.[ch] examples/*.[ch] examples/*.cc test/*.[ch]
+ astyle --options=.astylerc -nQ \
+ src/*.[ch] \
+ src/ed25519/e*.[ch] \
+ examples/*.[ch] \
+ examples/*.cc \
+ `find test -name '*.[ch]'`
AC_CACHE_SAVE
-AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile test/Makefile examples/Makefile])
+AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+ doc/Makefile
+ test/Makefile
+ test/blackbox/Makefile
+ test/blackbox/run_blackbox_tests/Makefile
+ test/blackbox/test_case_meta_conn_01/Makefile
+ test/blackbox/test_case_meta_conn_02/Makefile
+ test/blackbox/test_case_meta_conn_03/Makefile
+ test/blackbox/test_case_meta_conn_04/Makefile
+ test/blackbox/test_case_meta_conn_05/Makefile
+ examples/Makefile
+])
AC_OUTPUT
-*
-!*.*
-.*
-*/
*.log
*.trs
-*.o
-/Makefile
-/Makefile.in
-vgcore.*
-core
-core.*
+/basic
+/basicpp
+/channels
+/channels-cornercases
+/channels-fork
+/duplicate
+/echo-fork
+/import-export
+/invite-join
+/sign-verify
+/trio
+/*.[0123456789]
sign-verify.test \
trio.test
+SUBDIRS = blackbox
+
dist_check_SCRIPTS = $(TESTS)
AM_CPPFLAGS = $(PTHREAD_CFLAGS) -I${top_srcdir}/src -iquote. -Wall
--- /dev/null
+gen_invite
+node_sim_peer
+node_sim_nut
+node_sim_relay
+interfaces
--- /dev/null
+check_PROGRAMS = gen_invite
+
+SUBDIRS = \
+ run_blackbox_tests \
+ test_case_meta_conn_01 \
+ test_case_meta_conn_02 \
+ test_case_meta_conn_03 \
+ test_case_meta_conn_04 \
+ test_case_meta_conn_05
+
+gen_invite_SOURCES = util/gen_invite.c common/common_handlers.c common/test_step.c common/mesh_event_handler.c
+gen_invite_LDADD = ../../src/libmeshlink.la
+gen_invite_CFLAGS = -D_GNU_SOURCE
--- /dev/null
+/*
+ common_handlers.c -- Implementation of common callback handling and signal handling
+ functions for black box tests
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <ctype.h>
+#include "test_step.h"
+#include "common_handlers.h"
+
+char *lxc_bridge = NULL;
+black_box_state_t *state_ptr = NULL;
+
+bool meta_conn_status[10];
+
+bool test_running;
+
+static int meshlink_get_node_in_container(const char *name) {
+ int i;
+
+ for(i = 0; i < state_ptr->num_nodes; i++) {
+ if(!strcasecmp(state_ptr->node_names[i], name)) {
+ return i;
+ break;
+ }
+ }
+
+ return -1;
+}
+
+void mesh_close_signal_handler(int a) {
+ test_running = false;
+
+ exit(EXIT_SUCCESS);
+}
+
+void setup_signals(void) {
+ test_running = true;
+ signal(SIGTERM, mesh_close_signal_handler);
+}
+
+/* Return the IP Address of the Interface 'if_name'
+ The caller is responsible for freeing the dynamically allocated string that is returned */
+char *get_ip(const char *if_name) {
+ struct ifaddrs *ifaddr, *ifa;
+ char *ip;
+ int family;
+
+ ip = malloc(NI_MAXHOST);
+ assert(ip);
+ assert(getifaddrs(&ifaddr) != -1);
+
+ for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if(ifa->ifa_addr == NULL) {
+ continue;
+ }
+
+ family = ifa->ifa_addr->sa_family;
+
+ if(family == AF_INET && !strcmp(ifa->ifa_name, if_name)) {
+ assert(!getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST));
+ break;
+ }
+ }
+
+ return ip;
+}
+
+/* Return the IP Address of the Interface 'if_name'
+ The caller is responsible for freeing the dynamically allocated string that is returned */
+char *get_netmask(const char *if_name) {
+ struct ifaddrs *ifaddr, *ifa;
+ char *ip;
+ int family;
+
+ ip = malloc(NI_MAXHOST);
+ assert(ip);
+ assert(getifaddrs(&ifaddr) != -1);
+
+ for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if(ifa->ifa_addr == NULL) {
+ continue;
+ }
+
+ family = ifa->ifa_addr->sa_family;
+
+ if(family == AF_INET && !strcmp(ifa->ifa_name, if_name)) {
+ assert(!getnameinfo(ifa->ifa_netmask, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST));
+ break;
+ }
+ }
+
+ return ip;
+}
+
+/* Change the IP Address of an interface */
+void set_ip(const char *if_name, const char *new_ip) {
+ char set_ip_cmd[100];
+ assert(snprintf(set_ip_cmd, sizeof(set_ip_cmd), "ifconfig %s %s", if_name, new_ip) >= 0);
+ assert(system(set_ip_cmd) == 0);
+}
+
+/* Change the Netmask of an interface */
+void set_netmask(const char *if_name, const char *new_netmask) {
+ char set_mask_cmd[100];
+ assert(snprintf(set_mask_cmd, sizeof(set_mask_cmd), "ifconfig %s netmask %s", if_name, new_netmask) >= 0);
+ assert(system(set_mask_cmd) == 0);
+}
+
+/* Bring a network interface down (before making changes such as the IP Address) */
+void stop_nw_intf(const char *if_name) {
+ char nw_down_cmd[100];
+ assert(snprintf(nw_down_cmd, sizeof(nw_down_cmd), "ifconfig %s down", if_name) >= 0);
+ assert(system(nw_down_cmd) == 0);
+}
+
+/* Bring a network interface up (after bringing it down and making changes such as
+ the IP Address) */
+void start_nw_intf(const char *if_name) {
+ char nw_up_cmd[100];
+ assert(snprintf(nw_up_cmd, sizeof(nw_up_cmd), "ifconfig %s up", if_name) >= 0);
+ assert(system(nw_up_cmd) == 0);
+}
+
+void meshlink_callback_node_status(meshlink_handle_t *mesh, meshlink_node_t *node,
+ bool reachable) {
+ (void)mesh;
+ fprintf(stderr, "Node %s became %s\n", node->name, (reachable) ? "reachable" : "unreachable");
+}
+
+void meshlink_callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text) {
+ (void)mesh;
+ (void)level;
+
+ fprintf(stderr, "meshlink>> %s\n", text);
+
+ if(state_ptr) {
+ bool status;
+ char name[100];
+
+ if(sscanf(text, "Connection with %s activated", name) == 1) {
+ status = true;
+ } else if(sscanf(text, "Already connected to %s", name) == 1) {
+ status = true;
+ } else if(sscanf(text, "Connection closed by %s", name) == 1) {
+ status = false;
+ } else if(sscanf(text, "Closing connection with %s", name) == 1) {
+ status = false;
+ } else {
+ return;
+ }
+
+ int i = meshlink_get_node_in_container(name);
+ assert(i != -1);
+ meta_conn_status[i] = status;
+ }
+}
--- /dev/null
+/*
+ common_handlers.h -- Declarations of common callback handlers and signal handlers for
+ black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef COMMON_HANDLERS_H
+#define COMMON_HANDLERS_H
+
+#include "common_types.h"
+
+#define PRINT_TEST_CASE_HEADER() if(state_ptr) \
+ fprintf(stderr, "[ %s ]\n", state_ptr->test_case_name)
+#define PRINT_TEST_CASE_MSG(...) if(state_ptr) \
+ do { \
+ fprintf(stderr, "[ %s ] ", \
+ state_ptr->test_case_name); \
+ fprintf(stderr, __VA_ARGS__); \
+ } while(0)
+
+extern bool meta_conn_status[];
+extern bool node_reachable_status[];
+extern bool test_running;
+
+char *get_ip(const char *if_name);
+char *get_netmask(const char *if_name);
+void stop_nw_intf(const char *if_name);
+void start_nw_intf(const char *if_name);
+void set_ip(const char *if_name, const char *new_ip);
+void set_netmask(const char *if_name, const char *new_ip);
+void mesh_close_signal_handler(int a);
+void mesh_stop_start_signal_handler(int a);
+void setup_signals(void);
+void meshlink_callback_node_status(meshlink_handle_t *mesh, meshlink_node_t *node,
+ bool reachable);
+void meshlink_callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text);
+
+#endif // COMMON_HANDLERS_H
--- /dev/null
+/*
+ common_types.h -- Declarations of common types used in Black Box Testing
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef COMMON_TYPES_H
+#define COMMON_TYPES_H
+
+#include <stdbool.h>
+#include "../../../src/meshlink.h"
+
+#define NUT_NODE_NAME "nut"
+
+#define LXC_UTIL_REL_PATH "test/blackbox/util"
+#define LXC_RENAME_SCRIPT "lxc_rename.sh"
+#define LXC_RUN_SCRIPT "lxc_run.sh"
+#define LXC_COPY_SCRIPT "lxc_copy_file.sh"
+#define LXC_BUILD_SCRIPT "build_container.sh"
+
+typedef struct black_box_state {
+ char *test_case_name;
+ char **node_names;
+ int num_nodes;
+ bool test_result;
+} black_box_state_t;
+
+extern char *lxc_bridge;
+
+extern char *eth_if_name;
+
+extern black_box_state_t *state_ptr;
+
+extern char *meshlink_root_path;
+
+/* Meshlink Mesh Handle */
+extern meshlink_handle_t *mesh_handle;
+
+/* Flag to indicate if Mesh is running */
+extern bool mesh_started;
+
+#endif // COMMON_TYPES_H
--- /dev/null
+/*
+ containers.h -- Container Management API
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include "containers.h"
+#include "common_handlers.h"
+
+char *lxc_path = NULL;
+char *choose_arch;
+static char container_ips[10][100];
+
+/* Return the handle to an existing container after finding it by container name */
+struct lxc_container *find_container(const char *name) {
+ struct lxc_container **test_containers;
+ char **container_names;
+ int num_containers, i;
+
+ assert((num_containers = list_all_containers(lxc_path, &container_names,
+ &test_containers)) != -1);
+
+ for(i = 0; i < num_containers; i++) {
+ if(strcmp(container_names[i], name) == 0) {
+ return test_containers[i];
+ }
+ }
+
+ return NULL;
+}
+
+/* Rename a Container */
+void rename_container(const char *old_name, const char *new_name) {
+ char rename_command[200];
+ int rename_status;
+ struct lxc_container *old_container;
+
+ /* Stop the old container if its still running */
+ assert(old_container = find_container(old_name));
+ old_container->shutdown(old_container, CONTAINER_SHUTDOWN_TIMEOUT);
+ /* Call stop() in case shutdown() fails - one of these two will always succeed */
+ old_container->stop(old_container);
+ /* Rename the Container */
+ /* TO DO: Perform this operation using the LXC API - currently does not work via the API,
+ need to investigate and determine why it doesn't work, and make it work */
+ assert(snprintf(rename_command, sizeof(rename_command),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_RENAME_SCRIPT " %s %s %s", meshlink_root_path, lxc_path,
+ old_name, new_name) >= 0);
+ rename_status = system(rename_command);
+ PRINT_TEST_CASE_MSG("Container '%s' rename status: %d\n", old_name, rename_status);
+ assert(rename_status == 0);
+}
+
+/* Run 'cmd' inside the Container created for 'node' and return the first line of the output
+ or NULL if there is no output - useful when, for example, a meshlink invite is generated
+ by a node running inside a Container
+ 'cmd' is run as a daemon if 'daemonize' is true - this mode is useful for running node
+ simulations in Containers
+ The caller is responsible for freeing the returned string */
+char *run_in_container(const char *cmd, const char *node, bool daemonize) {
+ char attach_command[400];
+ char *attach_argv[4];
+ char container_find_name[100];
+ struct lxc_container *container;
+ FILE *attach_fp;
+ char *output = NULL;
+ size_t output_len;
+ int i;
+
+ assert(snprintf(container_find_name, sizeof(container_find_name), "%s_%s",
+ state_ptr->test_case_name, node) >= 0);
+ assert(container = find_container(container_find_name));
+
+ /* Run the command within the Container, either as a daemon or foreground process */
+ /* TO DO: Perform this operation using the LXC API - currently does not work using the API
+ Need to determine why it doesn't work, and make it work */
+ if(daemonize) {
+ for(i = 0; i < 3; i++) {
+ assert(attach_argv[i] = malloc(DAEMON_ARGV_LEN));
+ }
+
+ assert(snprintf(attach_argv[0], DAEMON_ARGV_LEN, "%s/" LXC_UTIL_REL_PATH "/" LXC_RUN_SCRIPT,
+ meshlink_root_path) >= 0);
+ strncpy(attach_argv[1], cmd, DAEMON_ARGV_LEN);
+ strncpy(attach_argv[2], container->name, DAEMON_ARGV_LEN);
+ attach_argv[3] = NULL;
+
+ /* To daemonize, create a child process and detach it from its parent (this program) */
+ if(fork() == 0) {
+ assert(daemon(1, 0) != -1); // Detach from the parent process
+ assert(execv(attach_argv[0], attach_argv) != -1); // Run exec() in the child process
+ }
+
+ for(i = 0; i < 3; i++) {
+ free(attach_argv[i]);
+ }
+ } else {
+ assert(snprintf(attach_command, sizeof(attach_command),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_RUN_SCRIPT " \"%s\" %s", meshlink_root_path, cmd,
+ container->name) >= 0);
+ assert(attach_fp = popen(attach_command, "r"));
+ /* If the command has an output, strip out any trailing carriage returns or newlines and
+ return it, otherwise return NULL */
+ assert(output = malloc(100));
+ output_len = sizeof(output);
+
+ if(getline(&output, &output_len, attach_fp) != -1) {
+ i = strlen(output) - 1;
+
+ while(output[i] == '\n' || output[i] == '\r') {
+ i--;
+ }
+
+ output[i + 1] = '\0';
+ } else {
+ free(output);
+ output = NULL;
+ }
+
+ assert(pclose(attach_fp) != -1);
+ }
+
+ return output;
+}
+
+/* Wait for a starting Container to obtain an IP Address, then save that IP for future use */
+void container_wait_ip(int node) {
+ char container_name[100], lxcls_command[200];
+ struct lxc_container *test_container;
+ char *ip;
+ size_t ip_len;
+ int i;
+ bool ip_found;
+ FILE *lxcls_fp;
+
+ assert(snprintf(container_name, sizeof(container_name), "%s_%s", state_ptr->test_case_name,
+ state_ptr->node_names[node]) >= 0);
+ assert(test_container = find_container(container_name));
+ assert(snprintf(lxcls_command, sizeof(lxcls_command),
+ "lxc-ls -f | grep %s | tr -s ' ' | cut -d ' ' -f 5", test_container->name) >= 0);
+ PRINT_TEST_CASE_MSG("Waiting for Container '%s' to acquire IP\n", test_container->name);
+ assert(ip = malloc(20));
+ ip_len = sizeof(ip);
+ ip_found = false;
+
+ while(!ip_found) {
+ assert(lxcls_fp = popen(lxcls_command, "r")); // Run command
+ assert(getline((char **)&ip, &ip_len, lxcls_fp) != -1); // Read its output
+ /* Strip newlines and carriage returns from output */
+ i = strlen(ip) - 1;
+
+ while(ip[i] == '\n' || ip[i] == '\r') {
+ i--;
+ }
+
+ ip[i + 1] = '\0';
+ ip_found = (strcmp(ip, "-") != 0); // If the output is not "-", IP has been acquired
+ assert(pclose(lxcls_fp) != -1);
+ sleep(1);
+ }
+
+ strncpy(container_ips[node], ip, sizeof(container_ips[node])); // Save the IP for future use
+ PRINT_TEST_CASE_MSG("Node '%s' has IP Address %s\n", state_ptr->node_names[node],
+ container_ips[node]);
+
+ free(ip);
+}
+
+/* Create all required test containers */
+void create_containers(const char *node_names[], int num_nodes) {
+ int i;
+ char container_name[100];
+ int create_status, snapshot_status, snap_restore_status;
+ struct lxc_container *first_container;
+
+ for(i = 0; i < num_nodes; i++) {
+ assert(snprintf(container_name, sizeof(container_name), "run_%s", node_names[i]) >= 0);
+
+ /* If this is the first Container, create it otherwise restore the snapshot saved
+ for the first Container to create an additional Container */
+ if(i == 0) {
+ assert(first_container = lxc_container_new(container_name, NULL));
+ assert(!first_container->is_defined(first_container));
+ create_status = first_container->createl(first_container, "download", NULL, NULL,
+ LXC_CREATE_QUIET, "-d", "ubuntu", "-r", "trusty", "-a", choose_arch, NULL);
+ fprintf(stderr, "Container '%s' create status: %d - %s\n", container_name,
+ first_container->error_num, first_container->error_string);
+ assert(create_status);
+ snapshot_status = first_container->snapshot(first_container, NULL);
+ fprintf(stderr, "Container '%s' snapshot status: %d - %s\n", container_name,
+ first_container->error_num, first_container->error_string);
+ assert(snapshot_status != -1);
+ } else {
+ snap_restore_status = first_container->snapshot_restore(first_container, "snap0",
+ container_name);
+ fprintf(stderr, "Snapshot restore to Container '%s' status: %d - %s\n", container_name,
+ first_container->error_num, first_container->error_string);
+ assert(snap_restore_status);
+ }
+ }
+}
+
+/* Setup Containers required for a test
+ This function should always be invoked in a CMocka context
+ after setting the state of the test case to an instance of black_box_state_t */
+void setup_containers(void **state) {
+ black_box_state_t *test_state = (black_box_state_t *)(*state);
+ int i, confbase_del_status;
+ char build_command[200];
+ struct lxc_container *test_container, *new_container;
+ char container_find_name[100];
+ char container_new_name[100];
+ int create_status, build_status;
+
+ PRINT_TEST_CASE_HEADER();
+
+ for(i = 0; i < test_state->num_nodes; i++) {
+ /* Find the run_<node-name> Container or create it if it doesn't exist */
+ assert(snprintf(container_find_name, sizeof(container_find_name), "run_%s",
+ test_state->node_names[i]) >= 0);
+
+ if(!(test_container = find_container(container_find_name))) {
+ assert(test_container = lxc_container_new(container_find_name, NULL));
+ assert(!test_container->is_defined(test_container));
+ create_status = test_container->createl(test_container, "download", NULL, NULL,
+ LXC_CREATE_QUIET, "-d", "ubuntu", "-r", "trusty", "-a", choose_arch, NULL);
+ PRINT_TEST_CASE_MSG("Container '%s' create status: %d - %s\n", container_find_name,
+ test_container->error_num, test_container->error_string);
+ assert(create_status);
+ }
+
+ /* Stop the Container if it's running */
+ test_container->shutdown(test_container, CONTAINER_SHUTDOWN_TIMEOUT);
+ /* Call stop() in case shutdown() fails
+ One of these two calls will always succeed */
+ test_container->stop(test_container);
+ /* Rename the Container to make it specific to this test case,
+ if a Container with the target name already exists, skip this step */
+ assert(snprintf(container_new_name, sizeof(container_new_name), "%s_%s",
+ test_state->test_case_name, test_state->node_names[i]) >= 0);
+
+ if(!(new_container = find_container(container_new_name))) {
+ rename_container(test_container->name, container_new_name);
+ assert(new_container = find_container(container_new_name));
+ }
+
+ /* Start the Container */
+ assert(new_container->start(new_container, 0, NULL));
+ /* Build the Container by copying required files into it */
+ assert(snprintf(build_command, sizeof(build_command),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_BUILD_SCRIPT " %s %s %s +x >/dev/null",
+ meshlink_root_path, test_state->test_case_name, test_state->node_names[i],
+ meshlink_root_path) >= 0);
+ build_status = system(build_command);
+ PRINT_TEST_CASE_MSG("Container '%s' build Status: %d\n", new_container->name,
+ build_status);
+ assert(build_status == 0);
+ /* Restart the Container after building it and wait for it to acquire an IP */
+ new_container->shutdown(new_container, CONTAINER_SHUTDOWN_TIMEOUT);
+ new_container->stop(new_container);
+ new_container->start(new_container, 0, NULL);
+ container_wait_ip(i);
+ }
+}
+
+/* Destroy all Containers with names containing 'run_' - Containers saved for debugging will
+ have names beginning with test_case_ ; 'run_' is reserved for temporary Containers
+ intended to be re-used for the next test */
+void destroy_containers(void) {
+ struct lxc_container **test_containers;
+ char **container_names;
+ int num_containers, i;
+
+ assert((num_containers = list_all_containers(lxc_path, &container_names,
+ &test_containers)) != -1);
+
+ for(i = 0; i < num_containers; i++) {
+ if(strstr(container_names[i], "run_")) {
+ fprintf(stderr, "Destroying Container '%s'\n", container_names[i]);
+ /* Stop the Container - it cannot be destroyed till it is stopped */
+ test_containers[i]->shutdown(test_containers[i], CONTAINER_SHUTDOWN_TIMEOUT);
+ /* Call stop() in case shutdown() fails
+ One of these two calls will always succeed */
+ test_containers[i]->stop(test_containers[i]);
+ /* Destroy the Container */
+ test_containers[i]->destroy(test_containers[i]);
+ /* call destroy_with_snapshots() in case destroy() fails
+ one of these two calls will always succeed */
+ test_containers[i]->destroy_with_snapshots(test_containers[i]);
+ }
+ }
+}
+
+/* Restart all the Containers being used in the current test case i.e. Containers with
+ names beginning with <test-case-name>_<node-name> */
+void restart_all_containers(void) {
+ char container_name[100];
+ struct lxc_container *test_container;
+ int i;
+
+ for(i = 0; i < state_ptr->num_nodes; i++) {
+ /* Shutdown, then start the Container, then wait for it to acquire an IP Address */
+ assert(snprintf(container_name, sizeof(container_name), "%s_%s", state_ptr->test_case_name,
+ state_ptr->node_names[i]) >= 0);
+ assert(test_container = find_container(container_name));
+ test_container->shutdown(test_container, CONTAINER_SHUTDOWN_TIMEOUT);
+ test_container->stop(test_container);
+ test_container->start(test_container, 0, NULL);
+ container_wait_ip(i);
+ }
+}
+
+/* Run the gen_invite command inside the 'inviter' container to generate an invite
+ for 'invitee', and return the generated invite which is output on the terminal */
+char *invite_in_container(const char *inviter, const char *invitee) {
+ char invite_command[200];
+ char *invite_url;
+
+ assert(snprintf(invite_command, sizeof(invite_command),
+ "LD_LIBRARY_PATH=/home/ubuntu/test/.libs /home/ubuntu/test/gen_invite %s %s "
+ "2> gen_invite.log", inviter, invitee) >= 0);
+ assert(invite_url = run_in_container(invite_command, inviter, false));
+ PRINT_TEST_CASE_MSG("Invite Generated from '%s' to '%s': %s\n", inviter,
+ invitee, invite_url);
+
+ return invite_url;
+}
+
+/* Run the node_sim_<nodename> program inside the 'node''s container */
+void node_sim_in_container(const char *node, const char *device_class, const char *invite_url) {
+ char node_sim_command[200];
+
+ assert(snprintf(node_sim_command, sizeof(node_sim_command),
+ "LD_LIBRARY_PATH=/home/ubuntu/test/.libs /home/ubuntu/test/node_sim_%s %s %s %s "
+ "1>&2 2>> node_sim_%s.log", node, node, device_class,
+ (invite_url) ? invite_url : "", node) >= 0);
+ run_in_container(node_sim_command, node, true);
+ PRINT_TEST_CASE_MSG("node_sim_%s started in Container\n", node);
+}
+
+/* Run the node_sim_<nodename> program inside the 'node''s container with event handling capable*/
+void node_sim_in_container_event(const char *node, const char *device_class,
+ const char *invite_url, const char *clientId, const char *import) {
+ char node_sim_command[200];
+
+ assert(snprintf(node_sim_command, sizeof(node_sim_command),
+ "LD_LIBRARY_PATH=/home/ubuntu/test/.libs /home/ubuntu/test/node_sim_%s %s %s %s %s %s "
+ "1>&2 2>> node_sim_%s.log", node, node, device_class,
+ clientId, import, (invite_url) ? invite_url : "", node) >= 0);
+ run_in_container(node_sim_command, node, true);
+ PRINT_TEST_CASE_MSG("node_sim_%s(Client Id :%s) started in Container with event handling\n",
+ node, clientId);
+ PRINT_TEST_CASE_MSG("node_sim_%s mesh event import string : %s\n",
+ node, import);
+}
+
+/* Run the node_step.sh script inside the 'node''s container to send the 'sig' signal to the
+ node_sim program in the container */
+void node_step_in_container(const char *node, const char *sig) {
+ char node_step_command[200];
+
+ assert(snprintf(node_step_command, sizeof(node_step_command),
+ "/home/ubuntu/test/node_step.sh lt-node_sim_%s %s 1>&2 2> node_step.log",
+ node, sig) >= 0);
+ run_in_container(node_step_command, node, false);
+ PRINT_TEST_CASE_MSG("Signal %s sent to node_sim_%s\n", sig, node);
+}
+
+/* Change the IP Address of the Container running 'node'
+ Changes begin from X.X.X.254 and continue iteratively till an available address is found */
+void change_ip(int node) {
+ char *gateway_addr;
+ char new_ip[20];
+ char *netmask;
+ char *last_dot_in_ip;
+ int last_ip_byte = 254;
+ FILE *if_fp;
+ char copy_command[200];
+ char container_name[100];
+ struct lxc_container *container;
+ int copy_file_stat;
+
+ /* Get IP Address of LXC Bridge Interface - this will be set up as the Gateway Address
+ of the Static IP assigned to the Container */
+ assert(gateway_addr = get_ip(lxc_bridge));
+ /* Get Netmask of LXC Brdige Interface */
+ assert(netmask = get_netmask(lxc_bridge));
+
+ /* Replace last byte of Container's IP with 254 to form the new Container IP */
+ assert(container_ips[node]);
+ strncpy(new_ip, container_ips[node], sizeof(new_ip));
+ assert(last_dot_in_ip = strrchr(new_ip, '.'));
+ assert(snprintf(last_dot_in_ip + 1, 4, "%d", last_ip_byte) >= 0);
+
+ /* Check that the new IP does not match the Container's existing IP
+ if it does, iterate till it doesn't */
+ /* TO DO: Make sure the IP does not conflict with any other running Container */
+ while(strcmp(new_ip, container_ips[node]) == 0) {
+ last_ip_byte--;
+ assert(snprintf(last_dot_in_ip + 1, 4, "%d", last_ip_byte) >= 0);
+ }
+
+ /* Create new 'interfaces' file for Container */
+ assert(if_fp = fopen("interfaces", "w"));
+ fprintf(if_fp, "auto lo\n");
+ fprintf(if_fp, "iface lo inet loopback\n");
+ fprintf(if_fp, "\n");
+ fprintf(if_fp, "auto eth0\n");
+ fprintf(if_fp, "iface eth0 inet static\n");
+ fprintf(if_fp, "\taddress %s\n", new_ip);
+ fprintf(if_fp, "\tnetmask %s\n", netmask);
+ fprintf(if_fp, "\tgateway %s\n", gateway_addr);
+ assert(fclose(if_fp) != EOF);
+
+ /* Copy 'interfaces' file into Container's /etc/network path */
+ assert(snprintf(copy_command, sizeof(copy_command),
+ "%s/" LXC_UTIL_REL_PATH "/" LXC_COPY_SCRIPT " interfaces %s_%s /etc/network/interfaces",
+ meshlink_root_path, state_ptr->test_case_name, state_ptr->node_names[node]) >= 0);
+ copy_file_stat = system(copy_command);
+ PRINT_TEST_CASE_MSG("Container '%s_%s' 'interfaces' file copy status: %d\n",
+ state_ptr->test_case_name, state_ptr->node_names[node], copy_file_stat);
+ assert(copy_file_stat == 0);
+
+ /* Restart Container to apply new IP Address */
+ assert(snprintf(container_name, sizeof(container_name), "%s_%s", state_ptr->test_case_name,
+ state_ptr->node_names[node]) >= 0);
+ assert(container = find_container(container_name));
+ container->shutdown(container, CONTAINER_SHUTDOWN_TIMEOUT);
+ /* Call stop() in case shutdown() fails
+ One of these two calls with always succeed */
+ container->stop(container);
+ assert(container->start(container, 0, NULL));
+
+ strncpy(container_ips[node], new_ip, sizeof(new_ip)); // Save the new IP Addres
+ PRINT_TEST_CASE_MSG("Node '%s' IP Address changed to %s\n", state_ptr->node_names[node],
+ container_ips[node]);
+}
--- /dev/null
+/*
+ containers.h -- Declarations for Container Management API
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+ Manav Kumar Mehta <manavkumarm@yahoo.com>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef CONTAINERS_H
+#define CONTAINERS_H
+
+#include <lxc/lxccontainer.h>
+
+#define DAEMON_ARGV_LEN 200
+#define CONTAINER_SHUTDOWN_TIMEOUT 5
+
+extern char *lxc_path;
+
+struct lxc_container *find_container(const char *name);
+void rename_container(const char *old_name, const char *new_name);
+char *run_in_container(const char *cmd, const char *node, bool daemonize);
+void container_wait_ip(int node);
+void create_containers(const char *node_names[], int num_nodes);
+void setup_containers(void **state);
+void destroy_containers(void);
+void restart_all_containers(void);
+char *invite_in_container(const char *inviter, const char *invitee);
+void node_sim_in_container(const char *node, const char *device_class, const char *invite_url);
+void node_sim_in_container_event(const char *node, const char *device_class,
+ const char *invite_url, const char *clientId, const char *import);
+void node_step_in_container(const char *node, const char *sig);
+void change_ip(int node);
+
+char *get_container_ip(int node);
+
+#endif // CONTAINERS_H
--- /dev/null
+/*
+ mesh_event_handler.c -- handling of mesh events API
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <time.h>
+#include "mesh_event_handler.h"
+
+#define SERVER_LISTEN_PORT "9000" /* Port number that is binded with mesh event server socket */
+
+// TODO: Implement mesh event handling with reentrant functions(if required).
+static struct sockaddr_in server_addr;
+static int client_fd = -1;
+static int server_fd = -1;
+
+char *mesh_event_sock_create(const char *if_name) {
+ struct sockaddr_in server;
+ char *ip;
+ struct ifreq req_if;
+ struct sockaddr_in *resp_if_addr;
+
+ if(if_name == NULL) {
+ return NULL;
+ }
+
+ server_fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if(server_fd < 0) {
+ perror("socket");
+ }
+
+ assert(server_fd >= 0);
+
+ int reuse = 1;
+ assert(setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) != -1);
+
+ memset(&req_if, 0, sizeof(req_if));
+ req_if.ifr_addr.sa_family = AF_INET;
+ strncpy(req_if.ifr_name, if_name, IFNAMSIZ - 1);
+ assert(ioctl(server_fd, SIOCGIFADDR, &req_if) != -1);
+ resp_if_addr = (struct sockaddr_in *) & (req_if.ifr_addr);
+
+ memset(&server, 0, sizeof(server));
+ server.sin_family = AF_INET;
+ server.sin_addr = resp_if_addr->sin_addr;
+ server.sin_port = htons(atoi(SERVER_LISTEN_PORT));
+ assert(bind(server_fd, (struct sockaddr *) &server, sizeof(struct sockaddr)) != -1);
+
+ assert(ip = malloc(30));
+ strncpy(ip, inet_ntoa(resp_if_addr->sin_addr), 20);
+ strcat(ip, ":");
+ strcat(ip, SERVER_LISTEN_PORT);
+
+ return ip;
+}
+
+void mesh_event_sock_connect(const char *import) {
+ char *port = NULL;
+
+ assert(import);
+
+ char *ip = strdup(import);
+ assert((port = strchr(ip, ':')) != NULL);
+ *port = '\0';
+ port++;
+
+ memset(&server_addr, 0, sizeof(server_addr));
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_addr.s_addr = inet_addr(ip);
+ server_addr.sin_port = htons(atoi(port));
+ client_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ free(ip);
+ assert(client_fd >= 0);
+}
+
+bool mesh_event_sock_send(int client_id, mesh_event_t event, void *payload, size_t payload_length) {
+ mesh_event_payload_t mesh_event_send_packet;
+ ssize_t send_ret;
+
+ // Packing the mesh event
+ assert(client_id >= 0);
+ assert(client_fd >= 0);
+ assert(event >= 0 && event < MAX_EVENT);
+ mesh_event_send_packet.client_id = client_id;
+ mesh_event_send_packet.mesh_event = event;
+
+ if((payload == NULL) || (payload_length == 0)) {
+ mesh_event_send_packet.payload_length = 0;
+ } else {
+ mesh_event_send_packet.payload_length = payload_length;
+ memmove(mesh_event_send_packet.payload, payload, payload_length);
+ }
+
+ send_ret = sendto(client_fd, &mesh_event_send_packet, sizeof(mesh_event_send_packet), 0, (const struct sockaddr *) &server_addr, sizeof(server_addr));
+
+ if(send_ret < 0) {
+ perror("sendto status");
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool wait_for_event(mesh_event_callback_t callback, int t) {
+ struct timeval timeout;
+ struct sockaddr client;
+ socklen_t soc_len;
+ fd_set read_fds;
+ int activity;
+ mesh_event_payload_t mesh_event_rec_packet;
+
+ assert(callback);
+ assert(server_fd >= -1);
+ assert(t >= 0);
+
+ timeout.tv_sec = t;
+ timeout.tv_usec = 0;
+ FD_ZERO(&read_fds);
+ FD_SET(server_fd, &read_fds);
+
+ while(1) {
+ activity = select(server_fd + 1, &read_fds, NULL, NULL, &timeout);
+ assert(activity != -1);
+
+ if(activity == 0) {
+ // If no activity happened for the timeout given
+ return false;
+ } else if(FD_ISSET(server_fd, &read_fds)) {
+ // Unpacking the mesh event
+ ssize_t recv_ret = recvfrom(server_fd, &mesh_event_rec_packet, sizeof(mesh_event_rec_packet), 0, &client, &soc_len);
+ assert(recv_ret == sizeof(mesh_event_rec_packet));
+ callback(mesh_event_rec_packet);
+ return true;
+ }
+ }// while
+}
--- /dev/null
+/*
+ mesh_event_handler.h
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef _MESH_EVENT_HANDLER_H_
+#define _MESH_EVENT_HANDLER_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <time.h>
+#include <stdint.h>
+
+/// Maximum length of the mesh event payload
+#define PAYLOAD_MAX_SIZE 1000
+
+/// mesh events
+// TODO: Add more mesh event if required.
+typedef enum {
+ NO_PREFERENCE = 0,
+ META_CONN_SUCCESSFUL,
+ META_CONN,
+ META_DISCONN,
+ META_CONN_CLOSED,
+ NODE_INVITATION,
+ CHANGED_IP_ADDRESS,
+ NODE_UNREACHABLE,
+ NODE_REACHABLE,
+ META_RECONN_SUCCESSFUL,
+ META_RECONN_FAILURE,
+ MESH_DATA_RECEIVED,
+ NODE_STARTED,
+ NODE_RESTARTED,
+ NODE_JOINED,
+ PORT_NO,
+ ERR_NETWORK,
+ MESH_DATA_VERIFED,
+ CHANNEL_OPENED,
+ CHANNEL_REQ_RECIEVED,
+ CHANNEL_CONNECTED,
+ CHANNEL_DATA_RECIEVED,
+ MESH_NODE_DISCOVERED,
+ INCOMING_META_CONN,
+ OUTGOING_META_CONN,
+ AUTO_DISCONN,
+
+ MAX_EVENT // Maximum event enum
+} mesh_event_t;
+
+/// mesh event UDP packet
+typedef struct mesh_event_payload {
+ uint32_t client_id;
+ mesh_event_t mesh_event;
+ uint16_t payload_length;
+ uint8_t payload[PAYLOAD_MAX_SIZE];
+} mesh_event_payload_t;
+
+/// callback for handling the mesh event
+/** mesh event callback called from wait_for_event() if the mesh event UDP server gets a mesh event.
+ *
+ * @param mesh_event_packet packet containing client-id, mesh event & payload (if any).
+ */
+typedef void (*mesh_event_callback_t)(mesh_event_payload_t mesh_event_packet);
+
+/// Creates an UDP server for listening mesh events.
+/** This function creates an UDP socket, binds it with given interface address and returns a NULL
+ * terminated string containing server's IP address & port number.
+ *
+ * @param ifname Name of the network interface to which the socket has to be created.
+ *
+ * @return This function returns a NULL terminated string which has IP address and
+ * port number of the server socket. The application should call free() after
+ * it has finished using the exported string.
+ */
+extern char *mesh_event_sock_create(const char *ifname);
+
+/// Waits for the mesh event for about the given timeout.
+/** This function waits for the mesh event that's expected to occur for the given timeout. If a mesh event
+ * is received then the given callback will be invoked.
+ *
+ * @param callback callback which handles the mesh event packet.
+ * @param timeout timeout for which the the function has to wait for the event.
+ *
+ * @return This function returns true if a mesh event occured else false if timeout exceeded.
+ */
+extern bool wait_for_event(mesh_event_callback_t callback, int timeout);
+
+/// Sends the mesh event to server.
+/** This function sends the mesh event to the server. At the server end it's expected to wait_for_event()
+ * otherwise the packet will be dropped.
+ *
+ * @param client_id Client id by which server can identify the client/node.
+ * @param event An enum describing the mesh event.
+ * @param payload Payload can also be attached along with the mesh event if any, else NULL can
+ * can be specified.
+ * @param payload_length Length of the payload if specified else 0 can be specified.
+ * the maximum payload size can be upto PAYLOAD_MAX_SIZE and if the
+ * PAYLOAD_MAX_SIZE macro is changed it should not exceed the UDP datagram size.
+ *
+ * @return This function returns true on success else returns false.
+ */
+extern bool mesh_event_sock_send(int client_id, mesh_event_t event, void *payload, size_t payload_length);
+
+/// Imports the server address, saves it and opens an UDP client socket.
+/** This function creates an UDP socket, binds it with given interface address and returns a NULL
+ * terminated string containing server's IP address & port number.
+ *
+ * @param server_address NULL terminated string that's exported by mesh_event_sock_create() which
+ * which contains IP address and port number of the mesh event server.
+ *
+ * @return void
+ */
+extern void mesh_event_sock_connect(const char *server_address);
+
+bool wait_for_event_only(mesh_event_callback_t callback, int t, mesh_event_t event);
+#endif // _MESH_EVENT_HANDLER_H_
--- /dev/null
+/*
+ tcpdump.c -- Implementation of Black Box Test Execution for meshlink
+
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <unistd.h>
+#include <sys/prctl.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include "common_handlers.h"
+#include "tcpdump.h"
+
+pid_t tcpdump_start(char *interface) {
+ pid_t tcpdump_pid;
+ char *argv[] = { "tcpdump", "-i", interface, NULL };
+ // child process have a pipe to the parent process when parent process terminates SIGPIPE kills the tcpdump
+ int pipes[2];
+ pipe(pipes);
+ PRINT_TEST_CASE_MSG("\x1b[32mLaunching TCP Dump ..\x1b[0m\n");
+
+ if((tcpdump_pid = fork()) == 0) {
+ prctl(PR_SET_PDEATHSIG, SIGHUP);
+ close(pipes[1]);
+ // Open log file for TCP Dump
+ int fd = open(TCPDUMP_LOG_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ assert(fd != -1);
+ close(STDOUT_FILENO);
+ assert(dup2(fd, STDOUT_FILENO) != -1);
+
+ // Launch TCPDump with port numbers of sleepy, gateway & relay
+ int ret = execvp("/usr/sbin/tcpdump", argv);
+ perror("execvp ");
+ assert(ret != -1);
+ } else {
+ close(pipes[0]);
+ return tcpdump_pid;
+ }
+}
+
+void tcpdump_stop(pid_t tcpdump_pid) {
+ PRINT_TEST_CASE_MSG("\n\x1b[32mStopping TCP Dump.\x1b[0m\n");
+ assert(!kill(tcpdump_pid, SIGTERM));
+}
--- /dev/null
+/*
+ tcpdump.h -- Declarations of common callback handlers and signal handlers for
+ black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef TCPDUMP_H
+#define TCPDUMP_H
+
+#define TCPDUMP_LOG_FILE "tcpdump.log"
+
+extern pid_t tcpdump_start(char *);
+extern void tcpdump_stop(pid_t tcpdump_pid);
+
+#endif // TCPDUMP_H
--- /dev/null
+/*
+ test_step.c -- Handlers for executing test steps during node simulation
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+ŝ
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "../../../src/meshlink.h"
+#include "test_step.h"
+#include "common_handlers.h"
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+meshlink_handle_t *mesh_handle = NULL;
+bool mesh_started = false;
+char *eth_if_name = NULL;
+
+meshlink_handle_t *execute_open(char *node_name, char *dev_class) {
+ /* Set up logging for Meshlink */
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ mesh_handle = meshlink_open("testconf", node_name, "node_sim", atoi(dev_class));
+ fprintf(stderr, "meshlink_open status: %s\n", meshlink_strerror(meshlink_errno));
+ PRINT_TEST_CASE_MSG("meshlink_open status: %s\n", meshlink_strerror(meshlink_errno));
+ assert(mesh_handle);
+
+ /* Set up logging for Meshlink with the newly acquired Mesh Handle */
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ /* Set up callback for node status (reachable / unreachable) */
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+
+ return mesh_handle;
+}
+
+char *execute_invite(char *invitee) {
+ char *invite_url = meshlink_invite(mesh_handle, invitee);
+
+ PRINT_TEST_CASE_MSG("meshlink_invite status: %s\n", meshlink_strerror(meshlink_errno));
+ assert(invite_url);
+
+ return invite_url;
+}
+
+void execute_join(char *invite_url) {
+ bool join_status;
+
+ /* The inviting node may take a moment to open its listening port
+ This sleep() prevents meshlink_join() from failing when the listening port is not open */
+ /* TO DO: Replace this with code that actually checks for the port being open, if possible */
+ PRINT_TEST_CASE_MSG("Sleeping 1 sec to allow inviting node to start listening...\n");
+ sleep(1);
+
+ PRINT_TEST_CASE_MSG("About to join with mesh_handle = %p, invite_url = %s\n", mesh_handle, invite_url);
+ join_status = meshlink_join(mesh_handle, invite_url);
+ PRINT_TEST_CASE_MSG("meshlink_join status: %s\n", meshlink_strerror(meshlink_errno));
+ assert(join_status);
+}
+
+void execute_start(void) {
+ bool start_init_status = meshlink_start(mesh_handle);
+
+ PRINT_TEST_CASE_MSG("meshlink_start status: %s\n", meshlink_strerror(meshlink_errno));
+ assert(start_init_status);
+ mesh_started = true;
+}
+
+void execute_stop(void) {
+ assert(mesh_handle);
+ meshlink_stop(mesh_handle);
+ mesh_started = false;
+}
+
+void execute_close(void) {
+ assert(mesh_handle);
+ meshlink_close(mesh_handle);
+}
+
+void execute_change_ip(void) {
+ char *eth_if_ip;
+ int last_byte;
+ char new_ip[20], gateway_ip[20];
+ char *last_dot_in_ip;
+ char *eth_if_netmask;
+ char route_chg_command[200];
+ int route_chg_status;
+
+ /* Get existing IP Address of Ethernet Bridge Interface */
+ assert(eth_if_ip = get_ip(eth_if_name));
+
+ /* Set new IP Address by replacing the last byte with last byte + 1 */
+ strncpy(new_ip, eth_if_ip, sizeof(new_ip));
+ assert(last_dot_in_ip = strrchr(new_ip, '.'));
+ last_byte = atoi(last_dot_in_ip + 1);
+ assert(snprintf(last_dot_in_ip + 1, 4, "%d", (last_byte > 253) ? 2 : (last_byte + 1)) >= 0);
+
+ /* TO DO: Check for IP conflicts with other interfaces and existing Containers */
+ /* Bring the network interface down before making changes */
+ stop_nw_intf(eth_if_name);
+ /* Save the netmask first, then restore it after setting the new IP Address */
+ assert(eth_if_netmask = get_netmask(eth_if_name));
+ set_ip(eth_if_name, new_ip);
+ set_netmask(eth_if_name, eth_if_netmask);
+ /* Bring the network interface back up again to apply changes */
+ start_nw_intf(eth_if_name);
+
+ /* Get Gateway's IP Address, by replacing the last byte with 1 in the current IP Address */
+ /* TO DO: Obtain the actual Gateway IP Address */
+ strncpy(gateway_ip, eth_if_ip, sizeof(gateway_ip));
+ assert(last_dot_in_ip = strrchr(gateway_ip, '.'));
+ assert(snprintf(last_dot_in_ip + 1, 4, "%d", 1) >= 0);
+
+ /* Add the default route back again, which would have been deleted when the
+ network interface was brought down */
+ /* TO DO: Perform this action using ioctl with SIOCADDRT */
+ /*assert(snprintf(route_chg_command, sizeof(route_chg_command), "route add default gw %s",
+ gateway_ip) >= 0);
+ route_chg_status = system(route_chg_command);
+ PRINT_TEST_CASE_MSG("Default Route Add status = %d\n", route_chg_status);
+ assert(route_chg_status == 0); */
+ // Not necessary for ubuntu versions of 16.04 and 18.04
+
+ PRINT_TEST_CASE_MSG("Node '%s' IP Address changed to %s\n", NUT_NODE_NAME, new_ip);
+
+ free(eth_if_ip);
+ free(eth_if_netmask);
+}
+
--- /dev/null
+/*
+ test_step.h -- Handlers for executing test steps during node simulation
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef TEST_STEP_H
+#define TEST_STEP_H
+
+#include "../../../src/meshlink.h"
+
+meshlink_handle_t *execute_open(char *node_name, char *dev_class);
+char *execute_invite(char *invitee);
+void execute_join(char *invite_url);
+void execute_start(void);
+void execute_stop(void);
+void execute_close(void);
+void execute_change_ip(void);
+
+#endif // TEST_STEP_H
--- /dev/null
+/run_blackbox_tests
--- /dev/null
+check_PROGRAMS = run_blackbox_tests
+
+run_blackbox_tests_SOURCES = \
+ run_blackbox_tests.c \
+ test_cases.c execute_tests.c \
+ ../common/mesh_event_handler.c \
+ ../common/containers.c \
+ ../common/tcpdump.c \
+ ../common/common_handlers.c \
+ ../common/test_step.c \
+ test_cases_destroy.c \
+ test_cases_export.c \
+ test_cases_get_all_nodes.c \
+ test_cases_get_fingerprint.c \
+ test_cases_invite.c \
+ test_cases_rec_cb.c \
+ test_cases_set_port.c \
+ test_cases_sign.c \
+ test_cases_verify.c \
+ test_cases_channel_ex.c \
+ test_cases_channel_get_flags.c \
+ test_cases_status_cb.c \
+ test_cases_set_log_cb.c \
+ test_cases_join.c \
+ test_cases_import.c \
+ test_cases_channel_set_accept_cb.c \
+ test_cases_channel_set_poll_cb.c \
+ test_cases_hint_address.c \
+ test_cases_channel_set_receive_cb.c \
+ test_cases_open.c \
+ test_cases_start.c \
+ test_cases_stop_close.c \
+ test_cases_pmtu.c \
+ test_cases_get_self.c \
+ test_cases_send.c \
+ test_cases_get_node.c \
+ test_cases_add_addr.c \
+ test_cases_get_ex_addr.c \
+ test_cases_add_ex_addr.c \
+ test_cases_get_port.c \
+ test_cases_blacklist.c \
+ test_cases_whitelist.c \
+ test_cases_default_blacklist.c \
+ test_cases_channel_open.c \
+ test_cases_channel_close.c \
+ test_cases_channel_send.c \
+ test_cases_channel_shutdown.c
+
+run_blackbox_tests_LDADD = ../../../src/libmeshlink.la -llxc -lcmocka
+run_blackbox_tests_CFLAGS = -D_GNU_SOURCE
+
--- /dev/null
+/*
+ execute_tests.c -- Utility functions for black box test execution
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include "execute_tests.h"
+#include "../common/common_handlers.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+
+int setup_test(void **state) {
+ int i;
+
+ fprintf(stderr, "Setting up Containers\n");
+ state_ptr = (black_box_state_t *)(*state);
+
+ for(i = 0; i < state_ptr->num_nodes; i++) {
+ meta_conn_status[i] = false;
+ }
+
+ setup_containers(state);
+
+ return EXIT_SUCCESS;
+}
+
+void execute_test(test_step_func_t step_func, void **state) {
+ black_box_state_t *test_state = (black_box_state_t *)(*state);
+
+ fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m : \x1b[34m%s\x1b[0m\n", test_state->test_case_name);
+ test_state->test_result = step_func();
+
+ if(!test_state->test_result) {
+ fail();
+ }
+}
+
+int teardown_test(void **state) {
+ black_box_state_t *test_state = (black_box_state_t *)(*state);
+ char container_old_name[100], container_new_name[100];
+ int i;
+
+ if(test_state->test_result) {
+ PRINT_TEST_CASE_MSG("Test successful! Shutting down nodes.\n");
+
+ for(i = 0; i < test_state->num_nodes; i++) {
+ /* Shut down node */
+ node_step_in_container(test_state->node_names[i], "SIGTERM");
+ /* Rename Container to run_<node-name> - this allows it to be re-used for the
+ next test, otherwise it will be ignored assuming that it has been saved
+ for debugging */
+ assert(snprintf(container_old_name, sizeof(container_old_name), "%s_%s",
+ test_state->test_case_name, test_state->node_names[i]) >= 0);
+ assert(snprintf(container_new_name, sizeof(container_new_name), "run_%s",
+ test_state->node_names[i]) >= 0);
+ rename_container(container_old_name, container_new_name);
+ }
+ }
+
+ state_ptr = NULL;
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+#ifndef EXECUTE_TESTS_H
+#define EXECUTE_TESTS_H
+
+/*
+ execute_tests.h -- header file for execute_tests.c
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+typedef bool (*test_step_func_t)(void);
+
+int setup_test(void **state);
+void execute_test(test_step_func_t step_func, void **state);
+int teardown_test(void **state);
+
+#endif // TEST_STEP_H
--- /dev/null
+/*
+ run_blackbox_tests.c -- Implementation of Black Box Test Execution for meshlink
+
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include "execute_tests.h"
+#include "test_cases.h"
+#include "test_cases_open.h"
+#include "test_cases_start.h"
+#include "test_cases_stop_close.h"
+#include "test_cases_send.h"
+#include "test_cases_pmtu.h"
+#include "test_cases_get_self.h"
+#include "test_cases_get_node.h"
+#include "test_cases_add_addr.h"
+#include "test_cases_get_ex_addr.h"
+#include "test_cases_add_ex_addr.h"
+#include "test_cases_get_port.h"
+#include "test_cases_blacklist.h"
+#include "test_cases_default_blacklist.h"
+#include "test_cases_whitelist.h"
+#include "test_cases_channel_open.h"
+#include "test_cases_channel_close.h"
+#include "test_cases_channel_send.h"
+#include "test_cases_channel_shutdown.h"
+
+#include "test_cases_destroy.h"
+#include "test_cases_get_all_nodes.h"
+#include "test_cases_get_fingerprint.h"
+#include "test_cases_rec_cb.h"
+#include "test_cases_sign.h"
+#include "test_cases_set_port.h"
+#include "test_cases_verify.h"
+#include "test_cases_invite.h"
+#include "test_cases_export.h"
+#include "test_cases_channel_ex.h"
+#include "test_cases_channel_get_flags.h"
+#include "test_cases_status_cb.h"
+#include "test_cases_set_log_cb.h"
+#include "test_cases_join.h"
+#include "test_cases_import.h"
+#include "test_cases_channel_set_accept_cb.h"
+#include "test_cases_channel_set_poll_cb.h"
+#include "test_cases_channel_set_receive_cb.h"
+#include "test_cases_hint_address.h"
+#include "../common/containers.h"
+#include "../common/common_handlers.h"
+
+char *meshlink_root_path = NULL;
+char *choose_arch = NULL;
+int total_tests;
+
+int main(int argc, char *argv[]) {
+ /* Set configuration */
+ assert(argc > 5);
+ meshlink_root_path = argv[1];
+ lxc_path = argv[2];
+ lxc_bridge = argv[3];
+ eth_if_name = argv[4];
+ choose_arch = argv[5];
+
+ int failed_tests = 0;
+
+ failed_tests += test_meta_conn();
+ failed_tests += test_meshlink_set_status_cb();
+ failed_tests += test_meshlink_join();
+ failed_tests += test_meshlink_set_channel_poll_cb();
+// failed_tests += test_meshlink_channel_open_ex();
+ failed_tests += test_meshlink_channel_get_flags();
+ failed_tests += test_meshlink_set_channel_accept_cb();
+ failed_tests += test_meshlink_destroy();
+ failed_tests += test_meshlink_export();
+ failed_tests += test_meshlink_get_fingerprint();
+ failed_tests += test_meshlink_get_all_nodes();
+ failed_tests += test_meshlink_set_port();
+ failed_tests += test_meshlink_sign();
+ failed_tests += test_meshlink_verify();
+ failed_tests += test_meshlink_import();
+ failed_tests += test_meshlink_invite();
+ failed_tests += test_meshlink_set_receive_cb();
+ failed_tests += test_meshlink_set_log_cb();
+ failed_tests += test_meshlink_set_channel_receive_cb();
+ failed_tests += test_meshlink_hint_address();
+
+ failed_tests += test_meshlink_open();
+ failed_tests += test_meshlink_start();
+ failed_tests += test_meshlink_stop_close();
+ failed_tests += test_meshlink_send();
+ failed_tests += test_meshlink_channel_send();
+ failed_tests += test_meshlink_channel_shutdown();
+ failed_tests += test_meshlink_pmtu();
+ failed_tests += test_meshlink_get_self();
+ failed_tests += test_meshlink_get_node();
+ failed_tests += test_meshlink_add_address();
+ failed_tests += test_meshlink_get_external_address();
+ failed_tests += test_meshlink_add_external_address();
+ failed_tests += test_meshlink_get_port();
+ failed_tests += test_meshlink_blacklist();
+ failed_tests += test_meshlink_whitelist();
+ failed_tests += test_meshlink_default_blacklist();
+ failed_tests += test_meshlink_channel_open();
+ failed_tests += test_meshlink_channel_close();
+
+ printf("[ PASSED ] %d test(s).\n", total_tests - failed_tests);
+ printf("[ FAILED ] %d test(s).\n", failed_tests);
+
+ return failed_tests;
+}
--- /dev/null
+/*
+ test_cases.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include "execute_tests.h"
+#include "test_cases.h"
+#include "pthread.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "../common/mesh_event_handler.h"
+
+#define RELAY_ID "0"
+#define PEER_ID "1"
+#define NUT_ID "2"
+
+static void test_case_meta_conn_01(void **state);
+static bool test_steps_meta_conn_01(void);
+static void test_case_meta_conn_02(void **state);
+static bool test_steps_meta_conn_02(void);
+static void test_case_meta_conn_03(void **state);
+static bool test_steps_meta_conn_03(void);
+static void test_case_meta_conn_04(void **state);
+static bool test_steps_meta_conn_04(void);
+static void test_case_meta_conn_05(void **state);
+static bool test_steps_meta_conn_05(void);
+
+/* State structure for Meta-connections Test Case #1 */
+static char *test_meta_conn_1_nodes[] = { "relay", "peer", "nut" };
+static black_box_state_t test_meta_conn_1_state = {
+ .test_case_name = "test_case_meta_conn_01",
+ .node_names = test_meta_conn_1_nodes,
+ .num_nodes = 3,
+};
+
+/* State structure for Meta-connections Test Case #2 */
+static char *test_meta_conn_2_nodes[] = { "relay", "peer", "nut" };
+static black_box_state_t test_meta_conn_2_state = {
+ .test_case_name = "test_case_meta_conn_02",
+ .node_names = test_meta_conn_2_nodes,
+ .num_nodes = 3,
+};
+
+/* State structure for Meta-connections Test Case #3 */
+static char *test_meta_conn_3_nodes[] = { "relay", "peer", "nut" };
+static black_box_state_t test_meta_conn_3_state = {
+ .test_case_name = "test_case_meta_conn_03",
+ .node_names = test_meta_conn_3_nodes,
+ .num_nodes = 3,
+};
+
+/* State structure for Meta-connections Test Case #4 */
+static char *test_meta_conn_4_nodes[] = { "peer", "nut" };
+static black_box_state_t test_meta_conn_4_state = {
+ .test_case_name = "test_case_meta_conn_04",
+ .node_names = test_meta_conn_4_nodes,
+ .num_nodes = 2,
+};
+
+/* State structure for Meta-connections Test Case #5 */
+static char *test_meta_conn_5_nodes[] = { "peer", "nut" };
+static black_box_state_t test_meta_conn_5_state = {
+ .test_case_name = "test_case_meta_conn_05",
+ .node_names = test_meta_conn_5_nodes,
+ .num_nodes = 2,
+};
+
+int black_box_group0_setup(void **state) {
+ const char *nodes[] = { "peer", "relay", "nut"};
+ int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
+
+ PRINT_TEST_CASE_MSG("Creating Containers\n");
+ destroy_containers();
+ create_containers(nodes, num_nodes);
+
+ return 0;
+}
+
+int black_box_group0_teardown(void **state) {
+ PRINT_TEST_CASE_MSG("Destroying Containers\n");
+ destroy_containers();
+
+ return 0;
+}
+
+int black_box_all_nodes_setup(void **state) {
+ const char *nodes[] = { "peer" };
+ int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
+
+ PRINT_TEST_CASE_MSG("Creating Containers\n");
+ destroy_containers();
+ create_containers(nodes, num_nodes);
+ PRINT_TEST_CASE_MSG("Created Containers\n");
+ return 0;
+}
+
+static bool meta_conn01_conn;
+static bool meta_conn01_closed;
+static bool meta_conn01_reconn;
+
+static void meta_conn01_cb(mesh_event_payload_t payload) {
+ char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
+ fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
+
+ switch(payload.mesh_event) {
+ case META_CONN_SUCCESSFUL :
+ meta_conn01_conn = true;
+ break;
+
+ case NODE_STARTED :
+ fprintf(stderr, "Node started\n");
+ break;
+
+ case META_CONN_CLOSED :
+ meta_conn01_closed = true;
+ break;
+
+ case META_RECONN_SUCCESSFUL :
+ meta_conn01_reconn = true;
+ break;
+ }
+}
+
+/* Execute Meta-connections Test Case # 1 - re-connection to peer after disconnection when
+ connected via a third node */
+static void test_case_meta_conn_01(void **state) {
+ execute_test(test_steps_meta_conn_01, state);
+}
+
+/* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
+ connected via a third (relay) node
+
+ Test Steps:
+ 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
+ 2. After connection to peer, terminate the peer node's running instance
+ 3. After peer becomes unreachable, wait 60 seconds then re-start the peer node's instance
+
+ Expected Result:
+ NUT is re-connected to peer
+*/
+static bool test_steps_meta_conn_01(void) {
+ char *invite_peer, *invite_nut;
+ bool result = false;
+ int i;
+ char *import;
+
+ import = mesh_event_sock_create(eth_if_name);
+ invite_peer = invite_in_container("relay", "peer");
+ invite_nut = invite_in_container("relay", NUT_NODE_NAME);
+ node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
+ wait_for_event(meta_conn01_cb, 5);
+ node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
+ wait_for_event(meta_conn01_cb, 5);
+ node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
+ wait_for_event(meta_conn01_cb, 5);
+
+ PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
+ assert(wait_for_event(meta_conn01_cb, 60));
+ assert(meta_conn01_conn);
+
+ PRINT_TEST_CASE_MSG("Sending SIGTERM to peer\n");
+ node_step_in_container("peer", "SIGTERM");
+ PRINT_TEST_CASE_MSG("Waiting for peer to become unreachable\n");
+ assert(wait_for_event(meta_conn01_cb, 60));
+ assert(meta_conn01_closed);
+
+ node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
+ wait_for_event(meta_conn01_cb, 5);
+ PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
+ wait_for_event(meta_conn01_cb, 60);
+
+ assert_int_equal(meta_conn01_reconn, true);
+
+ free(invite_peer);
+ free(invite_nut);
+
+ return true;
+}
+
+
+static bool meta_conn02_conn;
+
+static void meta_conn02_cb(mesh_event_payload_t payload) {
+ char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
+ fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
+
+ switch(payload.mesh_event) {
+ case META_CONN_SUCCESSFUL :
+ fprintf(stderr, "Meta Connection Successful\n");
+ meta_conn02_conn = true;
+ break;
+
+ case NODE_STARTED :
+ fprintf(stderr, "Node started\n");
+ break;
+ }
+
+ if(payload.payload_length) {
+ fprintf(stderr, " %s\n", (char *)payload.payload);
+ }
+}
+/* Execute Meta-connections Test Case # 2 - re-connection to peer via third node
+ after changing IP of NUT and peer */
+static void test_case_meta_conn_02(void **state) {
+ execute_test(test_steps_meta_conn_02, state);
+}
+/* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
+ after changing IP of NUT and peer
+
+ Test Steps:
+ 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
+ 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
+
+ Expected Result:
+ NUT is first disconnected from peer then automatically re-connected to peer
+*/
+static bool test_steps_meta_conn_02(void) {
+ char *invite_peer, *invite_nut;
+ bool result = false;
+ int i;
+ char *import;
+
+ import = mesh_event_sock_create(eth_if_name);
+ invite_peer = invite_in_container("relay", "peer");
+ invite_nut = invite_in_container("relay", NUT_NODE_NAME);
+ node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
+ wait_for_event(meta_conn02_cb, 5);
+ node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
+ wait_for_event(meta_conn02_cb, 5);
+ node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
+ wait_for_event(meta_conn02_cb, 5);
+
+ PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
+ assert(wait_for_event(meta_conn02_cb, 60));
+ assert(meta_conn02_conn);
+
+ meta_conn02_conn = false;
+ node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
+ wait_for_event(meta_conn02_cb, 5);
+ node_sim_in_container_event("nut", "1", NULL, NUT_ID, import);
+ wait_for_event(meta_conn02_cb, 5);
+
+ PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
+
+ if(!wait_for_event(meta_conn02_cb, 60)) {
+ return false;
+ }
+
+ result = meta_conn02_conn;
+
+ free(invite_peer);
+ free(invite_nut);
+
+ return result;
+}
+
+static bool meta_conn03_result;
+static bool meta_conn03_conn;
+
+static void meta_conn03_cb(mesh_event_payload_t payload) {
+ char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
+ fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
+
+ switch(payload.mesh_event) {
+ case META_CONN_SUCCESSFUL :
+ fprintf(stderr, "Meta Connection Successful\n");
+ meta_conn03_conn = true;
+ break;
+
+ case NODE_STARTED :
+ fprintf(stderr, "Node started\n");
+ break;
+
+ case META_RECONN_FAILURE :
+ fprintf(stderr, "Failed to reconnect with");
+ meta_conn03_result = false;
+ break;
+
+ case META_RECONN_SUCCESSFUL :
+ fprintf(stderr, "Reconnected\n");
+ meta_conn03_result = true;
+ break;
+ }
+}
+/* Execute Meta-connections Test Case # 3 - re-connection to peer via third node
+ after changing IP of peer */
+static void test_case_meta_conn_03(void **state) {
+ execute_test(test_steps_meta_conn_03, state);
+}
+/* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
+ after changing IP of peer
+
+ Test Steps:
+ 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
+ 2. After connection to peer, change the peer node's IP Address
+
+ Expected Result:
+ NUT is first disconnected from peer then automatically re-connected to peer
+*/
+static bool test_steps_meta_conn_03(void) {
+ char *invite_peer, *invite_nut;
+ bool result = false;
+ int i;
+ char *import;
+
+ import = mesh_event_sock_create(eth_if_name);
+ invite_peer = invite_in_container("relay", "peer");
+ invite_nut = invite_in_container("relay", NUT_NODE_NAME);
+ node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
+ wait_for_event(meta_conn03_cb, 5);
+ node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
+ wait_for_event(meta_conn03_cb, 5);
+ node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
+ wait_for_event(meta_conn03_cb, 5);
+
+ PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
+ assert(wait_for_event(meta_conn03_cb, 60));
+ assert(meta_conn03_conn);
+
+ PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
+ change_ip(1);
+ node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
+ wait_for_event(meta_conn03_cb, 5);
+ PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
+ wait_for_event(meta_conn03_cb, 5);
+ result = meta_conn03_result;
+ free(invite_peer);
+ free(invite_nut);
+
+ return result;
+}
+
+static char *invite_peer = NULL;
+static bool meta_conn04 = false;
+
+static void meta_conn04_cb(mesh_event_payload_t payload) {
+ char event_node_name[][10] = {"PEER", "NUT"};
+ fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
+
+ switch(payload.mesh_event) {
+ case META_CONN_SUCCESSFUL :
+ fprintf(stderr, "Meta Connection Successful\n");
+ meta_conn04 = true;
+ break;
+
+ case NODE_INVITATION :
+ fprintf(stderr, "Invitation generated\n");
+ invite_peer = malloc(payload.payload_length);
+ strcpy(invite_peer, (char *)payload.payload);
+ break;
+
+ case NODE_STARTED :
+ fprintf(stderr, "Node started\n");
+ break;
+ }
+}
+
+/* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
+ NUT and peer */
+static void test_case_meta_conn_04(void **state) {
+ execute_test(test_steps_meta_conn_04, state);
+}
+
+/* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
+ NUT and peer
+
+ Test Steps:
+ 1. Run NUT and peer nodes with NUT inviting the peer node
+ 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
+
+ Expected Result:
+ NUT is first disconnected from peer then automatically re-connected to peer
+*/
+static bool test_steps_meta_conn_04(void) {
+ bool result = false;
+ char *import;
+
+ import = mesh_event_sock_create(eth_if_name);
+ node_sim_in_container_event("nut", "1", NULL, "1", import);
+ wait_for_event(meta_conn04_cb, 5);
+
+ PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
+ wait_for_event(meta_conn04_cb, 5);
+
+ if(!invite_peer) {
+ return false;
+ }
+
+ PRINT_TEST_CASE_MSG("Running PEER node in the container\n");
+ node_sim_in_container_event("peer", "1", invite_peer, "0", import);
+ wait_for_event(meta_conn04_cb, 5);
+ PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
+
+ if(!wait_for_event(meta_conn04_cb, 60)) {
+ return false;
+ }
+
+ PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
+ change_ip(1);
+
+ node_sim_in_container_event("nut", "1", "restart", "1", import);
+ wait_for_event(meta_conn04_cb, 5);
+ PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
+ change_ip(0);
+ node_sim_in_container_event("peer", "1", NULL, "0", import);
+ wait_for_event(meta_conn04_cb, 5);
+
+ PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
+ wait_for_event(meta_conn04_cb, 5);
+ result = meta_conn04;
+
+ free(invite_peer);
+ free(import);
+ return result;
+}
+
+static char *invitation = NULL;
+
+static bool meta_conn05 = false;
+
+static void meta_conn05_cb(mesh_event_payload_t payload) {
+ char event_node_name[][10] = {"PEER", "NUT"};
+ fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
+
+ switch(payload.mesh_event) {
+ case META_CONN_SUCCESSFUL :
+ meta_conn05 = true;
+ break;
+
+ case NODE_INVITATION :
+ invitation = malloc(payload.payload_length);
+ strcpy(invitation, (char *)payload.payload);
+ break;
+
+ case NODE_STARTED :
+ fprintf(stderr, "Node started\n");
+ break;
+ }
+}
+
+/* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer */
+static void test_case_meta_conn_05(void **state) {
+ execute_test(test_steps_meta_conn_05, state);
+}
+
+/* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
+
+ Test Steps:
+ 1. Run NUT and peer nodes with NUT inviting the peer node
+ 2. After connection to peer, change the peer node's IP Address
+
+ Expected Result:
+ NUT is first disconnected from peer then automatically re-connected to peer
+*/
+static bool test_steps_meta_conn_05(void) {
+ bool result = false;
+ char *import;
+
+ import = mesh_event_sock_create(eth_if_name);
+ node_sim_in_container_event("nut", "1", NULL, "1", import);
+ wait_for_event(meta_conn05_cb, 5);
+
+ wait_for_event(meta_conn05_cb, 5);
+
+ if(!invitation) {
+ return false;
+ }
+
+ node_sim_in_container_event("peer", "1", invitation, "0", import);
+ wait_for_event(meta_conn05_cb, 5);
+
+ if(!wait_for_event(meta_conn05_cb, 5)) {
+ return false;
+ }
+
+ change_ip(0);
+ meta_conn05 = false;
+ node_sim_in_container_event("peer", "1", NULL, "0", import);
+ wait_for_event(meta_conn05_cb, 5);
+ PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
+ wait_for_event(meta_conn05_cb, 5);
+ result = meta_conn05;
+
+ free(invitation);
+ free(import);
+ return result;
+}
+
+int test_meta_conn(void) {
+ const struct CMUnitTest blackbox_group0_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_01, setup_test, teardown_test,
+ (void *)&test_meta_conn_1_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_02, setup_test, teardown_test,
+ (void *)&test_meta_conn_2_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_03, setup_test, teardown_test,
+ (void *)&test_meta_conn_3_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_04, setup_test, teardown_test,
+ (void *)&test_meta_conn_4_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_05, setup_test, teardown_test,
+ (void *)&test_meta_conn_5_state)
+ };
+ total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);
+}
--- /dev/null
+#ifndef TEST_CASES_H
+#define TEST_CASES_H
+
+/*
+ test_cases.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meta_conn(void);
+
+#endif // TEST_STEP_H
--- /dev/null
+/*
+ test_cases_add_addr.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_add_addr.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+
+static void test_case_mesh_add_address_01(void **state);
+static bool test_steps_mesh_add_address_01(void);
+static void test_case_mesh_add_address_02(void **state);
+static bool test_steps_mesh_add_address_02(void);
+static void test_case_mesh_add_address_03(void **state);
+static bool test_steps_mesh_add_address_03(void);
+
+/* State structure for meshlink_add_address Test Case #1 */
+static black_box_state_t test_mesh_add_address_01_state = {
+ .test_case_name = "test_case_mesh_add_address_01",
+};
+
+/* State structure for meshlink_add_address Test Case #2 */
+static black_box_state_t test_mesh_add_address_02_state = {
+ .test_case_name = "test_case_mesh_add_address_02",
+};
+
+/* State structure for meshlink_add_address Test Case #3 */
+static black_box_state_t test_mesh_add_address_03_state = {
+ .test_case_name = "test_case_mesh_add_address_03",
+};
+
+/* Execute meshlink_add_address Test Case # 1 */
+static void test_case_mesh_add_address_01(void **state) {
+ execute_test(test_steps_mesh_add_address_01, state);
+}
+
+/* Test Steps for meshlink_add_address Test Case # 1
+
+ Test Steps:
+ 1. Create node instance
+ 2. Add an address to the host node
+ 2. Open host file from confbase & verify address being added
+
+ Expected Result:
+ meshlink_add_address API adds the new address given to it's confbase
+*/
+static bool test_steps_mesh_add_address_01(void) {
+ char *node = "foo";
+ meshlink_destroy("add_conf.1");
+
+ // Create node instance
+ meshlink_handle_t *mesh = meshlink_open("add_conf.1", node, "chat", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ char *hostname = "localhost";
+ bool ret = meshlink_add_address(mesh, hostname);
+ assert_int_equal(ret, true);
+
+ // Open the foo host file from confbase to verify address being added
+ bool found = false;
+ FILE *fp = fopen("./add_conf.1/hosts/foo", "r");
+ assert(fp);
+ char line[100];
+
+ while(fgets(line, 100, fp) != NULL) {
+ if(strcasestr(line, "Address") && strcasestr(line, hostname)) {
+ found = true;
+ }
+ }
+
+ assert(!fclose(fp));
+
+ assert_int_equal(found, true);
+
+ // Clean up
+ meshlink_close(mesh);
+ meshlink_destroy("add_conf.1");
+ return true;
+}
+
+/* Execute meshlink_add_address Test Case # 2 */
+static void test_case_mesh_add_address_02(void **state) {
+ execute_test(test_steps_mesh_add_address_02, state);
+}
+
+/* Test Steps for meshlink_add_address Test Case # 2
+
+ Test Steps:
+ 1. Create node instance
+ 2. Call meshlink_add_address API using NULL as mesh handle argument
+
+ Expected Result:
+ meshlink_add_address API returns false by reporting error successfully.
+*/
+static bool test_steps_mesh_add_address_02(void) {
+ // Passing NULL as mesh handle argument to meshlink_add_address API
+ bool result = meshlink_add_address(NULL, "localhost");
+ assert_int_equal(result, false);
+
+ return true;
+}
+
+/* Execute meshlink_add_address Test Case # 3 */
+static void test_case_mesh_add_address_03(void **state) {
+ execute_test(test_steps_mesh_add_address_03, state);
+}
+
+/* Test Steps for meshlink_add_address Test Case # 3
+
+ Test Steps:
+ 1. Create node instance
+ 2. Call meshlink_add_address API using NULL as address argument
+
+ Expected Result:
+ meshlink_add_address API returns false by reporting error successfully.
+*/
+static bool test_steps_mesh_add_address_03(void) {
+ meshlink_destroy("add_conf.3");
+
+ // Create node instance
+ meshlink_handle_t *mesh = meshlink_open("add_conf.3", "foo", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ bool result = meshlink_add_address(mesh, NULL);
+ assert_int_equal(result, false);
+
+ meshlink_close(mesh);
+ meshlink_destroy("add_conf.3");
+ return true;
+}
+
+int test_meshlink_add_address(void) {
+ const struct CMUnitTest blackbox_add_addr_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_add_address_01, NULL, NULL,
+ (void *)&test_mesh_add_address_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_add_address_02, NULL, NULL,
+ (void *)&test_mesh_add_address_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_add_address_03, NULL, NULL,
+ (void *)&test_mesh_add_address_03_state)
+ };
+
+ total_tests += sizeof(blackbox_add_addr_tests) / sizeof(blackbox_add_addr_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_add_addr_tests, NULL, NULL);
+}
+
--- /dev/null
+#ifndef TEST_CASES_ADD_ADDR_H
+#define TEST_CASES_ADD_ADDR_H
+
+/*
+ test_cases_add_addr.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#include <stdbool.h>
+
+extern int test_meshlink_add_address(void);
+extern int total_tests;
+
+#endif //TEST_CASES_ADD_ADDR_H_INCLUDED
--- /dev/null
+/*
+ test_cases_add_ex_addr.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_add_ex_addr.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+
+static void test_case_mesh_add_ex_address_01(void **state);
+static bool test_steps_mesh_add_ex_address_01(void);
+static void test_case_mesh_add_ex_address_02(void **state);
+static bool test_steps_mesh_add_ex_address_02(void);
+
+/* State structure for meshlink_add_external_address Test Case #1 */
+static black_box_state_t test_mesh_add_ex_address_01_state = {
+ .test_case_name = "test_case_mesh_add_ex_address_01",
+};
+
+/* State structure for meshlink_add_external_address Test Case #2 */
+static black_box_state_t test_mesh_add_ex_address_02_state = {
+ .test_case_name = "test_case_mesh_add_ex_address_01",
+};
+
+/* Execute meshlink_add_external_address Test Case # 1 */
+void test_case_mesh_add_ex_address_01(void **state) {
+ execute_test(test_steps_mesh_add_ex_address_01, state);
+}
+
+/* Test Steps for meshlink_add_external_address Test Case # 1
+
+ Test Steps:
+ 1. Create node instance
+ 2. Get mesh's external address
+ 3. Add external address using meshlink_add_external_address API
+ 4. Open nodes confbase and read the external address from the list if addresses
+
+ Expected Result:
+ meshlink_add_external_address API adds the new address given to it's confbase
+*/
+bool test_steps_mesh_add_ex_address_01(void) {
+ meshlink_destroy("addex_conf.1");
+
+ // Create node instance
+ meshlink_handle_t *mesh = meshlink_open("addex_conf.1", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ char *external_address = meshlink_get_external_address(mesh);
+ assert(external_address);
+
+ bool ret = meshlink_add_external_address(mesh);
+ assert_int_equal(ret, true);
+
+ // Open the foo host file from confbase to verify address being added
+ bool found = false;
+ FILE *fp = fopen("./addex_conf.1/hosts/foo", "r");
+ assert(fp);
+ char line[100];
+
+ while(fgets(line, 100, fp) != NULL) {
+ if(strcasestr(line, "Address") && strcasestr(line, external_address)) {
+ found = true;
+ }
+ }
+
+ assert(!fclose(fp));
+
+ assert_int_equal(found, true);
+
+ meshlink_close(mesh);
+ meshlink_destroy("addex_conf.1");
+ return true;
+}
+
+/* Execute meshlink_add_external_address Test Case # 2 */
+void test_case_mesh_add_ex_address_02(void **state) {
+ execute_test(test_steps_mesh_add_ex_address_02, state);
+}
+
+/* Test Steps for meshlink_add_external_address Test Case # 2
+
+ Test Steps:
+ 1. Create node instance
+ 2. Call meshlink_add_external_address API using NULL as mesh handle argument
+
+ Expected Result:
+ meshlink_add_external_address API returns false by reporting error successfully.
+*/
+bool test_steps_mesh_add_ex_address_02(void) {
+ bool result = meshlink_add_external_address(NULL);
+ assert_int_equal(result, false);
+
+ return true;
+}
+
+int test_meshlink_add_external_address(void) {
+ const struct CMUnitTest blackbox_add_ex_addr_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_add_ex_address_01, NULL, NULL,
+ (void *)&test_mesh_add_ex_address_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_add_ex_address_02, NULL, NULL,
+ (void *)&test_mesh_add_ex_address_02_state)
+ };
+
+ total_tests += sizeof(blackbox_add_ex_addr_tests) / sizeof(blackbox_add_ex_addr_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_add_ex_addr_tests, NULL, NULL);
+}
+
--- /dev/null
+#ifndef TEST_CASES_ADD_EX_ADDR_H
+#define TEST_CASES_ADD_EX_ADDR_H
+
+/*
+ test_cases_add_ex_addr.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#include <stdbool.h>
+
+extern int test_meshlink_add_external_address(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_blacklist.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+#include "execute_tests.h"
+#include "test_cases_blacklist.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_blacklist_01(void **state);
+static bool test_steps_mesh_blacklist_01(void);
+static void test_case_mesh_blacklist_02(void **state);
+static bool test_steps_mesh_blacklist_02(void);
+static void test_case_mesh_blacklist_03(void **state);
+static bool test_steps_mesh_blacklist_03(void);
+
+/* State structure for meshlink_blacklist Test Case #1 */
+static black_box_state_t test_mesh_blacklist_01_state = {
+ .test_case_name = "test_case_mesh_blacklist_01",
+};
+
+/* State structure for meshlink_blacklist Test Case #2 */
+static black_box_state_t test_mesh_blacklist_02_state = {
+ .test_case_name = "test_case_mesh_blacklist_02",
+};
+
+/* State structure for meshlink_blacklist Test Case #3 */
+static black_box_state_t test_mesh_blacklist_03_state = {
+ .test_case_name = "test_case_mesh_blacklist_03",
+};
+
+/* Execute meshlink_blacklist Test Case # 1*/
+void test_case_mesh_blacklist_01(void **state) {
+ execute_test(test_steps_mesh_blacklist_01, state);
+}
+
+static bool received;
+
+static void receive(meshlink_handle_t *mesh, meshlink_node_t *src, const void *data, size_t len) {
+ const char *msg = data;
+ assert(len);
+
+ if(!strcmp(src->name, "bar") && len == 5 && !strcmp(msg, "test")) {
+ received = true;
+ }
+}
+
+static bool bar_reachable;
+
+static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
+ if(!strcmp(node->name, "bar") && reachable) {
+ bar_reachable = true;
+ }
+}
+
+
+/* Test Steps for meshlink_blacklist Test Case # 1
+
+ Test Steps:
+ 1. Open both the node instances
+ 2. Join bar node with foo and Send & Receive data
+ 3. Blacklist bar and Send & Receive data
+
+ Expected Result:
+ When default blacklist is disabled, foo node should receive data from bar
+ but when enabled foo node should not receive data
+*/
+bool test_steps_mesh_blacklist_01(void) {
+ meshlink_destroy("blacklist_conf.1");
+ meshlink_destroy("blacklist_conf.2");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh1 = meshlink_open("blacklist_conf.1", "foo", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("blacklist_conf.2", "bar", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_receive_cb(mesh1, receive);
+
+ // Start both instances
+ bar_reachable = false;
+ meshlink_set_node_status_cb(mesh1, status_cb);
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(1);
+
+ char *foo_export = meshlink_export(mesh1);
+ assert(foo_export != NULL);
+ assert(meshlink_import(mesh2, foo_export));
+ char *bar_export = meshlink_export(mesh2);
+ assert(meshlink_import(mesh1, bar_export));
+ sleep(5);
+ assert_int_equal(bar_reachable, true);
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar);
+ meshlink_node_t *foo = meshlink_get_node(mesh2, "foo");
+ assert(foo);
+
+ received = false;
+ assert(meshlink_send(mesh2, foo, "test", 5));
+ sleep(1);
+ assert(received);
+
+ meshlink_blacklist(mesh1, bar);
+
+ received = false;
+ assert(meshlink_send(mesh2, foo, "test", 5));
+ sleep(1);
+ assert_int_equal(received, false);
+
+ // Clean up.
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("blacklist_conf.1");
+ meshlink_destroy("blacklist_conf.2");
+ return true;
+}
+
+/* Execute meshlink_blacklist Test Case # 2*/
+void test_case_mesh_blacklist_02(void **state) {
+ execute_test(test_steps_mesh_blacklist_02, state);
+}
+
+
+/* Test Steps for meshlink_blacklist Test Case # 2
+
+ Test Steps:
+ 1. Calling meshlink_blacklist with NULL as mesh handle argument.
+
+ Expected Result:
+ meshlink_blacklist API handles the invalid parameter when called by giving proper error number.
+*/
+bool test_steps_mesh_blacklist_02(void) {
+ meshlink_destroy("blacklist_conf.3");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh = meshlink_open("blacklist_conf.3", "foo", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh != NULL);
+
+ meshlink_node_t *node = meshlink_get_self(mesh);
+ assert(node);
+
+ // Passing NULL as mesh handle and node handle being some valid node handle
+ meshlink_blacklist(NULL, node);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ // Clean up.
+ meshlink_close(mesh);
+ meshlink_destroy("blacklist_conf.3");
+ return true;
+}
+
+/* Execute meshlink_blacklist Test Case # 3*/
+void test_case_mesh_blacklist_03(void **state) {
+ execute_test(test_steps_mesh_blacklist_03, state);
+}
+
+/* Test Steps for meshlink_blacklist Test Case # 3
+
+ Test Steps:
+ 1. Create node instance
+ 2. Calling meshlink_blacklist with NULL as node handle argument.
+
+ Expected Result:
+ meshlink_blacklist API handles the invalid parameter when called by giving proper error number.
+*/
+bool test_steps_mesh_blacklist_03(void) {
+ meshlink_destroy("blacklist_conf.4");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh = meshlink_open("blacklist_conf.4", "foo", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh != NULL);
+
+ // Passing NULL as node handle and mesh handle being some valid mesh handle value
+ meshlink_blacklist(mesh, NULL);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ // Clean up.
+ meshlink_close(mesh);
+ meshlink_destroy("blacklist_conf.4");
+ return true;
+}
+
+int test_meshlink_blacklist(void) {
+ const struct CMUnitTest blackbox_blacklist_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_blacklist_01, NULL, NULL,
+ (void *)&test_mesh_blacklist_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_blacklist_02, NULL, NULL,
+ (void *)&test_mesh_blacklist_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_blacklist_03, NULL, NULL,
+ (void *)&test_mesh_blacklist_03_state)
+ };
+
+ total_tests += sizeof(blackbox_blacklist_tests) / sizeof(blackbox_blacklist_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_blacklist_tests, NULL, NULL);
+}
+
--- /dev/null
+#ifndef TEST_CASES_BLACKLIST_H
+#define TEST_CASES_BLACKLIST_H
+
+/*
+ test_cases_blacklist.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_blacklist(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_close.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_channel_close.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_channel_close_01(void **state);
+static bool test_steps_mesh_channel_close_01(void);
+static void test_case_mesh_channel_close_02(void **state);
+static bool test_steps_mesh_channel_close_02(void);
+
+/* State structure for meshlink_channel_close Test Case #1 */
+static black_box_state_t test_mesh_channel_close_01_state = {
+ .test_case_name = "test_case_mesh_channel_close_01",
+};
+
+/* State structure for meshlink_channel_close Test Case #2 */
+static black_box_state_t test_mesh_channel_close_02_state = {
+ .test_case_name = "test_case_mesh_channel_close_02",
+};
+
+/* Execute meshlink_channel_close Test Case # 1*/
+static void test_case_mesh_channel_close_01(void **state) {
+ execute_test(test_steps_mesh_channel_close_01, state);
+ return;
+}
+
+/* Test Steps for meshlink_channel_close Test Case # 1*/
+static bool test_steps_mesh_channel_close_01(void) {
+ bool result = false;
+ char *msg = NULL;
+ char buf[] = "bar";
+ msg = buf;
+ size_t len = sizeof(buf);
+ meshlink_destroy("chan_close_conf.3");
+ meshlink_destroy("chan_close_conf.4");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh1 = meshlink_open("chan_close_conf.3", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+
+ meshlink_handle_t *mesh2 = meshlink_open("chan_close_conf.4", "bar", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+
+ if(!mesh2) {
+ fprintf(stderr, "Could not initialize configuration for bar\n");
+ return false;
+ }
+
+ char *exp = meshlink_export(mesh1);
+ assert(exp != NULL);
+ assert(meshlink_import(mesh2, exp));
+ free(exp);
+ exp = meshlink_export(mesh2);
+ assert(exp != NULL);
+ assert(meshlink_import(mesh1, exp));
+ free(exp);
+
+ // Start both instances
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(2);
+
+ // Open a channel from foo to bar.
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar != NULL);
+ meshlink_channel_t *channel = meshlink_channel_open(mesh1, bar, 7, NULL, NULL, 0);
+ assert(channel != NULL);
+
+ meshlink_channel_close(NULL, channel);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+
+ // Clean up.
+
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("chan_close_conf.3");
+ meshlink_destroy("chan_close_conf.4");
+ return true;
+}
+
+/* Execute meshlink_channel_close Test Case # 2*/
+static void test_case_mesh_channel_close_02(void **state) {
+ execute_test(test_steps_mesh_channel_close_02, state);
+ return;
+}
+
+/* Test Steps for meshlink_channel_close Test Case # 2*/
+static bool test_steps_mesh_channel_close_02(void) {
+ meshlink_destroy("chan_close_conf.5");
+ // Open two new meshlink instance.
+
+ meshlink_handle_t *mesh = meshlink_open("chan_close_conf.5", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh != NULL);
+
+ // Start both instances
+ assert(meshlink_start(mesh));
+
+ // Pass NULL as mesh handle
+ meshlink_channel_close(mesh, NULL);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ // Clean up.
+
+ meshlink_close(mesh);
+ meshlink_destroy("chan_close_conf.5");
+ return true;
+}
+
+int test_meshlink_channel_close(void) {
+ const struct CMUnitTest blackbox_channel_close_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_close_01, NULL, NULL,
+ (void *)&test_mesh_channel_close_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_close_02, NULL, NULL,
+ (void *)&test_mesh_channel_close_02_state)
+ };
+
+ total_tests += sizeof(blackbox_channel_close_tests) / sizeof(blackbox_channel_close_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_channel_close_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNEL_CLOSE_H
+#define TEST_CASES_CHANNEL_CLOSE_H
+
+/*
+ test_cases_channel_close.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_channel_close(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+#ifndef TEST_CASES_CHANNEL_CONN_H
+#define TEST_CASES_CHANNEL_CONN_H
+
+/*
+ test_cases_channel_conn.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_case_channel_conn(void);
+
+#endif // TEST_CASES_CHANNEL_CONN_H
--- /dev/null
+/*
+ test_cases_channel_ex.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "test_cases_channel_ex.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <pthread.h>
+#include <cmocka.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+/* Modify this to change the port number */
+#define PORT 8000
+
+static void test_case_channel_ex_01(void **state);
+static bool test_steps_channel_ex_01(void);
+static void test_case_channel_ex_02(void **state);
+static bool test_steps_channel_ex_02(void);
+static void test_case_channel_ex_03(void **state);
+static bool test_steps_channel_ex_03(void);
+static void test_case_channel_ex_04(void **state);
+static bool test_steps_channel_ex_04(void);
+static void test_case_channel_ex_05(void **state);
+static bool test_steps_channel_ex_05(void);
+static void test_case_channel_ex_06(void **state);
+static bool test_steps_channel_ex_06(void);
+
+static void cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len);
+static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *dat, size_t len);
+
+/* channel_acc gives us access to test whether the accept callback has been invoked or not */
+static bool channel_acc;
+/* mutex for the common variable */
+pthread_mutex_t lock;
+
+static black_box_state_t test_case_channel_ex_01_state = {
+ .test_case_name = "test_case_channel_ex_01",
+};
+static black_box_state_t test_case_channel_ex_02_state = {
+ .test_case_name = "test_case_channel_ex_02",
+};
+static black_box_state_t test_case_channel_ex_03_state = {
+ .test_case_name = "test_case_channel_ex_03",
+};
+static black_box_state_t test_case_channel_ex_04_state = {
+ .test_case_name = "test_case_channel_ex_04",
+};
+static black_box_state_t test_case_channel_ex_05_state = {
+ .test_case_name = "test_case_channel_ex_05",
+};
+static black_box_state_t test_case_channel_ex_06_state = {
+ .test_case_name = "test_case_channel_ex_06",
+};
+static black_box_state_t test_case_channel_ex_07_state = {
+ .test_case_name = "test_case_channel_ex_07",
+};
+
+/* mutex for the common variable */
+static pthread_mutex_t accept_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
+
+static bool channel_acc;
+
+/* channel receive callback */
+static void cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len) {
+ (void)mesh;
+ (void)channel;
+ (void)dat;
+ (void)len;
+
+ return;
+}
+
+static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *dat, size_t len) {
+ (void)dat;
+ (void)len;
+ char *data = (char *) dat;
+ assert_int_equal(port, PORT);
+
+ pthread_mutex_lock(&accept_lock);
+ channel_acc = true;
+ assert(!pthread_cond_broadcast(&accept_cond));
+ pthread_mutex_unlock(&accept_lock);
+
+ return true;
+}
+
+/* Execute meshlink_channel_open_ex Test Case # 1 - testing meshlink_channel_open_ex API's
+ valid case by passing all valid arguments */
+static void test_case_channel_ex_01(void **state) {
+ execute_test(test_steps_channel_ex_01, state);
+}
+
+/* Test Steps for meshlink_channel_open_ex Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel to ourself
+
+ Expected Result:
+ Opens a channel and echoes the send queue data.
+*/
+/* TODO: When send queue & send queue length are passed with some value other
+ than NULL it throws segmentation fault*/
+static bool test_steps_channel_ex_01(void) {
+ /* Set up logging for Meshlink */
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
+
+ assert(meshlink_start(mesh_handle));
+
+ /* Getting node handle for itself */
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ char string[100] = "Test the 1st case";
+ pthread_mutex_lock(&lock);
+ channel_acc = false;
+ pthread_mutex_unlock(&lock);
+
+ /* Passing all valid arguments for meshlink_channel_open_ex */
+ meshlink_channel_t *channel = NULL;
+ channel = meshlink_channel_open_ex(mesh_handle, node, PORT, cb, string, strlen(string) + 1, MESHLINK_CHANNEL_UDP);
+ assert_int_not_equal(channel, NULL);
+
+ // Delay for establishing a channel
+ sleep(1);
+
+ pthread_mutex_lock(&lock);
+ bool ret = channel_acc;
+ pthread_mutex_unlock(&lock);
+
+ assert_int_equal(ret, true);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelexconf");
+
+ return true;
+}
+
+/* Execute meshlink_channel_open_ex Test Case # 2 - testing API's valid case by passing NULL and
+ 0 for send queue & it's length respectively and others with valid arguments */
+static void test_case_channel_ex_02(void **state) {
+ execute_test(test_steps_channel_ex_02, state);
+}
+/* Test Steps for meshlink_channel_open_ex Test Case # 2 - Valid case (TCP channel)
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel to ourself
+
+ Expected Result:
+ Opens a TCP channel successfully by setting channel_acc true*/
+static bool test_steps_channel_ex_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
+
+ assert(meshlink_start(mesh_handle));
+
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ pthread_mutex_lock(&lock);
+ channel_acc = false;
+ pthread_mutex_unlock(&lock);
+ sleep(1);
+
+ PRINT_TEST_CASE_MSG("Opening TCP alike channel ex\n");
+ /* Passing all valid arguments for meshlink_channel_open_ex */
+ meshlink_channel_t *channel;
+ channel = meshlink_channel_open_ex(mesh_handle, node, PORT, cb, NULL, 0, MESHLINK_CHANNEL_TCP);
+ assert_int_not_equal(channel, NULL);
+
+ // Delay for establishing a channel
+ sleep(1);
+ pthread_mutex_lock(&lock);
+ bool ret = channel_acc;
+ pthread_mutex_unlock(&lock);
+
+ assert_int_equal(ret, true);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelexconf");
+ return true;
+}
+
+/* Execute meshlink_channel_open_ex Test Case # 3 - Open a UDP channel */
+static void test_case_channel_ex_03(void **state) {
+ execute_test(test_steps_channel_ex_03, state);
+}
+/* Test Steps for meshlink_channel_open_ex Test Case # 3 - Valid case (UDP channel)
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel to ourself
+
+ Expected Result:
+ Opens a UDP channel successfully by setting channel_acc true */
+static bool test_steps_channel_ex_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
+
+ assert(meshlink_start(mesh_handle));
+
+ /* Getting node handle for itself */
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ pthread_mutex_lock(&lock);
+ channel_acc = false;
+ pthread_mutex_unlock(&lock);
+ sleep(1);
+
+ /* Passing all valid arguments for meshlink_channel_open_ex */
+ meshlink_channel_t *channel;
+ channel = meshlink_channel_open_ex(mesh_handle, node, PORT, cb, NULL, 0, MESHLINK_CHANNEL_UDP);
+ assert_int_not_equal(channel, NULL);
+
+ // Delay for establishing a channel
+ sleep(1);
+
+ pthread_mutex_lock(&lock);
+ bool ret = channel_acc;
+ pthread_mutex_unlock(&lock);
+
+ assert_int_equal(ret, true);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelexconf");
+ return true;
+}
+
+/* Execute meshlink_channel_open_ex Test Case # 4 - Open a TCP channel with no receive callback
+ and send queue */
+static void test_case_channel_ex_04(void **state) {
+ execute_test(test_steps_channel_ex_04, state);
+}
+/* Test Steps for meshlink_channel_open_ex Test Case # 4 - Valid Case (Disabling receive callback)
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel to ourself
+
+ Expected Result:
+ Opens a channel
+*/
+
+static bool test_steps_channel_ex_04(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
+
+ assert(meshlink_start(mesh_handle));
+
+ /* Getting node handle for itself */
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ pthread_mutex_lock(&lock);
+ channel_acc = false;
+ pthread_mutex_unlock(&lock);
+
+ /* Passing all valid arguments for meshlink_channel_open_ex i.e disabling receive callback and send queue */
+ meshlink_channel_t *channel;
+ channel = meshlink_channel_open_ex(mesh_handle, node, PORT, NULL, NULL, 0, MESHLINK_CHANNEL_UDP);
+ assert(channel != NULL);
+ // Delay for establishing a channel
+
+ pthread_mutex_lock(&lock);
+ bool ret = channel_acc;
+ pthread_mutex_unlock(&lock);
+
+ assert_int_equal(ret, true);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelexconf");
+ return true;
+}
+
+/* Execute meshlink_channel_open_ex Test Case # 5 - Opening channel using NULL as mesh handle argument
+ for the API */
+static void test_case_channel_ex_05(void **state) {
+ execute_test(test_steps_channel_ex_05, state);
+}
+/* Test Steps for meshlink_channel_open_ex Test Case # 5 - Invalid case (NULL as mesh argument)
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel by passing NULL as argument for mesh handle
+
+ Expected Result:
+ meshlink_channel_open_ex returns NULL as channel handle reporting error accordingly
+*/
+static bool test_steps_channel_ex_05(void) {
+ /* Set up logging for Meshlink */
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
+
+ assert(meshlink_start(mesh_handle));
+ /* Getting node handle for itself */
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ /* Trying to open channel using mesh handle as NULL argument */
+ meshlink_channel_t *channel = meshlink_channel_open_ex(NULL, node, PORT, cb, NULL, 0, MESHLINK_CHANNEL_TCP);
+ assert(channel == NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelexconf");
+ return true;
+}
+
+/* Execute meshlink_channel_open_ex Test Case # 6 - Opening channel using NULL as node handle argument
+ for the API*/
+static void test_case_channel_ex_06(void **state) {
+ execute_test(test_steps_channel_ex_06, state);
+}
+
+/* Test Steps for meshlink_channel_open_ex Test Case # 6 - Invalid case (NULL as node argument)
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel by passing NULL as argument for node handle
+
+ Expected Result:
+ meshlink_channel_open_ex returns NULL as channel handle reporting error accordingly
+*/
+static bool test_steps_channel_ex_06(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
+
+ assert(meshlink_start(mesh_handle));
+
+ /* Trying to open channel using node handle as NULL argument */
+ meshlink_channel_t *channel = meshlink_channel_open_ex(mesh_handle, NULL, PORT, cb, NULL, 0, MESHLINK_CHANNEL_TCP);
+
+ assert_int_equal(channel, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelexconf");
+ return true;
+}
+
+int test_meshlink_channel_open_ex(void) {
+ const struct CMUnitTest blackbox_channel_ex_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_01, NULL, NULL,
+ (void *)&test_case_channel_ex_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_02, NULL, NULL,
+ (void *)&test_case_channel_ex_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_03, NULL, NULL,
+ (void *)&test_case_channel_ex_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_04, NULL, NULL,
+ (void *)&test_case_channel_ex_04_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_05, NULL, NULL,
+ (void *)&test_case_channel_ex_05_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_06, NULL, NULL,
+ (void *)&test_case_channel_ex_06_state)
+ };
+
+ total_tests += sizeof(blackbox_channel_ex_tests) / sizeof(blackbox_channel_ex_tests[0]);
+
+ assert(pthread_mutex_init(&lock, NULL) == 0);
+ int failed = cmocka_run_group_tests(blackbox_channel_ex_tests, NULL, NULL);
+ assert(pthread_mutex_destroy(&lock) == 0);
+
+ return failed;
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNELS_EX_H
+#define TEST_CASES_CHANNELS_EX_H
+
+/*
+ test_cases_channel_ex.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_channel_open_ex(void);
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_get_flags.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_channel_get_flags.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+/* Modify this to change the port number */
+#define PORT 8000
+
+static void test_case_channel_get_flags_01(void **state);
+static bool test_steps_channel_get_flags_01(void);
+static void test_case_channel_get_flags_02(void **state);
+static bool test_steps_channel_get_flags_02(void);
+static void test_case_channel_get_flags_03(void **state);
+static bool test_steps_channel_get_flags_03(void);
+
+static black_box_state_t test_case_channel_get_flags_01_state = {
+ .test_case_name = "test_case_channel_get_flags_01",
+};
+static black_box_state_t test_case_channel_get_flags_02_state = {
+ .test_case_name = "test_case_channel_get_flags_02",
+};
+static black_box_state_t test_case_channel_get_flags_03_state = {
+ .test_case_name = "test_case_channel_get_flags_03",
+};
+static black_box_state_t test_case_channel_get_flags_04_state = {
+ .test_case_name = "test_case_channel_get_flags_04",
+};
+
+
+/* Execute meshlink_channel_get_flags Test Case # 1 - Valid case*/
+static void test_case_channel_get_flags_01(void **state) {
+ execute_test(test_steps_channel_get_flags_01, state);
+}
+/* Test Steps for meshlink_channel_get_flags Test Case # 1
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel to ourself (with TCP semantic here)
+ 3. Get flag(s) of that channel
+
+ Expected Result:
+ API returning exact flag that has been assigned while opening (here TCP)
+*/
+static bool test_steps_channel_get_flags_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("getflagsconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, NULL);
+
+ assert(meshlink_start(mesh_handle));
+
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+ sleep(1);
+
+ /* Passing all valid arguments for meshlink_channel_open_ex */
+ meshlink_channel_t *channel;
+ channel = meshlink_channel_open_ex(mesh_handle, node, PORT, NULL, NULL, 0, MESHLINK_CHANNEL_TCP);
+ assert(channel != NULL);
+
+ // Obtaining channel flags using meshlink_channel_get_flags
+ uint32_t flags = meshlink_channel_get_flags(mesh_handle, channel);
+ assert_int_equal(flags, MESHLINK_CHANNEL_TCP);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getflagsconf");
+
+ return true;
+}
+
+/* Execute meshlink_channel_get_flags Test Case # 2 - Invalid case*/
+static void test_case_channel_get_flags_02(void **state) {
+ execute_test(test_steps_channel_get_flags_02, state);
+}
+/* Test Steps for meshlink_channel_get_flags Test Case # 2
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Open channel to ourself (with TCP semantic here)
+ 3. Call meshlink_channel_get_flags by passing NULL as mesh handle argument
+
+ Expected Result:
+ API reporting error accordingly.
+*/
+static bool test_steps_channel_get_flags_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("getflagsconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, NULL);
+
+ assert(meshlink_start(mesh_handle));
+
+ /* Getting node handle for itself */
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+ sleep(1);
+
+ /* Passing all valid arguments for meshlink_channel_open_ex */
+ meshlink_channel_t *channel;
+ channel = meshlink_channel_open_ex(mesh_handle, node, PORT, NULL, NULL, 0, MESHLINK_CHANNEL_TCP);
+ assert(channel != NULL);
+
+ // passing NULL as mesh handle argument for meshlink_channel_get_flags
+ uint32_t flags = meshlink_channel_get_flags(NULL, channel);
+
+ assert_int_equal((int32_t)flags, -1);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getflagsconf");
+ return true;
+}
+
+/* Execute meshlink_channel_get flags Test Case # 3 - Invalid case*/
+static void test_case_channel_get_flags_03(void **state) {
+ execute_test(test_steps_channel_get_flags_03, state);
+}
+/* Test Steps for meshlink_channel_get_flags Test Case # 3
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 3. Call meshlink_channel_get_flags by passing NULL as channel handle argument
+
+ Expected Result:
+ API reporting error accordingly.
+*/
+static bool test_steps_channel_get_flags_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("getflagsconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
+ meshlink_set_channel_accept_cb(mesh_handle, NULL);
+
+ assert(meshlink_start(mesh_handle));
+
+ // passing NULL as channel handle argument for meshlink_channel_get_flags
+ uint32_t flags = meshlink_channel_get_flags(mesh_handle, NULL);
+
+ assert_int_equal((int32_t)flags, -1);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getflagsconf");
+ return true;
+}
+
+
+int test_meshlink_channel_get_flags(void) {
+ const struct CMUnitTest blackbox_channel_get_flags_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_get_flags_01, NULL, NULL,
+ (void *)&test_case_channel_get_flags_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_get_flags_02, NULL, NULL,
+ (void *)&test_case_channel_get_flags_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_get_flags_03, NULL, NULL,
+ (void *)&test_case_channel_get_flags_03_state)
+ };
+
+ total_tests += sizeof(blackbox_channel_get_flags_tests) / sizeof(blackbox_channel_get_flags_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_channel_get_flags_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNELS_SET_ACCEPT_H
+#define TEST_CASES_CHANNELS_SET_ACCEPT_H
+
+/*
+ test_cases_get_self.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_channel_get_flags(void);
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_open.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_channel_open.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_channel_open_01(void **state);
+static bool test_steps_mesh_channel_open_01(void);
+static void test_case_mesh_channel_open_02(void **state);
+static bool test_steps_mesh_channel_open_02(void);
+static void test_case_mesh_channel_open_03(void **state);
+static bool test_steps_mesh_channel_open_03(void);
+static void test_case_mesh_channel_open_04(void **state);
+static bool test_steps_mesh_channel_open_04(void);
+
+/* State structure for meshlink_channel_open Test Case #1 */
+static black_box_state_t test_mesh_channel_open_01_state = {
+ .test_case_name = "test_case_mesh_channel_open_01",
+};
+
+/* State structure for meshlink_channel_open Test Case #2 */
+static black_box_state_t test_mesh_channel_open_02_state = {
+ .test_case_name = "test_case_mesh_channel_open_02",
+};
+
+/* State structure for meshlink_channel_open Test Case #3 */
+static black_box_state_t test_mesh_channel_open_03_state = {
+ .test_case_name = "test_case_mesh_channel_open_03",
+};
+
+/* State structure for meshlink_channel_open Test Case #4 */
+static black_box_state_t test_mesh_channel_open_04_state = {
+ .test_case_name = "test_case_mesh_channel_open_04",
+};
+
+/* Execute meshlink_channel_open Test Case # 1*/
+static void test_case_mesh_channel_open_01(void **state) {
+ execute_test(test_steps_mesh_channel_open_01, state);
+}
+
+static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
+ (void)mesh;
+ (void)channel;
+}
+
+/* Test Steps for meshlink_channel_open Test Case # 1
+
+ Test Steps:
+ 1. Open both the node instances
+ 2. Join bar node with foo
+ 3. Open channel between the nodes
+
+ Expected Result:
+ meshlink_channel_open should open a channel by returning a channel handler
+*/
+static bool test_steps_mesh_channel_open_01(void) {
+ meshlink_destroy("channels_conf.1");
+ meshlink_destroy("channels_conf.2");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh1 = meshlink_open("channels_conf.1", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+ meshlink_handle_t *mesh2 = meshlink_open("channels_conf.2", "bar", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+
+ // Import and export both side's data
+ char *exp = meshlink_export(mesh1);
+ assert(exp != NULL);
+ assert(meshlink_import(mesh2, exp));
+ free(exp);
+ exp = meshlink_export(mesh2);
+ assert(exp != NULL);
+ assert(meshlink_import(mesh1, exp));
+ free(exp);
+
+ // Start both instances
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(2);
+
+ // Open a channel from foo to bar.
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar != NULL);
+ meshlink_channel_t *channel = meshlink_channel_open(mesh1, bar, 7000, receive_cb, NULL, 0);
+ assert_int_not_equal(channel, NULL);
+
+ // Clean up.
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("channels_conf.1");
+ meshlink_destroy("channels_conf.2");
+ return true;
+}
+
+/* Execute meshlink_channel_open Test Case # 2
+
+ Test Steps:
+ 1. Open both the node instances
+ 2. Join bar node with foo
+ 3. Open channel between the nodes with NULL as receive callback argument
+
+ Expected Result:
+ meshlink_channel_open should open a channel by returning a channel handler
+*/
+static void test_case_mesh_channel_open_02(void **state) {
+ execute_test(test_steps_mesh_channel_open_02, state);
+}
+
+/* Test Steps for meshlink_channel_open Test Case # 2*/
+static bool test_steps_mesh_channel_open_02(void) {
+ meshlink_destroy("channels_conf.3");
+ meshlink_destroy("channels_conf.4");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh1 = meshlink_open("channels_conf.3", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+ meshlink_handle_t *mesh2 = meshlink_open("channels_conf.4", "bar", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+
+ char *exp = meshlink_export(mesh1);
+ assert(exp != NULL);
+ assert(meshlink_import(mesh2, exp));
+ free(exp);
+ exp = meshlink_export(mesh2);
+ assert(exp != NULL);
+ assert(meshlink_import(mesh1, exp));
+ free(exp);
+
+ // Start both instances
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(1);
+
+ // Open a channel from foo to bar.
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar != NULL);
+
+ meshlink_channel_t *channel = meshlink_channel_open(mesh1, bar, 7000, NULL, NULL, 0);
+ assert_int_not_equal(channel, NULL);
+
+ // Clean up.
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("channels_conf.3");
+ meshlink_destroy("channels_conf.4");
+ return true;
+}
+
+/* Execute meshlink_channel_open Test Case # 3 */
+static void test_case_mesh_channel_open_03(void **state) {
+ execute_test(test_steps_mesh_channel_open_03, state);
+}
+
+/* Test Steps for meshlink_channel_open Test Case # 3
+
+ Test Steps:
+ 1. Create the node instance & obtain node handle
+ 2. Open a channel with NULL as mesh handle argument
+ and rest other arguments being valid.
+
+ Expected Result:
+ meshlink_channel_open API handles the invalid parameter
+ when called by giving proper error number.
+*/
+static bool test_steps_mesh_channel_open_03(void) {
+ meshlink_destroy("channels_conf.5");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh = meshlink_open("channels_conf.5", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh != NULL);
+
+ meshlink_node_t *node = meshlink_get_self(mesh);
+ assert(node);
+
+ meshlink_channel_t *channel = meshlink_channel_open(NULL, node, 7000, NULL, NULL, 0);
+ assert_int_equal(channel, NULL);
+
+ // Clean up.
+ meshlink_close(mesh);
+ meshlink_destroy("channels_conf.5");
+ return true;
+}
+
+/* Execute meshlink_channel_open Test Case # 4*/
+static void test_case_mesh_channel_open_04(void **state) {
+ execute_test(test_steps_mesh_channel_open_04, state);
+}
+
+/* Test Steps for meshlink_channel_open Test Case # 4
+
+ Test Steps:
+ 1. Create the node instance & obtain node handle
+ 2. Open a channel with NULL as node handle argument
+ and rest other arguments being valid.
+
+ Expected Result:
+ meshlink_channel_open API handles the invalid parameter
+ when called by giving proper error number.
+*/
+static bool test_steps_mesh_channel_open_04(void) {
+ meshlink_destroy("channels_conf.7");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh = meshlink_open("channels_conf.7", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh != NULL);
+
+ // Start both instances
+ assert(meshlink_start(mesh));
+
+ meshlink_channel_t *channel = meshlink_channel_open(mesh, NULL, 7000, NULL, NULL, 0);
+ assert_int_equal(channel, NULL);
+
+ // Clean up.
+ meshlink_close(mesh);
+ meshlink_destroy("channels_conf.7");
+ return true;
+}
+
+int test_meshlink_channel_open(void) {
+ const struct CMUnitTest blackbox_channel_open_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_open_01, NULL, NULL,
+ (void *)&test_mesh_channel_open_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_open_02, NULL, NULL,
+ (void *)&test_mesh_channel_open_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_open_03, NULL, NULL,
+ (void *)&test_mesh_channel_open_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_open_04, NULL, NULL,
+ (void *)&test_mesh_channel_open_04_state)
+ };
+
+ total_tests += sizeof(blackbox_channel_open_tests) / sizeof(blackbox_channel_open_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_channel_open_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNEL_OPEN_H
+#define TEST_CASES_CHANNEL_OPEN_H
+
+/*
+ test_cases_channel_open.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_channel_open(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_send.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_channel_send.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+#include <pthread.h>
+
+static void test_case_mesh_channel_send_01(void **state);
+static bool test_steps_mesh_channel_send_01(void);
+static void test_case_mesh_channel_send_02(void **state);
+static bool test_steps_mesh_channel_send_02(void);
+static void test_case_mesh_channel_send_03(void **state);
+static bool test_steps_mesh_channel_send_03(void);
+static void test_case_mesh_channel_send_04(void **state);
+static bool test_steps_mesh_channel_send_04(void);
+
+static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len);
+static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable);
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len);
+
+/* State structure for meshlink_channel_send Test Case #1 */
+static black_box_state_t test_mesh_channel_send_01_state = {
+ .test_case_name = "test_case_mesh_channel_send_01",
+};
+
+/* State structure for meshlink_channel_send Test Case #2 */
+static black_box_state_t test_mesh_channel_send_02_state = {
+ .test_case_name = "test_case_mesh_channel_send_02",
+};
+
+/* State structure for meshlink_channel_send Test Case #3 */
+static black_box_state_t test_mesh_channel_send_03_state = {
+ .test_case_name = "test_case_mesh_channel_send_03",
+};
+
+/* State structure for meshlink_channel_send Test Case #4 */
+static black_box_state_t test_mesh_channel_send_04_state = {
+ .test_case_name = "test_case_mesh_channel_send_04",
+};
+
+/* Execute meshlink_channel_send Test Case # 1*/
+static void test_case_mesh_channel_send_01(void **state) {
+ execute_test(test_steps_mesh_channel_send_01, state);
+}
+
+static pthread_mutex_t poll_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t bar_reach_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t bar_responded_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t poll_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t status_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t send_cond = PTHREAD_COND_INITIALIZER;
+
+static bool polled;
+static bool bar_reachable;
+static bool bar_responded;
+
+static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
+ (void)mesh;
+
+ if(!strcmp(node->name, "bar")) {
+ pthread_mutex_lock(& bar_reach_lock);
+ bar_reachable = reachable;
+ assert(!pthread_cond_broadcast(&status_cond));
+ pthread_mutex_unlock(& bar_reach_lock);
+ }
+}
+
+static bool reject_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+ (void)mesh;
+ (void)channel;
+ (void)port;
+ (void)data;
+ (void)len;
+ return false;
+}
+
+static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+ assert(port == 7);
+ assert(!len);
+
+ meshlink_set_channel_receive_cb(mesh, channel, receive_cb);
+
+ return true;
+}
+
+/* channel receive callback */
+static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len) {
+ if(len == 5 && !memcmp(dat, "Hello", 5)) {
+ pthread_mutex_lock(& bar_responded_lock);
+ bar_responded = true;
+ assert(!pthread_cond_broadcast(&send_cond));
+ pthread_mutex_unlock(& bar_responded_lock);
+ }
+}
+
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
+ (void)len;
+
+ meshlink_set_channel_poll_cb(mesh, channel, NULL);
+ pthread_mutex_lock(&poll_lock);
+ polled = true;
+ assert(!pthread_cond_broadcast(&poll_cond));
+ pthread_mutex_unlock(&poll_lock);
+}
+
+
+/* Test Steps for meshlink_channel_send Test Case # 1*/
+static bool test_steps_mesh_channel_send_01(void) {
+ struct timespec timeout = {0};
+ meshlink_destroy("chan_send_conf.1");
+ meshlink_destroy("chan_send_conf.2");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh1 = meshlink_open("chan_send_conf.1", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+ meshlink_handle_t *mesh2 = meshlink_open("chan_send_conf.2", "bar", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh1, MESHLINK_DEBUG, meshlink_callback_logger);
+ meshlink_set_log_cb(mesh2, MESHLINK_DEBUG, meshlink_callback_logger);
+
+ char *data = meshlink_export(mesh1);
+ assert(data);
+ assert(meshlink_import(mesh2, data));
+ free(data);
+ data = meshlink_export(mesh2);
+ assert(data);
+ assert(meshlink_import(mesh1, data));
+ free(data);
+
+ // Set the callbacks.
+
+ meshlink_set_channel_accept_cb(mesh1, reject_cb);
+ meshlink_set_channel_accept_cb(mesh2, accept_cb);
+
+ meshlink_set_node_status_cb(mesh1, status_cb);
+
+ // Start both instances
+ bar_reachable = false;
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&bar_reach_lock);
+
+ while(bar_reachable == false) {
+ assert(!pthread_cond_timedwait(&status_cond, &bar_reach_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&bar_reach_lock);
+
+ // Open a channel from foo to bar.
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar);
+
+ bar_responded = false;
+ meshlink_channel_t *channel = meshlink_channel_open(mesh1, bar, 7, NULL, NULL, 0);
+ meshlink_set_channel_poll_cb(mesh1, channel, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ assert(meshlink_channel_send(mesh1, channel, "Hello", 5) >= 0);
+
+ timeout.tv_sec = time(NULL) + 20;
+ pthread_mutex_lock(&bar_responded_lock);
+
+ if(bar_responded == false) {
+ assert(!pthread_cond_timedwait(&send_cond, &bar_responded_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&bar_responded_lock);
+
+ // Clean up.
+
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("chan_send_conf.1");
+ meshlink_destroy("chan_send_conf.2");
+
+ return true;
+}
+
+/* Execute meshlink_channel_send Test Case # 2*/
+static void test_case_mesh_channel_send_02(void **state) {
+ execute_test(test_steps_mesh_channel_send_02, state);
+}
+
+/* Test Steps for meshlink_channel_send Test Case # 2*/
+static bool test_steps_mesh_channel_send_02(void) {
+ struct timespec timeout = {0};
+ meshlink_destroy("chan_send_conf.5");
+
+ // Open new meshlink instance.
+
+ meshlink_handle_t *mesh1 = meshlink_open("chan_send_conf.5", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+
+ meshlink_set_channel_accept_cb(mesh1, accept_cb);
+
+ // Start node instance
+
+ assert(meshlink_start(mesh1));
+
+ meshlink_node_t *node = meshlink_get_self(mesh1);
+ assert(node);
+
+ meshlink_channel_t *channel = meshlink_channel_open(mesh1, node, 7, receive_cb, NULL, 0);
+ meshlink_set_channel_poll_cb(mesh1, channel, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ ssize_t send_return = meshlink_channel_send(NULL, channel, "Hello", 5);
+
+ assert_int_equal(send_return, -1);
+
+ // Clean up.
+
+ meshlink_close(mesh1);
+ meshlink_destroy("chan_send_conf.5");
+
+ return true;
+}
+
+/* Execute meshlink_channel_send Test Case # 3*/
+static void test_case_mesh_channel_send_03(void **state) {
+ execute_test(test_steps_mesh_channel_send_03, state);
+}
+
+/* Test Steps for meshlink_channel_send Test Case # 3*/
+static bool test_steps_mesh_channel_send_03(void) {
+ struct timespec timeout = {0};
+ meshlink_destroy("chan_send_conf.7");
+ // Open new meshlink instance.
+
+ meshlink_handle_t *mesh1 = meshlink_open("chan_send_conf.7", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+ meshlink_set_channel_accept_cb(mesh1, accept_cb);
+
+ // Start node instance
+
+ assert(meshlink_start(mesh1));
+
+ ssize_t send_return = meshlink_channel_send(mesh1, NULL, "Hello", 5);
+
+ assert_int_equal(send_return, -1);
+
+ // Clean up.
+
+ meshlink_close(mesh1);
+ meshlink_destroy("chan_send_conf.7");
+
+ return true;
+}
+
+/* Execute meshlink_channel_send Test Case # 4*/
+static void test_case_mesh_channel_send_04(void **state) {
+ execute_test(test_steps_mesh_channel_send_04, state);
+}
+
+/* Test Steps for meshlink_channel_send Test Case # 4*/
+static bool test_steps_mesh_channel_send_04(void) {
+ struct timespec timeout = {0};
+ meshlink_destroy("chan_send_conf.9");
+ // Open two new meshlink instance.
+
+ meshlink_handle_t *mesh1 = meshlink_open("chan_send_conf.9", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+
+ meshlink_set_channel_accept_cb(mesh1, accept_cb);
+
+ // Start node instance
+
+ assert(meshlink_start(mesh1));
+
+ meshlink_node_t *node = meshlink_get_self(mesh1);
+ assert(node);
+
+ meshlink_channel_t *channel = meshlink_channel_open(mesh1, node, 7, receive_cb, NULL, 0);
+ meshlink_set_channel_poll_cb(mesh1, channel, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ ssize_t send_return = meshlink_channel_send(mesh1, channel, NULL, 5);
+
+ assert_int_equal(send_return, -1);
+
+ // Clean up.
+
+ meshlink_close(mesh1);
+ meshlink_destroy("chan_send_conf.9");
+
+ return true;
+}
+
+int test_meshlink_channel_send(void) {
+ const struct CMUnitTest blackbox_channel_send_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_send_01, NULL, NULL,
+ (void *)&test_mesh_channel_send_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_send_02, NULL, NULL,
+ (void *)&test_mesh_channel_send_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_send_03, NULL, NULL,
+ (void *)&test_mesh_channel_send_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_send_04, NULL, NULL,
+ (void *)&test_mesh_channel_send_04_state)
+ };
+
+ total_tests += sizeof(blackbox_channel_send_tests) / sizeof(blackbox_channel_send_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_channel_send_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNEL_SEND_H
+#define TEST_CASES_CHANNEL_SEND_H
+
+/*
+ test_cases_channel_send.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_channel_send(void);
+extern int total_tests;
+
+
+
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_set_accept_cb.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "test_cases_channel_set_accept_cb.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+/* Modify this to change the port number */
+#define PORT 8000
+
+static void test_case_set_channel_accept_cb_01(void **state);
+static bool test_steps_set_channel_accept_cb_01(void);
+static void test_case_set_channel_accept_cb_02(void **state);
+static bool test_steps_set_channel_accept_cb_02(void);
+
+static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len);
+static bool channel_reject(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len);
+
+static bool channel_acc;
+static bool channel_rej;
+static bool polled;
+static bool rejected;
+
+/* mutex for the common variable */
+static pthread_mutex_t accept_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t reject_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t poll_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t lock_receive = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t reject_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t poll_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t receive_cond = PTHREAD_COND_INITIALIZER;
+
+static black_box_state_t test_case_channel_set_accept_cb_01_state = {
+ .test_case_name = "test_case_channel_set_accept_cb_01",
+};
+static black_box_state_t test_case_channel_set_accept_cb_02_state = {
+ .test_case_name = "test_case_channel_set_accept_cb_02",
+};
+
+/* channel receive callback */
+static void channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len) {
+ if(!len) {
+ if(!meshlink_errno) {
+ pthread_mutex_lock(& lock_receive);
+ rejected = true;
+ assert(!pthread_cond_broadcast(&receive_cond));
+ pthread_mutex_unlock(& lock_receive);
+ }
+ }
+}
+
+/* channel reject callback */
+static bool channel_reject(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+ (void)mesh;
+ (void)channel;
+ (void)port;
+ (void)data;
+ (void)len;
+ return false;
+}
+
+static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *dat, size_t len) {
+ (void)dat;
+ (void)len;
+ char *data = (char *) dat;
+ assert_int_equal(port, PORT);
+
+ pthread_mutex_lock(&accept_lock);
+ channel_acc = true;
+ assert(!pthread_cond_broadcast(&accept_cond));
+ pthread_mutex_unlock(&accept_lock);
+
+ return true;
+}
+
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
+ (void)len;
+ meshlink_set_channel_poll_cb(mesh, channel, NULL);
+ pthread_mutex_lock(&poll_lock);
+ polled = true;
+ assert(!pthread_cond_broadcast(&poll_cond));
+ pthread_mutex_unlock(&poll_lock);
+}
+
+/* Execute meshlink_channel_set_accept_cb Test Case # 1 - Valid case*/
+static void test_case_set_channel_accept_cb_01(void **state) {
+ execute_test(test_steps_set_channel_accept_cb_01, state);
+}
+/* Test Steps for meshlink_channel_set_accept_cb Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Set channel_accept callback for NUT's meshlink_set_channel_accept_cb API.
+ 3. Export and Import nodes.
+ 4. Open a channel with NUT from bar to invoke channel accept callback
+ 5. Open a channel with bar from NUT to invoke channel accept callback
+
+ Expected Result:
+ Opens a channel by invoking accept callback, when accept callback rejects the channel
+ it should invoke the other node's receive callback with length = 0 and no error.
+*/
+static bool test_steps_set_channel_accept_cb_01(void) {
+ /* deleting the confbase if already exists */
+ struct timespec timeout = {0};
+ meshlink_destroy("acceptconf1");
+ meshlink_destroy("acceptconf2");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instances */
+ meshlink_handle_t *mesh1 = meshlink_open("acceptconf1", "nut", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_handle_t *mesh2 = meshlink_open("acceptconf2", "bar", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh1, MESHLINK_INFO, meshlink_callback_logger);
+ meshlink_set_log_cb(mesh2, MESHLINK_INFO, meshlink_callback_logger);
+
+ meshlink_set_channel_accept_cb(mesh2, channel_reject);
+ meshlink_set_channel_accept_cb(mesh1, channel_accept);
+
+ /* Export and Import on both sides */
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ assert(meshlink_import(mesh1, exp2));
+ assert(meshlink_import(mesh2, exp1));
+
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(1);
+
+ meshlink_node_t *destination = meshlink_get_node(mesh2, "nut");
+ assert(destination != NULL);
+
+ /* Open channel for nut node from bar node which should be accepted */
+ polled = false;
+ channel_acc = false;
+ meshlink_channel_t *channel2 = meshlink_channel_open(mesh2, destination, PORT, NULL, NULL, 0);
+ assert(channel2);
+ meshlink_set_channel_poll_cb(mesh2, channel2, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&accept_lock);
+
+ while(channel_acc == false) {
+ assert(!pthread_cond_timedwait(&accept_cond, &accept_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&accept_lock);
+
+ /* Open channel for bar node from nut node which should be rejected */
+ polled = false;
+ rejected = false;
+ channel_acc = false;
+ destination = meshlink_get_node(mesh1, "bar");
+ assert(destination != NULL);
+
+ meshlink_channel_t *channel1 = meshlink_channel_open(mesh1, destination, PORT, channel_receive_cb, NULL, 0);
+ assert(channel1);
+ meshlink_set_channel_poll_cb(mesh1, channel1, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&lock_receive);
+
+ while(rejected == false) {
+ assert(!pthread_cond_timedwait(&receive_cond, &lock_receive, &timeout));
+ }
+
+ pthread_mutex_unlock(&lock_receive);
+
+ /* closing channel, meshes and destroying confbase */
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("acceptconf1");
+ meshlink_destroy("acceptconf2");
+
+ return true;
+}
+
+/* Execute meshlink_channel_set_accept_cb Test Case # 2 - Invalid case*/
+static void test_case_set_channel_accept_cb_02(void **state) {
+ execute_test(test_steps_set_channel_accept_cb_02, state);
+}
+/* Test Steps for meshlink_channel_set_accept_cb Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Passing NULL as mesh handle argument for channel accept callback.
+
+ Expected Result:
+ meshlink_channel_set_accept_cb returning proper meshlink_errno.
+*/
+static bool test_steps_set_channel_accept_cb_02(void) {
+ /* setting channel accept cb with NULL as mesh handle and valid callback */
+ meshlink_set_channel_accept_cb(NULL, channel_accept);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ return true;
+}
+
+
+int test_meshlink_set_channel_accept_cb(void) {
+ const struct CMUnitTest blackbox_channel_set_accept_cb_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_channel_accept_cb_01, NULL, NULL,
+ (void *)&test_case_channel_set_accept_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_channel_accept_cb_02, NULL, NULL,
+ (void *)&test_case_channel_set_accept_cb_02_state)
+ };
+
+ total_tests += sizeof(blackbox_channel_set_accept_cb_tests) / sizeof(blackbox_channel_set_accept_cb_tests[0]);
+
+ int failed = cmocka_run_group_tests(blackbox_channel_set_accept_cb_tests, NULL, NULL);
+
+ return failed;
+}
+
+
+
--- /dev/null
+#ifndef TEST_CASES_CHANNELS_SET_ACCEPT_CB_H
+#define TEST_CASES_CHANNELS_SET_ACCEPT_CB_H
+
+/*
+ test_cases_channel_set_accept_cb.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_set_channel_accept_cb(void);
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_set_poll_cb.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "test_cases_channel_set_poll_cb.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+/* Modify this to change the port number */
+#define PORT 8000
+
+static void test_case_channel_set_poll_cb_01(void **state);
+static bool test_steps_channel_set_poll_cb_01(void);
+static void test_case_channel_set_poll_cb_02(void **state);
+static bool test_steps_channel_set_poll_cb_02(void);
+static void test_case_channel_set_poll_cb_03(void **state);
+static bool test_steps_channel_set_poll_cb_03(void);
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len);
+
+static black_box_state_t test_case_channel_set_poll_cb_01_state = {
+ .test_case_name = "test_case_channel_set_poll_cb_01",
+};
+static black_box_state_t test_case_channel_set_poll_cb_02_state = {
+ .test_case_name = "test_case_channel_set_poll_cb_02",
+};
+static black_box_state_t test_case_channel_set_poll_cb_03_state = {
+ .test_case_name = "test_case_channel_set_poll_cb_03",
+};
+
+static bool polled;
+static bool reachable;
+
+static pthread_mutex_t poll_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t poll_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t reachable_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t reachable_cond = PTHREAD_COND_INITIALIZER;
+
+/* channel accept callback */
+static bool channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+ (void)mesh;
+ (void)channel;
+ (void)port;
+ (void)data;
+ (void)len;
+ return false;
+}
+
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
+ (void)len;
+ meshlink_set_channel_poll_cb(mesh, channel, NULL);
+ pthread_mutex_lock(&poll_lock);
+ polled = true;
+ assert(!pthread_cond_broadcast(&poll_cond));
+ pthread_mutex_unlock(&poll_lock);
+}
+
+static void node_status_cb(meshlink_handle_t *mesh, meshlink_node_t *source, bool reach) {
+ pthread_mutex_lock(&reachable_lock);
+ reachable = true;
+ assert(!pthread_cond_broadcast(&reachable_cond));
+ pthread_mutex_unlock(&reachable_lock);
+}
+
+/* Execute meshlink_channel_set_poll_cb Test Case # 1 */
+static void test_case_channel_set_poll_cb_01(void **state) {
+ execute_test(test_steps_channel_set_poll_cb_01, state);
+}
+/* Test Steps for meshlink_channel_set_poll_cb Test Case # 1
+
+ Test Steps:
+ 1. Run NUT
+ 2. Open channel of the NUT itself
+
+ Expected Result:
+ Opens a channel and also invokes poll callback.
+*/
+static bool test_steps_channel_set_poll_cb_01(void) {
+ /* deleting the confbase if already exists */
+ struct timespec timeout = {0};
+ meshlink_destroy("pollconf1");
+ meshlink_destroy("pollconf2");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instances */
+ meshlink_handle_t *mesh1 = meshlink_open("pollconf1", "nut", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_handle_t *mesh2 = meshlink_open("pollconf2", "bar", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh1, MESHLINK_INFO, meshlink_callback_logger);
+ meshlink_set_log_cb(mesh2, MESHLINK_INFO, meshlink_callback_logger);
+ meshlink_set_node_status_cb(mesh1, node_status_cb);
+ meshlink_set_channel_accept_cb(mesh1, channel_accept_cb);
+
+ /* Export and Import on both sides */
+ reachable = false;
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ assert(meshlink_import(mesh1, exp2));
+ assert(meshlink_import(mesh2, exp1));
+
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&reachable_lock);
+
+ while(reachable == false) {
+ assert(!pthread_cond_timedwait(&reachable_cond, &reachable_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&reachable_lock);
+
+ meshlink_node_t *destination = meshlink_get_node(mesh2, "nut");
+ assert(destination != NULL);
+
+ /* Open channel for nut node from bar node which should be accepted */
+ polled = false;
+ meshlink_channel_t *channel = meshlink_channel_open(mesh2, destination, PORT, NULL, NULL, 0);
+ assert(channel);
+ meshlink_set_channel_poll_cb(mesh2, channel, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ /* closing channel, meshes and destroying confbase */
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("pollconf1");
+ meshlink_destroy("pollconf2");
+
+ return true;
+}
+
+/* Execute meshlink_channel_set_poll_cb Test Case # 2 */
+static void test_case_channel_set_poll_cb_02(void **state) {
+ execute_test(test_steps_channel_set_poll_cb_02, state);
+}
+/* Test Steps for meshlink_channel_set_poll_cb Test Case # 2
+
+ Test Steps:
+ 1. Run NUT
+ 2. Open channel of the NUT itself
+ 3. Pass NULL as mesh handle argument for meshlink_set_channel_poll_cb API
+
+ Expected Result:
+ Reports error accordingly by returning NULL
+*/
+static bool test_steps_channel_set_poll_cb_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelpollconf3", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ assert(meshlink_start(mesh_handle));
+
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ /* Opening channel */
+ meshlink_channel_t *channel = meshlink_channel_open(mesh_handle, node, PORT, NULL, NULL, 0);
+ assert(channel != NULL);
+
+ /* Setting poll cb with NULL as mesh handler */
+ meshlink_set_channel_poll_cb(NULL, channel, poll_cb);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelpollconf3");
+ return true;
+}
+
+/* Execute meshlink_channel_set_poll_cb Test Case # 3 */
+static void test_case_channel_set_poll_cb_03(void **state) {
+ execute_test(test_steps_channel_set_poll_cb_03, state);
+}
+/* Test Steps for meshlink_channel_set_poll_cb Test Case # 3
+
+ Test Steps:
+ 1. Run NUT
+ 2. Open channel of the NUT itself
+ 3. Pass NULL as channel handle argument for meshlink_set_channel_poll_cb API
+
+ Expected Result:
+ Reports error accordingly by returning NULL
+*/
+static bool test_steps_channel_set_poll_cb_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelpollconf4", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ assert(meshlink_start(mesh_handle));
+
+ /* Setting poll cb with NULL as channel handler */
+ meshlink_set_channel_poll_cb(mesh_handle, NULL, poll_cb);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelpollconf4");
+ return true;
+}
+
+
+int test_meshlink_set_channel_poll_cb(void) {
+ const struct CMUnitTest blackbox_channel_set_poll_cb_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_set_poll_cb_01, NULL, NULL,
+ (void *)&test_case_channel_set_poll_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_set_poll_cb_02, NULL, NULL,
+ (void *)&test_case_channel_set_poll_cb_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_channel_set_poll_cb_03, NULL, NULL,
+ (void *)&test_case_channel_set_poll_cb_03_state)
+ };
+ total_tests += sizeof(blackbox_channel_set_poll_cb_tests) / sizeof(blackbox_channel_set_poll_cb_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_channel_set_poll_cb_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_SET_POLL_CB_H
+#define TEST_CASES_SET_POLL_CB_H
+
+/*
+ test_cases_set_poll_cb.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_set_channel_poll_cb(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_set_receive_cb.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "test_cases_channel_set_receive_cb.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+#include <errno.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+/* Modify this to change the port number */
+#define PORT 8000
+
+/* Modify this to change the channel receive callback access buffer */
+#define TCP_TEST 8000
+
+static void test_case_set_channel_receive_cb_01(void **state);
+static bool test_steps_set_channel_receive_cb_01(void);
+static void test_case_set_channel_receive_cb_02(void **state);
+static bool test_steps_set_channel_receive_cb_02(void);
+static void test_case_set_channel_receive_cb_03(void **state);
+static bool test_steps_set_channel_receive_cb_03(void);
+static void test_case_set_channel_receive_cb_04(void **state);
+static bool test_steps_set_channel_receive_cb_04(void);
+
+static void channel_poll(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len);
+static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len);
+
+static bool rec_stat = false;
+static bool accept_stat = false;
+
+/* mutex for the receive callback common resources */
+static pthread_mutex_t lock_accept = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t lock_receive = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t receive_cond = PTHREAD_COND_INITIALIZER;
+
+static black_box_state_t test_case_channel_set_receive_cb_01_state = {
+ .test_case_name = "test_case_channel_set_receive_cb_01",
+};
+static black_box_state_t test_case_channel_set_receive_cb_02_state = {
+ .test_case_name = "test_case_channel_set_receive_cb_02",
+};
+static black_box_state_t test_case_channel_set_receive_cb_03_state = {
+ .test_case_name = "test_case_channel_set_receive_cb_03",
+};
+static black_box_state_t test_case_channel_set_receive_cb_04_state = {
+ .test_case_name = "test_case_channel_set_receive_cb_04",
+};
+
+/* channel receive callback */
+static void channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len) {
+ pthread_mutex_lock(& lock_receive);
+ rec_stat = true;
+ assert(!pthread_cond_broadcast(&receive_cond));
+ pthread_mutex_unlock(& lock_receive);
+}
+
+static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+ meshlink_set_channel_receive_cb(mesh, channel, channel_receive_cb);
+
+ pthread_mutex_lock(& lock_accept);
+ accept_stat = true;
+ assert(!pthread_cond_broadcast(&accept_cond));
+ pthread_mutex_unlock(& lock_accept);
+
+ return true;
+}
+
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
+ (void)len;
+
+ meshlink_set_channel_poll_cb(mesh, channel, NULL);
+ assert(meshlink_channel_send(mesh, channel, "Hello", 5) >= 0);
+}
+
+/* Execute meshlink_channel_set_receive_cb Test Case # 1 */
+static void test_case_set_channel_receive_cb_01(void **state) {
+ execute_test(test_steps_set_channel_receive_cb_01, state);
+}
+/* Test Steps for meshlink_channel_set_receive_cb Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Run NUT and Open channel for itself.
+ 2. Set channel receive callback and send data.
+
+ Expected Result:
+ Opens a channel by invoking channel receive callback when data sent to it.
+*/
+static bool test_steps_set_channel_receive_cb_01(void) {
+ struct timespec timeout = {0};
+ meshlink_destroy("channelreceiveconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelreceiveconf", "nut", "node_sim", 1);
+ assert(mesh_handle != NULL);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_channel_accept_cb(mesh_handle, accept_cb);
+
+ assert(meshlink_start(mesh_handle));
+
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ rec_stat = false;
+ accept_stat = false;
+ meshlink_channel_t *channel = meshlink_channel_open(mesh_handle, node, 8000, NULL, NULL, 0);
+ meshlink_set_channel_poll_cb(mesh_handle, channel, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 20;
+ pthread_mutex_lock(& lock_accept);
+
+ while(accept_stat == false) {
+ assert(!pthread_cond_timedwait(&accept_cond, &lock_accept, &timeout));
+ }
+
+ pthread_mutex_unlock(& lock_accept);
+
+ timeout.tv_sec = time(NULL) + 20;
+ pthread_mutex_lock(& lock_receive);
+
+ while(rec_stat == false) {
+ assert(pthread_cond_timedwait(&receive_cond, &lock_receive, &timeout) == 0);
+ }
+
+ pthread_mutex_unlock(& lock_receive);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelreceiveconf");
+
+ return true;
+}
+
+/* Execute meshlink_channel_set_receive_cb Test Case # 2 */
+static void test_case_set_channel_receive_cb_02(void **state) {
+ execute_test(test_steps_set_channel_receive_cb_02, state);
+}
+/* Test Steps for meshlink_channel_set_receive_cb Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Run NUT and Open channel for itself.
+ 2. Set channel receive callback with NULL as mesh handle.
+
+ Expected Result:
+ meshlink_channel_set_receive_cb returning proper meshlink_errno.
+*/
+static bool test_steps_set_channel_receive_cb_02(void) {
+ meshlink_destroy("channelreceiveconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelreceiveconf", "nut", "node_sim", 1);
+ assert(mesh_handle != NULL);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_channel_accept_cb(mesh_handle, accept_cb);
+
+ /* Starting NUT */
+ assert(meshlink_start(mesh_handle));
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ meshlink_channel_t *channel = meshlink_channel_open_ex(mesh_handle, node, 8000, NULL, NULL, 0, MESHLINK_CHANNEL_UDP);
+ assert(channel != NULL);
+ meshlink_set_channel_poll_cb(mesh_handle, channel, poll_cb);
+
+ /* Setting channel for NUT using meshlink_set_channel_receive_cb API with NULL as mesh handle */
+ meshlink_set_channel_receive_cb(NULL, channel, channel_receive_cb);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelreceiveconf");
+
+ return true;
+}
+
+/* Execute meshlink_channel_set_receive_cb Test Case # 3 */
+static void test_case_set_channel_receive_cb_03(void **state) {
+ execute_test(test_steps_set_channel_receive_cb_03, state);
+}
+/* Test Steps for meshlink_channel_set_receive_cb Test Case # 3 - Invalid case
+
+ Test Steps:
+ 1. Run NUT and Open channel for itself.
+ 2. Set channel receive callback with NULL as channel handle.
+
+ Expected Result:
+ meshlink_channel_set_receive_cb returning proper meshlink_errno.
+*/
+static bool test_steps_set_channel_receive_cb_03(void) {
+ meshlink_destroy("channelreceiveconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelreceiveconf", "nut", "node_sim", 1);
+ fprintf(stderr, "meshlink_open status: %s\n", meshlink_strerror(meshlink_errno));
+ assert(mesh_handle != NULL);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_channel_accept_cb(mesh_handle, accept_cb);
+
+ /* Starting NUT */
+ assert(meshlink_start(mesh_handle));
+
+ /* Setting channel for NUT using meshlink_set_channel_receive_cb API channel handle as NULL */
+ meshlink_set_channel_receive_cb(mesh_handle, NULL, channel_receive_cb);
+
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelreceiveconf");
+ return true;
+}
+
+
+int test_meshlink_set_channel_receive_cb(void) {
+ const struct CMUnitTest blackbox_channel_set_receive_cb_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_channel_receive_cb_01, NULL, NULL,
+ (void *)&test_case_channel_set_receive_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_channel_receive_cb_02, NULL, NULL,
+ (void *)&test_case_channel_set_receive_cb_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_channel_receive_cb_03, NULL, NULL,
+ (void *)&test_case_channel_set_receive_cb_03_state)
+ };
+ total_tests += sizeof(blackbox_channel_set_receive_cb_tests) / sizeof(blackbox_channel_set_receive_cb_tests[0]);
+
+ int failed = cmocka_run_group_tests(blackbox_channel_set_receive_cb_tests, NULL, NULL);
+
+ return failed;
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNELS_SET_RECEIVE_H
+#define TEST_CASES_CHANNELS_SET_RECEIVE_H
+
+/*
+ test_cases_channel_set_receive_cb.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_set_channel_receive_cb(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_channel_shutdown.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_channel_shutdown.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_mesh_channel_shutdown_01(void **state);
+static bool test_steps_mesh_channel_shutdown_01(void);
+static void test_case_mesh_channel_shutdown_02(void **state);
+static bool test_steps_mesh_channel_shutdown_02(void);
+static void test_case_mesh_channel_shutdown_03(void **state);
+static bool test_steps_mesh_channel_shutdown_03(void);
+static void test_case_mesh_channel_shutdown_04(void **state);
+static bool test_steps_mesh_channel_shutdown_04(void);
+static void test_case_mesh_channel_shutdown_05(void **state);
+static bool test_steps_mesh_channel_shutdown_05(void);
+
+static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len);
+static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable);
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len);
+
+/* State structure for meshlink_channel_shutdown Test Case #1 */
+static black_box_state_t test_mesh_channel_shutdown_01_state = {
+ .test_case_name = "test_case_mesh_channel_shutdown_01",
+};
+
+/* State structure for meshlink_channel_shutdown Test Case #2 */
+static black_box_state_t test_mesh_channel_shutdown_02_state = {
+ .test_case_name = "test_case_mesh_channel_shutdown_02",
+};
+
+/* State structure for meshlink_channel_shutdown Test Case #3 */
+static black_box_state_t test_mesh_channel_shutdown_03_state = {
+ .test_case_name = "test_case_mesh_channel_shutdown_03",
+};
+
+/* State structure for meshlink_channel_shutdown Test Case #4 */
+static black_box_state_t test_mesh_channel_shutdown_04_state = {
+ .test_case_name = "test_case_mesh_channel_shutdown_04",
+};
+
+/* State structure for meshlink_channel_shutdown Test Case #5 */
+static black_box_state_t test_mesh_channel_shutdown_05_state = {
+ .test_case_name = "test_case_mesh_channel_shutdown_05",
+};
+
+static bool channel_acc;
+static bool polled;
+static bool foo_responded;
+static bool bar_responded;
+
+/* mutex for the common variable */
+static pthread_mutex_t accept_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t poll_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t bar_responded_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t foo_responded_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t poll_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t foo_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t bar_cond = PTHREAD_COND_INITIALIZER;
+
+static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+ assert(port == 7);
+ assert(!len);
+
+ meshlink_set_channel_receive_cb(mesh, channel, receive_cb);
+ channel->node->priv = channel;
+ pthread_mutex_lock(&accept_lock);
+ channel_acc = true;
+ assert(!pthread_cond_broadcast(&accept_cond));
+ pthread_mutex_unlock(&accept_lock);
+
+ return true;
+}
+
+/* channel receive callback */
+static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len) {
+ if(!strcmp(mesh->name, "foo")) {
+ pthread_mutex_lock(& foo_responded_lock);
+ foo_responded = true;
+ assert(!pthread_cond_broadcast(&foo_cond));
+ pthread_mutex_unlock(& foo_responded_lock);
+
+ } else if(!strcmp(mesh->name, "bar")) {
+ pthread_mutex_lock(& bar_responded_lock);
+ bar_responded = true;
+ assert(!pthread_cond_broadcast(&bar_cond));
+ pthread_mutex_unlock(& bar_responded_lock);
+
+ assert(meshlink_channel_send(mesh, channel, "echo", 4) >= 0);
+
+ }
+}
+
+static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
+ (void)len;
+
+ meshlink_set_channel_poll_cb(mesh, channel, NULL);
+ pthread_mutex_lock(&poll_lock);
+ polled = true;
+ assert(!pthread_cond_broadcast(&poll_cond));
+ pthread_mutex_unlock(&poll_lock);
+}
+
+/* Execute meshlink_channel_shutdown Test Case # 1*/
+static void test_case_mesh_channel_shutdown_01(void **state) {
+ execute_test(test_steps_mesh_channel_shutdown_01, state);
+}
+
+/* Test Steps for meshlink_channel_shutdown Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Open foo and bar instances and open a channel between them
+ 2. Send data through the channel.
+ 3. Shut down channel's read and send data
+ 4. Shutdown channel's write and send data
+
+ Expected Result:
+ Data is able to receive through channel before shutting down,
+ On shutting down read its should not able to receive data and when write
+ is shut down its should be able to send data through channel.
+*/
+static bool test_steps_mesh_channel_shutdown_01(void) {
+ struct timespec timeout = {0};
+ meshlink_destroy("chan_shutdown_conf.1");
+ meshlink_destroy("chan_shutdown_conf.2");
+ // Open two new meshlink instance.
+
+ meshlink_handle_t *mesh1 = meshlink_open("chan_shutdown_conf.1", "foo", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+
+ meshlink_handle_t *mesh2 = meshlink_open("chan_shutdown_conf.2", "bar", "channels", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+
+ char *data = meshlink_export(mesh1);
+ assert(data);
+ assert(meshlink_import(mesh2, data));
+ free(data);
+ data = meshlink_export(mesh2);
+ assert(data);
+ assert(meshlink_import(mesh1, data));
+ free(data);
+
+ // Set the callbacks.
+
+ meshlink_set_channel_accept_cb(mesh2, accept_cb);
+
+ // Start both instances
+
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(1);
+
+ // Open a channel from foo to bar.
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar);
+
+ meshlink_channel_t *channel1 = meshlink_channel_open(mesh1, bar, 7, receive_cb, NULL, 0);
+ meshlink_set_channel_poll_cb(mesh1, channel1, poll_cb);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&poll_lock);
+
+ while(polled == false) {
+ assert(!pthread_cond_timedwait(&poll_cond, &poll_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&poll_lock);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&accept_lock);
+
+ while(channel_acc == false) {
+ assert(!pthread_cond_timedwait(&accept_cond, &accept_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&accept_lock);
+
+ meshlink_channel_t *channel2 = bar->priv;
+
+ // Sending to bar and testing the echo
+
+ assert(meshlink_channel_send(mesh1, channel1, "echo", 4) >= 0);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&foo_responded_lock);
+
+ while(foo_responded == false) {
+ assert(!pthread_cond_timedwait(&foo_cond, &foo_responded_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&foo_responded_lock);
+ assert(foo_responded);
+
+ // Shutting down channel read
+
+ meshlink_channel_shutdown(mesh1, channel1, SHUT_RD);
+ bar_responded = false;
+ foo_responded = false;
+ assert(meshlink_channel_send(mesh1, channel1, "echo", 4) >= 0);
+
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&bar_responded_lock);
+
+ while(bar_responded == false) {
+ assert(!pthread_cond_timedwait(&bar_cond, &bar_responded_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&bar_responded_lock);
+ assert_int_equal(bar_responded, true);
+ sleep(1);
+ assert_int_equal(foo_responded, false);
+
+ // Shutting down channel write
+
+ meshlink_channel_shutdown(mesh1, channel1, SHUT_WR);
+
+ ssize_t send_ret = meshlink_channel_send(mesh1, channel1, "echo", 4);
+ assert_int_equal(send_ret, -1);
+
+ // Clean up.
+
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("chan_shutdown_conf.1");
+ meshlink_destroy("chan_shutdown_conf.2");
+
+ return true;
+}
+
+/* Execute meshlink_channel_shutdown Test Case # 2*/
+static void test_case_mesh_channel_shutdown_02(void **state) {
+ execute_test(test_steps_mesh_channel_shutdown_02, state);
+}
+
+/* Test Steps for meshlink_channel_shutdown Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Open node instance and create a channel
+ 2. Call meshlink_channel_shutdown API by passing NULL as mesh handle
+
+ Expected Result:
+ meshlink_channel_shutdown API should report proper error handling
+*/
+static bool test_steps_mesh_channel_shutdown_02(void) {
+ meshlink_destroy("channelshutdownconf.3");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelshutdownconf.3", "nut", "node_sim", 1);
+ assert(mesh_handle != NULL);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_channel_accept_cb(mesh_handle, accept_cb);
+
+ assert(meshlink_start(mesh_handle));
+
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ meshlink_channel_t *channel = meshlink_channel_open(mesh_handle, node, 8000, NULL, NULL, 0);
+ assert(channel);
+ meshlink_set_channel_poll_cb(mesh_handle, channel, poll_cb);
+
+ // Passing NULL as mesh handle and other arguments being valid
+
+ meshlink_channel_shutdown(NULL, channel, SHUT_WR);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelshutdownconf.3");
+
+ return true;
+}
+
+/* Execute meshlink_channel_shutdown Test Case # 3*/
+static void test_case_mesh_channel_shutdown_03(void **state) {
+ execute_test(test_steps_mesh_channel_shutdown_03, state);
+}
+
+/* Test Steps for meshlink_channel_shutdown Test Case # 3
+
+ Test Steps:
+ 1. Open node instance
+ 2. Call meshlink_channel_shutdown API by passing NULL as channel handle
+
+ Expected Result:
+ meshlink_channel_shutdown API should report proper error handling
+*/
+static bool test_steps_mesh_channel_shutdown_03(void) {
+ meshlink_destroy("channelshutdownconf.4");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("channelshutdownconf.4", "nut", "node_sim", 1);
+ assert(mesh_handle != NULL);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_channel_accept_cb(mesh_handle, accept_cb);
+
+ assert(meshlink_start(mesh_handle));
+
+ // Passing NULL as mesh handle and other arguments being valid
+
+ meshlink_channel_shutdown(mesh_handle, NULL, SHUT_WR);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("channelshutdownconf.4");
+
+ return true;
+}
+
+
+int test_meshlink_channel_shutdown(void) {
+ const struct CMUnitTest blackbox_channel_shutdown_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_shutdown_01, NULL, NULL,
+ (void *)&test_mesh_channel_shutdown_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_shutdown_02, NULL, NULL,
+ (void *)&test_mesh_channel_shutdown_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_channel_shutdown_03, NULL, NULL,
+ (void *)&test_mesh_channel_shutdown_03_state)
+ };
+ total_tests += sizeof(blackbox_channel_shutdown_tests) / sizeof(blackbox_channel_shutdown_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_channel_shutdown_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_CHANNEL_SHUTDOWN_H
+#define TEST_CASES_CHANNEL_SHUTDOWN_H
+
+/*
+ test_cases_channel_shutdown.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_channel_shutdown(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_default_blacklist.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+#include "execute_tests.h"
+#include "test_cases_default_blacklist.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "../../utils.h"
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_mesh_default_blacklist_01(void **state);
+static bool test_steps_mesh_default_blacklist_01(void);
+static void test_case_mesh_default_blacklist_02(void **state);
+static bool test_steps_mesh_default_blacklist_02(void);
+
+/* State structure for meshlink_default_blacklist Test Case #1 */
+static black_box_state_t test_mesh_default_blacklist_01_state = {
+ .test_case_name = "test_case_mesh_default_blacklist_01",
+};
+
+/* State structure for meshlink_default_blacklist Test Case #2 */
+static black_box_state_t test_mesh_default_blacklist_02_state = {
+ .test_case_name = "test_case_mesh_default_blacklist_02",
+};
+
+/* Execute meshlink_default_blacklist Test Case # 1*/
+static void test_case_mesh_default_blacklist_01(void **state) {
+ execute_test(test_steps_mesh_default_blacklist_01, state);
+ return;
+}
+
+static bool received = false;
+
+static void receive(meshlink_handle_t *mesh, meshlink_node_t *src, const void *data, size_t len) {
+ assert(len);
+
+ if(!strcmp(src->name, "bar") || !strcmp(src->name, "foz")) {
+ received = true;
+ }
+}
+
+static bool bar_reachable = false;
+static bool foz_reachable = false;
+
+void status_cb1(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
+ if(!strcmp(node->name, "bar")) {
+ bar_reachable = reachable;
+ } else if(!strcmp(node->name, "foz")) {
+ foz_reachable = reachable;
+ }
+}
+
+/* Test Steps for meshlink_default_blacklist Test Case # 1
+
+ Test Steps:
+ 1. Open all the node instances & Disable default blacklist
+ 2. Join bar node with foo and Send & Receive data
+ 3. Enable default blacklist and join foz node with foo node
+ and follow the steps done for bar node
+
+ Expected Result:
+ When default blacklist is disabled, foo node should receive data from bar
+ but when enabled foo node should not receive data from foz
+*/
+static bool test_steps_mesh_default_blacklist_01(void) {
+ meshlink_destroy("def_blacklist_conf.1");
+ meshlink_destroy("def_blacklist_conf.2");
+ meshlink_destroy("def_blacklist_conf.3");
+
+ // Open two new meshlink instance.
+ meshlink_handle_t *mesh1 = meshlink_open("def_blacklist_conf.1", "foo", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("def_blacklist_conf.2", "bar", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh3 = meshlink_open("def_blacklist_conf.3", "foz", "blacklist", DEV_CLASS_BACKBONE);
+ assert(mesh3);
+ meshlink_set_log_cb(mesh3, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_receive_cb(mesh1, receive);
+
+ meshlink_set_default_blacklist(mesh1, false);
+
+ // Start both instances
+ bar_reachable = false;
+ foz_reachable = false;
+ meshlink_set_node_status_cb(mesh1, status_cb1);
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ assert(meshlink_start(mesh3));
+ sleep(1);
+
+ char *foo_export = meshlink_export(mesh1);
+ assert(foo_export != NULL);
+ assert(meshlink_import(mesh2, foo_export));
+ char *bar_export = meshlink_export(mesh2);
+ assert(meshlink_import(mesh1, bar_export));
+ sleep(5);
+ assert(bar_reachable);
+
+ // Nodes should learn about each other
+ meshlink_node_t *foo = NULL;
+ foo = meshlink_get_node(mesh2, "foo");
+ assert(foo);
+
+ received = false;
+ assert(meshlink_send(mesh2, foo, "test", 5));
+ assert_after(received, 2);
+
+ // Enable default blacklist and join another node
+ meshlink_set_default_blacklist(mesh1, true);
+
+ char *foz_export = meshlink_export(mesh3);
+ assert(foz_export);
+ assert(meshlink_import(mesh1, foz_export));
+ assert(meshlink_import(mesh3, foo_export));
+ sleep(5);
+ assert(foz_reachable);
+
+ foo = meshlink_get_node(mesh3, "foo");
+ assert(foo);
+ assert(meshlink_send(mesh3, foo, "test", 5));
+ received = false;
+ assert(meshlink_send(mesh3, foo, "test", 5));
+ assert_after(!received, 2);
+
+ // Clean up.
+ free(foo_export);
+ free(foz_export);
+ free(bar_export);
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_close(mesh3);
+ meshlink_destroy("def_blacklist_conf.1");
+ meshlink_destroy("def_blacklist_conf.2");
+ meshlink_destroy("def_blacklist_conf.3");
+
+ return true;
+}
+
+/* Execute meshlink_default_blacklist Test Case # 2*/
+static void test_case_mesh_default_blacklist_02(void **state) {
+ execute_test(test_steps_mesh_default_blacklist_02, state);
+}
+
+/* Test Steps for meshlink_default_blacklist Test Case # 2
+
+ Test Steps:
+ 1. Calling meshlink_default_blacklist with NULL as mesh handle argument.
+
+ Expected Result:
+ meshlink_default_blacklist API handles the invalid parameter when called by giving proper error number.
+*/
+static bool test_steps_mesh_default_blacklist_02(void) {
+ // Passing NULL as mesh handle argument to the API
+ meshlink_set_default_blacklist(NULL, true);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ return true;
+}
+
+int test_meshlink_default_blacklist(void) {
+ const struct CMUnitTest blackbox_default_blacklist_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_default_blacklist_01, NULL, NULL,
+ (void *)&test_mesh_default_blacklist_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_default_blacklist_02, NULL, NULL,
+ (void *)&test_mesh_default_blacklist_02_state)
+ };
+
+ total_tests += sizeof(blackbox_default_blacklist_tests) / sizeof(blackbox_default_blacklist_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_default_blacklist_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_DEFAULT_BLACKLIST_H
+#define TEST_CASES_DEFAULT_BLACKLIST_H
+
+/*
+ test_cases_default_blacklist.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_default_blacklist(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_destroy.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "test_cases_destroy.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_meshlink_destroy_01(void **state);
+static bool test_meshlink_destroy_01(void);
+static void test_case_meshlink_destroy_02(void **state);
+static bool test_meshlink_destroy_02(void);
+static void test_case_meshlink_destroy_03(void **state);
+static bool test_meshlink_destroy_03(void);
+
+static black_box_state_t test_case_meshlink_destroy_01_state = {
+ .test_case_name = "test_case_meshlink_destroy_01",
+};
+static black_box_state_t test_case_meshlink_destroy_02_state = {
+ .test_case_name = "test_case_meshlink_destroy_02",
+};
+static black_box_state_t test_case_meshlink_destroy_03_state = {
+ .test_case_name = "test_case_meshlink_destroy_03",
+};
+
+
+/* Execute destroy Test Case # 1 - valid case*/
+static void test_case_meshlink_destroy_01(void **state) {
+ execute_test(test_meshlink_destroy_01, state);
+}
+
+/* Test Steps for destroy Test Case # 1 - Valid case
+ Test Steps:
+ 1. Open instance for NUT
+ 2. Close NUT, and destroy the confbase
+ 3. Open the same confbase directory
+
+ Expected Result:
+ confbase should be deleted
+*/
+static bool test_meshlink_destroy_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ char *confbase = "destroyconf";
+ mesh_handle = meshlink_open(confbase, "nut", "node_sim", 1);
+ assert(mesh_handle);
+
+ meshlink_close(mesh_handle);
+
+ // Destroying NUT's confbase
+ bool result = meshlink_destroy(confbase);
+ assert_int_equal(result, true);
+
+ // Verify whether confbase is removed or not
+ DIR *dir = opendir(confbase);
+ assert_int_equal(dir, NULL);
+
+ return true;
+}
+
+/* Execute destroy Test Case # 2 - passing NULL argument to the API */
+static void test_case_meshlink_destroy_02(void **state) {
+ execute_test(test_meshlink_destroy_02, state);
+}
+
+/* Test Steps for destroy Test Case # 2 - Invalid case
+ Test Steps:
+ 1. Just passing NULL as argument to the API
+
+ Expected Result:
+ Return false reporting failure
+*/
+static bool test_meshlink_destroy_02(void) {
+ // Passing NULL as an argument to meshlink_destroy
+ bool result = meshlink_destroy(NULL);
+ assert_int_equal(result, false);
+
+ return true;
+}
+
+/* Execute status Test Case # 3 - destroying non existing file */
+static void test_case_meshlink_destroy_03(void **state) {
+ execute_test(test_meshlink_destroy_03, state);
+}
+/* Test Steps for destroy Test Case # 3 - Invalid case
+ Test Steps:
+ 1. unlink if there's any such test file
+ 2. Call API with that file name
+
+ Expected Result:
+ Return false reporting failure
+*/
+static bool test_meshlink_destroy_03(void) {
+ bool result = false;
+
+ // Deletes if there is any file named 'non_existing' already
+ unlink("non_existing");
+
+ // Passing non-existing file as an argument to meshlink_destroy
+ result = meshlink_destroy("non_existing");
+ assert_int_equal(result, false);
+
+ return true;
+}
+
+
+int test_meshlink_destroy(void) {
+ const struct CMUnitTest blackbox_destroy_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_meshlink_destroy_01, NULL, NULL,
+ (void *)&test_case_meshlink_destroy_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meshlink_destroy_02, NULL, NULL,
+ (void *)&test_case_meshlink_destroy_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meshlink_destroy_03, NULL, NULL,
+ (void *)&test_case_meshlink_destroy_03_state)
+ };
+
+ total_tests += sizeof(blackbox_destroy_tests) / sizeof(blackbox_destroy_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_destroy_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_DESTROY_H
+#define TEST_CASES_DESTROY_H
+
+/*
+ test_cases_destroy.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_destroy(void);
+
+#endif // TEST_CASES_DESTROY_H
--- /dev/null
+/*
+ test_cases_export.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "test_cases_export.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_export_01(void **state);
+static bool test_export_01(void);
+static void test_case_export_02(void **state);
+static bool test_export_02(void);
+
+/* State structure for export API Test Case #1 */
+static black_box_state_t test_case_export_01_state = {
+ .test_case_name = "test_case_export_01",
+};
+/* State structure for export API Test Case #2 */
+static black_box_state_t test_case_export_02_state = {
+ .test_case_name = "test_case_export_02",
+};
+
+
+/* Execute export Test Case # 1 - valid case*/
+static void test_case_export_01(void **state) {
+ execute_test(test_export_01, state);
+}
+/* Test Steps for export Test Case # 1 - Valid case
+ Test Steps:
+ 1. Run NUT
+ 2. Export mesh
+
+ Expected Result:
+ API returns a NULL terminated string containing meta data of NUT.
+*/
+static bool test_export_01(void) {
+ meshlink_destroy("exportconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("exportconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ char *expo = meshlink_export(mesh_handle);
+ assert_int_not_equal(expo, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("exportconf");
+
+ return true;
+}
+
+/* Execute export Test Case # 2 - Invalid case*/
+static void test_case_export_02(void **state) {
+ execute_test(test_export_02, state);
+}
+/* Test Steps for export Test Case # 2 - Invalid case
+ Test Steps:
+ 1. Run NUT
+ 2. calling meshlink_export by passing NULL as mesh handle
+
+ Expected Result:
+ API returns NULL reporting error when NULL being passed as mesh handle.
+*/
+static bool test_export_02(void) {
+ // Calling export API with NULL as mesh handle
+ char *expo = meshlink_export(NULL);
+ assert_int_equal(expo, NULL);
+
+ return true;
+}
+
+
+int test_meshlink_export(void) {
+ const struct CMUnitTest blackbox_export_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_export_01, NULL, NULL,
+ (void *)&test_case_export_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_export_02, NULL, NULL,
+ (void *)&test_case_export_02_state)
+ };
+
+ total_tests += sizeof(blackbox_export_tests) / sizeof(blackbox_export_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_export_tests, NULL, NULL);
+}
+
--- /dev/null
+#ifndef TEST_CASES_EXPORT_H
+#define TEST_CASES_EXPORT_H
+
+/*
+ test_cases_export.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_export(void);
+
+#endif
--- /dev/null
+/*
+ test_cases_get_all_nodes.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "test_cases_get_all_nodes.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_get_all_nodes_01(void **state);
+static bool test_get_all_nodes_01(void);
+static void test_case_get_all_nodes_02(void **state);
+static bool test_get_all_nodes_02(void);
+static void test_case_get_all_nodes_03(void **state);
+static bool test_get_all_nodes_03(void);
+static void test_case_get_all_nodes_04(void **state);
+static bool test_get_all_nodes_04(void);
+
+/* State structure for get_all_nodes Test Case #1 */
+static black_box_state_t test_case_get_all_nodes_01_state = {
+ .test_case_name = "test_case_get_all_nodes_01",
+};
+
+/* State structure for get_all_nodes Test Case #2 */
+static black_box_state_t test_case_get_all_nodes_02_state = {
+ .test_case_name = "test_case_get_all_nodes_02",
+};
+
+/* State structure for get_all_nodes Test Case #3 */
+static black_box_state_t test_case_get_all_nodes_03_state = {
+ .test_case_name = "test_case_get_all_nodes_03",
+};
+
+/* Execute get_all_nodes Test Case # 1 - Valid case - get all nodes in the mesh */
+static void test_case_get_all_nodes_01(void **state) {
+ execute_test(test_get_all_nodes_01, state);
+}
+/* Test Steps for get_all_nodes Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Open NUT and get list of nodes
+ 2. Open bar and join with NUT
+ 3. get list of nodes together
+
+ Expected Result:
+ Obtaining list of nodes in the mesh at the given instance
+*/
+static bool test_get_all_nodes_01(void) {
+ meshlink_destroy("getnodeconf1");
+ meshlink_destroy("getnodeconf2");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance for NUT */
+ meshlink_handle_t *mesh1 = meshlink_open("getnodeconf1", "nut", "node_sim", DEV_CLASS_STATIONARY);
+ assert(mesh1);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ size_t nnodes = 0;
+ meshlink_node_t **nodes = NULL;
+ nodes = meshlink_get_all_nodes(mesh1, nodes, &nnodes);
+ assert_int_not_equal(nodes, NULL);
+ assert_int_equal(nnodes, 1);
+
+ /* Create meshlink instance for bar */
+ meshlink_handle_t *mesh2 = meshlink_open("getnodeconf2", "bar", "node_sim", DEV_CLASS_STATIONARY);
+ assert(mesh2);
+
+ /* importing and exporting mesh meta data */
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ assert(meshlink_import(mesh1, exp2));
+ assert(meshlink_import(mesh2, exp1));
+
+ nodes = meshlink_get_all_nodes(mesh1, nodes, &nnodes);
+ assert_int_not_equal(nodes, NULL);
+ assert_int_equal(nnodes, 2);
+
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("getnodeconf1");
+ meshlink_destroy("getnodeconf2");
+
+ return true;
+}
+
+
+
+/* Execute get_all_nodes Test Case # 2 - Invalid case - get all nodes in the mesh passing NULL */
+static void test_case_get_all_nodes_02(void **state) {
+ execute_test(test_get_all_nodes_02, state);
+}
+
+/* Test Steps for get_all_nodes Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Passing NULL as mesh handle argument for meshlink_get_all_nodes
+
+ Expected Result:
+ Error reported correctly by returning NULL
+*/
+static bool test_get_all_nodes_02(void) {
+ meshlink_node_t **nodes = NULL;
+ size_t nmemb = 0;
+
+ meshlink_node_t **node = meshlink_get_all_nodes(NULL, nodes, &nmemb);
+ assert_int_equal(nodes, NULL);
+
+ return true;
+}
+
+/* Execute get_all_nodes Test Case # 3 - Invalid case - get all nodes in the mesh passing NULL as nmeb arg */
+static void test_case_get_all_nodes_03(void **state) {
+ execute_test(test_get_all_nodes_03, state);
+}
+/* Test Steps for get_all_nodes Test Case # 3 - Invalid case
+
+ Test Steps:
+ 1. Passing NULL as pointer to node members argument for meshlink_get_all_nodes
+
+ Expected Result:
+ Error reported correctly by returning NULL
+*/
+static bool test_get_all_nodes_03(void) {
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("getallnodesconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ assert(meshlink_start(mesh_handle));
+
+ meshlink_node_t **nodes = NULL;
+ nodes = meshlink_get_all_nodes(mesh_handle, nodes, NULL);
+ assert_int_equal(nodes, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getallnodesconf");
+
+ return true;
+}
+
+int test_meshlink_get_all_nodes(void) {
+ const struct CMUnitTest blackbox_get_all_nodes[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_get_all_nodes_01, NULL, NULL,
+ (void *)&test_case_get_all_nodes_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_get_all_nodes_02, NULL, NULL,
+ (void *)&test_case_get_all_nodes_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_get_all_nodes_03, NULL, NULL,
+ (void *)&test_case_get_all_nodes_03_state)
+ };
+ total_tests += sizeof(blackbox_get_all_nodes) / sizeof(blackbox_get_all_nodes[0]);
+
+ return cmocka_run_group_tests(blackbox_get_all_nodes, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_GET_ALL_NODES_H
+#define TEST_CASES_GET_ALL_NODES_H
+
+/*
+ test_cases_get_all_nodes.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_get_all_nodes(void);
+
+#endif
--- /dev/null
+/*
+ test_cases_get_ex_addr.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_get_ex_addr.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_get_address_01(void **state);
+static bool test_steps_mesh_get_address_01(void);
+static void test_case_mesh_get_address_02(void **state);
+static bool test_steps_mesh_get_address_02(void);
+static void test_case_mesh_get_address_03(void **state);
+static bool test_steps_mesh_get_address_03(void);
+
+/* State structure for meshlink_get_external_address Test Case #1 */
+static black_box_state_t test_mesh_get_address_01_state = {
+ .test_case_name = "test_case_mesh_get_address_01",
+};
+
+/* State structure for meshlink_get_external_address Test Case #2 */
+static black_box_state_t test_mesh_get_address_02_state = {
+ .test_case_name = "test_case_mesh_get_address_02",
+};
+
+/* State structure for meshlink_get_external_address Test Case #3 */
+static black_box_state_t test_mesh_get_address_03_state = {
+ .test_case_name = "test_case_mesh_get_address_03",
+};
+
+/* Execute meshlink_get_external_address Test Case # 1 */
+static void test_case_mesh_get_address_01(void **state) {
+ execute_test(test_steps_mesh_get_address_01, state);
+}
+
+/* Test Steps for meshlink_get_external_address Test Case # 1
+
+ Test Steps:
+ 1. Create an instance of the node & start it
+ 2. Get node's external address using meshlink_get_external_address
+
+ Expected Result:
+ API returns the external address successfully.
+*/
+static bool test_steps_mesh_get_address_01(void) {
+ meshlink_handle_t *mesh = meshlink_open("getex_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+ assert(meshlink_start(mesh));
+
+ char *addr = meshlink_get_external_address(mesh);
+ assert_int_not_equal(addr, NULL);
+
+ free(addr);
+ meshlink_close(mesh);
+ meshlink_destroy("getex_conf");
+ return true;
+}
+
+/* Execute meshlink_get_external_address Test Case # 2 */
+static void test_case_mesh_get_address_02(void **state) {
+ execute_test(test_steps_mesh_get_address_02, state);
+}
+
+/* Test Steps for meshlink_get_external_address Test Case # 2
+
+ Test Steps:
+ 1. Obtain external address by passing NULL as mesh handle
+ to meshlink_get_external_address API
+
+ Expected Result:
+ Return NULL by reporting error successfully.
+*/
+static bool test_steps_mesh_get_address_02(void) {
+ char *ext = meshlink_get_external_address(NULL);
+ assert_int_equal(ext, NULL);
+
+ return true;
+}
+
+/* Execute meshlink_get_external_address Test Case # 3 */
+static void test_case_mesh_get_address_03(void **state) {
+ execute_test(test_steps_mesh_get_address_03, state);
+}
+
+/* Test Steps for meshlink_get_external_address Test Case # 3 - Functionality test
+
+ Test Steps:
+ 1. Create an instance of the node
+ 2. Get node's external address using meshlink_get_external_address
+
+ Expected Result:
+ API returns the external address successfully even if the mesh is started.
+*/
+static bool test_steps_mesh_get_address_03(void) {
+ meshlink_handle_t *mesh = meshlink_open("getex_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+ assert(meshlink_start(mesh));
+
+ char *addr = meshlink_get_external_address(mesh);
+ assert_int_not_equal(addr, NULL);
+
+ free(addr);
+ meshlink_close(mesh);
+ meshlink_destroy("getex_conf");
+ return true;
+}
+
+int test_meshlink_get_external_address(void) {
+ const struct CMUnitTest blackbox_get_ex_addr_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_address_01, NULL, NULL,
+ (void *)&test_mesh_get_address_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_address_02, NULL, NULL,
+ (void *)&test_mesh_get_address_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_address_03, NULL, NULL,
+ (void *)&test_mesh_get_address_03_state)
+ };
+ total_tests += sizeof(blackbox_get_ex_addr_tests) / sizeof(blackbox_get_ex_addr_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_get_ex_addr_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_GET_EX_ADDR_H
+#define TEST_CASES_GET_EX_ADDR_H
+
+/*
+ test_cases_get_ex_addr.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_get_external_address(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_get_fingerprint.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "test_cases_get_fingerprint.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_get_fingerprint_cb_01(void **state);
+static bool test_get_fingerprint_cb_01(void);
+static void test_case_get_fingerprint_cb_02(void **state);
+static bool test_get_fingerprint_cb_02(void);
+static void test_case_get_fingerprint_cb_03(void **state);
+static bool test_get_fingerprint_cb_03(void);
+
+/* State structure for get_fingerprint Test Case #1 */
+static black_box_state_t test_case_get_fingerprint_cb_01_state = {
+ .test_case_name = "test_case_get_fingerprint_cb_01",
+};
+/* State structure for get_fingerprint Test Case #2 */
+static black_box_state_t test_case_get_fingerprint_cb_02_state = {
+ .test_case_name = "test_case_get_fingerprint_cb_02",
+};
+/* State structure for get_fingerprint Test Case #3 */
+static black_box_state_t test_case_get_fingerprint_cb_03_state = {
+ .test_case_name = "test_case_get_fingerprint_cb_03",
+};
+
+/* Execute get_fingerprint Test Case # 1 - Valid Case of obtaing publickey of NUT */
+static void test_case_get_fingerprint_cb_01(void **state) {
+ execute_test(test_get_fingerprint_cb_01, state);
+}
+/* Test Steps for get_fingerprint Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Get node handle for ourself(for NUT) and obtain fingerprint
+
+ Expected Result:
+ Obtain fingerprint of NUT successfully.
+*/
+static bool test_get_fingerprint_cb_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("getfingerprintconf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ char *fp = meshlink_get_fingerprint(mesh_handle, node);
+ assert_int_not_equal(fp, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getfingerprintconf");
+
+ return true;
+}
+
+/* Execute get_fingerprint Test Case # 2 - Invalid Case - trying t0 obtain publickey of a node in a
+ mesh by passing NULL as mesh handle argument*/
+static void test_case_get_fingerprint_cb_02(void **state) {
+ execute_test(test_get_fingerprint_cb_02, state);
+}
+
+/* Test Steps for get_fingerprint Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Get node handle for ourself(for NUT)
+ 3. Obtain fingerprint by passing NULL as mesh handle
+
+ Expected Result:
+ Return NULL by reporting error successfully.
+*/
+static bool test_get_fingerprint_cb_02(void) {
+ /* Set up logging for Meshlink */
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ PRINT_TEST_CASE_MSG("Opening NUT\n");
+ meshlink_handle_t *mesh_handle = meshlink_open("getfingerprintconf", "nut", "test", 1);
+ assert(mesh_handle);
+
+ /* Set up logging for Meshlink with the newly acquired Mesh Handle */
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ /* Getting node handle for itself */
+ meshlink_node_t *node = meshlink_get_self(mesh_handle);
+ assert(node != NULL);
+
+ /* passing NULL as mesh handle for meshlink_get_fingerprint API */
+ char *fp = meshlink_get_fingerprint(NULL, node);
+ assert_int_equal(fp, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getfingerprintconf");
+
+ return true;
+}
+
+/* Execute get_fingerprint Test Case # 3 - Invalid Case - trying t0 obtain publickey of a node in a
+ mesh by passing NULL as node handle argument */
+static void test_case_get_fingerprint_cb_03(void **state) {
+ execute_test(test_get_fingerprint_cb_03, state);
+}
+/* Test Steps for get_fingerprint Test Case # 3 - Invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Get node handle for ourself(for NUT)
+ 3. Obtain fingerprint by passing NULL as node handle
+
+ Expected Result:
+ Return NULL by reporting error successfully.
+*/
+static bool test_get_fingerprint_cb_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("getfingerprintconf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ char *fp = meshlink_get_fingerprint(mesh_handle, NULL);
+ assert_int_equal(fp, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getfingerprintconf");
+
+ return true;
+}
+
+int test_meshlink_get_fingerprint(void) {
+ const struct CMUnitTest blackbox_get_fingerprint_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_get_fingerprint_cb_01, NULL, NULL,
+ (void *)&test_case_get_fingerprint_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_get_fingerprint_cb_02, NULL, NULL,
+ (void *)&test_case_get_fingerprint_cb_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_get_fingerprint_cb_03, NULL, NULL,
+ (void *)&test_case_get_fingerprint_cb_03_state)
+ };
+
+ total_tests += sizeof(blackbox_get_fingerprint_tests) / sizeof(blackbox_get_fingerprint_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_get_fingerprint_tests, NULL, NULL);
+
+}
--- /dev/null
+#ifndef TEST_CASES_GET_FINGERPRINT_H
+#define TEST_CASES_GET_FINGERPRINT_H
+
+/*
+ test_cases_get_fingerprint.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_get_fingerprint(void);
+extern int total_tests;
+
+#endif // TEST_CASES_GET_FINGERPRINT_H
--- /dev/null
+/*
+ test_cases_get_node.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_get_node.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_mesh_get_node_01(void **state);
+static bool test_steps_mesh_get_node_01(void);
+static void test_case_mesh_get_node_02(void **state);
+static bool test_steps_mesh_get_node_02(void);
+static void test_case_mesh_get_node_03(void **state);
+static bool test_steps_mesh_get_node_03(void);
+static void test_case_mesh_get_node_04(void **state);
+static bool test_steps_mesh_get_node_04(void);
+
+/* State structure for meshlink_get_node Test Case #1 */
+static black_box_state_t test_mesh_get_node_01_state = {
+ .test_case_name = "test_case_mesh_get_node_01",
+};
+
+/* State structure for meshlink_get_node Test Case #2 */
+static black_box_state_t test_mesh_get_node_02_state = {
+ .test_case_name = "test_case_mesh_get_node_02",
+};
+
+/* State structure for meshlink_get_node Test Case #3 */
+static black_box_state_t test_mesh_get_node_03_state = {
+ .test_case_name = "test_case_mesh_get_node_03",
+};
+
+/* State structure for meshlink_get_node Test Case #4 */
+static black_box_state_t test_mesh_get_node_04_state = {
+ .test_case_name = "test_case_mesh_get_node_04",
+};
+
+/* Execute meshlink_get_node Test Case # 1 */
+static void test_case_mesh_get_node_01(void **state) {
+ execute_test(test_steps_mesh_get_node_01, state);
+}
+
+/* Test Steps for meshlink_get_node Test Case # 1
+
+ Test Steps:
+ 1. Open nodes instance
+ 2. Get node's handle
+
+ Expected Result:
+ node handle of it's own is obtained
+*/
+static bool test_steps_mesh_get_node_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_destroy("getnode1");
+ meshlink_destroy("getnode2");
+
+ // Opening NUT and bar nodes
+ meshlink_handle_t *mesh1 = meshlink_open("getnode1", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("getnode2", "bar", "test", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Exporting and Importing mutually
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ bool imp1 = meshlink_import(mesh1, exp2);
+ assert(imp1);
+ bool imp2 = meshlink_import(mesh2, exp1);
+ assert(imp2);
+
+ // Get node handles
+ meshlink_node_t *get_node = meshlink_get_node(mesh1, "bar");
+ assert_int_not_equal(get_node, NULL);
+ get_node = meshlink_get_node(mesh1, "nut");
+ assert_int_not_equal(get_node, NULL);
+
+ // Cleanup
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("getnode1");
+ meshlink_destroy("getnode2");
+ return true;
+}
+
+/* Execute meshlink_get_node Test Case # 2 */
+static void test_case_mesh_get_node_02(void **state) {
+ execute_test(test_steps_mesh_get_node_02, state);
+}
+
+/* Test Steps for meshlink_get_node Test Case # 2
+
+ Test Steps:
+ 1. Get node handles by passing NULL as mesh handle argument
+
+ Expected Result:
+ Reports error successfully by returning NULL
+*/
+static bool test_steps_mesh_get_node_02(void) {
+ meshlink_node_t *get_node = meshlink_get_node(NULL, "foo");
+ assert_int_equal(get_node, NULL);
+
+ return true;
+}
+
+/* Execute meshlink_get_node Test Case # 3 */
+static void test_case_mesh_get_node_03(void **state) {
+ execute_test(test_steps_mesh_get_node_03, state);
+}
+
+/* Test Steps for meshlink_get_node Test Case # 3
+
+ Test Steps:
+ 1. Get node handles by passing NULL as node name argument
+
+ Expected Result:
+ Reports error successfully by returning NULL
+*/
+static bool test_steps_mesh_get_node_03(void) {
+ meshlink_handle_t *mesh = meshlink_open("node_conf.3", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh);
+ assert(meshlink_start(mesh));
+
+ meshlink_node_t *get_node = meshlink_get_node(mesh, NULL);
+ assert_int_equal(get_node, NULL);
+
+ meshlink_close(mesh);
+ meshlink_destroy("node_conf.3");
+ return true;
+}
+
+/* Execute meshlink_get_node Test Case # 4 */
+static void test_case_mesh_get_node_04(void **state) {
+ execute_test(test_steps_mesh_get_node_04, state);
+}
+
+/* Test Steps for meshlink_get_node Test Case # 4
+
+ Test Steps:
+ 1. Open node instance
+ 2. Get node handle with the name of the node
+ that's not in the mesh
+
+ Expected Result:
+ Reports error successfully by returning NULL
+*/
+static bool test_steps_mesh_get_node_04(void) {
+ meshlink_handle_t *mesh = meshlink_open("node_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh);
+ assert(meshlink_start(mesh));
+
+ const char *nonexisting_node = "bar";
+ meshlink_node_t *get_node = meshlink_get_node(mesh, nonexisting_node);
+ assert_int_equal(get_node, NULL);
+
+ meshlink_close(mesh);
+ meshlink_destroy("node_conf");
+ return true;
+}
+
+int test_meshlink_get_node(void) {
+ const struct CMUnitTest blackbox_get_node_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_node_01, NULL, NULL,
+ (void *)&test_mesh_get_node_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_node_02, NULL, NULL,
+ (void *)&test_mesh_get_node_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_node_03, NULL, NULL,
+ (void *)&test_mesh_get_node_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_node_04, NULL, NULL,
+ (void *)&test_mesh_get_node_04_state)
+ };
+
+ total_tests += sizeof(blackbox_get_node_tests) / sizeof(blackbox_get_node_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_get_node_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_GET_NODE_H
+#define TEST_CASES_GET_NODE_H
+
+/*
+ test_cases_get_node.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_get_node(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_get_port.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_get_port.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_get_port_01(void **state);
+static bool test_steps_mesh_get_port_01(void);
+static void test_case_mesh_get_port_02(void **state);
+static bool test_steps_mesh_get_port_02(void);
+
+/* State structure for meshlink_get_port Test Case #1 */
+static black_box_state_t test_mesh_get_port_01_state = {
+ .test_case_name = "test_case_mesh_get_port_01",
+};
+
+/* State structure for meshlink_get_port Test Case #2 */
+static black_box_state_t test_mesh_get_port_02_state = {
+ .test_case_name = "test_case_mesh_get_port_02",
+};
+
+/* Execute meshlink_get_port Test Case # 1 */
+static void test_case_mesh_get_port_01(void **state) {
+ execute_test(test_steps_mesh_get_port_01, state);
+}
+
+/* Test Steps for meshlink_get_port Test Case # 1
+
+ Test Steps:
+ 1. Open node instance
+ 2. Run the node instance
+ 3. Obtain port of that mesh using meshlink_get_port API
+
+ Expected Result:
+ API returns valid port number.
+*/
+static bool test_steps_mesh_get_port_01(void) {
+ meshlink_handle_t *mesh = meshlink_open("port_conf", "foo", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh);
+ assert(meshlink_start(mesh));
+
+ int port = meshlink_get_port(mesh);
+ assert_int_not_equal(port, -1);
+
+ meshlink_close(mesh);
+ meshlink_destroy("port_conf");
+ return true;
+}
+
+/* Execute meshlink_get_port Test Case # 2 */
+static void test_case_mesh_get_port_02(void **state) {
+ execute_test(test_steps_mesh_get_port_02, state);
+}
+
+/* Test Steps for meshlink_get_port Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Pass NULL as mesh handle argument to meshlink_get_port API
+
+ Expected Result:
+ Reports error successfully by returning -1
+*/
+static bool test_steps_mesh_get_port_02(void) {
+ int port = meshlink_get_port(NULL);
+ assert_int_equal(port, -1);
+
+ return true;
+}
+
+int test_meshlink_get_port(void) {
+ const struct CMUnitTest blackbox_get_port_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_port_01, NULL, NULL,
+ (void *)&test_mesh_get_port_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_port_02, NULL, NULL,
+ (void *)&test_mesh_get_port_02_state)
+ };
+
+ total_tests += sizeof(blackbox_get_port_tests) / sizeof(blackbox_get_port_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_get_port_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_GET_PORT_H
+#define TEST_CASES_GET_PORT_H
+
+/*
+ test_cases_get_port.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_get_port(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_get_port.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_get_self.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_get_self_01(void **state);
+static bool test_steps_mesh_get_self_01(void);
+static void test_case_mesh_get_self_02(void **state);
+static bool test_steps_mesh_get_self_02(void);
+
+/* State structure for meshlink_get_self Test Case #1 */
+static black_box_state_t test_mesh_get_self_01_state = {
+ .test_case_name = "test_case_mesh_get_self_01",
+};
+
+/* State structure for meshlink_get_self Test Case #2 */
+static black_box_state_t test_mesh_get_self_02_state = {
+ .test_case_name = "test_case_mesh_get_self_02",
+};
+
+/* Execute meshlink_get_self Test Case # 1 */
+static void test_case_mesh_get_self_01(void **state) {
+ execute_test(test_steps_mesh_get_self_01, state);
+}
+
+/* Test Steps for meshlink_get_self Test Case # 1
+
+ Test Steps:
+ 1. Open node instance
+ 2. Get node's self handle
+
+ Expected Result:
+ node handle of it's own is obtained
+*/
+static bool test_steps_mesh_get_self_01(void) {
+ meshlink_handle_t *mesh = meshlink_open("self_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh);
+
+ assert(meshlink_start(mesh));
+ meshlink_node_t *dest_node = meshlink_get_self(mesh);
+ assert_int_not_equal(dest_node, NULL);
+
+ if(strcmp(dest_node->name, "foo")) {
+ return false;
+ }
+
+ meshlink_close(mesh);
+ meshlink_destroy("self_conf");
+ return true;
+
+}
+
+/* Execute meshlink_get_self Test Case # 2 */
+static void test_case_mesh_get_self_02(void **state) {
+ execute_test(test_steps_mesh_get_self_02, state);
+}
+
+/* Test Steps for meshlink_get_self Test Case # 2
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Export and Import mutually
+
+ Expected Result:
+ Both the nodes imports successfully
+*/
+static bool test_steps_mesh_get_self_02(void) {
+ meshlink_node_t *dest_node = meshlink_get_self(NULL);
+ assert_int_equal(dest_node, NULL);
+
+ return true;
+}
+
+int test_meshlink_get_self(void) {
+ const struct CMUnitTest blackbox_get_self_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_self_01, NULL, NULL,
+ (void *)&test_mesh_get_self_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_get_self_02, NULL, NULL,
+ (void *)&test_mesh_get_self_02_state)
+ };
+
+ total_tests += sizeof(blackbox_get_self_tests) / sizeof(blackbox_get_self_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_get_self_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_GET_SELF_H
+#define TEST_CASES_GET_SELF_H
+
+/*
+ test_cases_get_self.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_get_self(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_hint_address.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_hint_address.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+/* Port number used in the structure */
+#define PORT 8000
+
+/* hint address used in the socket structure */
+#define ADDR "10.1.1.1"
+
+static void test_case_hint_address_01(void **state);
+static bool test_steps_hint_address_01(void);
+
+static black_box_state_t test_case_hint_address_01_state = {
+ .test_case_name = "test_case_hint_address_01",
+};
+
+
+/* Execute meshlink_hint_address Test Case # 1 - Valid Case*/
+void test_case_hint_address_01(void **state) {
+ execute_test(test_steps_hint_address_01, state);
+}
+/* Test Steps for meshlink_hint_address Test Case # 1 - Valid case */
+bool test_steps_hint_address_01(void) {
+ meshlink_destroy("hintconf1");
+ meshlink_destroy("hintconf2");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance for the nodes
+ meshlink_handle_t *mesh1 = meshlink_open("hintconf1", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1);
+ meshlink_handle_t *mesh2 = meshlink_open("hintconf2", "bar", "test", DEV_CLASS_STATIONARY);
+ assert(mesh2);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // importing and exporting mesh meta data
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ assert(meshlink_import(mesh1, exp2));
+ assert(meshlink_import(mesh2, exp1));
+ free(exp1);
+ free(exp2);
+
+ // Nodes should learn about each other
+ sleep(1);
+
+ // Start the nodes
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+
+ // socket structure to be hinted
+ struct sockaddr_in hint;
+ hint.sin_family = AF_INET;
+ hint.sin_port = htons(PORT);
+ assert(inet_aton(ADDR, &hint.sin_addr));
+
+ // Getting node handle for the NUT itself
+ meshlink_node_t *node = meshlink_get_node(mesh1, "bar");
+ assert(node != NULL);
+
+ meshlink_hint_address(mesh_handle, node, (struct sockaddr *)&hint);
+
+ int fp;
+ fp = open("./hintconf1/hosts/bar", O_RDONLY);
+ assert(fp >= 0);
+ off_t fsize = lseek(fp, 0, SEEK_END);
+ assert(fsize >= 0);
+ char *buff = (char *) calloc(1, fsize + 1);
+ assert(buff != NULL);
+ assert(lseek(fp, 0, SEEK_SET) == 0);
+ assert(read(fp, buff, fsize) >= 0);
+ buff[fsize] = '\0';
+ assert(close(fp) != -1);
+
+ assert_int_not_equal(strstr(buff, ADDR), NULL);
+
+ free(buff);
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("hintconf1");
+ meshlink_destroy("hintconf2");
+
+ return true;
+}
+
+
+int test_meshlink_hint_address(void) {
+ const struct CMUnitTest blackbox_hint_address_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_hint_address_01, NULL, NULL,
+ (void *)&test_case_hint_address_01_state)
+ };
+
+ total_tests += sizeof(blackbox_hint_address_tests) / sizeof(blackbox_hint_address_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_hint_address_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_HINT_H
+#define TEST_CASES_HINT_H
+
+/*
+ test_cases_hint_address.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_hint_address(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_import.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_import.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_import_01(void **state);
+static bool test_import_01(void);
+static void test_case_import_02(void **state);
+static bool test_import_02(void);
+static void test_case_import_03(void **state);
+static bool test_import_03(void);
+static void test_case_import_04(void **state);
+static bool test_import_04(void);
+static void test_case_import_05(void **state);
+static bool test_import_05(void);
+static void test_case_import_06(void **state);
+static bool test_import_06(void);
+
+/* State structure for import API Test Case #1 */
+static black_box_state_t test_case_import_01_state = {
+ .test_case_name = "test_case_import_01",
+};
+/* State structure for import API Test Case #2 */
+static black_box_state_t test_case_import_02_state = {
+ .test_case_name = "test_case_import_02",
+};
+/* State structure for import API Test Case #3 */
+static black_box_state_t test_case_import_03_state = {
+ .test_case_name = "test_case_import_03",
+};
+/* State structure for import API Test Case #4 */
+static black_box_state_t test_case_import_04_state = {
+ .test_case_name = "test_case_import_04",
+};
+/* State structure for import API Test Case #5 */
+static black_box_state_t test_case_import_05_state = {
+ .test_case_name = "test_case_import_05",
+};
+/* State structure for import API Test Case #6 */
+static black_box_state_t test_case_import_06_state = {
+ .test_case_name = "test_case_import_06",
+};
+
+
+/* Execute import Test Case # 1 - valid case*/
+static void test_case_import_01(void **state) {
+ execute_test(test_import_01, state);
+}
+/* Test Steps for meshlink_import Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Export and Import mutually
+
+ Expected Result:
+ Both the nodes imports successfully
+*/
+static bool test_import_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+
+ // Opening NUT and bar nodes
+ meshlink_handle_t *mesh1 = meshlink_open("importconf1", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("importconf2", "bar", "test", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Exporting and Importing mutually
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ bool imp1 = meshlink_import(mesh1, exp2);
+ bool imp2 = meshlink_import(mesh2, exp1);
+
+ assert_int_equal(imp1 && imp2, true);
+
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+ return imp1 && imp2;
+}
+
+/* Execute import Test Case # 2 - invalid case*/
+static void test_case_import_02(void **state) {
+ execute_test(test_import_02, state);
+}
+/* Test Steps for meshlink_import Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Passing NULL as mesh handle argument for meshlink_import API
+
+ Expected Result:
+ Reports error successfully by returning false
+*/
+static bool test_import_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+
+ // Opening NUT and bar nodes
+ meshlink_handle_t *mesh1 = meshlink_open("importconf1", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("importconf2", "bar", "test", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Exporting & Importing nodes
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+
+ bool imp1 = meshlink_import(NULL, exp2);
+ bool imp2 = meshlink_import(mesh2, exp1);
+ assert_int_equal((!imp1) && imp2, true);
+
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+ return true;
+}
+
+
+/* Execute import Test Case # 3 - invalid case*/
+static void test_case_import_03(void **state) {
+ execute_test(test_import_03, state);
+}
+/* Test Steps for meshlink_import Test Case # 3 - Invalid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Passing NULL as exported data argument for meshlink_import API
+
+ Expected Result:
+ Reports error successfully by returning false
+*/
+static bool test_import_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+
+ /* Opening NUT and bar nodes */
+ meshlink_handle_t *mesh1 = meshlink_open("importconf1", "nut", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("importconf2", "bar", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Exporting & Importing nodes */
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+
+ bool imp1 = meshlink_import(mesh1, NULL);
+ bool imp2 = meshlink_import(mesh2, exp1);
+
+ assert_int_equal((!imp1) && imp2, true);
+
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+ return true;
+}
+
+/* Execute import Test Case # 4 - invalid case garbage string*/
+static void test_case_import_04(void **state) {
+ execute_test(test_import_04, state);
+}
+/* Test Steps for meshlink_import Test Case # 4 - Invalid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Passing some garbage string(NULL terminated)
+ as an argument for meshlink_import API
+
+ Expected Result:
+ Reports error successfully by returning false
+*/
+static bool test_import_04(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+
+ // Opening NUT and bar nodes
+ meshlink_handle_t *mesh1 = meshlink_open("importconf1", "nut", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("importconf2", "bar", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Exporting & Importing nodes
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+
+ // Importing NUT with garbage string as exported data argument
+ bool imp1 = meshlink_import(mesh1, "1/2/3");
+ bool imp2 = meshlink_import(mesh2, exp1);
+ assert_int_equal((!imp1) && imp2, true);
+
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+ return true;
+}
+
+/* Execute import Test Case # 5 - valid case*/
+static void test_case_import_05(void **state) {
+ execute_test(test_import_05, state);
+}
+/* Test Steps for meshlink_import Test Case # 5 - Invalid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test) & bar meshes.
+ 2. Export and Import mutually
+ 2. Try to import NUT again/twice at 'bar' node
+
+ Expected Result:
+ Reports error successfully by returning false
+*/
+static bool test_import_05(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+
+ /* Opening NUT and bar nodes */
+ meshlink_handle_t *mesh1 = meshlink_open("importconf1", "nut", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("importconf2", "bar", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Exporting & Importing nodes */
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ bool imp1 = meshlink_import(mesh1, exp2);
+ assert(imp1);
+ bool imp2 = meshlink_import(mesh2, exp1);
+ assert(imp2);
+
+ /** Trying to import twice **/
+ bool imp3 = meshlink_import(mesh2, exp1);
+
+ assert_int_equal(imp3, false);
+
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("importconf1");
+ meshlink_destroy("importconf2");
+ return true;
+}
+
+int test_meshlink_import(void) {
+ const struct CMUnitTest blackbox_import_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_import_01, NULL, NULL,
+ (void *)&test_case_import_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_import_02, NULL, NULL,
+ (void *)&test_case_import_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_import_03, NULL, NULL,
+ (void *)&test_case_import_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_import_04, NULL, NULL,
+ (void *)&test_case_import_04_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_import_05, NULL, NULL,
+ (void *)&test_case_import_05_state)
+ };
+ total_tests += sizeof(blackbox_import_tests) / sizeof(blackbox_import_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_import_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_IMPORT_H
+#define TEST_CASES_IMPORT_H
+
+/*
+ test_cases_import.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_import(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_invite.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_invite.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_invite_01(void **state);
+static bool test_invite_01(void);
+static void test_case_invite_02(void **state);
+static bool test_invite_02(void);
+static void test_case_invite_03(void **state);
+static bool test_invite_03(void);
+static void test_case_invite_04(void **state);
+static bool test_invite_04(void);
+
+/* State structure for invite API Test Case #1 */
+static black_box_state_t test_case_invite_01_state = {
+ .test_case_name = "test_case_invite_01",
+};
+
+/* State structure for invite API Test Case #2 */
+static black_box_state_t test_case_invite_02_state = {
+ .test_case_name = "test_case_invite_02",
+};
+
+/* State structure for invite API Test Case #3 */
+static black_box_state_t test_case_invite_03_state = {
+ .test_case_name = "test_case_invite_03",
+};
+
+/* State structure for invite API Test Case #4 */
+static black_box_state_t test_case_invite_04_state = {
+ .test_case_name = "test_case_invite_04",
+};
+
+/* Execute invite Test Case # 1 - valid case*/
+static void test_case_invite_01(void **state) {
+ execute_test(test_invite_01, state);
+}
+/*Test Steps for meshlink_invite Test Case # 1 - Valid case
+ Test Steps:
+ 1. Run NUT
+ 2. Invite 'new' node
+
+ Expected Result:
+ Generates an invitation
+*/
+static bool test_invite_01(void) {
+ meshlink_destroy("inviteconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ meshlink_handle_t *mesh_handle = meshlink_open("inviteconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ char *invitation = meshlink_invite(mesh_handle, "new");
+ assert_int_equal(invitation, NULL);
+
+ free(invitation);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("inviteconf");
+ return true;
+}
+
+/* Execute invite Test Case # 2 - Invalid case*/
+static void test_case_invite_02(void **state) {
+ execute_test(test_invite_02, state);
+}
+/*Test Steps for meshlink_invite Test Case # 2 - Invalid case
+ Test Steps:
+ 1. Calling meshlink_invite API with NULL as mesh handle argument
+
+ Expected Result:
+ Reports appropriate error by returning NULL
+*/
+static bool test_invite_02(void) {
+ // Trying to generate INVITATION by passing NULL as mesh link handle
+ char *invitation = meshlink_invite(NULL, "nut");
+ assert_int_equal(invitation, NULL);
+
+ return true;
+}
+
+/* Execute invite Test Case # 3 - Invalid case*/
+static void test_case_invite_03(void **state) {
+ execute_test(test_invite_03, state);
+}
+/*Test Steps for meshlink_invite Test Case # 3 - Invalid case
+ Test Steps:
+ 1. Run NUT
+ 2. Call meshlink_invite with NULL node name argument
+
+ Expected Result:
+ Reports appropriate error by returning NULL
+*/
+static bool test_invite_03(void) {
+ meshlink_destroy("inviteconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ meshlink_handle_t *mesh_handle = meshlink_open("inviteconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Trying to generate INVITATION by passing NULL as mesh link handle
+ char *invitation = meshlink_invite(mesh_handle, NULL);
+ assert_int_equal(invitation, NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("inviteconf");
+ return true;
+}
+
+/* Execute invite Test Case # 4 - Functionality test*/
+static void test_case_invite_04(void **state) {
+ execute_test(test_invite_04, state);
+}
+/*Test Steps for meshlink_invite Test Case # 4 - Functionality test
+
+ Test Steps:
+ 1. Create node instance
+ 2. Add a new address to the mesh and invite a node
+ 3. Add another new address and invite a node
+
+ Expected Result:
+ Newly added address should be there in the invitation.
+*/
+static bool test_invite_04(void) {
+ meshlink_destroy("inviteconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ meshlink_handle_t *mesh_handle = meshlink_open("inviteconf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ char *hostname1 = "127.1.1.1";
+ bool ret = meshlink_add_address(mesh_handle, hostname1);
+ char *invitation = meshlink_invite(mesh_handle, "foo");
+ assert_int_not_equal(strstr(invitation, hostname1), NULL);
+
+ char *hostname2 = "127.1.2.3";
+ ret = meshlink_add_address(mesh_handle, hostname2);
+ invitation = meshlink_invite(mesh_handle, "bar");
+
+ // Verify we have both the added addresses
+ assert_int_not_equal(strstr(invitation, hostname1), NULL);
+ assert_int_not_equal(strstr(invitation, hostname2), NULL);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("inviteconf");
+
+ return true;
+}
+
+int test_meshlink_invite(void) {
+ const struct CMUnitTest blackbox_invite_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_invite_01, NULL, NULL,
+ (void *)&test_case_invite_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_invite_02, NULL, NULL,
+ (void *)&test_case_invite_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_invite_03, NULL, NULL,
+ (void *)&test_case_invite_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_invite_04, NULL, NULL,
+ (void *)&test_case_invite_04_state)
+ };
+
+ total_tests += sizeof(blackbox_invite_tests) / sizeof(blackbox_invite_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_invite_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_INVITE_H
+#define TEST_CASES_INVITE_H
+
+/*
+ test_cases_invite.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_invite(void);
+
+#endif
--- /dev/null
+/*
+ test_cases_join.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_join.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_meshlink_join_01(void **state);
+static bool test_meshlink_join_01(void);
+static void test_case_meshlink_join_02(void **state);
+static bool test_meshlink_join_02(void);
+static void test_case_meshlink_join_03(void **state);
+static bool test_meshlink_join_03(void);
+static void test_case_meshlink_join_04(void **state);
+static bool test_meshlink_join_04(void);
+
+/* State structure for join Test Case #1 */
+static black_box_state_t test_case_join_01_state = {
+ .test_case_name = "test_case_join_01",
+};
+
+/* State structure for join Test Case #1 */
+static black_box_state_t test_case_join_02_state = {
+ .test_case_name = "test_case_join_02",
+};
+
+/* State structure for join Test Case #1 */
+static black_box_state_t test_case_join_03_state = {
+ .test_case_name = "test_case_join_03",
+};
+
+static bool join_status;
+
+/* status callback */
+static void status_callback(meshlink_handle_t *mesh, meshlink_node_t *source, bool reach) {
+ (void)mesh;
+
+ if(!strcmp(source->name, "relay")) {
+ join_status = reach;
+ }
+}
+
+/* Execute join Test Case # 1 - valid case*/
+static void test_case_meshlink_join_01(void **state) {
+ execute_test(test_meshlink_join_01, state);
+}
+
+/* Test Steps for meshlink_join Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Generate invite in relay container and run 'relay' node
+ 2. Run NUT
+ 3. Join NUT with relay using invitation generated.
+
+ Expected Result:
+ NUT joins relay using the invitation generated.
+*/
+static bool test_meshlink_join_01(void) {
+ meshlink_destroy("join_conf.1");
+ meshlink_destroy("join_conf.2");
+
+ // Create node instances
+ meshlink_handle_t *mesh1 = meshlink_open("join_conf.1", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("join_conf.2", "relay", "test", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Setting node status callback
+ meshlink_set_node_status_cb(mesh1, status_callback);
+
+ // Inviting nut
+ meshlink_start(mesh2);
+ char *invitation = meshlink_invite(mesh2, "nut");
+ assert(invitation);
+
+ // Joining Node-Under-Test with relay
+ bool ret = meshlink_join(mesh1, invitation);
+ assert_int_equal(ret, true);
+ assert(meshlink_start(mesh1));
+ sleep(1);
+
+ assert_int_equal(join_status, true);
+
+ free(invitation);
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("join_conf.1");
+ meshlink_destroy("join_conf.2");
+
+ return true;
+}
+
+/* Execute join Test Case # 2 - Invalid case*/
+static void test_case_meshlink_join_02(void **state) {
+ execute_test(test_meshlink_join_02, state);
+}
+
+/* Test Steps for meshlink_join Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Call meshlink_join with NULL as mesh handler argument.
+
+ Expected Result:
+ report error accordingly when NULL is passed as mesh handle argument
+*/
+static bool test_meshlink_join_02(void) {
+ meshlink_destroy("join_conf.3");
+
+ // Create node instances
+ meshlink_handle_t *mesh1 = meshlink_open("join_conf.3", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ char *invitation = meshlink_invite(mesh1, "nodex");
+
+ /* meshlink_join called with NULL as mesh handle and with valid invitation */
+ bool ret = meshlink_join(NULL, invitation);
+ assert_int_equal(ret, false);
+
+ free(invitation);
+ meshlink_close(mesh1);
+ meshlink_destroy("join_conf.3");
+
+ return true;
+}
+
+/* Execute join Test Case # 3- Invalid case*/
+static void test_case_meshlink_join_03(void **state) {
+ execute_test(test_meshlink_join_03, state);
+}
+
+/* Test Steps for meshlink_join Test Case # 3 - Invalid case
+
+ Test Steps:
+ 1. Run NUT
+ 1. Call meshlink_join with NULL as invitation argument.
+
+ Expected Result:
+ Report error accordingly when NULL is passed as invite argument
+*/
+static bool test_meshlink_join_03(void) {
+ meshlink_destroy("joinconf.4");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ mesh_handle = meshlink_open("joinconf.4", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Passing NULL as invitation to join API*/
+ bool ret = meshlink_join(mesh_handle, NULL);
+ assert_int_equal(ret, false);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("joinconf.4");
+ return true;
+}
+
+int test_meshlink_join(void) {
+ const struct CMUnitTest blackbox_join_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_meshlink_join_01, NULL, NULL,
+ (void *)&test_case_join_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meshlink_join_02, NULL, NULL,
+ (void *)&test_case_join_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_meshlink_join_03, NULL, NULL,
+ (void *)&test_case_join_03_state)
+ };
+ total_tests += sizeof(blackbox_join_tests) / sizeof(blackbox_join_tests[0]);
+
+ int failed = cmocka_run_group_tests(blackbox_join_tests, NULL, NULL);
+
+ return failed;
+}
+
--- /dev/null
+#ifndef TEST_CASES_JOIN_H
+#define TEST_CASES_JOIN_H
+
+/*
+ test_cases_join.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_join(void);
+extern int total_tests;
+
+
+#endif
--- /dev/null
+/*
+ test_cases_open.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_open.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_mesh_open_01(void **state);
+static bool test_steps_mesh_open_01(void);
+static void test_case_mesh_open_02(void **state);
+static bool test_steps_mesh_open_02(void);
+static void test_case_mesh_open_03(void **state);
+static bool test_steps_mesh_open_03(void);
+static void test_case_mesh_open_04(void **state);
+static bool test_steps_mesh_open_04(void);
+static void test_case_mesh_open_05(void **state);
+static bool test_steps_mesh_open_05(void);
+
+/* State structure for meshlink_open Test Case #1 */
+static black_box_state_t test_mesh_open_01_state = {
+ .test_case_name = "test_case_mesh_open_01",
+};
+
+/* State structure for meshlink_open Test Case #2 */
+static black_box_state_t test_mesh_open_02_state = {
+ .test_case_name = "test_case_mesh_open_02",
+};
+
+/* State structure for meshlink_open Test Case #3 */
+static black_box_state_t test_mesh_open_03_state = {
+ .test_case_name = "test_case_mesh_open_03",
+};
+
+/* State structure for meshlink_open Test Case #4 */
+static black_box_state_t test_mesh_open_04_state = {
+ .test_case_name = "test_case_mesh_open_04",
+};
+
+/* State structure for meshlink_open Test Case #5 */
+static black_box_state_t test_mesh_open_05_state = {
+ .test_case_name = "test_case_mesh_open_05",
+};
+
+/* Execute meshlink_open Test Case # 1*/
+static void test_case_mesh_open_01(void **state) {
+ execute_test(test_steps_mesh_open_01, state);
+}
+
+/* Test Steps for meshlink_open Test Case # 1
+
+ Test Steps:
+ 1. Open the node instance using meshlink_open
+
+ Expected Result:
+ meshlink_open API should successfully return a mesh handle.
+*/
+static bool test_steps_mesh_open_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh = meshlink_open("open_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert_int_not_equal(mesh, NULL);
+
+ meshlink_close(mesh);
+ meshlink_destroy("open_conf");
+ return true;
+}
+
+/* Execute meshlink_open Test Case # 2*/
+static void test_case_mesh_open_02(void **state) {
+ execute_test(test_steps_mesh_open_02, state);
+}
+
+/* Test Steps for meshlink_open Test Case # 2
+
+ Test Steps:
+ 1. Open the node instance using meshlink_open with NULL as confbase argument
+
+ Expected Result:
+ meshlink_open API should successfully report error by returning NULL pointer
+*/
+static bool test_steps_mesh_open_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh = meshlink_open(NULL, "foo", "test", DEV_CLASS_STATIONARY);
+ assert_int_equal(mesh, NULL);
+
+ return true;
+}
+
+/* Execute meshlink_open Test Case # 3 */
+static void test_case_mesh_open_03(void **state) {
+ execute_test(test_steps_mesh_open_03, state);
+}
+
+/* Test Steps for meshlink_open Test Case # 3
+
+ Test Steps:
+ 1. Open the node instance using meshlink_open with NULL as node name argument
+
+ Expected Result:
+ meshlink_open API should successfully report error by returning NULL pointer
+*/
+static bool test_steps_mesh_open_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh = meshlink_open("openconf", NULL, "test", DEV_CLASS_STATIONARY);
+ assert_int_equal(mesh, NULL);
+
+ meshlink_destroy("open_conf");
+ return true;
+}
+
+/* Execute meshlink_open Test Case # 4*/
+static void test_case_mesh_open_04(void **state) {
+ execute_test(test_steps_mesh_open_04, state);
+}
+
+/* Test Steps for meshlink_open Test Case # 4
+
+ Test Steps:
+ 1. Open the node instance using meshlink_open with NULL as app name argument
+
+ Expected Result:
+ meshlink_open API should successfully report error by returning NULL pointer
+*/
+static bool test_steps_mesh_open_04(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh = meshlink_open("openconf", "foo", NULL, DEV_CLASS_STATIONARY);
+ assert_int_equal(mesh, NULL);
+
+ meshlink_destroy("open_conf");
+ return true;
+}
+
+/* Execute meshlink_open Test Case # 5*/
+static void test_case_mesh_open_05(void **state) {
+ execute_test(test_steps_mesh_open_05, state);
+}
+
+/* Test Steps for meshlink_open Test Case # 5
+
+ Test Steps:
+ 1. Open the node instance using meshlink_open with invalid device class argument
+
+ Expected Result:
+ meshlink_open API should successfully report error by returning NULL pointer
+*/
+static bool test_steps_mesh_open_05(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh = meshlink_open("openconf", "foo", "test", -1);
+ assert_int_equal(mesh, NULL);
+
+ meshlink_destroy("open_conf");
+ return true;
+}
+
+int test_meshlink_open(void) {
+ const struct CMUnitTest blackbox_open_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_open_01, NULL, NULL,
+ (void *)&test_mesh_open_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_open_02, NULL, NULL,
+ (void *)&test_mesh_open_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_open_03, NULL, NULL,
+ (void *)&test_mesh_open_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_open_04, NULL, NULL,
+ (void *)&test_mesh_open_04_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_open_05, NULL, NULL,
+ (void *)&test_mesh_open_05_state)
+
+ };
+ total_tests += sizeof(blackbox_open_tests) / sizeof(blackbox_open_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_open_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_OPEN_H
+#define TEST_CASES_OPEN_H
+
+/*
+ test_cases_open.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_open(void);
+extern int total_tests;
+
+#endif // TEST_STEP_OPEN_H
--- /dev/null
+/*
+ test_cases_pmtu.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_pmtu.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_pmtu_01(void **state);
+static bool test_steps_mesh_pmtu_01(void);
+static void test_case_mesh_pmtu_02(void **state);
+static bool test_steps_mesh_pmtu_02(void);
+static void test_case_mesh_pmtu_03(void **state);
+static bool test_steps_mesh_pmtu_03(void);
+
+/* State structure for meshlink_get_pmtu Test Case #1 */
+static black_box_state_t test_mesh_pmtu_01_state = {
+ .test_case_name = "test_case_mesh_pmtu_01",
+};
+
+/* State structure for meshlink_get_pmtu Test Case #2 */
+static black_box_state_t test_mesh_pmtu_02_state = {
+ .test_case_name = "test_case_mesh_pmtu_02",
+};
+
+/* State structure for meshlink_get_pmtu Test Case #3 */
+static black_box_state_t test_mesh_pmtu_03_state = {
+ .test_case_name = "test_case_mesh_pmtu_03",
+};
+
+/* Execute meshlink_get_pmtu Test Case # 1 */
+static void test_case_mesh_pmtu_01(void **state) {
+ execute_test(test_steps_mesh_pmtu_01, state);
+}
+
+/* Test Steps for meshlink_get_pmtu Test Case # 1
+
+ Test Steps:
+ 1. Create node instance & get self handle
+ 2. Obtain MTU size
+
+ Expected Result:
+ meshlink_get_pmtu should return valid MTU size of a node
+*/
+static bool test_steps_mesh_pmtu_01(void) {
+ meshlink_handle_t *mesh = meshlink_open("pmtu_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ assert(meshlink_start(mesh));
+ meshlink_node_t *dest_node = meshlink_get_self(mesh);
+ assert(dest_node != NULL);
+
+ ssize_t pmtu = meshlink_get_pmtu(mesh, dest_node);
+ assert_int_not_equal(pmtu, -1);
+
+ meshlink_close(mesh);
+ meshlink_destroy("pmtu_conf");
+ return true;
+}
+
+/* Execute meshlink_get_pmtu Test Case # 2
+
+ Test Steps:
+ 1. Create node instance & get self handle
+ 2. Try to obtain MTU size by passing NULL as mesh handle to API
+
+ Expected Result:
+ meshlink_get_pmtu should return -1 reporting the error
+*/
+static void test_case_mesh_pmtu_02(void **state) {
+ execute_test(test_steps_mesh_pmtu_02, state);
+}
+
+/* Test Steps for meshlink_get_pmtu Test Case # 2*/
+static bool test_steps_mesh_pmtu_02(void) {
+ meshlink_handle_t *mesh = meshlink_open("pmtu_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ assert(meshlink_start(mesh));
+ meshlink_node_t *dest_node = meshlink_get_self(mesh);
+ assert(dest_node != NULL);
+
+ ssize_t pmtu = meshlink_get_pmtu(NULL, dest_node);
+ assert_int_equal(pmtu, -1);
+
+ meshlink_close(mesh);
+ meshlink_destroy("pmtu_conf");
+ return true;
+}
+
+/* Execute meshlink_get_pmtu Test Case # 3 */
+static void test_case_mesh_pmtu_03(void **state) {
+ execute_test(test_steps_mesh_pmtu_03, state);
+}
+
+/* Test Steps for meshlink_get_pmtu Test Case # 3
+
+ Test Steps:
+ 1. Create node instance & get self handle
+ 2. Try to obtain MTU size by passing NULL as node handle to API
+
+ Expected Result:
+ meshlink_get_pmtu should return -1 reporting the error
+*/
+static bool test_steps_mesh_pmtu_03(void) {
+ meshlink_handle_t *mesh = meshlink_open("pmtu_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ assert(meshlink_start(mesh));
+
+ ssize_t pmtu = meshlink_get_pmtu(mesh, NULL);
+ assert_int_equal(pmtu, -1);
+
+ meshlink_close(mesh);
+ meshlink_destroy("pmtu_conf");
+ return true;
+}
+
+int test_meshlink_pmtu(void) {
+ const struct CMUnitTest blackbox_pmtu_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_pmtu_01, NULL, NULL,
+ (void *)&test_mesh_pmtu_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_pmtu_02, NULL, NULL,
+ (void *)&test_mesh_pmtu_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_pmtu_03, NULL, NULL,
+ (void *)&test_mesh_pmtu_03_state)
+ };
+
+ total_tests += sizeof(blackbox_pmtu_tests) / sizeof(blackbox_pmtu_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_pmtu_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_PMTU_H
+#define TEST_CASES_PMTU_H
+
+/*
+ test_cases_pmtu.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_pmtu(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+/*
+ test_cases_rec_cb.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "execute_tests.h"
+#include "test_cases.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "test_cases_rec_cb.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_set_rec_cb_01(void **state);
+static bool test_set_rec_cb_01(void);
+static void test_case_set_rec_cb_02(void **state);
+static bool test_set_rec_cb_02(void);
+static void test_case_set_rec_cb_03(void **state);
+static bool test_set_rec_cb_03(void);
+static void test_case_set_rec_cb_04(void **state);
+static bool test_set_rec_cb_04(void);
+
+/* Test Steps for meshlink_set_receive_cb Test Case #1 */
+static black_box_state_t test_case_set_rec_cb_01_state = {
+ .test_case_name = "test_case_set_rec_cb_01",
+};
+
+/* Test Steps for meshlink_set_receive_cb Test Case #2 */
+static black_box_state_t test_case_set_rec_cb_02_state = {
+ .test_case_name = "test_case_set_rec_cb_02",
+};
+
+/* Test Steps for meshlink_set_receive_cb Test Case #3 */
+static black_box_state_t test_case_set_rec_cb_03_state = {
+ .test_case_name = "test_case_set_rec_cb_03",
+};
+
+static bool received;
+
+/* mutex for the common variable */
+pthread_mutex_t lock;
+
+/* receive callback function */
+static void rec_cb(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
+ assert(len);
+
+ pthread_mutex_lock(&lock);
+
+ if(len == 5 && !memcmp(data, "test", 5)) {
+ received = true;
+ }
+
+ pthread_mutex_unlock(&lock);
+}
+
+/* Execute meshlink_set_receive_cb Test Case # 1 - Valid case */
+static void test_case_set_rec_cb_01(void **state) {
+ execute_test(test_set_rec_cb_01, state);
+}
+/* Test Steps for meshlink_set_receive_cb Test Case # 1
+
+ Test Steps:
+ 1. Open NUT
+ 2. Set receive callback for the NUT
+ 3. Echo NUT with some data.
+
+ Expected Result:
+ Receive callback should be invoked when NUT echoes or sends data for itself.
+*/
+static bool test_set_rec_cb_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("set_receive_cb_conf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_receive_cb(mesh_handle, rec_cb);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ assert(meshlink_start(mesh_handle));
+ sleep(1);
+
+ pthread_mutex_lock(&lock);
+ received = false;
+ pthread_mutex_unlock(&lock);
+ meshlink_node_t *node_handle = meshlink_get_self(mesh_handle);
+ assert(node_handle);
+ assert(meshlink_send(mesh_handle, node_handle, "test", 5));
+ sleep(1);
+
+ pthread_mutex_lock(&lock);
+ assert_int_equal(received, true);
+ pthread_mutex_unlock(&lock);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("set_receive_cb_conf");
+ return true;
+}
+
+
+/* Execute meshlink_set_receive_cb Test Case # 2 - Invalid case */
+static void test_case_set_rec_cb_02(void **state) {
+ execute_test(test_set_rec_cb_02, state);
+}
+/* Test Steps for meshlink_set_receive_cb Test Case # 2
+
+ Test Steps:
+ 1. Call meshlink_set_receive_cb with NULL as mesh handle argument
+
+ Expected Result:
+ meshlink_set_receive_cb API reports proper error accordingly.
+*/
+static bool test_set_rec_cb_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Setting receive callback with NULL as mesh handle
+ meshlink_set_receive_cb(NULL, rec_cb);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ return true;
+}
+
+/* Execute meshlink_set_receive_cb Test Case # 3 - Functionality Test, Trying to set receive call back after
+ starting the mesh */
+static void test_case_set_rec_cb_03(void **state) {
+ execute_test(test_set_rec_cb_03, state);
+}
+/* Test Steps for meshlink_set_receive_cb Test Case # 3
+
+ Test Steps:
+ 1. Open NUT
+ 2. Starting mesh
+ 2. Set receive callback for the NUT
+ 3. Echo NUT with some data.
+
+ Expected Result:
+ Receive callback can be invoked when NUT echoes or sends data for itself
+*/
+static bool test_set_rec_cb_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ /* Create meshlink instance */
+ meshlink_handle_t *mesh_handle = meshlink_open("set_receive_cb_conf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ assert(meshlink_start(mesh_handle));
+ sleep(1);
+ meshlink_set_receive_cb(mesh_handle, rec_cb);
+
+ pthread_mutex_lock(&lock);
+ received = false;
+ pthread_mutex_unlock(&lock);
+ meshlink_node_t *node_handle = meshlink_get_self(mesh_handle);
+ assert(node_handle);
+ assert(meshlink_send(mesh_handle, node_handle, "test", 5));
+ sleep(1);
+
+ pthread_mutex_lock(&lock);
+ assert_int_equal(received, true);
+ pthread_mutex_unlock(&lock);
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("set_receive_cb_conf");
+ return true;
+}
+
+int test_meshlink_set_receive_cb(void) {
+ const struct CMUnitTest blackbox_receive_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_rec_cb_01, NULL, NULL,
+ (void *)&test_case_set_rec_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_rec_cb_02, NULL, NULL,
+ (void *)&test_case_set_rec_cb_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_rec_cb_03, NULL, NULL,
+ (void *)&test_case_set_rec_cb_03_state)
+ };
+ total_tests += sizeof(blackbox_receive_tests) / sizeof(blackbox_receive_tests[0]);
+
+ assert(pthread_mutex_init(&lock, NULL) == 0);
+ int failed = cmocka_run_group_tests(blackbox_receive_tests, NULL, NULL);
+ assert(pthread_mutex_destroy(&lock) == 0);
+
+ return failed;
+}
--- /dev/null
+#ifndef TEST_CASES_SET_REC_CB_H
+#define TEST_CASES_SET_REC_CB_H
+
+/*
+ test_cases_rec_cb.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_set_receive_cb(void);
+extern int total_tests;
+
+#endif // TEST_CASES_SET_REC_CB_H
--- /dev/null
+/*
+ test_cases_send.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_send.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_send_01(void **state);
+static bool test_steps_mesh_send_01(void);
+static void test_case_mesh_send_02(void **state);
+static bool test_steps_mesh_send_02(void);
+static void test_case_mesh_send_03(void **state);
+static bool test_steps_mesh_send_03(void);
+
+/* State structure for meshlink_send Test Case #1 */
+static black_box_state_t test_mesh_send_01_state = {
+ .test_case_name = "test_case_mesh_send_01",
+};
+
+/* State structure for meshlink_send Test Case #2 */
+static black_box_state_t test_mesh_send_02_state = {
+ .test_case_name = "test_case_mesh_send_02",
+};
+
+/* State structure for meshlink_send Test Case #3 */
+static black_box_state_t test_mesh_send_03_state = {
+ .test_case_name = "test_case_mesh_send_03",
+};
+
+/* State structure for meshlink_send Test Case #4 */
+static black_box_state_t test_mesh_send_04_state = {
+ .test_case_name = "test_case_mesh_send_04",
+};
+
+/* State structure for meshlink_send Test Case #5 */
+static black_box_state_t test_mesh_send_05_state = {
+ .test_case_name = "test_case_mesh_send_05",
+};
+
+/* State structure for meshlink_send Test Case #6 */
+static black_box_state_t test_mesh_send_06_state = {
+ .test_case_name = "test_case_mesh_send_06",
+};
+
+/* Execute meshlink_send Test Case # 1 */
+static void test_case_mesh_send_01(void **state) {
+ execute_test(test_steps_mesh_send_01, state);
+}
+
+static bool receive_data = false;
+static void receive(meshlink_handle_t *mesh, meshlink_node_t *dest_node, const void *data, size_t len) {
+ const char *msg = data;
+
+ assert(len);
+
+ if(!memcmp(data, "test", 5)) {
+ receive_data = true;
+ }
+}
+
+/* Test Steps for meshlink_send Test Case # 1
+
+ Test Steps:
+ 1. Open instance of foo node
+ 2. Run and send data to itself
+
+ Expected Result:
+ Node should receive data sent to itself
+*/
+static bool test_steps_mesh_send_01(void) {
+ bool result = false;
+
+ meshlink_handle_t *mesh = meshlink_open("send_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+ meshlink_set_receive_cb(mesh, receive);
+ assert(meshlink_start(mesh));
+ sleep(1);
+ meshlink_node_t *dest_node = meshlink_get_self(mesh);
+ assert(dest_node);
+
+ receive_data = false;
+ result = meshlink_send(mesh, dest_node, "test", 5);
+ assert_int_equal(result, true);
+ sleep(1);
+ assert_int_equal(receive_data, true);
+
+ meshlink_close(mesh);
+ meshlink_destroy("send_conf");
+ return result;
+}
+
+/* Execute meshlink_send Test Case # 2
+
+ Test Steps:
+ 1. Open instance of foo node
+ 2. meshlink_send with NULL as mesh handle
+
+ Expected Result:
+ meshlink_send returns false because of NULL handle
+*/
+static void test_case_mesh_send_02(void **state) {
+ execute_test(test_steps_mesh_send_02, state);
+}
+
+/* Test Steps for meshlink_send Test Case # 2*/
+static bool test_steps_mesh_send_02(void) {
+ meshlink_handle_t *mesh = meshlink_open("send_conf", "foo", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+ meshlink_set_receive_cb(mesh, receive);
+
+ assert(meshlink_start(mesh));
+ meshlink_node_t *dest_node = meshlink_get_self(mesh);
+ assert(dest_node);
+
+ bool ret = meshlink_send(NULL, dest_node, "test", 5);
+ assert_int_equal(ret, false);
+
+ meshlink_close(mesh);
+ meshlink_destroy("send_conf");
+ return true;
+}
+
+/* Execute meshlink_send Test Case # 3
+
+ Test Steps:
+ 1. Open instance of foo node
+ 2. meshlink_send with NULL as node handle
+
+ Expected Result:
+ meshlink_send returns false because of NULL handle
+*/
+static void test_case_mesh_send_03(void **state) {
+ execute_test(test_steps_mesh_send_03, state);
+}
+
+/* Test Steps for meshlink_send Test Case # 3*/
+static bool test_steps_mesh_send_03(void) {
+ meshlink_handle_t *mesh = meshlink_open("send_conf", "foo", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+ meshlink_set_receive_cb(mesh, receive);
+
+ assert(meshlink_start(mesh));
+
+ bool ret = meshlink_send(mesh, NULL, "test", 5);
+ assert_int_equal(ret, false);
+
+ meshlink_close(mesh);
+ meshlink_destroy("send_conf");
+ return true;
+}
+
+int test_meshlink_send(void) {
+ const struct CMUnitTest blackbox_send_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_send_01, NULL, NULL,
+ (void *)&test_mesh_send_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_send_02, NULL, NULL,
+ (void *)&test_mesh_send_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_send_03, NULL, NULL,
+ (void *)&test_mesh_send_03_state)
+ };
+
+ total_tests += sizeof(blackbox_send_tests) / sizeof(blackbox_send_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_send_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_SEND_H
+#define TEST_CASES_SEND_H
+
+/*
+ test_cases_send.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_send(void);
+extern int total_tests;
+
+
+#endif
--- /dev/null
+/*
+ test_cases_set_log_cb.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_set_log_cb.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_set_log_cb_01(void **state);
+static bool test_set_log_cb_01(void);
+static void test_case_set_log_cb_02(void **state);
+static bool test_set_log_cb_02(void);
+static void test_case_set_log_cb_03(void **state);
+static bool test_set_log_cb_03(void);
+
+/* log variable gives access to the log callback to know whether invoked or not */
+static bool log;
+
+/* State structure for log callback Test Case #1 */
+static black_box_state_t test_case_set_log_cb_01_state = {
+ .test_case_name = "test_case_set_log_cb_01",
+};
+
+/* State structure for log callback Test Case #2 */
+static black_box_state_t test_case_set_log_cb_02_state = {
+ .test_case_name = "test_case_set_log_cb_02",
+};
+
+
+/* log callback */
+static void log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) {
+ fprintf(stderr, "Received log text : %s\n", text);
+ log = true;
+}
+
+/* Execute meshlink_set_log_cb Test Case # 1 - Valid case */
+static void test_case_set_log_cb_01(void **state) {
+ execute_test(test_set_log_cb_01, state);
+}
+/* Test Steps for meshlink_set_receive_cb Test Case # 1
+
+ Test Steps:
+ 1. Run relay and Open NUT
+ 2. Set log callback for the NUT and Start NUT
+
+ Expected Result:
+ log callback should be invoked when NUT joins with relay.
+*/
+static bool test_set_log_cb_01(void) {
+ meshlink_destroy("logconf");
+
+ // Create meshlink instance for NUT
+
+ meshlink_handle_t *mesh = meshlink_open("logconf", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh != NULL);
+
+ // Set up logging for Meshlink with the newly acquired Mesh Handle
+
+ log = false;
+ meshlink_set_log_cb(mesh, TEST_MESHLINK_LOG_LEVEL, log_cb);
+
+ // Starting node to log
+
+ bool mesh_start = meshlink_start(mesh);
+ assert(mesh_start);
+
+ bool ret = log;
+
+ assert_int_equal(ret, true);
+
+ // closing meshes and destroying confbase
+
+ meshlink_close(mesh);
+ meshlink_destroy("logconf");
+
+ return true;
+}
+
+/* Execute meshlink_set_log_cb Test Case # 2 - Invalid case */
+static void test_case_set_log_cb_02(void **state) {
+ execute_test(test_set_log_cb_02, state);
+}
+/* Test Steps for meshlink_set_poll_cb Test Case # 2
+
+ Test Steps:
+ 1. Calling meshlink_set_poll_cb with some invalid integer other than the valid enums.
+
+ Expected Result:
+ set poll callback handles the invalid parameter when called by giving proper error number.
+*/
+static bool test_set_log_cb_02(void) {
+
+ // Setting an invalid level
+
+ meshlink_set_log_cb(NULL, 1000, NULL);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ return true;
+}
+
+
+int test_meshlink_set_log_cb(void) {
+ const struct CMUnitTest blackbox_log_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_log_cb_01, NULL, NULL,
+ (void *)&test_case_set_log_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_log_cb_02, NULL, NULL,
+ (void *)&test_case_set_log_cb_02_state)
+ };
+ total_tests += sizeof(blackbox_log_tests) / sizeof(blackbox_log_tests[0]);
+
+ int failed = cmocka_run_group_tests(blackbox_log_tests, NULL, NULL);
+
+ return failed;
+}
--- /dev/null
+#ifndef TEST_CASES_SET_LOG_CB_H
+#define TEST_CASES_SET_LOG_CB_H
+
+/*
+ test_cases_set_log_cb.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_set_log_cb(void);
+extern int total_tests;
+
+#endif // TEST_CASES_SET_LOG_H
--- /dev/null
+/*
+ test_cases_set_port.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_destroy.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include "test_cases_set_port.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_set_port_01(void **state);
+static bool test_set_port_01(void);
+static void test_case_set_port_02(void **state);
+static bool test_set_port_02(void);
+static void test_case_set_port_03(void **state);
+static bool test_set_port_03(void);
+
+/* State structure for set port API Test Case #1 */
+static black_box_state_t test_case_set_port_01_state = {
+ .test_case_name = "test_case_set_port_01",
+};
+/* State structure for set port API Test Case #2 */
+static black_box_state_t test_case_set_port_02_state = {
+ .test_case_name = "test_case_set_port_02",
+};
+/* State structure for set port API Test Case #3 */
+static black_box_state_t test_case_set_port_03_state = {
+ .test_case_name = "test_case_set_port_03",
+};
+
+
+/* Execute meshlink_set_port Test Case # 1 - valid case*/
+static void test_case_set_port_01(void **state) {
+ execute_test(test_set_port_01, state);
+}
+/* Test Steps for meshlink_set_port Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Open NUT(Node Under Test)
+ 2. Set Port for NUT
+
+ Expected Result:
+ Set the new port to the NUT.
+*/
+static bool test_set_port_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+
+ mesh_handle = meshlink_open("setportconf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Get old port and set a new port number
+
+ int port;
+ port = meshlink_get_port(mesh_handle);
+ assert(port > 0);
+ bool ret = meshlink_set_port(mesh_handle, 8000);
+ port = meshlink_get_port(mesh_handle);
+
+ assert_int_equal(port, 8000);
+ assert_int_equal(ret, true);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("setportconf");
+ return true;
+}
+
+/* Execute meshlink_set_port Test Case # 2 - Invalid case*/
+static void test_case_set_port_02(void **state) {
+ execute_test(test_set_port_02, state);
+}
+
+/* Test Steps for meshlink_set_port Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Pass NULL as mesh handle argument for meshlink_set_port
+
+ Expected Result:
+ Report false indicating error.
+*/
+static bool test_set_port_02(void) {
+ // meshlink_set_port called using NULL as mesh handle
+
+ bool ret = meshlink_set_port(NULL, 8000);
+
+ assert_int_equal(ret, false);
+ return false;
+}
+
+
+/* Execute meshlink_set_port Test Case # 3 - Setting port after starting mesh*/
+static void test_case_set_port_03(void **state) {
+ execute_test(test_set_port_03, state);
+}
+
+/* Test Steps for meshlink_set_port Test Case # 2 - functionality test
+
+ Test Steps:
+ 1. Open and start NUT and then try to set new port number
+
+ Expected Result:
+ New port number cannot be set while mesh is running.
+*/
+static bool test_set_port_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+
+ mesh_handle = meshlink_open("getportconf", "nut", "test", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Setting port after starting NUT
+ bool ret = meshlink_set_port(mesh_handle, 50000);
+ assert_int_equal(ret, false);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("getportconf");
+}
+
+
+int test_meshlink_set_port(void) {
+ const struct CMUnitTest blackbox_set_port_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_port_01, NULL, NULL,
+ (void *)&test_case_set_port_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_port_02, NULL, NULL,
+ (void *)&test_case_set_port_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_port_03, NULL, NULL,
+ (void *)&test_case_set_port_03_state)
+ };
+ total_tests += sizeof(blackbox_set_port_tests) / sizeof(blackbox_set_port_tests[0]);
+ return cmocka_run_group_tests(blackbox_set_port_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_SET_PORT_H
+#define TEST_CASES_SET_PORT_H
+
+/*
+ test_cases_set_port.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_set_port(void);
+
+#endif // TEST_CASES_SET_PORT
--- /dev/null
+/*
+ test_cases_sign.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_sign.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_sign_01(void **state);
+static bool test_sign_01(void);
+static void test_case_sign_02(void **state);
+static bool test_sign_02(void);
+static void test_case_sign_03(void **state);
+static bool test_sign_03(void);
+static void test_case_sign_04(void **state);
+static bool test_sign_04(void);
+static void test_case_sign_05(void **state);
+static bool test_sign_05(void);
+static void test_case_sign_06(void **state);
+static bool test_sign_06(void);
+static void test_case_sign_07(void **state);
+static bool test_sign_07(void);
+
+/* State structure for sign API Test Case #1 */
+static black_box_state_t test_case_sign_01_state = {
+ .test_case_name = "test_case_sign_01",
+};
+
+/* State structure for sign API Test Case #2 */
+static black_box_state_t test_case_sign_02_state = {
+ .test_case_name = "test_case_sign_02",
+};
+
+/* State structure for sign API Test Case #3 */
+static black_box_state_t test_case_sign_03_state = {
+ .test_case_name = "test_case_sign_03",
+};
+
+/* State structure for sign API Test Case #4 */
+static black_box_state_t test_case_sign_04_state = {
+ .test_case_name = "test_case_sign_04",
+};
+
+/* State structure for sign API Test Case #5 */
+static black_box_state_t test_case_sign_05_state = {
+ .test_case_name = "test_case_sign_05",
+};
+
+/* State structure for sign API Test Case #6 */
+static black_box_state_t test_case_sign_06_state = {
+ .test_case_name = "test_case_sign_06",
+};
+
+/* State structure for sign API Test Case #7 */
+static black_box_state_t test_case_sign_07_state = {
+ .test_case_name = "test_case_sign_07",
+};
+
+
+/* Execute sign_data Test Case # 1 - Valid case - sign a data successfully*/
+static void test_case_sign_01(void **state) {
+ execute_test(test_sign_01, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Sign data
+
+ Expected Result:
+ Signs data successfully
+*/
+static bool test_sign_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ meshlink_handle_t *mesh_handle = meshlink_open("signconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Signing data
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+
+ // Clean up
+ meshlink_close(mesh_handle);
+ meshlink_destroy("signconf");
+
+ return ret;
+}
+
+/* Execute sign_data Test Case # 2 - Invalid case - meshlink_sign passing NULL as mesh handle argument*/
+static void test_case_sign_02(void **state) {
+ execute_test(test_sign_02, state);
+ return;
+}
+
+/* Test Steps for meshlink_sign Test Case # 2 - invalid case
+
+ Test Steps:
+ 1. meshlink_sign API called by passing NULL as mesh handle argument
+
+ Expected Result:
+ API returns false hinting the error.
+*/
+static bool test_sign_02(void) {
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+
+ // Calling meshlink_sign API
+ bool ret = meshlink_sign(NULL, data, strlen(data) + 1, sig, &ssize);
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing NULL as mesh_handle arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing NULL as mesh_handle arg\n");
+ return false;
+}
+
+/* Execute sign_data Test Case # 3 - Invalid case - meshlink_sign passing data to be signed as NULL */
+static void test_case_sign_03(void **state) {
+ execute_test(test_sign_03, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 3 - invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. meshlink_sign API called by passing NULL as data argument
+ that has to be signed.
+
+ Expected Result:
+ API returns false hinting the error.
+*/
+static bool test_sign_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ meshlink_handle_t *mesh_handle = meshlink_open("signconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Signing Data
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, NULL, strlen(data) + 1, sig, &ssize);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("signconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing NULL as data arg\n");
+ return true;
+ } else {
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing NULL as data arg\n");
+ return false;
+ }
+}
+
+/* Execute sign_data Test Case # 4 - Invalid case - meshlink_sign passing 0 as size of data
+ to be signed */
+static void test_case_sign_04(void **state) {
+ execute_test(test_sign_04, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 3 - invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. meshlink_sign API called by passing 0 as size of data to be signed
+
+ Expected Result:
+ API returns false hinting the error.
+*/
+static bool test_sign_04(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+
+ meshlink_handle_t *mesh_handle = meshlink_open("signconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Signing data
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, 0, sig, &ssize);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("signconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing 0 as size of data arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing 0 as size of data arg\n");
+ return false;
+}
+
+/* Execute sign_data Test Case # 5 - Invalid case - meshlink_sign passing NULL as
+ signature buffer argument*/
+static void test_case_sign_05(void **state) {
+ execute_test(test_sign_05, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 5 - invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. meshlink_sign API called by passing NULL for signature buffer argument
+
+ Expected Result:
+ API returns false hinting the error.
+*/
+static bool test_sign_05(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+
+ meshlink_handle_t *mesh_handle = meshlink_open("signconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Signing data
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, NULL, &ssize);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("signconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing NULL as sign arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing NULL as sign arg\n");
+ return false;
+}
+
+/* Execute sign_data Test Case # 6 - Invalid case - meshlink_sign passing NULL for size of
+ signature argument */
+static void test_case_sign_06(void **state) {
+ execute_test(test_sign_06, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 6 - invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. meshlink_sign API called by passing NULL for size of signature buffer argument
+
+ Expected Result:
+ API returns false hinting the error.
+*/
+static bool test_sign_06(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+ meshlink_handle_t *mesh_handle = meshlink_open("signconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Signing data
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, NULL);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("signconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing NULL as signsize arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing NULL as signsize arg\n");
+ return false;
+}
+
+/* Execute sign_data Test Case # 7 - Invalid case - meshlink_sign passing size of signature < MESHLINK_SIGLEN*/
+static void test_case_sign_07(void **state) {
+ execute_test(test_sign_07, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 6 - invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. meshlink_sign API called by passing size of signature < MESHLINK_SIGLEN
+
+ Expected Result:
+ API returns false hinting the error.
+*/
+static bool test_sign_07(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Create meshlink instance
+
+ meshlink_handle_t *mesh_handle = meshlink_open("signconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ // Signing data
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = 5; //5 < MESHLINK_SIGLEN
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+
+ // Cleanup
+
+ meshlink_stop(mesh_handle);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("signconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing signsize < MESHLINK_SIGLEN arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing signsize < MESHLINK_SIGLEN arg\n");
+ return false;
+}
+
+
+int test_meshlink_sign(void) {
+ const struct CMUnitTest blackbox_sign_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_01, NULL, NULL,
+ (void *)&test_case_sign_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_02, NULL, NULL,
+ (void *)&test_case_sign_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_03, NULL, NULL,
+ (void *)&test_case_sign_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_04, NULL, NULL,
+ (void *)&test_case_sign_04_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_05, NULL, NULL,
+ (void *)&test_case_sign_05_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_06, NULL, NULL,
+ (void *)&test_case_sign_06_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_sign_07, NULL, NULL,
+ (void *)&test_case_sign_07_state)
+ };
+ total_tests += sizeof(blackbox_sign_tests) / sizeof(blackbox_sign_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_sign_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_SIGN_H
+#define TEST_CASES_SIGN_H
+
+/*
+ test_cases_sign.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_sign(void);
+
+#endif // TEST_CASES_SIGN_H
--- /dev/null
+/*
+ test_cases_start.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_start.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+
+static void test_case_mesh_start_01(void **state);
+static bool test_steps_mesh_start_01(void);
+static void test_case_mesh_start_02(void **state);
+static bool test_steps_mesh_start_02(void);
+
+/* State structure for meshlink_start Test Case #1 */
+static black_box_state_t test_mesh_start_01_state = {
+ .test_case_name = "test_case_mesh_start_01",
+};
+
+/* State structure for meshlink_start Test Case #2 */
+static black_box_state_t test_mesh_start_02_state = {
+ .test_case_name = "test_case_mesh_start_02",
+};
+
+/* Execute meshlink_start Test Case # 1*/
+static void test_case_mesh_start_01(void **state) {
+ execute_test(test_steps_mesh_start_01, state);
+}
+
+/* Test Steps for meshlink_start Test Case # 1
+
+ Test Steps:
+ 1. Open Instance & start node
+
+ Expected Result:
+ Successfully node instance should be running
+*/
+static bool test_steps_mesh_start_01(void) {
+
+ // Open instance
+
+ bool result = false;
+ meshlink_handle_t *mesh = meshlink_open("start_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh);
+
+ // Run node instance
+
+ result = meshlink_start(mesh);
+
+ // Clean up
+ meshlink_close(mesh);
+ meshlink_destroy("start_conf");
+
+ if(!result) {
+ fprintf(stderr, "meshlink_start status1: %s\n", meshlink_strerror(meshlink_errno));
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/* Execute meshlink_start Test Case # 2*/
+static void test_case_mesh_start_02(void **state) {
+ execute_test(test_steps_mesh_start_02, state);
+}
+
+/* Test Steps for meshlink_start Test Case # 2
+
+ Test Steps:
+ 1. Calling meshlink_start with NULL as mesh handle argument.
+
+ Expected Result:
+ meshlink_start API handles the invalid parameter by returning false.
+*/
+static bool test_steps_mesh_start_02(void) {
+ bool result = false;
+ meshlink_destroy("start_conf");
+ meshlink_handle_t *mesh = meshlink_open("start_conf", "foo", "test", DEV_CLASS_STATIONARY);
+ assert(mesh);
+
+ // Run instance with NULL argument
+
+ result = meshlink_start(NULL);
+ assert_int_equal(result, true);
+
+ // Clean up
+
+ meshlink_close(mesh);
+ meshlink_destroy("start_conf");
+ return true;
+}
+
+int test_meshlink_start(void) {
+ const struct CMUnitTest blackbox_start_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_start_01, NULL, NULL,
+ (void *)&test_mesh_start_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_start_02, NULL, NULL,
+ (void *)&test_mesh_start_02_state)
+
+ };
+
+ total_tests += sizeof(blackbox_start_tests) / sizeof(blackbox_start_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_start_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_START_H
+#define TEST_CASES_START_H
+
+/*
+ test_cases_start.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_start(void);
+extern int total_tests;
+
+
+
+#endif
--- /dev/null
+/*
+ test_cases_status_cb.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_status_cb.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_set_status_cb_01(void **state);
+static bool test_set_status_cb_01(void);
+static void test_case_set_status_cb_02(void **state);
+static bool test_set_status_cb_02(void);
+
+/* status variable gives access to the status callback to know whether invoked or not */
+static bool status;
+
+/* State structure for status callback Test Case #1 */
+static black_box_state_t test_case_set_status_cb_01_state = {
+ .test_case_name = "test_case_set_status_cb_01",
+};
+
+/* State structure for status callback Test Case #2 */
+static black_box_state_t test_case_set_status_cb_02_state = {
+ .test_case_name = "test_case_set_status_cb_02",
+};
+
+
+static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *source, bool reach) {
+ fprintf(stderr, "In status callback\n");
+
+ if(reach) {
+ fprintf(stderr, "[ %s ] node reachable\n", source->name);
+ } else {
+ fprintf(stderr, "[ %s ] node not reachable\n", source->name) ;
+ }
+
+ status = reach;
+}
+
+/* Execute status callback Test Case # 1 - valid case */
+static void test_case_set_status_cb_01(void **state) {
+ execute_test(test_set_status_cb_01, state);
+}
+
+/* Test Steps for meshlink_set_status_cb Test Case # 1
+
+ Test Steps:
+ 1. Run bar and nut node instances
+ 2. Set status callback for the NUT and Start NUT
+
+ Expected Result:
+ status callback should be invoked when NUT connects/disconnects with 'relay' node.
+*/
+static bool test_set_status_cb_01(void) {
+ meshlink_destroy("set_status_cb_conf.1");
+ meshlink_destroy("set_status_cb_conf.2");
+
+ // Opening NUT and bar nodes
+ meshlink_handle_t *mesh1 = meshlink_open("set_status_cb_conf.1", "nut", "test", DEV_CLASS_STATIONARY);
+ assert(mesh1 != NULL);
+ meshlink_set_log_cb(mesh1, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("set_status_cb_conf.2", "bar", "test", DEV_CLASS_STATIONARY);
+ assert(mesh2 != NULL);
+ meshlink_set_log_cb(mesh2, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+
+ // Set up callback for node status
+ meshlink_set_node_status_cb(mesh1, status_cb);
+
+ // Exporting and Importing mutually
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ bool imp1 = meshlink_import(mesh1, exp2);
+ bool imp2 = meshlink_import(mesh2, exp1);
+
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+ sleep(1);
+
+ // Test for status from status callback
+ assert_int_equal(status, true);
+
+ meshlink_close(mesh2);
+ sleep(1);
+
+ // Test for status from status callback
+ assert_int_equal(status, false);
+
+ free(exp1);
+ free(exp2);
+ meshlink_close(mesh1);
+ meshlink_destroy("set_status_cb_conf.1");
+ meshlink_destroy("set_status_cb_conf.2");
+
+ return true;
+}
+
+/* Execute status callback Test Case # 2 - Invalid case */
+static void test_case_set_status_cb_02(void **state) {
+ execute_test(test_set_status_cb_02, state);
+}
+
+/* Test Steps for meshlink_set_status_cb Test Case # 2
+
+ Test Steps:
+ 1. Calling meshlink_set_status_cb with NULL as mesh handle argument.
+
+ Expected Result:
+ set poll callback handles the invalid parameter when called by giving proper error number.
+*/
+static bool test_set_status_cb_02(void) {
+
+ // Create meshlink instance
+
+ meshlink_destroy("set_status_cb_conf.3");
+ meshlink_handle_t *mesh_handle = meshlink_open("set_status_cb_conf.3", "nut", "node_sim", 1);
+ assert(mesh_handle);
+
+ // Pass NULL as meshlink_set_node_status_cb's argument
+
+ meshlink_set_node_status_cb(NULL, status_cb);
+ meshlink_errno_t meshlink_errno_buff = meshlink_errno;
+ assert_int_equal(meshlink_errno_buff, MESHLINK_EINVAL);
+
+ // Clean up
+
+ meshlink_close(mesh_handle);
+ meshlink_destroy("set_status_cb_conf.3");
+ return true;
+}
+
+
+int test_meshlink_set_status_cb(void) {
+ const struct CMUnitTest blackbox_status_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_status_cb_01, NULL, NULL,
+ (void *)&test_case_set_status_cb_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_set_status_cb_02, NULL, NULL,
+ (void *)&test_case_set_status_cb_02_state)
+ };
+ total_tests += sizeof(blackbox_status_tests) / sizeof(blackbox_status_tests[0]);
+
+ int failed = cmocka_run_group_tests(blackbox_status_tests, NULL, NULL);
+
+ return failed;
+}
--- /dev/null
+#ifndef TEST_CASES_SET_STATUS_CB_H
+#define TEST_CASES_SET_STATUS_CB_H
+
+/*
+ test_cases_status_cb.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_set_status_cb(void);
+extern int total_tests;
+
+#endif // TEST_CASES_SET_STATUS_CB_H
--- /dev/null
+/*
+ test_cases_stop_close.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_stop_close.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#define CLOSE_FILE_PATH "/home/sairoop/meshlink/test/blackbox/test_case_close/mesh_close"
+#define VALGRIND_LOG "valgrind.log"
+
+static void test_case_mesh_close_01(void **state);
+static bool test_steps_mesh_close_01(void);
+static void test_case_mesh_stop_01(void **state);
+static bool test_steps_mesh_stop_01(void);
+
+/* State structure for meshlink_close Test Case #1 */
+static black_box_state_t test_mesh_close_01_state = {
+ .test_case_name = "test_case_mesh_close_01",
+};
+
+/* State structure for meshlink_close Test Case #1 */
+static black_box_state_t test_mesh_stop_01_state = {
+ .test_case_name = "test_case_mesh_stop_01",
+};
+
+/* Execute meshlink_close Test Case # 1*/
+static void test_case_mesh_close_01(void **state) {
+ execute_test(test_steps_mesh_close_01, state);
+}
+
+/* Test Steps for meshlink_close Test Case # 1*/
+
+static bool test_steps_mesh_close_01(void) {
+ meshlink_close(NULL);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ return true;
+}
+
+/* Execute meshlink_stop Test Case # 1*/
+static void test_case_mesh_stop_01(void **state) {
+ execute_test(test_steps_mesh_stop_01, state);
+}
+
+/* Test Steps for meshlink_stop Test Case # 1*/
+static bool test_steps_mesh_stop_01(void) {
+ meshlink_stop(NULL);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ return true;
+}
+
+int test_meshlink_stop_close(void) {
+ const struct CMUnitTest blackbox_stop_close_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_stop_01, NULL, NULL,
+ (void *)&test_mesh_stop_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_close_01, NULL, NULL,
+ (void *)&test_mesh_close_01_state)
+ };
+
+ total_tests += sizeof(blackbox_stop_close_tests) / sizeof(blackbox_stop_close_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_stop_close_tests, NULL, NULL);
+}
+
--- /dev/null
+#ifndef TEST_CASES_STOP_CLOSE_H
+#define TEST_CASES_STOP_CLOSE_H
+
+/*
+ test_cases_stop_close.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_stop_close(void);
+extern int total_tests;
+
+
+#endif
--- /dev/null
+/*
+ test_cases_verify.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_verify.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+/* Modify this to change the logging level of Meshlink */
+#define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
+
+static void test_case_verify_01(void **state);
+static bool test_verify_01(void);
+static void test_case_verify_02(void **state);
+static bool test_verify_02(void);
+static void test_case_verify_03(void **state);
+static bool test_verify_03(void);
+static void test_case_verify_04(void **state);
+static bool test_verify_04(void);
+static void test_case_verify_05(void **state);
+static bool test_verify_05(void);
+static void test_case_verify_06(void **state);
+static bool test_verify_06(void);
+static void test_case_verify_07(void **state);
+static bool test_verify_07(void);
+static void test_case_verify_08(void **state);
+static bool test_verify_08(void);
+
+/* State structure for verify API Test Case #1 */
+static black_box_state_t test_case_verify_01_state = {
+ .test_case_name = "test_case_verify_01",
+};
+
+/* State structure for verify API Test Case #2 */
+static black_box_state_t test_case_verify_02_state = {
+ .test_case_name = "test_case_verify_02",
+};
+
+/* State structure for verify API Test Case #3 */
+static black_box_state_t test_case_verify_03_state = {
+ .test_case_name = "test_case_verify_03",
+};
+
+/* State structure for verify API Test Case #4 */
+static black_box_state_t test_case_verify_04_state = {
+ .test_case_name = "test_case_verify_04",
+};
+
+/* State structure for verify API Test Case #5 */
+static black_box_state_t test_case_verify_05_state = {
+ .test_case_name = "test_case_verify_05",
+};
+
+/* State structure for verify API Test Case #6 */
+static black_box_state_t test_case_verify_06_state = {
+ .test_case_name = "test_case_verify_06",
+};
+
+
+
+/* Execute meshlink_verify Test Case # 1 - Valid case - verify a data successfully*/
+void test_case_verify_01(void **state) {
+ execute_test(test_verify_01, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 1 - Valid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Sign data with meshlink_sign
+ 3. Verify data with the sign buffer used while signing
+
+ Expected Result:
+ Verifies data successfully with the apt signature
+*/
+bool test_verify_01(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh_handle = meshlink_open("verifyconf", "nut", "node_sim", DEV_CLASS_BACKBONE);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+ assert(ret);
+
+ meshlink_node_t *source = meshlink_get_node(mesh_handle, "nut");
+ assert(source);
+ ret = meshlink_verify(mesh_handle, source, data, strlen(data) + 1, sig, ssize);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("verifyconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_verify FAILED to verify data\n");
+ return false;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_verify Successfuly verified data\n");
+ return true;
+}
+
+
+/* Execute verify_data Test Case # 2 - Invalid case - meshlink_verify passing NULL args*/
+void test_case_verify_02(void **state) {
+ execute_test(test_verify_02, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 2 - Invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Sign data with meshlink_sign
+ 3. Trying to pass NULL as mesh handle argument
+ and other arguments being valid
+
+ Expected Result:
+ Reports error accordingly by returning false
+*/
+bool test_verify_02(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh_handle = meshlink_open("verifyconf", "nut", "node_sim", DEV_CLASS_BACKBONE);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool sret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+ assert(sret);
+
+ meshlink_node_t *source = meshlink_get_node(mesh_handle, "nut");
+ assert(source != NULL);
+ bool ret = meshlink_verify(NULL, source, data, strlen(data) + 1, sig, ssize);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("verifyconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_sign Successfuly reported error on passing NULL as mesh_handle arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_sign FAILED to report error on passing NULL as mesh_handle arg\n");
+ return false;
+}
+
+
+/* Execute verify_data Test Case # 3 - Invalid case - meshlink_verify passing NULL args*/
+void test_case_verify_03(void **state) {
+ execute_test(test_verify_03, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 3 - Invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Sign data with meshlink_sign
+ 3. Trying to pass NULL as source node handle argument
+ and other arguments being valid
+
+ Expected Result:
+ Reports error accordingly by returning false
+*/
+bool test_verify_03(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh_handle = meshlink_open("verifyconf", "nut", "node_sim", DEV_CLASS_BACKBONE);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+ assert(ret);
+ ret = meshlink_verify(mesh_handle, NULL, data, strlen(data) + 1, sig, ssize);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("verifyconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_verify successfully reported NULL as node_handle arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_verify FAILED to report NULL as node_handle arg\n");
+ return false;
+}
+
+/* Execute verify_data Test Case # 4 - Invalid case - meshlink_verify passing NULL args*/
+void test_case_verify_04(void **state) {
+ execute_test(test_verify_04, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 4 - Invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Sign data with meshlink_sign
+ 3. Trying to pass NULL as signed data argument
+ and other arguments being valid
+
+ Expected Result:
+ Reports error accordingly by returning false
+*/
+bool test_verify_04(void) {
+ meshlink_destroy("verifyconf");
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh_handle = meshlink_open("verifyconf", "nut", "node_sim", DEV_CLASS_BACKBONE);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+ assert(ret);
+ meshlink_node_t *source = meshlink_get_node(mesh_handle, "nut");
+ assert(source != NULL);
+ ret = meshlink_verify(mesh_handle, source, NULL, strlen(data) + 1, sig, ssize);
+ meshlink_stop(mesh_handle);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("verifyconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_verify successfully reported NULL as data arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_verify FAILED to report NULL as data arg\n");
+ return false;
+}
+
+
+/* Execute verify_data Test Case # 5 - Invalid case - meshlink_verify passing NULL args*/
+void test_case_verify_05(void **state) {
+ execute_test(test_verify_05, state);
+}
+
+/* Test Steps for meshlink_sign Test Case # 5 - Invalid case
+
+ Test Steps:
+ 1. Run NUT(Node Under Test)
+ 2. Sign data with meshlink_sign
+ 3. Trying to pass NULL as signature buffer argument
+ and other arguments being valid
+
+ Expected Result:
+ Reports error accordingly by returning false
+*/
+bool test_verify_05(void) {
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh_handle = meshlink_open("verifyconf", "nut", "node_sim", 1);
+ assert(mesh_handle);
+ meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ assert(meshlink_start(mesh_handle));
+
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh_handle, data, strlen(data) + 1, sig, &ssize);
+ assert(ret);
+ meshlink_node_t *source = meshlink_get_node(mesh_handle, "nut");
+ assert(source != NULL);
+
+ ret = meshlink_verify(mesh_handle, source, data, strlen(data) + 1, NULL, ssize);
+ meshlink_stop(mesh_handle);
+ meshlink_close(mesh_handle);
+ meshlink_destroy("verifyconf");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_verify successfully NULL as sign arg\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_verify FAILED to report NULL as sign arg\n");
+ return false;
+}
+
+/* Execute verify_data Test Case # 6 - Functionality test, when a wrong source node is mentioned to verify
+ the signed data */
+void test_case_verify_06(void **state) {
+ execute_test(test_verify_06, state);
+}
+
+/* Test Steps for meshlink_verify Test Case # 6 - Functionality Test
+
+ Test Steps:
+ 1. Run NUT(Node Under Test) and peer
+ 2. Sign using peer as source node.
+ 3. Verify with NUT but passing NUT as source node rather than
+ 'peer' as source node
+
+ Expected Result:
+ API returns false when it detects the wrong source node
+*/
+bool test_verify_06(void) {
+ /* deleting the confbase if already exists */
+ meshlink_destroy("verifyconf1");
+ meshlink_destroy("verifyconf2");
+ /* Set up logging for Meshlink */
+ meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
+ meshlink_handle_t *mesh1 = meshlink_open("verifyconf1", "nut", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh1);
+ meshlink_handle_t *mesh2 = meshlink_open("verifyconf2", "bar", "chat", DEV_CLASS_STATIONARY);
+ assert(mesh2);
+
+ char *exp1 = meshlink_export(mesh1);
+ assert(exp1 != NULL);
+ char *exp2 = meshlink_export(mesh2);
+ assert(exp2 != NULL);
+ assert(meshlink_import(mesh1, exp2));
+ assert(meshlink_import(mesh2, exp1));
+
+ /* signing done by peer node */
+ char *data = "Test";
+ char sig[MESHLINK_SIGLEN];
+ size_t ssize = MESHLINK_SIGLEN;
+ bool ret = meshlink_sign(mesh2, data, strlen(data) + 1, sig, &ssize);
+ assert(ret);
+
+ meshlink_node_t *source_nut = meshlink_get_self(mesh1);
+ assert(source_nut);
+ ret = meshlink_verify(mesh_handle, source_nut, data, strlen(data) + 1, sig, ssize);
+ meshlink_close(mesh1);
+ meshlink_close(mesh2);
+ meshlink_destroy("verifyconf1");
+ meshlink_destroy("verifyconf2");
+
+ if(!ret) {
+ PRINT_TEST_CASE_MSG("meshlink_verify successfully returned 'false' when a wrong source node used to verify the data\n");
+ return true;
+ }
+
+ PRINT_TEST_CASE_MSG("meshlink_verify FAILED to report error when a wrong source is mentioned\n");
+ return false;
+}
+
+
+int test_meshlink_verify(void) {
+ const struct CMUnitTest blackbox_verify_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_verify_01, NULL, NULL,
+ (void *)&test_case_verify_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_verify_02, NULL, NULL,
+ (void *)&test_case_verify_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_verify_03, NULL, NULL,
+ (void *)&test_case_verify_03_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_verify_04, NULL, NULL,
+ (void *)&test_case_verify_04_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_verify_05, NULL, NULL,
+ (void *)&test_case_verify_05_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_verify_06, NULL, NULL,
+ (void *)&test_case_verify_06_state)
+ };
+
+ total_tests += sizeof(blackbox_verify_tests) / sizeof(blackbox_verify_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_verify_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_VERIFY_H
+#define TEST_CASES_VERIFY_H
+
+/*
+ test_cases_verify.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+
+#include <stdbool.h>
+
+extern int total_tests;
+extern int test_meshlink_verify(void);
+
+#endif // TEST_CASES_VERIFY_H
--- /dev/null
+/*
+ test_cases_whitelist.c -- Execution of specific meshlink black box test cases
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "execute_tests.h"
+#include "test_cases_whitelist.h"
+#include "../common/containers.h"
+#include "../common/test_step.h"
+#include "../common/common_handlers.h"
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "../../utils.h"
+
+static void test_case_mesh_whitelist_01(void **state);
+static bool test_steps_mesh_whitelist_01(void);
+static void test_case_mesh_whitelist_02(void **state);
+static bool test_steps_mesh_whitelist_02(void);
+static void test_case_mesh_whitelist_03(void **state);
+static bool test_steps_mesh_whitelist_03(void);
+
+/* State structure for meshlink_whitelist Test Case #1 */
+static black_box_state_t test_mesh_whitelist_01_state = {
+ .test_case_name = "test_case_mesh_whitelist_01",
+};
+
+/* State structure for meshlink_whitelist Test Case #2 */
+static black_box_state_t test_mesh_whitelist_02_state = {
+ .test_case_name = "test_case_mesh_whitelist_02",
+};
+
+/* State structure for meshlink_whitelist Test Case #3 */
+static black_box_state_t test_mesh_whitelist_03_state = {
+ .test_case_name = "test_case_mesh_whitelist_03",
+};
+
+static bool rec_stat;
+static bool reachable;
+static pthread_mutex_t lock_receive = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t receive_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t reachable_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t reachable_cond = PTHREAD_COND_INITIALIZER;
+
+
+/* Execute meshlink_whitelist Test Case # 1*/
+static void test_case_mesh_whitelist_01(void **state) {
+ execute_test(test_steps_mesh_whitelist_01, state);
+}
+
+
+static void receive(meshlink_handle_t *mesh, meshlink_node_t *src, const void *data, size_t len) {
+ const char *msg = data;
+ assert(len);
+
+ pthread_mutex_lock(& lock_receive);
+ rec_stat = true;
+ assert(!pthread_cond_broadcast(&receive_cond));
+ pthread_mutex_unlock(& lock_receive);
+
+}
+
+static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reach) {
+ if(!strcmp(node->name, "bar")) {
+ pthread_mutex_lock(&reachable_lock);
+ reachable = reach;
+ assert(!pthread_cond_broadcast(&reachable_cond));
+ pthread_mutex_unlock(&reachable_lock);
+ }
+}
+
+
+/* Test Steps for meshlink_whitelist Test Case # 1
+
+ Test Steps:
+ 1. Run 2 node instances
+ 2. Blacklist one node and again whitelist the blacklisted node
+
+ Expected Result:
+ meshlink_whitelist API whitelists the blacklisted node
+*/
+static bool test_steps_mesh_whitelist_01(void) {
+ struct timespec timeout = {0};
+
+ // Open two new meshlink instance.
+
+ meshlink_destroy("whitelist_conf.1");
+ meshlink_destroy("whitelist_conf.2");
+ meshlink_handle_t *mesh1 = meshlink_open("whitelist_conf.1", "foo", "test", DEV_CLASS_BACKBONE);
+ assert(mesh1);
+ meshlink_set_log_cb(mesh1, MESHLINK_DEBUG, meshlink_callback_logger);
+ meshlink_handle_t *mesh2 = meshlink_open("whitelist_conf.2", "bar", "test", DEV_CLASS_BACKBONE);
+ assert(mesh2);
+ meshlink_set_log_cb(mesh2, MESHLINK_DEBUG, meshlink_callback_logger);
+ meshlink_set_receive_cb(mesh2, receive);
+ meshlink_set_receive_cb(mesh1, receive);
+
+ // Export & Import to join the mesh
+
+ reachable = false;
+ char *data = meshlink_export(mesh1);
+ assert(data);
+ assert(meshlink_import(mesh2, data));
+ free(data);
+ data = meshlink_export(mesh2);
+ assert(data);
+ assert(meshlink_import(mesh1, data));
+ free(data);
+
+ // Start both instances
+
+ meshlink_set_node_status_cb(mesh1, status_cb);
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+
+ // Nodes should know each other
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&reachable_lock);
+
+ while(reachable == false) {
+ assert(!pthread_cond_timedwait(&reachable_cond, &reachable_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&reachable_lock);
+ sleep(1);
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar);
+ meshlink_node_t *foo = meshlink_get_node(mesh2, "foo");
+ assert(foo);
+
+ rec_stat = false;
+ assert(meshlink_send(mesh1, bar, "test", 5));
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(& lock_receive);
+
+ if(rec_stat == false) {
+ assert(pthread_cond_timedwait(&receive_cond, &lock_receive, &timeout) == 0);
+ }
+
+ pthread_mutex_unlock(& lock_receive);
+
+
+ meshlink_blacklist(mesh1, foo);
+
+ rec_stat = false;
+ assert(meshlink_send(mesh1, bar, "test", 5));
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(& lock_receive);
+
+ if(rec_stat == false) {
+ int err = pthread_cond_timedwait(&receive_cond, &lock_receive, &timeout);
+ assert(err == ETIMEDOUT);
+ }
+
+ pthread_mutex_unlock(& lock_receive);
+ meshlink_whitelist(mesh1, foo);
+
+ rec_stat = false;
+ bool result = meshlink_send(mesh2, foo, "test", 5);
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(& lock_receive);
+
+ if(rec_stat == false) {
+ assert(pthread_cond_timedwait(&receive_cond, &lock_receive, &timeout) == 0);
+ }
+
+ pthread_mutex_unlock(& lock_receive);
+
+ // Clean up.
+
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("whitelist_conf.1");
+ meshlink_destroy("whitelist_conf.2");
+
+ return result;
+}
+
+/* Test Steps for meshlink_whitelist Test Case # 2
+
+ Test Steps:
+ 1. Calling meshlink_whitelist with NULL as mesh handle argument.
+
+ Expected Result:
+ meshlink_whitelist API handles the invalid parameter when called by giving proper error number.
+*/
+static void test_case_mesh_whitelist_02(void **state) {
+ execute_test(test_steps_mesh_whitelist_02, state);
+}
+
+/* Test Steps for meshlink_whitelist Test Case # 2*/
+static bool test_steps_mesh_whitelist_02(void) {
+ struct timespec timeout = {0};
+
+ // Open two new meshlink instance.
+
+ meshlink_destroy("whitelist_conf.3");
+ meshlink_destroy("whitelist_conf.4");
+ meshlink_handle_t *mesh1 = meshlink_open("whitelist_conf.3", "foo", "test", DEV_CLASS_BACKBONE);
+ assert(mesh1);
+ meshlink_handle_t *mesh2 = meshlink_open("whitelist_conf.4", "bar", "test", DEV_CLASS_BACKBONE);
+ assert(mesh2);
+ meshlink_set_receive_cb(mesh2, receive);
+ meshlink_set_receive_cb(mesh1, receive);
+
+ char *data = meshlink_export(mesh1);
+ assert(data);
+ assert(meshlink_import(mesh2, data));
+ free(data);
+ data = meshlink_export(mesh2);
+ assert(data);
+ assert(meshlink_import(mesh1, data));
+ free(data);
+
+ // Start both instances
+
+ reachable = false;
+ meshlink_set_node_status_cb(mesh1, status_cb);
+ assert(meshlink_start(mesh1));
+ assert(meshlink_start(mesh2));
+
+ // Nodes should know each other
+ timeout.tv_sec = time(NULL) + 10;
+ pthread_mutex_lock(&reachable_lock);
+
+ while(reachable == false) {
+ assert(!pthread_cond_timedwait(&reachable_cond, &reachable_lock, &timeout));
+ }
+
+ pthread_mutex_unlock(&reachable_lock);
+
+ meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
+ assert(bar);
+ meshlink_node_t *foo = meshlink_get_node(mesh2, "foo");
+ assert(foo);
+
+ assert(meshlink_send(mesh1, bar, "test", 5));
+
+ meshlink_blacklist(mesh1, foo);
+
+ // Passing NULL as mesh handle but with valid node handle 'foo'
+
+ meshlink_whitelist(NULL, foo);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ // Clean up.
+
+ meshlink_close(mesh2);
+ meshlink_close(mesh1);
+ meshlink_destroy("whitelist_conf.3");
+ meshlink_destroy("whitelist_conf.4");
+
+ return true;
+}
+
+/* Execute meshlink_whitelist Test Case # 3*/
+static void test_case_mesh_whitelist_03(void **state) {
+ execute_test(test_steps_mesh_whitelist_03, state);
+}
+
+/* Test Steps for meshlink_whitelist Test Case # 3
+
+ Test Steps:
+ 1. Calling meshlink_whitelist with NULL as node handle argument.
+
+ Expected Result:
+ meshlink_whitelist API handles the invalid parameter when called by giving proper error number.
+*/
+static bool test_steps_mesh_whitelist_03(void) {
+ // Open meshlink instance.
+
+ meshlink_destroy("whitelist_conf");
+ meshlink_handle_t *mesh = meshlink_open("whitelist_conf", "foo", "test", DEV_CLASS_BACKBONE);
+ assert(mesh);
+
+ // Start instance
+ assert(meshlink_start(mesh));
+
+ meshlink_whitelist(mesh, NULL);
+ assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
+
+ // Clean up.
+
+ meshlink_close(mesh);
+ meshlink_destroy("whitelist_conf");
+ return true;
+}
+
+int test_meshlink_whitelist(void) {
+ const struct CMUnitTest blackbox_whitelist_tests[] = {
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_whitelist_01, NULL, NULL,
+ (void *)&test_mesh_whitelist_01_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_whitelist_02, NULL, NULL,
+ (void *)&test_mesh_whitelist_02_state),
+ cmocka_unit_test_prestate_setup_teardown(test_case_mesh_whitelist_03, NULL, NULL,
+ (void *)&test_mesh_whitelist_03_state)
+ };
+
+ total_tests += sizeof(blackbox_whitelist_tests) / sizeof(blackbox_whitelist_tests[0]);
+
+ return cmocka_run_group_tests(blackbox_whitelist_tests, NULL, NULL);
+}
--- /dev/null
+#ifndef TEST_CASES_WHITELIST_H
+#define TEST_CASES_WHITELIST_H
+
+/*
+ test_cases_whitelist.h -- Declarations for Individual Test Case implementation functions
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <stdbool.h>
+
+extern int test_meshlink_whitelist(void);
+extern int total_tests;
+
+#endif
--- /dev/null
+check_PROGRAMS = node_sim_relay node_sim_peer node_sim_nut
+
+node_sim_peer_SOURCES = node_sim_peer.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_peer_LDADD = ../../../src/libmeshlink.la
+node_sim_peer_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_relay_SOURCES = node_sim_relay.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_relay_LDADD = ../../../src/libmeshlink.la
+node_sim_relay_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_nut_SOURCES = node_sim_nut.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_nut_LDADD = ../../../src/libmeshlink.la
+node_sim_nut_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+static bool conn_status = false;
+
+static void callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text) {
+ char connection_match_msg[100];
+
+ fprintf(stderr, "meshlink>> %s\n", text);
+
+ if(strstr(text, "Connection") || strstr(text, "connection")) {
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg) && strstr(text, "activated")) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Already connected to peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection closed by peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Closing connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+ }
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ int client_id = -1;
+ bool result = false;
+ int i;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ execute_open(argv[1], argv[2]);
+ meshlink_set_log_cb(mesh_handle, MESHLINK_INFO, callback_logger);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ /* Connectivity of peer */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Connected with Peer\n");
+ assert(mesh_event_sock_send(client_id, META_CONN_SUCCESSFUL, "Connected with Peer", 30));
+
+ /* Connectivity of peer */
+ while(conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Closed connection with Peer\n");
+ assert(mesh_event_sock_send(client_id, META_CONN_CLOSED, "Connection closed with Peer", 30));
+
+ /* Connectivity of peer */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Connected with Peer\n");
+ assert(mesh_event_sock_send(client_id, META_RECONN_SUCCESSFUL, "Reconnected with Peer", 30));
+
+ execute_close();
+
+ return 0;
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+check_PROGRAMS = node_sim_peer node_sim_relay node_sim_nut
+
+node_sim_peer_SOURCES = node_sim_peer.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_peer_LDADD = ../../../src/libmeshlink.la
+node_sim_peer_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_relay_SOURCES = node_sim_relay.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_relay_LDADD = ../../../src/libmeshlink.la
+node_sim_relay_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_nut_SOURCES = node_sim_nut.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_nut_LDADD = ../../../src/libmeshlink.la
+node_sim_nut_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+static bool conn_status = false;
+
+static void callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text) {
+ char connection_match_msg[100];
+
+ fprintf(stderr, "meshlink>> %s\n", text);
+
+ if(strstr(text, "Connection") || strstr(text, "connection")) {
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg) && strstr(text, "activated")) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Already connected to peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection closed by peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Closing connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+ }
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ int client_id = -1;
+ bool result = false;
+ int i;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ execute_open(argv[1], argv[2]);
+ meshlink_set_log_cb(mesh_handle, MESHLINK_INFO, callback_logger);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ /* Connectivity of peer */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Connected with Peer\n");
+ assert(mesh_event_sock_send(client_id, META_CONN_SUCCESSFUL, "Connected with Peer", 30));
+
+ execute_close();
+
+ return 0;
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+
+ int client_id = -1;
+
+ if((argv[CMD_LINE_ARG_CLIENTID]) && (argv[CMD_LINE_ARG_IMPORTSTR])) {
+ client_id = atoi(argv[CMD_LINE_ARG_CLIENTID]);
+ mesh_event_sock_connect(argv[CMD_LINE_ARG_IMPORTSTR]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[CMD_LINE_ARG_NODENAME], argv[CMD_LINE_ARG_DEVCLASS]);
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+check_PROGRAMS = node_sim_peer node_sim_relay node_sim_nut
+
+node_sim_peer_SOURCES = node_sim_peer.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_peer_LDADD = ../../../src/libmeshlink.la
+node_sim_peer_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_relay_SOURCES = node_sim_relay.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_relay_LDADD = ../../../src/libmeshlink.la
+node_sim_relay_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_nut_SOURCES = node_sim_nut.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_nut_LDADD = ../../../src/libmeshlink.la
+node_sim_nut_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+static bool conn_status = false;
+
+void callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text) {
+ char connection_match_msg[100];
+
+ fprintf(stderr, "meshlink>> %s\n", text);
+
+ if(strstr(text, "Connection") || strstr(text, "connection")) {
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg) && strstr(text, "activated")) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Already connected to peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection closed by peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Closing connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+ }
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ int client_id = -1;
+ bool result = false;
+ int i;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ execute_open(argv[1], argv[2]);
+ meshlink_set_log_cb(mesh_handle, MESHLINK_DEBUG, callback_logger);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+ mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0);
+
+ /* Connectivity of peer is checked using meshlink_get_node API */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ sleep(1);
+ fprintf(stderr, "Connected with Peer\n");
+ mesh_event_sock_send(client_id, META_CONN_SUCCESSFUL, "Connected with Peer", 30);
+
+ conn_status = false;
+ fprintf(stderr, "Waiting 120 sec for peer to be re-connected\n");
+
+ for(i = 0; i < 120; i++) {
+ if(conn_status) {
+ result = true;
+ break;
+ }
+
+ sleep(1);
+ }
+
+ if(result) {
+ fprintf(stderr, "Re-connected with Peer\n");
+ mesh_event_sock_send(client_id, META_RECONN_SUCCESSFUL, "Peer", 30);
+ } else {
+ fprintf(stderr, "Failed to reconnect with Peer\n");
+ mesh_event_sock_send(client_id, META_RECONN_FAILURE, "Peer", 30);
+ }
+
+ execute_close();
+
+ return 0;
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+check_PROGRAMS = node_sim_relay node_sim_peer node_sim_nut
+
+node_sim_peer_SOURCES = node_sim_peer.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_peer_LDADD = ../../../src/libmeshlink.la
+node_sim_peer_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_relay_SOURCES = node_sim_relay.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_relay_LDADD = ../../../src/libmeshlink.la
+node_sim_relay_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_nut_SOURCES = node_sim_nut.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_nut_LDADD = ../../../src/libmeshlink.la
+node_sim_nut_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+static bool conn_status = false;
+
+void callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text) {
+ char connection_match_msg[100];
+
+ fprintf(stderr, "meshlink>> %s\n", text);
+
+ if(strstr(text, "Connection") || strstr(text, "connection")) {
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg) && strstr(text, "activated")) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Already connected to peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection closed by peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Closing connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+ }
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int i, clientId = -1;
+ bool result;
+ char *invite_peer;
+
+ if((argv[3]) && (argv[4])) {
+ clientId = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ execute_open(argv[1], argv[2]);
+ meshlink_set_log_cb(mesh_handle, MESHLINK_INFO, callback_logger);
+
+ execute_start();
+
+ if(!mesh_event_sock_send(clientId, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ if(!argv[CMD_LINE_ARG_INVITEURL]) {
+ fprintf(stderr, "Generating Inviation to PEER\n");
+ invite_peer = execute_invite("peer");
+ assert(invite_peer != NULL);
+
+ if(!mesh_event_sock_send(clientId, NODE_INVITATION, invite_peer, strlen(invite_peer) + 1)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ fprintf(stderr, "Waiting for PEER to be connected\n");
+
+ /* Connectivity of peer is checked */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Connected with Peer\n");
+
+ if(!mesh_event_sock_send(clientId, META_CONN_SUCCESSFUL, "Connected with Peer", 30)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+
+ int clientid = -1;
+
+ if((argv[3]) && (argv[4])) {
+ clientid = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+ execute_start();
+
+ if(clientid != -1) {
+ mesh_event_sock_send(clientid, NODE_STARTED, NULL, 0);
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+check_PROGRAMS = node_sim_relay node_sim_peer node_sim_nut
+
+node_sim_peer_SOURCES = node_sim_peer.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_peer_LDADD = ../../../src/libmeshlink.la
+node_sim_peer_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_relay_SOURCES = node_sim_relay.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_relay_LDADD = ../../../src/libmeshlink.la
+node_sim_relay_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
+
+node_sim_nut_SOURCES = node_sim_nut.c ../common/common_handlers.c ../common/test_step.c ../common/mesh_event_handler.c
+node_sim_nut_LDADD = ../../../src/libmeshlink.la
+node_sim_nut_CFLAGS = -D_GNU_SOURCE -fsanitize=leak
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+static bool conn_status = false;
+
+void callback_logger(meshlink_handle_t *mesh, meshlink_log_level_t level,
+ const char *text) {
+ char connection_match_msg[100];
+
+ fprintf(stderr, "meshlink>> %s\n", text);
+
+ if(strstr(text, "Connection") || strstr(text, "connection")) {
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg) && strstr(text, "activated")) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Already connected to peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = true;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Connection closed by peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+
+ assert(snprintf(connection_match_msg, sizeof(connection_match_msg),
+ "Closing connection with peer") >= 0);
+
+ if(strstr(text, connection_match_msg)) {
+ conn_status = false;
+ return;
+ }
+ }
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int i, clientId = -1;
+ bool result;
+ char *invite_peer;
+
+ if((argv[3]) && (argv[4])) {
+ clientId = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ execute_open(argv[1], argv[2]);
+ meshlink_set_log_cb(mesh_handle, MESHLINK_INFO, callback_logger);
+
+ if(argv[CMD_LINE_ARG_INVITEURL]) {
+ execute_join(argv[CMD_LINE_ARG_INVITEURL]);
+ }
+
+ execute_start();
+
+ if(!mesh_event_sock_send(clientId, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ fprintf(stderr, "Generating Inviation to PEER\n");
+ invite_peer = execute_invite("peer");
+ assert(invite_peer != NULL);
+
+ if(!mesh_event_sock_send(clientId, NODE_INVITATION, invite_peer, strlen(invite_peer) + 1)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ fprintf(stderr, "Waiting for PEER to be connected\n");
+
+ /* Connectivity of peer is checked */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Connected with Peer\n");
+
+ if(!mesh_event_sock_send(clientId, META_CONN_SUCCESSFUL, "Connected with Peer", 30)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ conn_status = false;
+ fprintf(stderr, "Waiting for PEER to be re-connected\n");
+
+ /* Connectivity of peer */
+ while(!conn_status) {
+ sleep(1);
+ }
+
+ fprintf(stderr, "Re-connected with Peer\n");
+
+ if(!mesh_event_sock_send(clientId, META_CONN_SUCCESSFUL, "Connected with Peer", 30)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+ int client_id = -1;
+
+ if((argv[3]) && (argv[4])) {
+ client_id = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+
+ if(argv[5]) {
+ execute_join(argv[5]);
+ }
+
+ execute_start();
+
+ if(client_id != -1) {
+ if(!mesh_event_sock_send(client_id, NODE_STARTED, NULL, 0)) {
+ fprintf(stderr, "Trying to resend mesh event\n");
+ sleep(1);
+ }
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+/*
+ node_sim.c -- Implementation of Node Simulation for Meshlink Testing
+ for meta connection test case 01 - re-connection of
+ two nodes when relay node goes down
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../common/common_handlers.h"
+#include "../common/test_step.h"
+#include "../common/mesh_event_handler.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_DEVCLASS 2
+#define CMD_LINE_ARG_CLIENTID 3
+#define CMD_LINE_ARG_IMPORTSTR 4
+#define CMD_LINE_ARG_INVITEURL 5
+
+int main(int argc, char *argv[]) {
+ struct timeval main_loop_wait = { 5, 0 };
+
+ int clientid = -1;
+
+ if((argv[3]) && (argv[4])) {
+ clientid = atoi(argv[3]);
+ mesh_event_sock_connect(argv[4]);
+ }
+
+ /* Setup required signals */
+ setup_signals();
+
+ /* Execute test steps */
+ execute_open(argv[1], argv[2]);
+ execute_start();
+
+ if(clientid != -1) {
+ mesh_event_sock_send(clientid, NODE_STARTED, NULL, 0);
+ }
+
+ /* All test steps executed - wait for signals to stop/start or close the mesh */
+ while(test_running) {
+ select(1, NULL, NULL, NULL, &main_loop_wait);
+ }
+
+ execute_close();
+}
--- /dev/null
+#!/bin/sh
+# build_container.sh -- Script to populate an LXC Container with the files
+# required to run a Meshlink Node Simulation.
+# Designed to run on unprivileged Containers.
+# Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Read command-line arguments
+testcase=$1
+nodename=$2
+meshlinkrootpath=$3
+setx=$4
+
+# Set configuration for required folders, programs and scripts
+# Folder Paths
+ltlibfolder=".libs"
+meshlinksrclibpath="${meshlinkrootpath}/src/${ltlibfolder}"
+cattasrclibpath="${meshlinkrootpath}/catta/src/${ltlibfolder}"
+blackboxpath="${meshlinkrootpath}/test/blackbox"
+blackboxlibpath="${meshlinkrootpath}/test/blackbox/${ltlibfolder}"
+blackboxutilpath="${blackboxpath}/util"
+testcasepath="${blackboxpath}/${testcase}"
+testcaselibpath="${blackboxpath}/${testcase}/${ltlibfolder}"
+mirrorfolder="test"
+mirrorfolderpath="${testcasepath}/${mirrorfolder}"
+mirrorfolderlibpath="${mirrorfolderpath}/${ltlibfolder}"
+containerdstpath="/home/ubuntu/${mirrorfolder}"
+containerconfbase="/testconf"
+containerlogpath=""
+# Program/Script Names
+ltprefix="lt-"
+nodestepscript="node_step.sh"
+nodesimpgm="node_sim_${nodename}"
+nodesimltscript="${ltprefix}${nodesimpgm}"
+geninvitepgm="gen_invite"
+geninviteltscript="${ltprefix}${geninvitepgm}"
+lxccopydirscript="lxc_copy_dir.sh"
+lxccopyfilescript="lxc_copy_file.sh"
+lxcrunscript="lxc_run.sh"
+# Container Name
+containername="${testcase}_${nodename}"
+
+# Run Libtool Wrapper Scripts once in their built paths in order to generate lt-<program> script inside .libs directory
+${blackboxpath}/${geninvitepgm} >/dev/null 2>/dev/null
+${testcasepath}/${nodesimpgm} >/dev/null 2>/dev/null
+
+set ${setx}
+
+# Create Meshlink Container Mirror Folder (Delete any existing folder before creating new folder)
+rm -rf ${mirrorfolderpath} >/dev/null 2>/dev/null
+mkdir ${mirrorfolderpath}
+
+# Populate Mirror Folder
+# Copy Wrapper Scripts for Utility Programs
+cp ${blackboxpath}/${geninvitepgm} ${mirrorfolderpath}
+cp ${testcasepath}/${nodesimpgm} ${mirrorfolderpath}
+# Copy Utility Scripts
+cp ${blackboxutilpath}/${nodestepscript} ${mirrorfolderpath}
+# Set Script Permissions
+chmod 755 ${mirrorfolderpath}/*
+# Copy Binaries, lt- Scripts and Required Libraries
+mkdir ${mirrorfolderlibpath}
+cp ${blackboxlibpath}/* ${mirrorfolderlibpath}
+cp ${testcaselibpath}/*${nodesimpgm}* ${mirrorfolderlibpath}
+cp ${meshlinksrclibpath}/* ${mirrorfolderlibpath}
+cp ${cattasrclibpath}/* ${mirrorfolderlibpath}
+
+# Copy mirror folder into LXC Container
+# Delete Destination Folder
+${blackboxutilpath}/${lxcrunscript} "rm -rf ${containerdstpath}" ${containername}
+# Delete Meshlink confbase folder and logs from Container - every new test case starts on a clean slate
+${blackboxutilpath}/${lxcrunscript} "rm -rf ${containerconfbase}" ${containername}
+${blackboxutilpath}/${lxcrunscript} "rm ${containerlogpath}/*.log" ${containername}
+# Create Destination Folder and Copy Files
+${blackboxutilpath}/${lxccopydirscript} ${mirrorfolderpath} ${containername} ${containerdstpath}
+# Kill any running instances of the Node Simulation Program
+${blackboxutilpath}/${lxcrunscript} "${containerdstpath}/${nodestepscript} ${ltprefix}${nodesimpgm} SIGTERM 2>/dev/null" ${containername}
+# Restore the 'interfaces' file in the Container
+echo "auto lo" > interfaces
+echo "iface lo inet loopback" >> interfaces
+echo "" >> interfaces
+echo "auto eth0" >> interfaces
+echo "iface eth0 inet dhcp" >> interfaces
+${blackboxutilpath}/${lxccopyfilescript} interfaces ${containername} /etc/network/interfaces
+
+set +x
--- /dev/null
+/*
+ gen_invite.c -- Black Box Test Utility to generate a meshlink invite
+ Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+
+ 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "../../../src/meshlink.h"
+#include "../common/test_step.h"
+
+#define CMD_LINE_ARG_NODENAME 1
+#define CMD_LINE_ARG_INVITEE 2
+
+int main(int argc, char *argv[]) {
+ char *invite = NULL;
+
+ /* Start mesh, generate an invite and print out the invite */
+ execute_open(argv[CMD_LINE_ARG_NODENAME], "1");
+ execute_start();
+ invite = execute_invite(argv[CMD_LINE_ARG_INVITEE]);
+ printf("%s\n", invite);
+ //execute_close();
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+cp ../${1}/node_sim_${2} .
+mkdir .libs 2>/dev/null
+cp ../${1}/.libs/*node_sim_${2}* .libs
--- /dev/null
+# lxc_copy.sh -- Script to transfer multiple files into an LXC Container
+# Designed to work on unprivileged Containers
+# Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Read command-line arguments
+srcdir=$1
+containername=$2
+containerdstdir=$3
+
+# Create destination directory inside container and copy source directory contents into it
+# by 'tar'ing the source directory and un'tar'ing it inside the container
+lxc-attach -n ${containername} -- mkdir ${containerdstdir}
+tar -C ${srcdir} -c . | lxc-attach -n ${containername} -- tar -C ${containerdstdir} -xvp
--- /dev/null
+# lxc_copy.sh -- Script to transfer multiple files into an LXC Container
+# Designed to work on unprivileged Containers
+# Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Read Command-line arguments
+srcfilepath=$1
+containername=$2
+dstfilepath=$3
+
+# Copy file into Container
+cat ${srcfilepath} | lxc-attach -n ${containername} -- sh -c "cat > ${dstfilepath}"
--- /dev/null
+# lxc_rename.sh - Script to rename an LXC Container
+# Designed to work on unprivileged Containers
+# Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Read command-line arguments
+lxcpath=$1
+oldname=$2
+newname=$3
+
+# Run command inside Container by attaching to the Container and sending it the command
+mv ${lxcpath}/${oldname} ${lxcpath}/${newname}
+sed {s/${oldname}/${newname}/} ${lxcpath}/${newname}/config > ${lxcpath}/${newname}/config1
+mv ${lxcpath}/${newname}/config1 ${lxcpath}/${newname}/config
+#lxc-copy -n ${oldname} -P lxcpath -N ${newname} -p lxcpath -R
+exit $?
--- /dev/null
+#!/bin/sh
+# lxc_run.sh - Script to run a command inside an LXC Container
+# Designed to work on unprivileged Containers
+# Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Read command-line arguments
+cmd=${1}
+containername=${2}
+
+# Run command inside Container by attaching to the Container and sending it the command
+echo "${cmd}" | lxc-attach -n ${containername} --
+exit $?
--- /dev/null
+# node_step.sh -- Script to send signal to control Mesh Node Simulation
+# Copyright (C) 2018 Guus Sliepen <guus@meshlink.io>
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Read command-line arguments
+prog_name=$1
+signal=$2
+
+# Find instance of running program and send the named signal to it
+pid=`/bin/pidof -s ${prog_name}`
+kill -${signal} ${pid}
+exit $?
--- /dev/null
+#!/bin/sh
+meshlinkrootpath=$(realpath ${0%/*}/..)
+host=$(hostname)
+lxcpath=$(lxc-config lxc.lxcpath)
+lxcbridge="lxcbr0"
+ethifname=$(ip route show default | awk '{print $5}' | head -1)
+arch=$(dpkg --print-architecture)
+
+test -f $HOME/.config/meshlink_blackbox.conf && . $HOME/.config/meshlink_blackbox.conf
+
+${0%/*}/blackbox/run_blackbox_tests/run_blackbox_tests ${meshlinkrootpath} ${lxcpath} ${lxcbridge} ${ethifname} ${arch} 2> run_blackbox_test_cases.log