Initial Awawawa
This commit is contained in:
145
backend/tests/test_main.c
Normal file
145
backend/tests/test_main.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* Minimal unit test runner: ./test_runner [test_name ...] */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../src/config.h"
|
||||
#include "../src/json.h"
|
||||
#include "../src/net.h"
|
||||
#include "../src/proto.h"
|
||||
#include "../src/services.h"
|
||||
|
||||
static int failures;
|
||||
|
||||
#define CHECK(cond) do { \
|
||||
if (!(cond)) { \
|
||||
fprintf(stderr, " %s:%d: CHECK(%s) failed\n", __FILE__, __LINE__, #cond); \
|
||||
failures++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Tests */
|
||||
|
||||
static void test_config(void)
|
||||
{
|
||||
struct pb_config c;
|
||||
config_defaults(&c);
|
||||
char l1[] = "Role = target";
|
||||
char l2[] = " TargetPort=2200 # not a comment, atoi stops";
|
||||
char l3[] = "# comment";
|
||||
char l4[] = "IdentityFile = \" /etc/x \"";
|
||||
char l5[] = "SysopPassword = secret";
|
||||
char l6[] = "garbage";
|
||||
CHECK(config_parse_line(&c, l1) == 0 && c.role == ROLE_TARGET);
|
||||
CHECK(config_parse_line(&c, l2) == 0 && c.target_port == 2200);
|
||||
CHECK(config_parse_line(&c, l3) == 0);
|
||||
CHECK(config_parse_line(&c, l4) == 0 && !strcmp(c.identity_file, " /etc/x "));
|
||||
CHECK(config_parse_line(&c, l5) == 0);
|
||||
CHECK(config_parse_line(&c, l6) == -1);
|
||||
}
|
||||
|
||||
static void test_lines(void)
|
||||
{
|
||||
struct buf b;
|
||||
buf_init(&b);
|
||||
char out[PB_MAX_LINE];
|
||||
buf_append(&b, "HELLO abc 7701\r\nSINK 1 tcp", 26);
|
||||
CHECK(line_next(&b, out, sizeof(out)) == 1 && !strcmp(out, "HELLO abc 7701"));
|
||||
CHECK(line_next(&b, out, sizeof(out)) == 0);
|
||||
buf_append(&b, " 0.0.0.0 80\n", 12);
|
||||
CHECK(line_next(&b, out, sizeof(out)) == 1);
|
||||
char *f[PB_MAX_FIELDS];
|
||||
CHECK(line_split(out, f, PB_MAX_FIELDS) == 5 && !strcmp(f[4], "80"));
|
||||
buf_free(&b);
|
||||
|
||||
char s1[16] = "a b\tc";
|
||||
field_sanitise(s1);
|
||||
CHECK(!strcmp(s1, "a_b_c"));
|
||||
char s2[4] = "";
|
||||
field_sanitise(s2);
|
||||
CHECK(!strcmp(s2, "-"));
|
||||
}
|
||||
|
||||
static void test_udp_frames(void)
|
||||
{
|
||||
struct buf b;
|
||||
buf_init(&b);
|
||||
const char *p;
|
||||
CHECK(udp_frame_append(&b, "hello", 5) == 0);
|
||||
CHECK(udp_frame_append(&b, "", 0) == 0);
|
||||
CHECK(udp_frame_peek(&b, &p) == 5 && !memcmp(p, "hello", 5));
|
||||
buf_consume(&b, 7);
|
||||
CHECK(udp_frame_peek(&b, &p) == -2);
|
||||
buf_consume(&b, 2);
|
||||
CHECK(udp_frame_peek(&b, &p) == 0);
|
||||
buf_append(&b, "\x00\x03" "ab", 4);
|
||||
CHECK(udp_frame_peek(&b, &p) == 0); // incomplete
|
||||
buf_free(&b);
|
||||
}
|
||||
|
||||
static void test_services_parse(void)
|
||||
{
|
||||
struct svc_entry e;
|
||||
// 127.0.0.1:22 LISTEN, as printed on a little endian machine.
|
||||
const char *tcp = " 0: 0100007F:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12345 1 0000000000000000 100 0 0 10 0";
|
||||
CHECK(services_parse_line(tcp, 0, 0, &e) == 1);
|
||||
CHECK(e.port == 22 && e.inode == 12345 && e.proto == PROTO_TCP);
|
||||
// Established connection is skipped.
|
||||
const char *est = " 1: 0100007F:0016 0100007F:D431 01 00000000:00000000 00:00000000 00000000 0 0 222 1 0000000000000000 100 0 0 10 0";
|
||||
CHECK(services_parse_line(est, 0, 0, &e) == 0);
|
||||
// :: port 53 UDP
|
||||
const char *udp6 = " 10: 00000000000000000000000000000000:0035 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 999 2 0000000000000000 0";
|
||||
CHECK(services_parse_line(udp6, 1, 1, &e) == 1);
|
||||
CHECK(e.port == 53 && !strcmp(e.addr, "::") && e.proto == PROTO_UDP);
|
||||
CHECK(services_parse_line("bogus", 0, 0, &e) == -1);
|
||||
}
|
||||
|
||||
static void test_json(void)
|
||||
{
|
||||
struct buf b;
|
||||
buf_init(&b);
|
||||
json_str(&b, "a\"b\\c\n\x01");
|
||||
buf_append(&b, "", 1);
|
||||
CHECK(!strcmp(b.data, "\"a\\\"b\\\\c\\n\\u0001\""));
|
||||
buf_free(&b);
|
||||
}
|
||||
|
||||
static void test_token(void)
|
||||
{
|
||||
char a[PB_TOKEN_LEN + 1], b[PB_TOKEN_LEN + 1];
|
||||
CHECK(random_token(a, sizeof(a)) == 0 && strlen(a) == PB_TOKEN_LEN);
|
||||
CHECK(random_token(b, sizeof(b)) == 0 && strcmp(a, b));
|
||||
}
|
||||
|
||||
/* Runner */
|
||||
|
||||
static const struct { const char *name; void (*fn)(void); } tests[] = {
|
||||
{ "config", test_config },
|
||||
{ "lines", test_lines },
|
||||
{ "udp_frames", test_udp_frames },
|
||||
{ "services_parse", test_services_parse },
|
||||
{ "json", test_json },
|
||||
{ "token", test_token },
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ran = 0;
|
||||
for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
|
||||
int want = argc < 2;
|
||||
for (int a = 1; a < argc; a++)
|
||||
want |= !strcmp(argv[a], tests[i].name);
|
||||
if (!want)
|
||||
continue;
|
||||
int before = failures;
|
||||
tests[i].fn();
|
||||
printf("%s %s\n", failures == before ? "ok " : "FAIL", tests[i].name);
|
||||
ran++;
|
||||
}
|
||||
if (!ran) {
|
||||
fprintf(stderr, "no matching tests\n");
|
||||
return 2;
|
||||
}
|
||||
return failures ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user