0.0.002
ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
This commit is contained in:
1 parent
f0f91540be
commit
b735900f2e
323 files changed
+134347
-343
No files matched your search
@@ -0,0 +1,391 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#define main dat_thang_program_main
|
||||
#include "../src/ddat_gui.c"
|
||||
#undef main
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <process.h>
|
||||
#define test_mkdir(path) _mkdir(path)
|
||||
#define test_setenv(name, value) _putenv_s((name), (value))
|
||||
#define test_pid _getpid
|
||||
#define test_close_socket(fd) closesocket(fd)
|
||||
typedef int test_socklen_t;
|
||||
typedef SOCKET test_socket_t;
|
||||
#define test_socket_valid(fd) ((fd) != INVALID_SOCKET)
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#define test_mkdir(path) mkdir((path), 0700)
|
||||
#define test_setenv(name, value) setenv((name), (value), 1)
|
||||
#define test_pid getpid
|
||||
#define test_close_socket(fd) close(fd)
|
||||
typedef socklen_t test_socklen_t;
|
||||
typedef int test_socket_t;
|
||||
#define test_socket_valid(fd) ((fd) >= 0)
|
||||
#endif
|
||||
|
||||
static uint16_t unused_udp_port(void)
|
||||
{
|
||||
test_socket_t fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
struct sockaddr_in address;
|
||||
test_socklen_t length = sizeof(address);
|
||||
uint16_t port;
|
||||
assert(test_socket_valid(fd));
|
||||
memset(&address, 0, sizeof(address));
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
assert(bind(fd, (struct sockaddr *)&address, sizeof(address)) == 0);
|
||||
assert(getsockname(fd, (struct sockaddr *)&address, &length) == 0);
|
||||
port = ntohs(address.sin_port);
|
||||
test_close_socket(fd);
|
||||
return port;
|
||||
}
|
||||
|
||||
static void pause_one_millisecond(void)
|
||||
{
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
static void set_network_environment(uint16_t local_port, uint16_t bootstrap_port)
|
||||
{
|
||||
char value[32];
|
||||
snprintf(value, sizeof(value), "%u", (unsigned)local_port);
|
||||
assert(test_setenv("DDAT_PORT", value) == 0);
|
||||
snprintf(value, sizeof(value), "127.0.0.1:%u", (unsigned)bootstrap_port);
|
||||
assert(test_setenv("DDAT_BOOTSTRAP", value) == 0);
|
||||
}
|
||||
|
||||
static int peer_ready(const gui_state_t *state)
|
||||
{
|
||||
size_t i;
|
||||
if (!state->session_initialized) return 0;
|
||||
for (i = 0; i < state->session.peer_count; i++)
|
||||
if (state->session.peers[i].state == DAT_SESSION_PEER_READY) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DAT_GUI_TEST_MEDIA
|
||||
static int test_fm_audio_is_playing(gui_state_t *state)
|
||||
{
|
||||
gui_fm_voice_t *voice = (gui_fm_voice_t *)state->fm_voice_ptr;
|
||||
int active;
|
||||
if (!voice || !state->audio_device) return 0;
|
||||
SDL_LockAudioDevice(state->audio_device);
|
||||
active = voice->active;
|
||||
SDL_UnlockAudioDevice(state->audio_device);
|
||||
return active;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static gui_state_t left, right;
|
||||
char root[1024];
|
||||
char left_home[1024], right_home[1024], file_path[1200], destination[1200];
|
||||
char feed_directory[1024];
|
||||
uint8_t content_key[32];
|
||||
uint16_t left_port, right_port;
|
||||
Uint32 now;
|
||||
int elapsed;
|
||||
#ifdef _WIN32
|
||||
WSADATA winsock;
|
||||
int fixture_attempt;
|
||||
assert(WSAStartup(MAKEWORD(2, 2), &winsock) == 0);
|
||||
for (fixture_attempt = 0; fixture_attempt < 1000; fixture_attempt++) {
|
||||
assert(snprintf(root, sizeof(root), "build/windows/test-gui-p2p-%ld-%d",
|
||||
(long)test_pid(), fixture_attempt) < (int)sizeof(root));
|
||||
if (test_mkdir(root) == 0) break;
|
||||
}
|
||||
assert(fixture_attempt < 1000);
|
||||
#else
|
||||
strcpy(root, "/tmp/ddat-gui-p2p-XXXXXX");
|
||||
#endif
|
||||
memset(&left, 0, sizeof(left));
|
||||
memset(&right, 0, sizeof(right));
|
||||
left_port = unused_udp_port();
|
||||
right_port = unused_udp_port();
|
||||
if (right_port == left_port) right_port = (uint16_t)(left_port + 1);
|
||||
#ifndef _WIN32
|
||||
assert(mkdtemp(root) != NULL);
|
||||
#endif
|
||||
assert(snprintf(file_path, sizeof(file_path), "%s/payload.txt", root) <
|
||||
(int)sizeof(file_path));
|
||||
{
|
||||
FILE *file = fopen(file_path, "wb");
|
||||
assert(file != NULL);
|
||||
assert(fputs("a real GUI Cesspool to uTP to SLEEP block", file) >= 0);
|
||||
assert(fclose(file) == 0);
|
||||
}
|
||||
assert(snprintf(left_home, sizeof(left_home), "%s/left-home", root) < (int)sizeof(left_home));
|
||||
assert(snprintf(right_home, sizeof(right_home), "%s/right-home", root) < (int)sizeof(right_home));
|
||||
assert(test_mkdir(left_home) == 0);
|
||||
assert(test_mkdir(right_home) == 0);
|
||||
assert(snprintf(destination, sizeof(destination), "%s/download", root) < (int)sizeof(destination));
|
||||
assert(test_mkdir(destination) == 0);
|
||||
assert(test_setenv("HOME", left_home) == 0);
|
||||
assert(test_setenv("USERPROFILE", left_home) == 0);
|
||||
#ifdef DAT_GUI_TEST_MEDIA
|
||||
assert(SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO) == 0);
|
||||
#else
|
||||
assert(SDL_Init(SDL_INIT_TIMER) == 0);
|
||||
#endif
|
||||
assert(dat_scheme_runtime_init(&left.metadata_scheme) == 0);
|
||||
strcpy(left.archive_path, root);
|
||||
strcpy(right.archive_path, destination);
|
||||
assert(prepare_archive(&left) == 0);
|
||||
assert(left.archive_open && left.version >= 1);
|
||||
left.selected_version = 0;
|
||||
assert(click_archive_version_bar(&left, 210, 80, 84));
|
||||
assert(left.selected_version == 0);
|
||||
assert(!click_archive_version_bar(&left, 209, 80, 84));
|
||||
assert(!click_archive_version_bar(&left, 210, 73, 84));
|
||||
assert(!click_archive_version_bar(&left, 242, 80, 84));
|
||||
assert(click_archive_version_bar(&left, 226, 80, 84));
|
||||
assert(left.selected_version == 1);
|
||||
left.selected_version = left.version;
|
||||
assert(click_archive_version_bar(&left, 226, 80, 84));
|
||||
assert(left.selected_version == left.version);
|
||||
assert(click_archive_version_bar(&left, 210, 80, 84));
|
||||
assert(left.selected_version == left.version - 1);
|
||||
{
|
||||
dat_link_t link, parsed;
|
||||
char address[DAT_LINK_BYTES];
|
||||
memset(&link, 0, sizeof(link));
|
||||
memcpy(link.key, left.archive_key_bytes, sizeof(link.key));
|
||||
link.has_version = 1;
|
||||
link.version = left.selected_version;
|
||||
assert(dat_link_format(&link, address, sizeof(address)) == 0);
|
||||
assert(dat_link_parse(address, &parsed) == 0);
|
||||
assert(parsed.has_version && parsed.version == left.selected_version);
|
||||
}
|
||||
{
|
||||
dat_archive_t source;
|
||||
char uri[DAT_URL_BYTES];
|
||||
assert(dat_archive_open(&source, root) == 0);
|
||||
memcpy(right.remote_metadata_key, source.metadata_key, sizeof(right.remote_metadata_key));
|
||||
right.remote_key_valid = 1;
|
||||
assert(dat_key_to_url(source.metadata_key, uri) == 0);
|
||||
strcpy(right.remote_address, uri);
|
||||
strcpy(right.remote_archive, uri + 6);
|
||||
strcpy(right.remote_site, "P2P TEST SOURCE");
|
||||
strcpy(right.remote_version, "LATEST");
|
||||
assert(strlen(destination) + sizeof("/.dat") <= sizeof(feed_directory));
|
||||
strcpy(feed_directory, destination);
|
||||
strcat(feed_directory, "/.dat");
|
||||
memcpy(content_key, source.content_key, sizeof(content_key));
|
||||
dat_archive_close(&source);
|
||||
}
|
||||
assert(sleep_crypto_init() == 0);
|
||||
set_network_environment(left_port, right_port);
|
||||
network_start(&left);
|
||||
assert(left.network_requested && left.session_initialized);
|
||||
assert(!left.online); /* Reachability starts false until a response arrives. */
|
||||
assert(test_setenv("HOME", right_home) == 0);
|
||||
assert(test_setenv("USERPROFILE", right_home) == 0);
|
||||
set_network_environment(right_port, left_port);
|
||||
network_start_remote_import(&right);
|
||||
assert(right.network_requested && right.session_initialized);
|
||||
assert(!right.online);
|
||||
assert(!memcmp(right.identity.pubkey, right.pool.net.peerid, 32));
|
||||
for (elapsed = 0; elapsed < 12000; elapsed++) {
|
||||
now = SDL_GetTicks();
|
||||
network_pump(&left, now);
|
||||
if (memcmp(right.identity.pubkey, right.pool.net.peerid, 32)) {
|
||||
fprintf(stderr, "left client pump overwrote right Cesspool identity at %d ms\\n", elapsed);
|
||||
abort();
|
||||
}
|
||||
network_pump(&right, now);
|
||||
if (memcmp(right.identity.pubkey, right.pool.net.peerid, 32)) {
|
||||
size_t changed;
|
||||
for (changed = 0; changed < 32 &&
|
||||
right.identity.pubkey[changed] == right.pool.net.peerid[changed]; changed++) {}
|
||||
fprintf(stderr, "right identity changed during P2P pump at %d ms: byte %lu %02x -> %02x pool=%d online=%d status=%s\n",
|
||||
elapsed, (unsigned long)changed, right.identity.pubkey[changed],
|
||||
right.pool.net.peerid[changed], right.pool_initialized, right.online,
|
||||
right.network_status);
|
||||
abort();
|
||||
}
|
||||
if (peer_ready(&left) && peer_ready(&right) && right.session.content_key_known &&
|
||||
sleep_feed_has(&right.content_feed, 1)) break;
|
||||
pause_one_millisecond();
|
||||
}
|
||||
if (!peer_ready(&left) || !peer_ready(&right)) {
|
||||
fprintf(stderr, "peer setup timeout: L=%02x%02x R=%02x%02x left discovered=%lu peers=%lu ps=%d mask=%u rx=%lu tx=%llu/%llu status=%s; right discovered=%lu peers=%lu ps=%d mask=%u rx=%lu tx=%llu/%llu status=%s\n",
|
||||
left.identity.pubkey[0],left.identity.pubkey[1],right.identity.pubkey[0],right.identity.pubkey[1],
|
||||
(unsigned long)discovered_peer_count(&left),
|
||||
(unsigned long)left.session.peer_count,
|
||||
left.session.peers[0].state, left.session.peers[0].remote_feed_mask,
|
||||
(unsigned long)left.session.peers[0].rx_buffer_len,
|
||||
(unsigned long long)left.bytes_received,
|
||||
(unsigned long long)left.bytes_sent, left.network_status,
|
||||
(unsigned long)discovered_peer_count(&right),
|
||||
(unsigned long)right.session.peer_count,
|
||||
right.session.peers[0].state, right.session.peers[0].remote_feed_mask,
|
||||
(unsigned long)right.session.peers[0].rx_buffer_len,
|
||||
(unsigned long long)right.bytes_received,
|
||||
(unsigned long long)right.bytes_sent, right.network_status);
|
||||
for (size_t i = 0; i < GUI_TRANSPORT_MAX; i++) {
|
||||
if (left.transports[i].used)
|
||||
fprintf(stderr, "left transport %lu state=%d wait=%d auth=%d hello=%d/%d ack=%d/%d seq=%u recv=%u inflight=%lu\n",
|
||||
(unsigned long)i, left.transports[i].utp.state,
|
||||
left.transports[i].waiting_incoming, left.transports[i].authenticated,
|
||||
left.transports[i].hello_sent, left.transports[i].hello_received,
|
||||
left.transports[i].ack_sent, left.transports[i].ack_received,
|
||||
left.transports[i].utp.sequence, left.transports[i].utp.acknowledgement,
|
||||
(unsigned long)left.transports[i].utp.bytes_in_flight);
|
||||
if (right.transports[i].used)
|
||||
fprintf(stderr, "right transport %lu state=%d wait=%d auth=%d hello=%d/%d ack=%d/%d seq=%u recv=%u inflight=%lu\n",
|
||||
(unsigned long)i, right.transports[i].utp.state,
|
||||
right.transports[i].waiting_incoming, right.transports[i].authenticated,
|
||||
right.transports[i].hello_sent, right.transports[i].hello_received,
|
||||
right.transports[i].ack_sent, right.transports[i].ack_received,
|
||||
right.transports[i].utp.sequence, right.transports[i].utp.acknowledgement,
|
||||
(unsigned long)right.transports[i].utp.bytes_in_flight);
|
||||
}
|
||||
for (size_t i = 0; i < left.pool.peer_count; i++)
|
||||
fprintf(stderr, "left known peer %lu port=%u topic=%d\n", (unsigned long)i,
|
||||
ntohs(((struct sockaddr_in *)&left.pool.peers[i].address.addr)->sin_port),
|
||||
!memcmp(left.pool.peers[i].discovery_topic, left.discovery_topic, 32));
|
||||
for (size_t i = 0; i < right.pool.peer_count; i++)
|
||||
fprintf(stderr, "right known peer %lu port=%u topic=%d\n", (unsigned long)i,
|
||||
ntohs(((struct sockaddr_in *)&right.pool.peers[i].address.addr)->sin_port),
|
||||
!memcmp(right.pool.peers[i].discovery_topic, right.discovery_topic, 32));
|
||||
abort();
|
||||
}
|
||||
assert(right.content_feed.length > 1);
|
||||
assert(left.session.peers[0].payload_bytes_sent > 0);
|
||||
assert(right.session.peers[0].payload_bytes_received > 0);
|
||||
assert(sleep_feed_has(&right.content_feed, 1));
|
||||
if (!transport_by_id(&left, right.identity.pubkey)) {
|
||||
fprintf(stderr, "identity mismatch: L identity=%02x pool=%02x session=%02x; R identity=%02x pool=%02x session=%02x\n",
|
||||
left.identity.pubkey[0], left.pool.net.peerid[0], left.session.peer_id[0],
|
||||
right.identity.pubkey[0], right.pool.net.peerid[0], right.session.peer_id[0]);
|
||||
for (size_t i = 0; i < GUI_TRANSPORT_MAX; i++)
|
||||
fprintf(stderr, "left transport slot %lu used=%d state=%d auth=%d peer=%02x expected=%02x sessionpeer=%02x session=%d\n",
|
||||
(unsigned long)i, left.transports[i].used, left.transports[i].utp.state,
|
||||
left.transports[i].authenticated, left.transports[i].peer_id[0],
|
||||
right.identity.pubkey[0], left.session.peers[0].peer_id[0],
|
||||
left.session.peers[0].state);
|
||||
abort();
|
||||
}
|
||||
assert(transport_by_id(&left, right.identity.pubkey)->authenticated);
|
||||
assert(transport_by_id(&right, left.identity.pubkey) != NULL);
|
||||
assert(transport_by_id(&right, left.identity.pubkey)->authenticated);
|
||||
transfer_disconnect(&left, 0, 0);
|
||||
assert(left.transfer_paused[0] && left.session.peers[0].paused);
|
||||
assert(peer_ready(&left) && peer_ready(&right));
|
||||
transfer_resume(&left, 0);
|
||||
assert(!left.transfer_paused[0] && !left.session.peers[0].paused);
|
||||
for (elapsed = 0; elapsed < 5000; elapsed++) {
|
||||
now = SDL_GetTicks();
|
||||
network_pump(&left, now);
|
||||
network_pump(&right, now);
|
||||
if (peer_ready(&left) && peer_ready(&right)) break;
|
||||
pause_one_millisecond();
|
||||
}
|
||||
if (!peer_ready(&left) || !peer_ready(&right))
|
||||
fprintf(stderr, "resume timeout IDs=%02x/%02x: left session=%d transport=%d/%d wait=%d auth=%d hello=%d/%d ack=%d/%d right session=%d transport=%d/%d wait=%d auth=%d hello=%d/%d ack=%d/%d statuses=%s | %s\n",
|
||||
left.identity.pubkey[0], right.identity.pubkey[0],
|
||||
left.session.peers[0].state, left.transports[0].used,
|
||||
left.transports[0].utp.state, left.transports[0].waiting_incoming,
|
||||
left.transports[0].authenticated, left.transports[0].hello_sent,
|
||||
left.transports[0].hello_received, left.transports[0].ack_sent,
|
||||
left.transports[0].ack_received, right.session.peers[0].state,
|
||||
right.transports[0].used, right.transports[0].utp.state,
|
||||
right.transports[0].waiting_incoming, right.transports[0].authenticated,
|
||||
right.transports[0].hello_sent, right.transports[0].hello_received,
|
||||
right.transports[0].ack_sent, right.transports[0].ack_received,
|
||||
left.network_status, right.network_status);
|
||||
assert(peer_ready(&left) && peer_ready(&right));
|
||||
assert(left.online && right.online);
|
||||
memcpy(left.chat_peer_id,right.identity.pubkey,32);
|
||||
left.chat_open=1;strcpy(left.chat_input,"hello from cable over the authenticated peer link");
|
||||
if (cable_chat_send(&left) != 0) {
|
||||
gui_transport_peer_t *chat_transport = transport_by_id(&left, left.chat_peer_id);
|
||||
fprintf(stderr, "chat after resume: transport=%p used=%d auth=%d utp=%d session=%d errno=%d\n",
|
||||
(void *)chat_transport, chat_transport ? chat_transport->used : 0,
|
||||
chat_transport ? chat_transport->authenticated : 0,
|
||||
chat_transport ? chat_transport->utp.state : 0,
|
||||
left.session.peers[0].state, errno);
|
||||
abort();
|
||||
}
|
||||
for(elapsed=0;elapsed<3000;elapsed++){
|
||||
now=SDL_GetTicks();network_pump(&left,now);network_pump(&right,now);
|
||||
if(right.chat_line_count)break;
|
||||
pause_one_millisecond();
|
||||
}
|
||||
assert(right.chat_line_count==1);
|
||||
assert(!strcmp(right.chat_lines[0].text,"hello from cable over the authenticated peer link"));
|
||||
assert(!right.chat_lines[0].outgoing);
|
||||
{
|
||||
uint8_t *received = NULL;
|
||||
size_t received_length = 0;
|
||||
dat_archive_t downloaded;
|
||||
sleep_metadata_entry_t entry;
|
||||
const char expected[] = "a real GUI Cesspool to uTP to SLEEP block";
|
||||
assert(dat_archive_open(&downloaded, destination) == 0);
|
||||
assert(dat_archive_find(&downloaded, "payload.txt", &entry) == 0);
|
||||
assert(dat_archive_read_file(&downloaded, &entry, &received, &received_length) == 0);
|
||||
assert(received_length == sizeof(expected) - 1);
|
||||
assert(!memcmp(received, expected, received_length));
|
||||
free(received);
|
||||
received = NULL;
|
||||
dat_archive_close(&downloaded);
|
||||
assert(sleep_feed_read(&right.content_feed, 1, &received, &received_length) == 0);
|
||||
/* A content feed block is not the same thing as one source file: the
|
||||
* archive reader reconstructs files from metadata offsets and blocks. */
|
||||
assert(received_length > 0);
|
||||
free(received);
|
||||
}
|
||||
sleep_feed_close(&right.content_feed);
|
||||
assert(sleep_feed_open_remote(&right.content_feed, feed_directory,
|
||||
"content", content_key) == 0);
|
||||
assert(sleep_feed_has(&right.content_feed, 1));
|
||||
{
|
||||
sleep_feed_t restored;
|
||||
memset(&restored, 0, sizeof(restored));
|
||||
strcpy(restored.directory, feed_directory);
|
||||
strcpy(restored.name, "content");
|
||||
assert(sleep_feed_load_remote(&restored, content_key) == 0);
|
||||
assert(sleep_feed_has(&restored, 1));
|
||||
sleep_feed_close(&restored);
|
||||
}
|
||||
#ifdef DAT_GUI_TEST_MEDIA
|
||||
left.audio_enabled = 1;
|
||||
fm_audio_start(&left);
|
||||
assert(left.audio_device != 0);
|
||||
audio_cue_broadcast(&right, 1);
|
||||
for (elapsed = 0; elapsed < 2000; elapsed++) {
|
||||
now = SDL_GetTicks();
|
||||
network_pump(&left, now);
|
||||
network_pump(&right, now);
|
||||
if (((gui_fm_voice_t *)left.fm_voice_ptr)->dolphin && test_fm_audio_is_playing(&left)) break;
|
||||
pause_one_millisecond();
|
||||
}
|
||||
assert(((gui_fm_voice_t *)left.fm_voice_ptr)->dolphin);
|
||||
assert(test_fm_audio_is_playing(&left));
|
||||
fm_audio_play(&left);
|
||||
assert(test_fm_audio_is_playing(&left));
|
||||
SDL_Delay(2100);
|
||||
assert(!test_fm_audio_is_playing(&left));
|
||||
fm_audio_stop(&left);
|
||||
#endif
|
||||
network_stop(&right);
|
||||
network_stop(&left);
|
||||
dat_scheme_runtime_close(&left.metadata_scheme);
|
||||
SDL_Quit();
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
#ifdef DAT_GUI_TEST_MEDIA
|
||||
puts("dat-thang authenticated Cesspool transfer, chat, and dolphin cue: PASS");
|
||||
#else
|
||||
puts("dat-thang authenticated Cesspool archive transfer, pause/resume, and chat: PASS");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user