]> git.meshlink.io Git - meshlink/blob - test/blackbox/common/test_step.c
4a2bf853896886c03d7f9fdeb13dbd91aa359eed
[meshlink] / test / blackbox / common / test_step.c
1 /*
2     test_step.c -- Handlers for executing test steps during node simulation
3     Copyright (C) 2018  Guus Sliepen <guus@meshlink.io>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 ŝ
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <assert.h>
23 #include <string.h>
24 #include "../../../src/meshlink.h"
25 #include "test_step.h"
26 #include "common_handlers.h"
27
28 /* Modify this to change the logging level of Meshlink */
29 #define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
30
31 meshlink_handle_t *mesh_handle = NULL;
32 bool mesh_started = false;
33 char *eth_if_name = NULL;
34
35 meshlink_handle_t *execute_open(char *node_name, char *dev_class) {
36         /* Set up logging for Meshlink */
37         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
38
39         /* Create meshlink instance */
40         mesh_handle = meshlink_open("testconf", node_name, "node_sim", atoi(dev_class));
41         fprintf(stderr, "meshlink_open status: %s\n", meshlink_strerror(meshlink_errno));
42         PRINT_TEST_CASE_MSG("meshlink_open status: %s\n", meshlink_strerror(meshlink_errno));
43         assert(mesh_handle);
44
45         /* Set up logging for Meshlink with the newly acquired Mesh Handle */
46         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
47         /* Set up callback for node status (reachable / unreachable) */
48         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
49
50         return mesh_handle;
51 }
52
53 char *execute_invite(char *invitee) {
54         char *invite_url = meshlink_invite(mesh_handle, invitee);
55
56         PRINT_TEST_CASE_MSG("meshlink_invite status: %s\n", meshlink_strerror(meshlink_errno));
57         assert(invite_url);
58
59         return invite_url;
60 }
61
62 void execute_join(char *invite_url) {
63         bool join_status;
64
65         /* The inviting node may take a moment to open its listening port
66             This sleep() prevents meshlink_join() from failing when the listening port is not open */
67         /* TO DO: Replace this with code that actually checks for the port being open, if possible */
68         PRINT_TEST_CASE_MSG("Sleeping 1 sec to allow inviting node to start listening...\n");
69         sleep(1);
70
71         PRINT_TEST_CASE_MSG("About to join with mesh_handle = %p, invite_url = %s\n", mesh_handle, invite_url);
72         join_status = meshlink_join(mesh_handle, invite_url);
73         PRINT_TEST_CASE_MSG("meshlink_join status: %s\n", meshlink_strerror(meshlink_errno));
74         assert(join_status);
75 }
76
77 void execute_start(void) {
78         bool start_init_status = meshlink_start(mesh_handle);
79
80         PRINT_TEST_CASE_MSG("meshlink_start status: %s\n", meshlink_strerror(meshlink_errno));
81         assert(start_init_status);
82         mesh_started = true;
83 }
84
85 void execute_stop(void) {
86         assert(mesh_handle);
87         meshlink_stop(mesh_handle);
88         mesh_started = false;
89 }
90
91 void execute_close(void) {
92         assert(mesh_handle);
93         meshlink_close(mesh_handle);
94 }
95
96 void execute_change_ip(void) {
97         char *eth_if_ip;
98         int last_byte;
99         char new_ip[20], gateway_ip[20];
100         char *last_dot_in_ip;
101         char *eth_if_netmask;
102         char route_chg_command[200];
103         int route_chg_status;
104
105         /* Get existing IP Address of Ethernet Bridge Interface */
106         assert(eth_if_ip = get_ip(eth_if_name));
107
108         /* Set new IP Address by replacing the last byte with last byte + 1 */
109         strncpy(new_ip, eth_if_ip, sizeof(new_ip));
110         assert(last_dot_in_ip = strrchr(new_ip, '.'));
111         last_byte = atoi(last_dot_in_ip + 1);
112         assert(snprintf(last_dot_in_ip + 1, 4, "%d", (last_byte > 253) ? 2 : (last_byte + 1)) >= 0);
113
114         /* TO DO: Check for IP conflicts with other interfaces and existing Containers */
115         /* Bring the network interface down before making changes */
116         stop_nw_intf(eth_if_name);
117         /* Save the netmask first, then restore it after setting the new IP Address */
118         assert(eth_if_netmask = get_netmask(eth_if_name));
119         set_ip(eth_if_name, new_ip);
120         set_netmask(eth_if_name, eth_if_netmask);
121         /* Bring the network interface back up again to apply changes */
122         start_nw_intf(eth_if_name);
123
124         /* Get Gateway's IP Address, by replacing the last byte with 1 in the current IP Address */
125         /* TO DO: Obtain the actual Gateway IP Address */
126         strncpy(gateway_ip, eth_if_ip, sizeof(gateway_ip));
127         assert(last_dot_in_ip = strrchr(gateway_ip, '.'));
128         assert(snprintf(last_dot_in_ip + 1, 4, "%d", 1) >= 0);
129
130         /* Add the default route back again, which would have been deleted when the
131             network interface was brought down */
132         /* TO DO: Perform this action using ioctl with SIOCADDRT */
133         /*assert(snprintf(route_chg_command, sizeof(route_chg_command), "route add default gw %s",
134           gateway_ip) >= 0);
135          route_chg_status = system(route_chg_command);
136          PRINT_TEST_CASE_MSG("Default Route Add status = %d\n", route_chg_status);
137          assert(route_chg_status == 0); */
138         // Not necessary for ubuntu versions of 16.04 and 18.04
139
140         PRINT_TEST_CASE_MSG("Node '%s' IP Address changed to %s\n", NUT_NODE_NAME, new_ip);
141
142         free(eth_if_ip);
143         free(eth_if_netmask);
144 }
145