#include #include #include #include #include #include #include "lflinkedlist.h" #include "lfnetwork.h" #include "lfset.h" #include "lfstack.h" #include "lfbinarytree.h" #include "lfvector.h" #include "lfmath.h" #include "lfstring.h" #include "lfcrypto.h" #include "lfparsing.h" #include "lfinput.h" #if defined(__APPLE__) || defined(__MACH__) #include "lfmacos.h" #endif /* defined(__APPLE__) || defined(__MACH__) */ void print_ll(List *list) { LL_ITER(list) { printf(" %d", *((int *) node->data)); } printf("\n"); } void test_ll() { printf("\n--- LIST TEST ---\n"); List *list = malloc(sizeof(List)); ll_init(list, NULL); int i = 1; int j = 2; int k = 4; ll_ins_next(list, list->head, (void *) &i); ll_ins_next(list, list->tail, (void *) &j); ll_ins_next(list, list->tail, (void *) &k); printf("List: "); print_ll(list); void *data; ll_remove_next(list, list->head, &data); printf("List: "); print_ll(list); assert(*(int*)data == 2); printf("Removed: %d\n", *((int *) data)); ll_destroy(list); free(list); } int int_match(const void *a, const void *b) { return *((int *) a) == *((int *) b); } void test_set() { printf("\n--- SET TEST ---\n"); Set *set = malloc(sizeof(Set)); set_init(set, int_match, NULL); int i = 1; int j = 2; int k = 2; set_insert(set, (void *) &i); set_insert(set, (void *) &j); set_insert(set, (void *) &k); int i2 = 1; int j2 = 4; Set *set2 = malloc(sizeof(Set)); set_init(set2, int_match, NULL); set_insert(set2, (void *) &i2); set_insert(set2, (void *) &j2); printf("Set 1:"); print_ll(set); printf("Set 2:"); print_ll(set2); printf("\n"); Set *set_u = malloc(sizeof(Set)); Set *set_i = malloc(sizeof(Set)); Set *set_d = malloc(sizeof(Set)); set_union(set_u, set, set2); printf("Union:"); print_ll(set_u); set_difference(set_d, set, set2); printf("Difference:"); print_ll(set_d); set_intersection(set_i, set, set2); printf("Intersection:"); print_ll(set_i); set_destroy(set); set_destroy(set2); set_destroy(set_u); set_destroy(set_i); set_destroy(set_d); free(set); free(set2); free(set_u); free(set_i); free(set_d); } void test_stack() { printf("\n--- STACK TEST ---\n"); Stack *stack = malloc(sizeof(Stack)); stack_init(stack, NULL); int a = 1, b = 2; stack_push(stack, &a); stack_push(stack, &b); printf("Stack size: %lu\n", stack->size); int *p = NULL; stack_pop(stack, (void **) &p); printf("b = %d\n", *p); stack_pop(stack, (void **) &p); printf("a = %d\n", *p); printf("Stack size: %lu\n", stack->size); stack_destroy(stack); free(stack); stack = NULL; } void test_bintree() { printf("\n--- BINARY TREE TEST ---\n"); BinTree *tree = malloc(sizeof(BinTree)); bintree_init(tree, NULL); int root = 0; int l1 = 1; int l2 = 2; int r1 = 12; int r2 = 200; bintree_ins_left(tree, NULL, &root); bintree_ins_left(tree, tree->root, &l1); bintree_ins_left(tree, tree->root->left, &l2); bintree_ins_right(tree, tree->root->left, &r2); bintree_ins_right(tree, tree->root, &r1); bintree_ins_right(tree, tree->root->right, &r2); bintree_ins_left(tree, tree->root->right, &l1); bintree_debug_print(tree); printf("Changing r2\n"); r2 = 100; bintree_debug_print(tree); bintree_destroy(tree); free(tree); tree = NULL; } void test_math() { printf("\n--- MATH TEST ---\n"); int i = 1, j = 2; assert(max_int(i, j) == j); printf("Between %d and %d, %d is larger\n", i, j, max_int(i, j)); printf("Between %d and %d, %d is smaller\n", i, j, min_int(i, j)); char *s = "10101101"; printf("Binary: %s\n", s); printf("Decimal: %d\n", binstr_to_int(s)); char *s2 = "1010_1101"; printf("Binary: %s\n", s2); printf("Decimal: %d\n", binstr_to_int(s2)); i = 10; i = clamp_int(i, 2, 5); assert(i == 5); printf("\nGenerate line from 0,0 to 2,5\n"); size_t sz = 0; Point *line = bresenham(0, 0, 2, 5, &sz); for (size_t idx = 0; idx < sz; idx++) { printf("%d,%d ", line[idx].x, line[idx].y); } printf("\n"); free(line); } void print_vector(Vector *vec) { for (size_t i = 0; i < vec->length; ++i) { int t = *(int*)vec_at(vec, i); printf("%d ", t); } printf("\n"); } void test_vector() { printf("\n--- VECTOR TEST ---\n"); Vector *v = malloc(sizeof(Vector)); vec_init(v, NULL); int e0 = 0; int e1 = 1; int e2 = 2; int e3 = 3; int e4 = 4; vec_push(v, &e0); assert(v->length == 1); int *t = (int*)vec_at(v, 0); assert(*t == 0); vec_push(v, &e1); vec_push(v, &e2); assert(v->length == 3); // test access outside bounds t = (int*)vec_safe_at(v, 3); assert(t == NULL); printf("Before insert: "); print_vector(v); vec_push(v, &e4); vec_insert(v, &e3, 3); printf("After insert: "); print_vector(v); t = (int*)vec_at(v, 3); assert(*t == e3); t = (int*)vec_at(v, 4); assert(*t == e4); const int *min = vec_min(v, vec_cmp_int); const int *max = vec_max(v, vec_cmp_int); printf("min: %d\n", *min); printf("max: %d\n", *max); assert(*min == e0); assert(*max == e4); t = (int*)vec_remove(v, 1); assert(t != NULL); assert(*t == 1); printf("After removal: "); print_vector(v); t = (int*)vec_remove(v, 10); assert(t == NULL); printf("\ncap before shrink: %zu\n", vec_cap(v)); vec_shrink(v); assert(vec_len(v) == vec_cap(v)); printf("cap after shrink: %zu\n", vec_cap(v)); vec_destroy(v); free(v); } void test_string() { printf("\n--- STRING TEST ---\n"); const char* haystack = "Test one two one and also maybe two but not Gabe's least favorite number, which is not one."; const char* needles[] = { "one", "two", "Gabe" }; size_t sub_sz = 0; size_t *subs = NULL; find_substrings(haystack, needles[0], &sub_sz, &subs); assert(sub_sz == 3); assert(subs[0] == 5); assert(subs[1] == 13); assert(subs[2] == 87); const char *s = substr(haystack, subs[0], strlen(needles[0])); assert(strcmp(s, needles[0]) == 0); free(s); free(subs); subs = NULL; find_substrings(haystack, needles[1], &sub_sz, &subs); assert(sub_sz == 2); assert(subs[0] == 9); free(subs); subs = NULL; find_substrings("test one two", "nope", &sub_sz, &subs); assert(sub_sz == 0); assert(subs == NULL); free(subs); subs = NULL; find_substrings("123", "nopes", &sub_sz, &subs); assert(sub_sz == 0); assert(subs == NULL); free(subs); subs = NULL; printf("Passes all string tests\n"); } void test_crypto() { printf("\n--- CRYPTO TEST ---\n"); char *in = "BUTT"; unsigned char *s = b64_encode(in, strlen(in)); assert(strcmp(s, "QlVUVA==") == 0); free(s); char *in2 = "a longer base64 test, apparently"; s = b64_encode(in2, strlen(in2)); assert(strcmp(s, "YSBsb25nZXIgYmFzZTY0IHRlc3QsIGFwcGFyZW50bHk=") == 0); free(s); char *out2 = "YSBsb25nZXIgYmFzZTY0IHRlc3QsIGFwcGFyZW50bHk="; size_t s_sz = 0; s = (char *)b64_decode(out2, strlen(out2), &s_sz); assert(strcmp(s, "a longer base64 test, apparently") == 0); assert(strlen(s) == s_sz); free(s); s = hex_decode("DEADBEEF", &s_sz); unsigned char h[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; for (size_t i = 0; i < 4; ++i) { assert(s[i] == h[i]); } free(s); // Odd number of characters s = hex_decode("f00f5", &s_sz); unsigned char h2[4] = { 0x0F, 0x00, 0xF5 }; for (size_t i = 0; i < 3; ++i) { assert(s[i] == h2[i]); } free(s); // leading 0x s = hex_decode("0xf00f5", &s_sz); for (size_t i = 0; i < 3; ++i) { assert(s[i] == h2[i]); } free(s); s = hex_encode(h, 4); assert(strcmp(s, "deadbeef") == 0); free(s); // "Sup?" unsigned char hexsup[4] = { 0x53, 0x75, 0x70, 0x3F }; s = hex_to_str(hexsup, 4); assert(strcmp(s, "Sup?") == 0); free(s); s = repeating_key_xor_s("TEST", "HI"); const char *enc = hex_encode(s, 4); assert(strcmp(enc, "1c0c1b1d") == 0); free(enc); free(s); unsigned char ua[2] = { 0x2, 0xF }; unsigned char ub[2] = { 0x4, 0xE }; unsigned int hamming = hamming_distance(ua, ub, 2); assert(hamming == 3); hamming = hamming_distance_s("this is a test", "wokka wokka!!!"); assert(hamming == 37); printf("Passes all crypto tests\n"); } void test_parsing() { printf("\n--- PARSING TEST ---\n"); char *nonsense = "8d82jI|dms~<>s2d"; char *english = "This is an English sentence!"; assert(simple_english_scoring(english) > simple_english_scoring(nonsense)); printf("Passes all parsing tests\n"); } #define NET_MSG "TEST SEND" void tcp_test_handler(Server *s) { struct sockaddr_storage client_addr; socklen_t client_addr_sz = sizeof(client_addr); int new_fd = accept(s->fd, (struct sockaddr *)&client_addr, &client_addr_sz); assert(new_fd != -1); assert(send(new_fd, NET_MSG, 10, 0) != -1); close(new_fd); } void *tcp_server_thread(void *vargp) { Server *server = new_server(SERVERTYPE_TCP, "18632", tcp_test_handler); serve(server, DEFAULT_BACKLOG); delete_server(server); } void udp_test_handler(Server *s) { struct sockaddr_storage client_addr; socklen_t client_addr_sz = sizeof(client_addr); char recv_buf[128]; int r = (int)recvfrom(s->fd, recv_buf, 128, 0, (struct sockaddr*)&client_addr, &client_addr_sz); assert(r > 0); assert(strcmp(recv_buf, NET_MSG) == 0); } void *udp_server_thread(void *vargp) { Server *server = new_server(SERVERTYPE_UDP, "18633", udp_test_handler); serve(server, DEFAULT_BACKLOG); delete_server(server); } void test_network() { printf("\n--- NETWORK TEST ---\n"); pthread_t srv_tid; pthread_create(&srv_tid, NULL, tcp_server_thread, NULL); sleep(1); const char *s = capture_system("echo hello | nc localhost 18632", 0); assert(strcmp(s, NET_MSG) == 0); free((char *)s); pthread_join(srv_tid, NULL); printf("Passed TCP test\n"); pthread_create(&srv_tid, NULL, udp_server_thread, NULL); sleep(1); system("echo hello | nc localhost 18633"); assert(strcmp(s, NET_MSG) == 0); pthread_join(srv_tid, NULL); printf("Passed UDP test\n"); } #if defined(__APPLE__) || defined(__MACH__) void test_macos() { printf("\n--- macOS TEST ---\n"); pid_t pid = getpid(); ProcessData *pd = new_ProcessData(); for (int i = 0; i < 4; i++) { update_process(pid, pd); printf("CPU: %.2f\n", pd->percent_cpu); sleep(1); } free(pd); } #endif int main() { test_ll(); test_set(); test_stack(); test_bintree(); test_math(); test_vector(); test_string(); test_crypto(); test_parsing(); test_network(); #if defined(__APPLE__) || defined(__MACH__) test_macos(); #endif return 0; }