test_storage: further refactoring, added test functionality, and TESTING.md to describe testing approach

This commit is contained in:
Ian Clowes 2020-06-07 16:02:56 +01:00 committed by Polynomialdivision
parent bd35961de8
commit 292ccb01f2
9 changed files with 513 additions and 117 deletions

View file

@ -175,6 +175,8 @@ void print_probe_entry(probe_entry entry);
int eval_probe_metric(struct probe_entry_s probe_entry);
void denied_req_array_insert(auth_entry entry);
auth_entry denied_req_array_delete(auth_entry entry);
auth_entry insert_to_denied_req_array(auth_entry entry, int inc_counter);

View file

@ -43,8 +43,6 @@ int compare_station_count(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compar
int compare_ssid(uint8_t *bssid_addr_own, uint8_t *bssid_addr_to_compare);
void denied_req_array_insert(auth_entry entry);
int denied_req_array_go_next(char sort_order[], int i, auth_entry entry,
auth_entry next_entry);

5
src/test/ap_auto.script Normal file
View file

@ -0,0 +1,5 @@
# Basic test of array entry handling
ap_add_auto 10 20
ap_show
ap_del_auto 10 20
ap_show

View file

@ -0,0 +1,5 @@
# Basic test of array entry handling
auth_entry_add_auto 10 20
auth_entry_show
auth_entry_del_auto 10 20
auth_entry_show

View file

@ -0,0 +1,5 @@
# Basic test of array entry handling
client_add_auto 10 20
client_show
client_del_auto 10 20
client_show

View file

@ -0,0 +1,6 @@
# Basic test of array entry handling
probe_sort bcfs
probe_add_auto 10 20
probe_show
probe_del_auto 10 20
probe_show

View file

@ -1,6 +1,7 @@
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include "dawn_iwinfo.h"
#include "utils.h"
@ -9,126 +10,21 @@
#include "datastorage.h"
#include "uface.h"
/*** External functions ***/
/*** SUT functions we use that are not in header files (like "friend" functions) ***/
void ap_array_insert(ap entry);
ap ap_array_delete(ap entry);
/*** Testing structures, etc ***/
union __attribute__((__packed__)) mac_mangler
union __attribute__((__packed__)) pac_a_mac
{
struct {
uint8_t b[6];
uint8_t pos[6];
uint8_t packing[2];
} u8;
uint64_t u64;
};
/*** Test code */
int ap_array_helper_auto(int action, int i0, int i1);
int ap_array_helper_auto(int action, int i0, int i1)
{
int m;
int step = (i0 > i1) ? -1 : 1;
int ret = 0;
switch (action)
{
case 0:
case 1:
m = i0;
int cont = 1;
while (cont) {
union mac_mangler this_mac;
ap ap0;
this_mac.u64 = m;
memcpy(ap0.bssid_addr, this_mac.u8.b, sizeof(ap0.bssid_addr));
if (action == 0)
ap_array_insert(ap0);
else
ap_array_delete(ap0);
if (m == i1)
cont = 0;
else
m += step;
}
break;
default:
ret = 1;
break;
}
return ret;
}
int main(int argc, char** argv)
{
int ret = 0;
int args_ok = 1;
int arg_consumed = 0;
printf("DAWN datastorage.c test harness. Ready for commands...\n");
int this_arg = 1;
argv++;
while (args_ok)
{
if (strcmp(*argv, "help") == 0)
{
arg_consumed = 1;
if (this_arg + arg_consumed > argc) goto next_command;
printf("Help is on its way...\n");
}
else if (strcmp(*argv, "ap_show") == 0)
{
arg_consumed = 1;
if (this_arg + arg_consumed > argc) goto next_command;
print_ap_array();
}
else if (strcmp(*argv, "ap_add_auto") == 0)
{
arg_consumed = 3;
if (this_arg + arg_consumed > argc) goto next_command;
ap_array_helper_auto(0, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
else if (strcmp(*argv, "ap_del_auto") == 0)
{
arg_consumed = 3;
if (this_arg + arg_consumed > argc) goto next_command;
ap_array_helper_auto(1, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
else
{
arg_consumed = 1;
if (this_arg + arg_consumed > argc) goto next_command;
printf("COMMAND \"%s\": Unknown - skipping!\n", *argv);
}
next_command:
this_arg += arg_consumed;
if (this_arg > argc)
{
printf("Commands are mangled at: \"%s\"!\n", *argv);
args_ok = 0;
}
else if (this_arg == argc)
args_ok = 0;
else
argv += arg_consumed;
}
printf("\n\nDAWN datastorage.c test harness - finshed. \n");
return ret;
}
/*** Test Stub Functions - Called by SUT ***/
void ubus_send_beacon_report(uint8_t client[], int id)
{
printf("send_beacon_report() was called...\n");
@ -140,7 +36,7 @@ int send_set_probe(uint8_t client_addr[])
return 0;
}
void wnm_disassoc_imminent(uint32_t id, const uint8_t *client_addr, char* dest_ap, uint32_t duration)
void wnm_disassoc_imminent(uint32_t id, const uint8_t* client_addr, char* dest_ap, uint32_t duration)
{
printf("wnm_disassoc_imminent() was called...\n");
}
@ -150,7 +46,7 @@ void add_client_update_timer(time_t time)
printf("add_client_update_timer() was called...\n");
}
void del_client_interface(uint32_t id, const uint8_t *client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time)
void del_client_interface(uint32_t id, const uint8_t* client_addr, uint32_t reason, uint8_t deauth, uint32_t ban_time)
{
printf("del_client_interface() was called...\n");
}
@ -161,21 +57,389 @@ int ubus_send_probe_via_network(struct probe_entry_s probe_entry)
return 0;
}
int get_rssi_iwinfo(uint8_t *client_addr)
int get_rssi_iwinfo(uint8_t* client_addr)
{
printf("get_rssi_iwinfo() was called...\n");
return 0;
}
int get_expected_throughput_iwinfo(uint8_t *client_addr)
int get_expected_throughput_iwinfo(uint8_t* client_addr)
{
printf("get_expected_throughput_iwinfo() was called...\n");
return 0;
}
int get_bandwidth_iwinfo(uint8_t *client_addr, float *rx_rate, float *tx_rate)
int get_bandwidth_iwinfo(uint8_t* client_addr, float* rx_rate, float* tx_rate)
{
printf("get_bandwidth_iwinfo() was called...\n");
return 0;
}
/*** Local Function Prototypes ***/
#define HELPER_ACTION_ADD 0x0000
#define HELPER_ACTION_DEL 0x1000
#define HELPER_ACTION_MASK 0x1000
#define HELPER_AP 0x0001
#define HELPER_CLIENT 0x0002
#define HELPER_AUTH_ENTRY 0x0004
#define HELPER_PROBE_ARRAY 0x0008
int array_auto_helper(int action, int i0, int i1);
int client_array_auto_helper(int action, int i0, int i1);
int auth_entry_array_auto_helper(int action, int i0, int i1);
int probe_array_auto_helper(int action, int i0, int i1);
/*** Test narness code */
int array_auto_helper(int action, int i0, int i1)
{
int m = i0;
int step = (i0 > i1) ? -1 : 1;
int ret = 0;
int cont = 1;
while (cont) {
union pac_a_mac this_mac;
this_mac.u64 = m;
switch (action & ~HELPER_ACTION_MASK)
{
case HELPER_AP:
; // Empty statement to allow label before declaration
ap ap0;
memcpy(ap0.bssid_addr, &this_mac.u8.pos[0], sizeof(ap0.bssid_addr));
if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD)
ap_array_insert(ap0);
else
ap_array_delete(ap0);
break;
case HELPER_CLIENT:
; // Empty statement to allow label before declaration
client client0;
memcpy(client0.bssid_addr, &this_mac.u8.pos[0], sizeof(client0.bssid_addr));
memcpy(client0.client_addr, &this_mac.u8.pos[0], sizeof(client0.client_addr));
if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD)
client_array_insert(client0);
else
client_array_delete(client0);
break;
case HELPER_PROBE_ARRAY:
; // Empty statement to allow label before declaration
probe_entry probe0;
memcpy(probe0.bssid_addr, &this_mac.u8.pos[0], sizeof(probe0.bssid_addr));
memcpy(probe0.client_addr, &this_mac.u8.pos[0], sizeof(probe0.client_addr));
if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD)
probe_array_insert(probe0);
else
probe_array_delete(probe0);
break;
case HELPER_AUTH_ENTRY:
; // Empty statement to allow label before declaration
auth_entry auth_entry0;
memcpy(auth_entry0.bssid_addr, &this_mac.u8.pos[0], sizeof(auth_entry0.bssid_addr));
memcpy(auth_entry0.client_addr, &this_mac.u8.pos[0], sizeof(auth_entry0.client_addr));
if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD)
denied_req_array_insert(auth_entry0);
else
denied_req_array_delete(auth_entry0);
break;
default:
printf("HELPER error - which entity?\n");
ret = -1;
}
if (m == i1)
cont = 0;
else
m += step;
}
return ret;
}
int consume_actions(int argc, char* argv[]);
int consume_actions(int argc, char* argv[])
{
int ret = 0;
int args_required = 0; // Suppress compiler warming by assigning initial value
int curr_arg = 0;
while (curr_arg < argc && ret == 0)
{
if (strcmp(*argv, "probe_sort") == 0)
{
args_required = 2;
if (curr_arg + args_required <= argc)
{
strcpy(sort_string, argv[1]);
}
}
else if (strcmp(*argv, "ap_show") == 0)
{
args_required = 1;
print_ap_array();
}
else if (strcmp(*argv, "probe_show") == 0)
{
args_required = 1;
print_probe_array();
}
else if (strcmp(*argv, "client_show") == 0)
{
args_required = 1;
print_client_array();
}
else if (strcmp(*argv, "auth_entry_show") == 0)
{
args_required = 1;
printf("--------APs------\n");
for (int i = 0; i <= denied_req_last; i++) {
print_auth_entry(denied_req_array[i]);
}
printf("------------------\n");
}
else if (strcmp(*argv, "ap_add_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_AP | HELPER_ACTION_ADD, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "ap_del_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_AP | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "probe_add_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_PROBE_ARRAY | HELPER_ACTION_ADD, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "probe_del_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_PROBE_ARRAY | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "client_add_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_CLIENT | HELPER_ACTION_ADD, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "client_del_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_CLIENT | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "auth_entry_add_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_AUTH_ENTRY | HELPER_ACTION_ADD, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "auth_entry_del_auto") == 0)
{
args_required = 3;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_AUTH_ENTRY | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else
{
args_required = 1;
printf("COMMAND \"%s\": Unknown - stopping!\n", *argv);
ret = -1;
}
curr_arg += args_required;
if (curr_arg <= argc)
{
// Still need to continue consuming args
argv += args_required;
}
else
{
// There aren't enough args left to give the parameters of the current action
printf("Commands are mangled at: \"%s\"!\n", *argv);
ret = -1;
}
}
return ret;
}
int process_script_line(char* line, size_t len);
#define MAX_LINE_ARGS 5
int process_script_line(char* line, size_t len)
{
int argc = 0;
char* argv[MAX_LINE_ARGS];
bool in_white = true;
bool force_blank = false;
int ret = 0;
//printf("%lu: \"%s\"\n", len, line);
while (len > 0 && !ret)
{
if (isblank(*line) || (*line == '\n') || (*line == '\r') || (*line == '#') || force_blank)
{
if (*line == '#')
{
//printf("Blanking 0x%02X...\n", *line);
force_blank = true;
}
//printf("Zapping 0x%02X...\n", *line);
*line = '\0';
in_white = true;
}
else
{
if (in_white)
{
//printf("Marking 0x%02X...\n", *line);
if (argc == MAX_LINE_ARGS)
{
printf("ERROR: Script line exceeds permitted arg count!\n");
ret = -1;
}
else
{
argv[argc] = line;
argc++;
in_white = false;
}
}
}
len--;
line++;
}
if (!ret)
ret = consume_actions(argc, argv);
return ret;
}
int main(int argc, char* argv[])
{
FILE* fp;
char* line = NULL;
size_t len = 0;
ssize_t read;
int ret = 0;
printf("DAWN datastorage.c test harness...\n\n");
if ((argc == 1) || !strcmp(*(argv + 1), "help") || !strcmp(*(argv + 1), "--help") || !strcmp(*(argv + 1), "-h"))
{
printf("Usage: %s [commands]\n\n", *argv);
printf(" [action [arg...]]... : Read test actions from command line\n");
printf(" --script [file]... : Read test script from file(s) (NB: \"-\" is a valid name\n");
printf(" indicating STDIN) {-s}\n");
printf(" - : Read test script from STDIN (and remaining arguments\n");
printf(" as script file names)\n");
printf(" --help : This help message {-h, help}\n");
printf("NB: Contents of {braces} indicate equivalent command\n");
}
else
{
// Step past command name on args, ie argv[0]
argc--;
argv++;
if (!strcmp(*argv, "--script") || !strcmp(*argv, "-s") || !strcmp(*argv, "-"))
{
if (!strcmp(*argv, "--script") || !strcmp(*argv, "-s"))
{
argc--;
argv++;
}
// Read script from file[s]
while (argc > 0 && ret == 0)
{
if (!strcmp(*argv, "-"))
{
fp = stdin;
printf("Consuming script from STDIN\n");
}
else
{
fp = fopen(*argv, "r");
if (fp == NULL)
{
printf("Error opening script file: %s\n", *argv);
ret = -1;
}
else
{
printf("Consuming script file: %s\n", *argv);
}
}
if (ret == 0)
{
read = getline(&line, &len, fp);
while (!ret && read != -1)
{
printf("Processing: %s\n", line);
ret = process_script_line(line, read);
if (!ret)
read = getline(&line, &len, fp);
}
if (fp != stdin)
fclose(fp);
if (line)
free(line);
}
argc--;
argv++;
}
}
else
{
// Take direct input on command line
ret = consume_actions(argc, argv);
}
}
printf("\nDAWN datastorage.c test harness - finshed. \n");
return ret;
}

View file

@ -42,7 +42,7 @@ int hwaddr_aton(const char *txt, uint8_t *addr) {
b = hex_to_bin(*txt++);
if (b < 0) return -1;
*addr++ = (a << 4) | b;
// TODO: Should NUL terminator be checked for? Is aa:bb:cc:dd:ee:ff00 valid input?
// TODO: Should NUL terminator be checked for? Is aa:bb:cc:dd:ee:ff00 valid input?
if (i < (ETH_ALEN - 1) && *txt++ != ':') return -1;
}