2021-01-02 13:10:00 -05:00
|
|
|
#include "ssb.h"
|
|
|
|
|
2022-06-04 13:04:51 -04:00
|
|
|
#include "mem.h"
|
2021-08-22 15:41:27 -04:00
|
|
|
#include "ssb.db.h"
|
2021-10-24 11:46:30 -04:00
|
|
|
#include "ssb.js.h"
|
2021-09-06 14:23:22 -04:00
|
|
|
#include "tests.h"
|
2022-01-22 15:47:10 -05:00
|
|
|
#include "util.js.h"
|
2021-08-22 15:41:27 -04:00
|
|
|
|
2021-01-02 13:10:00 -05:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sqlite3.h>
|
|
|
|
#include <uv.h>
|
|
|
|
|
2022-01-22 15:47:10 -05:00
|
|
|
#include "quickjs-libc.h"
|
|
|
|
|
2021-09-06 14:23:22 -04:00
|
|
|
void tf_ssb_test_id_conversion(const tf_test_options_t* options)
|
2021-01-02 13:10:00 -05:00
|
|
|
{
|
|
|
|
printf("Testing id conversion.\n");
|
|
|
|
uint8_t bin[k_id_bin_len] = { 0 };
|
|
|
|
char str[k_id_base64_len] = { 0 };
|
|
|
|
const char* k_id = "@bzRTe6hgOII2yZ1keGGoNoQgostjQc830trHc453crY=.ed25519";
|
|
|
|
(void)bin;
|
|
|
|
(void)str;
|
|
|
|
(void)k_id;
|
2022-05-20 21:38:13 -04:00
|
|
|
bool b = tf_ssb_id_str_to_bin(bin, k_id);
|
|
|
|
(void)b;
|
|
|
|
assert(b);
|
|
|
|
b = tf_ssb_id_bin_to_str(str, sizeof(str), bin);
|
|
|
|
assert(b);
|
|
|
|
b = strcmp(str, k_id) == 0;
|
|
|
|
assert(b);
|
2021-01-02 13:10:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct _test_t {
|
|
|
|
tf_ssb_t* ssb0;
|
|
|
|
tf_ssb_t* ssb1;
|
2022-11-02 19:34:44 -04:00
|
|
|
tf_ssb_t* ssb2;
|
2021-01-02 13:10:00 -05:00
|
|
|
int connection_count0;
|
|
|
|
int connection_count1;
|
2022-11-02 19:34:44 -04:00
|
|
|
int connection_count2;
|
|
|
|
int broadcast_count0;
|
|
|
|
int broadcast_count1;
|
|
|
|
int broadcast_count2;
|
2021-01-02 13:10:00 -05:00
|
|
|
} test_t;
|
|
|
|
|
|
|
|
static void _ssb_test_connections_changed(tf_ssb_t* ssb, tf_ssb_change_t change, tf_ssb_connection_t* connection, void* user_data)
|
|
|
|
{
|
|
|
|
test_t* test = user_data;
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
const char** c = tf_ssb_get_connection_ids(ssb);
|
2021-10-10 17:51:38 -04:00
|
|
|
for (const char** p = c; *p; p++)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
count++;
|
|
|
|
}
|
2022-06-04 13:04:51 -04:00
|
|
|
tf_free(c);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (ssb == test->ssb0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("callback0 change=%d connection=%p\n", change, connection);
|
|
|
|
test->connection_count0 = count;
|
2021-10-10 17:51:38 -04:00
|
|
|
}
|
|
|
|
else if (ssb == test->ssb1)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("callback1 change=%d connection=%p\n", change, connection);
|
|
|
|
test->connection_count1 = count;
|
|
|
|
}
|
2022-11-02 19:34:44 -04:00
|
|
|
else if (ssb == test->ssb2)
|
|
|
|
{
|
|
|
|
printf("callback2 change=%d connection=%p\n", change, connection);
|
|
|
|
test->connection_count2 = count;
|
|
|
|
}
|
|
|
|
printf("conns = %d %d %d\n", test->connection_count0, test->connection_count1, test->connection_count2);
|
2021-01-02 13:10:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void _count_messages_callback(JSValue row, void* user_data)
|
|
|
|
{
|
|
|
|
int* count = user_data;
|
|
|
|
++*count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _ssb_test_count_messages(tf_ssb_t* ssb)
|
|
|
|
{
|
|
|
|
int count = 0;
|
2021-08-22 15:41:27 -04:00
|
|
|
tf_ssb_db_visit_query(ssb, "SELECT * FROM messages", JS_UNDEFINED, _count_messages_callback, &count);
|
2021-01-02 13:10:00 -05:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2021-11-17 18:47:55 -05:00
|
|
|
static void _message_added(tf_ssb_t* ssb, const char* id, void* user_data)
|
|
|
|
{
|
|
|
|
++*(int*)user_data;
|
|
|
|
}
|
|
|
|
|
2022-01-22 15:47:10 -05:00
|
|
|
static void _ssb_test_idle(uv_idle_t* idle)
|
|
|
|
{
|
|
|
|
tf_ssb_t* ssb = idle->data;
|
|
|
|
JSRuntime* runtime = JS_GetRuntime(tf_ssb_get_context(ssb));
|
|
|
|
while (JS_IsJobPending(runtime))
|
|
|
|
{
|
|
|
|
JSContext* context = NULL;
|
|
|
|
int r = JS_ExecutePendingJob(runtime, &context);
|
|
|
|
JSValue result = JS_GetException(context);
|
|
|
|
if (context)
|
|
|
|
{
|
|
|
|
tf_util_report_error(context, result);
|
|
|
|
}
|
|
|
|
if (r < 0)
|
|
|
|
{
|
|
|
|
js_std_dump_error(context);
|
|
|
|
}
|
|
|
|
else if (r == 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-06 14:23:22 -04:00
|
|
|
void tf_ssb_test_ssb(const tf_test_options_t* options)
|
2021-01-02 13:10:00 -05:00
|
|
|
{
|
|
|
|
printf("Testing SSB.\n");
|
|
|
|
sqlite3* db0 = NULL;
|
|
|
|
sqlite3* db1 = NULL;
|
|
|
|
|
2022-05-20 21:38:13 -04:00
|
|
|
int r = sqlite3_open(":memory:", &db0);
|
|
|
|
(void)r;
|
|
|
|
assert(r == SQLITE_OK);
|
|
|
|
r = sqlite3_open(":memory:", &db1);
|
|
|
|
assert(r == SQLITE_OK);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
uv_loop_t loop = { 0 };
|
|
|
|
uv_loop_init(&loop);
|
|
|
|
|
2022-10-14 08:27:34 -04:00
|
|
|
tf_ssb_t* ssb0 = tf_ssb_create(&loop, NULL, db0);
|
2021-10-24 11:46:30 -04:00
|
|
|
tf_ssb_register(tf_ssb_get_context(ssb0), ssb0);
|
2022-10-14 08:27:34 -04:00
|
|
|
tf_ssb_t* ssb1 = tf_ssb_create(&loop, NULL, db1);
|
2021-10-24 11:46:30 -04:00
|
|
|
tf_ssb_register(tf_ssb_get_context(ssb1), ssb1);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
2022-01-22 15:47:10 -05:00
|
|
|
uv_idle_t idle0 = { .data = ssb0 };
|
|
|
|
uv_idle_init(&loop, &idle0);
|
|
|
|
uv_idle_start(&idle0, _ssb_test_idle);
|
|
|
|
|
|
|
|
uv_idle_t idle1 = { .data = ssb1 };
|
|
|
|
uv_idle_init(&loop, &idle1);
|
|
|
|
uv_idle_start(&idle1, _ssb_test_idle);
|
|
|
|
|
2021-01-02 13:10:00 -05:00
|
|
|
test_t test = {
|
|
|
|
.ssb0 = ssb0,
|
|
|
|
.ssb1 = ssb1,
|
|
|
|
};
|
|
|
|
|
2021-09-06 13:50:38 -04:00
|
|
|
tf_ssb_add_connections_changed_callback(ssb0, _ssb_test_connections_changed, NULL, &test);
|
|
|
|
tf_ssb_add_connections_changed_callback(ssb1, _ssb_test_connections_changed, NULL, &test);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
tf_ssb_generate_keys(ssb0);
|
|
|
|
tf_ssb_generate_keys(ssb1);
|
|
|
|
|
|
|
|
char id0[k_id_base64_len] = { 0 };
|
|
|
|
char id1[k_id_base64_len] = { 0 };
|
|
|
|
bool b = tf_ssb_whoami(ssb0, id0, sizeof(id0));
|
|
|
|
(void)b;
|
|
|
|
assert(b);
|
2021-09-08 20:15:57 -04:00
|
|
|
b = tf_ssb_whoami(ssb1, id1, sizeof(id1));
|
2021-01-02 13:10:00 -05:00
|
|
|
assert(b);
|
|
|
|
printf("ID %s and %s\n", id0, id1);
|
|
|
|
|
|
|
|
char blob_id[k_id_base64_len] = { 0 };
|
|
|
|
const char* k_blob = "Hello, blob!";
|
2022-10-12 08:27:32 -04:00
|
|
|
b = tf_ssb_db_blob_store(ssb0, (const uint8_t*)k_blob, strlen(k_blob), blob_id, sizeof(blob_id), NULL);
|
2021-01-02 13:10:00 -05:00
|
|
|
assert(b);
|
|
|
|
|
|
|
|
tf_ssb_append_post(ssb0, "Hello, world!");
|
|
|
|
tf_ssb_append_post(ssb0, "First post.");
|
|
|
|
|
|
|
|
JSContext* context = tf_ssb_get_context(ssb0);
|
|
|
|
JSValue message = JS_NewObject(context);
|
|
|
|
JS_SetPropertyStr(context, message, "type", JS_NewString(context, "post"));
|
|
|
|
JS_SetPropertyStr(context, message, "text", JS_NewString(context, "First post."));
|
|
|
|
JSValue mentions = JS_NewArray(context);
|
|
|
|
JSValue mention = JS_NewObject(context);
|
|
|
|
JS_SetPropertyStr(context, mention, "link", JS_NewString(context, blob_id));
|
|
|
|
JS_SetPropertyUint32(context, mentions, 0, mention);
|
|
|
|
JS_SetPropertyStr(context, message, "mentions", mentions);
|
|
|
|
tf_ssb_append_message(ssb0, message);
|
|
|
|
JS_FreeValue(context, message);
|
|
|
|
|
2022-05-20 21:38:13 -04:00
|
|
|
b = tf_ssb_db_blob_get(ssb0, blob_id, NULL, NULL);
|
|
|
|
assert(b);
|
|
|
|
b = !tf_ssb_db_blob_get(ssb1, blob_id, NULL, NULL);
|
|
|
|
assert(b);
|
2021-01-02 13:10:00 -05:00
|
|
|
tf_ssb_server_open(ssb0, 12347);
|
|
|
|
|
|
|
|
uint8_t id0bin[k_id_bin_len];
|
|
|
|
tf_ssb_id_str_to_bin(id0bin, id0);
|
|
|
|
tf_ssb_connect(ssb1, "127.0.0.1", 12347, id0bin);
|
|
|
|
|
2021-10-31 15:39:16 -04:00
|
|
|
printf("Waiting for connection.\n");
|
2021-01-02 13:10:00 -05:00
|
|
|
while (test.connection_count0 != 1 ||
|
2021-10-10 17:51:38 -04:00
|
|
|
test.connection_count1 != 1)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
tf_ssb_server_close(ssb0);
|
|
|
|
|
2021-10-31 15:39:16 -04:00
|
|
|
printf("Waiting for messages.\n");
|
2021-10-10 17:51:38 -04:00
|
|
|
while (_ssb_test_count_messages(ssb1) < 3)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
|
2021-10-31 15:39:16 -04:00
|
|
|
printf("Waiting for blob.\n");
|
2021-10-10 17:51:38 -04:00
|
|
|
while (!tf_ssb_db_blob_get(ssb1, blob_id, NULL, NULL))
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
2021-11-17 18:47:55 -05:00
|
|
|
|
|
|
|
printf("Waiting for message to self.\n");
|
|
|
|
int count0 = 0;
|
|
|
|
int count1 = 0;
|
|
|
|
tf_ssb_add_message_added_callback(ssb0, _message_added, NULL, &count0);
|
|
|
|
tf_ssb_add_message_added_callback(ssb1, _message_added, NULL, &count1);
|
|
|
|
tf_ssb_append_post(ssb0, "Message to self.");
|
|
|
|
while (count0 == 0)
|
|
|
|
{
|
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
tf_ssb_remove_message_added_callback(ssb0, _message_added, &count0);
|
|
|
|
|
|
|
|
printf("Waiting for message from other.\n");
|
|
|
|
while (count1 == 0)
|
|
|
|
{
|
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
tf_ssb_remove_message_added_callback(ssb1, _message_added, &count1);
|
2021-01-02 17:48:33 -05:00
|
|
|
printf("done\n");
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
tf_ssb_send_close(ssb1);
|
|
|
|
|
2022-01-22 15:47:10 -05:00
|
|
|
uv_close((uv_handle_t*)&idle0, NULL);
|
|
|
|
uv_close((uv_handle_t*)&idle1, NULL);
|
|
|
|
|
2021-01-02 13:10:00 -05:00
|
|
|
uv_run(&loop, UV_RUN_DEFAULT);
|
|
|
|
|
|
|
|
tf_ssb_destroy(ssb0);
|
|
|
|
tf_ssb_destroy(ssb1);
|
|
|
|
|
|
|
|
uv_loop_close(&loop);
|
|
|
|
|
|
|
|
sqlite3_close(db0);
|
|
|
|
sqlite3_close(db1);
|
|
|
|
}
|
|
|
|
|
2022-11-02 19:34:44 -04:00
|
|
|
static void _broadcasts_visit(const struct sockaddr_in* addr, tf_ssb_connection_t* tunnel, const uint8_t* pub, void* user_data)
|
|
|
|
{
|
|
|
|
int* count = user_data;
|
|
|
|
(*count)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _broadcasts_changed(tf_ssb_t* ssb, void* user_data)
|
|
|
|
{
|
|
|
|
int* count = NULL;
|
|
|
|
test_t* test = user_data;
|
|
|
|
if (ssb == test->ssb0)
|
|
|
|
{
|
|
|
|
count = &test->broadcast_count0;
|
|
|
|
}
|
|
|
|
else if (ssb == test->ssb1)
|
|
|
|
{
|
|
|
|
count = &test->broadcast_count1;
|
|
|
|
}
|
|
|
|
else if (ssb == test->ssb2)
|
|
|
|
{
|
|
|
|
count = &test->broadcast_count2;
|
|
|
|
}
|
|
|
|
*count = 0;
|
|
|
|
tf_ssb_visit_broadcasts(ssb, _broadcasts_visit, count);
|
|
|
|
printf("BROADCASTS %d %d %d\n", test->broadcast_count0, test->broadcast_count1, test->broadcast_count2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tf_ssb_test_rooms(const tf_test_options_t* options)
|
|
|
|
{
|
|
|
|
printf("Testing Rooms.\n");
|
|
|
|
sqlite3* db0 = NULL;
|
|
|
|
sqlite3* db1 = NULL;
|
|
|
|
sqlite3* db2 = NULL;
|
|
|
|
|
|
|
|
int r = sqlite3_open(":memory:", &db0);
|
|
|
|
(void)r;
|
|
|
|
assert(r == SQLITE_OK);
|
|
|
|
r = sqlite3_open(":memory:", &db1);
|
|
|
|
assert(r == SQLITE_OK);
|
|
|
|
r = sqlite3_open(":memory:", &db2);
|
|
|
|
assert(r == SQLITE_OK);
|
|
|
|
|
|
|
|
uv_loop_t loop = { 0 };
|
|
|
|
uv_loop_init(&loop);
|
|
|
|
|
|
|
|
tf_ssb_t* ssb0 = tf_ssb_create(&loop, NULL, db0);
|
|
|
|
tf_ssb_register(tf_ssb_get_context(ssb0), ssb0);
|
|
|
|
tf_ssb_t* ssb1 = tf_ssb_create(&loop, NULL, db1);
|
|
|
|
tf_ssb_register(tf_ssb_get_context(ssb1), ssb1);
|
|
|
|
tf_ssb_t* ssb2 = tf_ssb_create(&loop, NULL, db2);
|
|
|
|
tf_ssb_register(tf_ssb_get_context(ssb2), ssb2);
|
|
|
|
|
|
|
|
uv_idle_t idle0 = { .data = ssb0 };
|
|
|
|
uv_idle_init(&loop, &idle0);
|
|
|
|
uv_idle_start(&idle0, _ssb_test_idle);
|
|
|
|
|
|
|
|
uv_idle_t idle1 = { .data = ssb1 };
|
|
|
|
uv_idle_init(&loop, &idle1);
|
|
|
|
uv_idle_start(&idle1, _ssb_test_idle);
|
|
|
|
|
|
|
|
uv_idle_t idle2 = { .data = ssb2 };
|
|
|
|
uv_idle_init(&loop, &idle2);
|
|
|
|
uv_idle_start(&idle2, _ssb_test_idle);
|
|
|
|
|
|
|
|
test_t test =
|
|
|
|
{
|
|
|
|
.ssb0 = ssb0,
|
|
|
|
.ssb1 = ssb1,
|
|
|
|
.ssb2 = ssb2,
|
|
|
|
};
|
|
|
|
|
|
|
|
tf_ssb_add_connections_changed_callback(ssb0, _ssb_test_connections_changed, NULL, &test);
|
|
|
|
tf_ssb_add_connections_changed_callback(ssb1, _ssb_test_connections_changed, NULL, &test);
|
|
|
|
tf_ssb_add_connections_changed_callback(ssb2, _ssb_test_connections_changed, NULL, &test);
|
|
|
|
|
|
|
|
tf_ssb_add_broadcasts_changed_callback(ssb0, _broadcasts_changed, NULL, &test);
|
|
|
|
tf_ssb_add_broadcasts_changed_callback(ssb1, _broadcasts_changed, NULL, &test);
|
|
|
|
tf_ssb_add_broadcasts_changed_callback(ssb2, _broadcasts_changed, NULL, &test);
|
|
|
|
|
|
|
|
tf_ssb_generate_keys(ssb0);
|
|
|
|
tf_ssb_generate_keys(ssb1);
|
|
|
|
tf_ssb_generate_keys(ssb2);
|
|
|
|
|
|
|
|
char id0[k_id_base64_len] = { 0 };
|
|
|
|
char id1[k_id_base64_len] = { 0 };
|
|
|
|
char id2[k_id_base64_len] = { 0 };
|
|
|
|
bool b = tf_ssb_whoami(ssb0, id0, sizeof(id0));
|
|
|
|
(void)b;
|
|
|
|
assert(b);
|
|
|
|
b = tf_ssb_whoami(ssb1, id1, sizeof(id1));
|
|
|
|
assert(b);
|
|
|
|
b = tf_ssb_whoami(ssb2, id2, sizeof(id2));
|
|
|
|
assert(b);
|
|
|
|
printf("ID %s, %s, %s\n", id0, id1, id2);
|
|
|
|
|
|
|
|
tf_ssb_server_open(ssb0, 12347);
|
|
|
|
|
|
|
|
uint8_t id0bin[k_id_bin_len];
|
|
|
|
tf_ssb_id_str_to_bin(id0bin, id0);
|
|
|
|
tf_ssb_connect(ssb1, "127.0.0.1", 12347, id0bin);
|
|
|
|
tf_ssb_connect(ssb2, "127.0.0.1", 12347, id0bin);
|
|
|
|
|
|
|
|
printf("Waiting for connection.\n");
|
|
|
|
while (test.connection_count0 != 2 ||
|
|
|
|
test.connection_count1 != 1 ||
|
|
|
|
test.connection_count2 != 1)
|
|
|
|
{
|
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
tf_ssb_server_close(ssb0);
|
|
|
|
|
|
|
|
while (test.broadcast_count1 != 1 ||
|
|
|
|
test.broadcast_count2 != 1)
|
|
|
|
{
|
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
|
|
|
|
tf_ssb_connection_t* connections[4];
|
|
|
|
int count = tf_ssb_get_connections(ssb1, connections, 4);
|
|
|
|
assert(count == 1);
|
|
|
|
|
|
|
|
int32_t tunnel_request_number = tf_ssb_connection_next_request_number(connections[0]);
|
|
|
|
|
|
|
|
JSContext* context = tf_ssb_get_context(ssb1);
|
|
|
|
JSValue message = JS_NewObject(context);
|
|
|
|
JSValue name = JS_NewArray(context);
|
|
|
|
JS_SetPropertyUint32(context, name, 0, JS_NewString(context, "tunnel"));
|
|
|
|
JS_SetPropertyUint32(context, name, 1, JS_NewString(context, "connect"));
|
|
|
|
JS_SetPropertyStr(context, message, "name", name);
|
|
|
|
JSValue args = JS_NewArray(context);
|
|
|
|
JSValue arg = JS_NewObject(context);
|
|
|
|
JS_SetPropertyStr(context, arg, "portal", JS_NewString(context, id0));
|
|
|
|
JS_SetPropertyStr(context, arg, "target", JS_NewString(context, id2));
|
|
|
|
JS_SetPropertyUint32(context, args, 0, arg);
|
|
|
|
JS_SetPropertyStr(context, message, "args", args);
|
|
|
|
JS_SetPropertyStr(context, message, "type", JS_NewString(context, "duplex"));
|
|
|
|
|
|
|
|
JSValue message_json = JS_JSONStringify(context, message, JS_NULL, JS_NULL);
|
|
|
|
size_t size;
|
|
|
|
const char* raw = JS_ToCStringLen(context, &size, message_json);
|
|
|
|
tf_ssb_connection_rpc_send(
|
|
|
|
connections[0],
|
|
|
|
k_ssb_rpc_flag_json | k_ssb_rpc_flag_stream,
|
|
|
|
tunnel_request_number,
|
|
|
|
(const uint8_t*)raw,
|
|
|
|
size,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
JS_FreeCString(context, raw);
|
|
|
|
JS_FreeValue(context, message_json);
|
|
|
|
JS_FreeValue(context, message);
|
|
|
|
|
|
|
|
tf_ssb_connection_t* tun0 = tf_ssb_connection_tunnel_create(connections[0], tunnel_request_number, id2);
|
|
|
|
printf("tun0 = %p\n", tun0);
|
|
|
|
|
|
|
|
printf("Done.\n");
|
|
|
|
|
|
|
|
while (test.connection_count0 != 2 ||
|
|
|
|
test.connection_count1 != 2 ||
|
|
|
|
test.connection_count2 != 2)
|
|
|
|
{
|
|
|
|
uv_run(&loop, UV_RUN_ONCE);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("Done.\n");
|
|
|
|
|
|
|
|
tf_ssb_send_close(ssb1);
|
|
|
|
tf_ssb_send_close(ssb2);
|
|
|
|
|
|
|
|
uv_close((uv_handle_t*)&idle0, NULL);
|
|
|
|
uv_close((uv_handle_t*)&idle1, NULL);
|
|
|
|
uv_close((uv_handle_t*)&idle2, NULL);
|
|
|
|
|
|
|
|
uv_run(&loop, UV_RUN_DEFAULT);
|
|
|
|
|
|
|
|
tf_ssb_destroy(ssb0);
|
|
|
|
tf_ssb_destroy(ssb1);
|
|
|
|
tf_ssb_destroy(ssb2);
|
|
|
|
|
|
|
|
uv_loop_close(&loop);
|
|
|
|
|
|
|
|
sqlite3_close(db0);
|
|
|
|
sqlite3_close(db1);
|
|
|
|
sqlite3_close(db2);
|
|
|
|
}
|
|
|
|
|
2021-09-06 14:23:22 -04:00
|
|
|
void tf_ssb_test_following(const tf_test_options_t* options)
|
2021-01-02 13:10:00 -05:00
|
|
|
{
|
|
|
|
printf("Testing following.\n");
|
|
|
|
sqlite3* db0 = NULL;
|
2022-05-20 21:38:13 -04:00
|
|
|
int r = sqlite3_open(":memory:", &db0);
|
|
|
|
(void)r;
|
|
|
|
assert(r == SQLITE_OK);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
uv_loop_t loop = { 0 };
|
|
|
|
uv_loop_init(&loop);
|
|
|
|
|
2022-10-14 08:27:34 -04:00
|
|
|
tf_ssb_t* ssb0 = tf_ssb_create(&loop, NULL, db0);
|
2021-01-02 13:10:00 -05:00
|
|
|
tf_ssb_generate_keys(ssb0);
|
|
|
|
|
2022-10-14 08:27:34 -04:00
|
|
|
tf_ssb_t* ssb1 = tf_ssb_create(&loop, NULL, db0);
|
2021-01-02 13:10:00 -05:00
|
|
|
tf_ssb_generate_keys(ssb1);
|
|
|
|
|
2022-10-14 08:27:34 -04:00
|
|
|
tf_ssb_t* ssb2 = tf_ssb_create(&loop, NULL, db0);
|
2021-01-02 13:10:00 -05:00
|
|
|
tf_ssb_generate_keys(ssb2);
|
|
|
|
|
|
|
|
char id0[k_id_base64_len] = { 0 };
|
|
|
|
char id1[k_id_base64_len] = { 0 };
|
|
|
|
char id2[k_id_base64_len] = { 0 };
|
|
|
|
tf_ssb_whoami(ssb0, id0, sizeof(id0));
|
|
|
|
tf_ssb_whoami(ssb1, id1, sizeof(id1));
|
|
|
|
tf_ssb_whoami(ssb2, id2, sizeof(id2));
|
|
|
|
|
|
|
|
JSContext* context = NULL;
|
|
|
|
JSValue message;
|
|
|
|
|
|
|
|
#define FOLLOW(ssb, id, follow) \
|
|
|
|
context = tf_ssb_get_context(ssb); \
|
|
|
|
message = JS_NewObject(context); \
|
|
|
|
JS_SetPropertyStr(context, message, "type", JS_NewString(context, "contact")); \
|
|
|
|
JS_SetPropertyStr(context, message, "contact", JS_NewString(context, id)); \
|
|
|
|
JS_SetPropertyStr(context, message, "following", follow ? JS_TRUE : JS_FALSE); \
|
|
|
|
tf_ssb_append_message(ssb, message); \
|
|
|
|
JS_FreeValue(context, message); \
|
|
|
|
context = NULL
|
|
|
|
|
2021-09-08 20:37:02 -04:00
|
|
|
#if 1
|
|
|
|
/* TODO: This test doesn't actually really test anything anymore. */
|
|
|
|
#define DUMP(id, depth)
|
|
|
|
#else
|
2021-01-02 13:10:00 -05:00
|
|
|
#define DUMP(id, depth) \
|
2021-10-10 17:51:38 -04:00
|
|
|
do \
|
|
|
|
{ \
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("following %d:\n", depth); \
|
|
|
|
const char** tf_ssb_get_following_deep(tf_ssb_t* ssb_param, const char** ids, int depth_param); \
|
|
|
|
const char** f = tf_ssb_get_following_deep(ssb0, (const char*[]) { id, NULL }, depth); \
|
2021-10-10 17:51:38 -04:00
|
|
|
for (const char** p = f; p && *p; p++) \
|
|
|
|
{ \
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("* %s\n", *p); \
|
|
|
|
} \
|
|
|
|
printf("\n"); \
|
2022-06-04 13:04:51 -04:00
|
|
|
tf_free(f); \
|
2021-10-10 17:51:38 -04:00
|
|
|
} \
|
|
|
|
while (0)
|
2021-09-08 20:37:02 -04:00
|
|
|
#endif
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
FOLLOW(ssb0, id1, true);
|
|
|
|
FOLLOW(ssb1, id2, true);
|
|
|
|
FOLLOW(ssb2, id0, true);
|
|
|
|
DUMP(id0, 2);
|
|
|
|
DUMP(id1, 2);
|
|
|
|
DUMP(id2, 2);
|
|
|
|
FOLLOW(ssb0, id1, false);
|
|
|
|
//FOLLOW(ssb0, id1, true);
|
|
|
|
//FOLLOW(ssb0, id1, true);
|
|
|
|
DUMP(id0, 1);
|
|
|
|
DUMP(id1, 2);
|
|
|
|
//FOLLOW(ssb0, id1, false);
|
|
|
|
//DUMP(1);
|
|
|
|
//DUMP(1);
|
|
|
|
|
|
|
|
#undef FOLLOW
|
|
|
|
#undef DUMP
|
|
|
|
|
|
|
|
uv_run(&loop, UV_RUN_DEFAULT);
|
|
|
|
|
|
|
|
tf_ssb_destroy(ssb0);
|
|
|
|
tf_ssb_destroy(ssb1);
|
|
|
|
tf_ssb_destroy(ssb2);
|
|
|
|
|
|
|
|
uv_loop_close(&loop);
|
|
|
|
|
|
|
|
sqlite3_close(db0);
|
|
|
|
}
|