From 35e0d8b68a958c71b2dc90b9bceff718b29b75fb Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Mon, 6 Sep 2021 18:23:22 +0000 Subject: [PATCH] Add some test infrastructure. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3658 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- src/main.c | 9 +++- src/ssb.c | 1 + src/ssb.h | 2 - src/ssb.qjs.c | 14 +++--- src/ssb.tests.c | 16 ++----- src/ssb.tests.h | 7 +++ src/tests.c | 110 ++++++++++++++++++++++++++++++------------------ src/tests.h | 8 +++- 8 files changed, 103 insertions(+), 64 deletions(-) create mode 100644 src/ssb.tests.h diff --git a/src/main.c b/src/main.c index dd3fae958..589c12f99 100644 --- a/src/main.c +++ b/src/main.c @@ -119,10 +119,12 @@ void shedPrivileges() static int _tf_command_test(const char* file, int argc, char* argv[]) { typedef struct args_t { + const char* tests; bool help; } args_t; xoptOption options[] = { + { "tests", 't', offsetof(args_t, tests), NULL, XOPT_TYPE_STRING, NULL, "Comma-separated list of test names to run." }, { "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." }, XOPT_NULLOPTION, }; @@ -140,7 +142,12 @@ static int _tf_command_test(const char* file, int argc, char* argv[]) return 2; } - tf_tests(file); + tf_test_options_t test_options = + { + .exe_path = file, + .tests = args.tests, + }; + tf_tests(&test_options); return 0; xopt_help: if (extras) { diff --git a/src/ssb.c b/src/ssb.c index b80a6c24b..e98da6c63 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -1511,6 +1511,7 @@ static JSValue _tf_ssb_connection_send_json(JSContext* context, JSValueConst thi size, _tf_ssb_connection_send_json_response, JS_IsFunction(context, argv[1]) ? JS_VALUE_GET_PTR(JS_DupValue(context, argv[1])) : NULL); + JS_FreeCString(context, message); return JS_UNDEFINED; } diff --git a/src/ssb.h b/src/ssb.h index 5f9cc7601..a3b9e71f5 100644 --- a/src/ssb.h +++ b/src/ssb.h @@ -82,8 +82,6 @@ void tf_ssb_send_close(tf_ssb_t* ssb); bool tf_ssb_id_str_to_bin(uint8_t* bin, const char* str); bool tf_ssb_id_bin_to_str(char* str, size_t str_size, const uint8_t* bin); -void tf_ssb_test(); - typedef void (tf_ssb_rpc_callback_t)(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data); void tf_ssb_register_rpc(tf_ssb_t* ssb, const char** name, tf_ssb_rpc_callback_t* callback, tf_ssb_rpc_cleanup_t* cleanup, void* user_data); diff --git a/src/ssb.qjs.c b/src/ssb.qjs.c index dff202212..0bbd53ab7 100644 --- a/src/ssb.qjs.c +++ b/src/ssb.qjs.c @@ -339,7 +339,6 @@ static JSValue _tf_ssb_rpc_send_json(JSContext* context, JSValueConst this_val, JSValue message_val = JS_JSONStringify(context, argv[0], JS_NULL, JS_NULL); size_t size; const char* message = JS_ToCStringLen(context, &size, message_val); - JS_FreeValue(context, message_val); tf_ssb_connection_rpc_send( connection, @@ -350,6 +349,8 @@ static JSValue _tf_ssb_rpc_send_json(JSContext* context, JSValueConst this_val, NULL, NULL); JS_FreeValue(context, connection_val); + JS_FreeCString(context, message); + JS_FreeValue(context, message_val); return JS_UNDEFINED; } @@ -488,7 +489,7 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch break; case k_tf_ssb_change_connect: { - JSValue object = /*JS_DupValue(context,*/ tf_ssb_connection_get_object(connection);//); + JSValue object = JS_DupValue(context, tf_ssb_connection_get_object(connection)); JSValue args[] = { JS_NewString(context, "add"), @@ -497,13 +498,13 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch printf("calling function for ptr %p IsFunction=%d\n", user_data, JS_IsFunction(context, callback)); response = JS_Call(context, callback, JS_UNDEFINED, 2, args); _check_call(context, response); - //JS_FreeValue(context, object); + JS_FreeValue(context, args[0]); + JS_FreeValue(context, object); } break; case k_tf_ssb_change_remove: { - printf("CHANGE_REMOVE\n"); - JSValue object = /*JS_DupValue(context,*/ tf_ssb_connection_get_object(connection);//); + JSValue object = JS_DupValue(context, tf_ssb_connection_get_object(connection)); JSValue args[] = { JS_NewString(context, "remove"), @@ -511,7 +512,8 @@ static void _tf_ssb_rpc_on_connections_changed_callback(tf_ssb_t* ssb, tf_ssb_ch }; response = JS_Call(context, callback, JS_UNDEFINED, 2, args); _check_call(context, response); - //JS_FreeValue(context, object); + JS_FreeValue(context, args[0]); + JS_FreeValue(context, object); } break; } diff --git a/src/ssb.tests.c b/src/ssb.tests.c index 1f23fba13..621477ce8 100644 --- a/src/ssb.tests.c +++ b/src/ssb.tests.c @@ -2,6 +2,7 @@ #include "ssb.db.h" #include "ssb.qjs.h" +#include "tests.h" #include #include @@ -9,7 +10,7 @@ #include #include -static void _tf_ssb_test_id_conversion() +void tf_ssb_test_id_conversion(const tf_test_options_t* options) { printf("Testing id conversion.\n"); uint8_t bin[k_id_bin_len] = { 0 }; @@ -64,7 +65,7 @@ static int _ssb_test_count_messages(tf_ssb_t* ssb) return count; } -static void _tf_ssb_test_ssb() +void tf_ssb_test_ssb(const tf_test_options_t* options) { printf("Testing SSB.\n"); sqlite3* db0 = NULL; @@ -158,7 +159,7 @@ static void _tf_ssb_test_ssb() sqlite3_close(db1); } -static void _tf_ssb_test_following() +void tf_ssb_test_following(const tf_test_options_t* options) { printf("Testing following.\n"); sqlite3* db0 = NULL; @@ -236,12 +237,3 @@ static void _tf_ssb_test_following() sqlite3_close(db0); } - -void tf_ssb_test() -{ - printf("tf_ssb_test() starting.\n"); - _tf_ssb_test_id_conversion(); - _tf_ssb_test_ssb(); - _tf_ssb_test_following(); - printf("tf_ssb_test() completed successfully.\n"); -} diff --git a/src/ssb.tests.h b/src/ssb.tests.h new file mode 100644 index 000000000..11ce688c5 --- /dev/null +++ b/src/ssb.tests.h @@ -0,0 +1,7 @@ +#pragma once + +typedef struct _tf_test_options_t tf_test_options_t; + +void tf_ssb_test_id_conversion(const tf_test_options_t* options); +void tf_ssb_test_ssb(const tf_test_options_t* options); +void tf_ssb_test_following(const tf_test_options_t* options); diff --git a/src/tests.c b/src/tests.c index 4e3b44d74..7c6c90059 100644 --- a/src/tests.c +++ b/src/tests.c @@ -1,20 +1,22 @@ #include "tests.h" -#include "ssb.h" +#include "ssb.tests.h" #include +#include #include #include +#include #include -static void _test_nop(const char* exe_path) +static void _test_nop(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, "print('hi');"); fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); (void)result; @@ -22,7 +24,7 @@ static void _test_nop(const char* exe_path) assert(WEXITSTATUS(result) == 0); } -static void _test_child(const char* exe_path) +static void _test_child(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -43,7 +45,7 @@ static void _test_child(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); (void)result; @@ -54,7 +56,7 @@ static void _test_child(const char* exe_path) unlink("out/child.js"); } -static void _test_promise(const char* exe_path) +static void _test_promise(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -83,7 +85,7 @@ static void _test_promise(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); (void)result; @@ -94,7 +96,7 @@ static void _test_promise(const char* exe_path) unlink("out/child.js"); } -static void _test_promise_remote_throw(const char* exe_path) +static void _test_promise_remote_throw(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -127,7 +129,7 @@ static void _test_promise_remote_throw(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); (void)result; @@ -138,7 +140,7 @@ static void _test_promise_remote_throw(const char* exe_path) unlink("out/child.js"); } -static void _test_promise_remote_reject(const char* exe_path) +static void _test_promise_remote_reject(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -173,7 +175,7 @@ static void _test_promise_remote_reject(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); (void)result; @@ -184,7 +186,7 @@ static void _test_promise_remote_reject(const char* exe_path) unlink("out/child.js"); } -static void _test_database(const char* exe_path) +static void _test_database(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -219,7 +221,7 @@ static void _test_database(const char* exe_path) unlink("out/testdb.sqlite"); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 --db-path=out/testdb.sqlite -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 --db-path=out/testdb.sqlite -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -230,7 +232,7 @@ static void _test_database(const char* exe_path) unlink("out/testdb.sqlite"); } -static void _test_this(const char* exe_path) +static void _test_this(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -240,7 +242,7 @@ static void _test_this(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -250,7 +252,7 @@ static void _test_this(const char* exe_path) unlink("out/test.js"); } -static void _test_await(const char* exe_path) +static void _test_await(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -273,7 +275,7 @@ static void _test_await(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -283,7 +285,7 @@ static void _test_await(const char* exe_path) unlink("out/test.js"); } -static void _test_require(const char* exe_path) +static void _test_require(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -312,7 +314,7 @@ static void _test_require(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -323,7 +325,7 @@ static void _test_require(const char* exe_path) unlink("out/required.js"); } -static void _test_exit(const char* exe_path) +static void _test_exit(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, "require('blah');"); @@ -334,7 +336,7 @@ static void _test_exit(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -345,7 +347,7 @@ static void _test_exit(const char* exe_path) unlink("out/blah.js"); } -static void _test_icu(const char* exe_path) +static void _test_icu(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -354,7 +356,7 @@ static void _test_icu(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -364,7 +366,7 @@ static void _test_icu(const char* exe_path) unlink("out/test.js"); } -static void _test_uint8array(const char* exe_path) +static void _test_uint8array(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -404,7 +406,7 @@ static void _test_uint8array(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -415,7 +417,7 @@ static void _test_uint8array(const char* exe_path) unlink("out/child.js"); } -static void _test_socket(const char* exe_path) +static void _test_socket(const tf_test_options_t* options) { FILE* file = fopen("out/test.js", "w"); fprintf(file, @@ -468,7 +470,7 @@ static void _test_socket(const char* exe_path) fclose(file); char command[256]; - snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", exe_path); + snprintf(command, sizeof(command), "%s run --ssb-port=0 -s out/test.js", options->exe_path); printf("%s\n", command); int result = system(command); printf("returned %d\n", WEXITSTATUS(result)); @@ -478,21 +480,45 @@ static void _test_socket(const char* exe_path) unlink("out/test.js"); } -void tf_tests(const char* exe_path) +static void _tf_test_run(const tf_test_options_t* options, const char* name, void (*test)(const tf_test_options_t* options)) { - tf_ssb_test(); - _test_nop(exe_path); - _test_child(exe_path); - _test_promise(exe_path); - _test_promise_remote_throw(exe_path); - _test_promise_remote_reject(exe_path); - _test_database(exe_path); - _test_this(exe_path); - _test_await(exe_path); - _test_require(exe_path); - _test_exit(exe_path); - _test_icu(exe_path); - _test_uint8array(exe_path); - _test_socket(exe_path); + bool specified = false; + if (options->tests) { + char* dup = strdup(options->tests); + char* state = NULL; + const char* t = NULL; + while ((t = strtok_r(t ? NULL : dup, ",", &state)) != NULL) { + if (strcmp(t, name) == 0) { + specified = true; + break; + } + } + free(dup); + } + + if (!options->tests || specified) { + printf("Running test %s.", name); + test(options); + } +} + +void tf_tests(const tf_test_options_t* options) +{ + _tf_test_run(options, "ssb", tf_ssb_test_ssb); + _tf_test_run(options, "ssb_id", tf_ssb_test_id_conversion); + _tf_test_run(options, "ssb_following", tf_ssb_test_following); + _tf_test_run(options, "nop", _test_nop); + _tf_test_run(options, "child", _test_child); + _tf_test_run(options, "promise", _test_promise); + _tf_test_run(options, "promise_remote_throw", _test_promise_remote_throw); + _tf_test_run(options, "promise_remote_reject", _test_promise_remote_reject); + _tf_test_run(options, "database", _test_database); + _tf_test_run(options, "this", _test_this); + _tf_test_run(options, "await", _test_await); + _tf_test_run(options, "require", _test_require); + _tf_test_run(options, "exit", _test_exit); + _tf_test_run(options, "icu", _test_icu); + _tf_test_run(options, "uint8array", _test_uint8array); + _tf_test_run(options, "socket", _test_socket); printf("Tests completed.\n"); } diff --git a/src/tests.h b/src/tests.h index 65799dc4e..b3297885d 100644 --- a/src/tests.h +++ b/src/tests.h @@ -1,3 +1,9 @@ #pragma once -void tf_tests(const char* exe_path); +typedef struct _tf_test_options_t +{ + const char* exe_path; + const char* tests; +} tf_test_options_t; + +void tf_tests(const tf_test_options_t* options);