2026-05-07 08:01:35 -04:00
#include <logos_test.h>
2026-02-23 11:37:43 -03:00
#include <plugin.h>
2026-06-25 10:10:16 -03:00
#include "test_helpers.h"
2026-02-17 14:05:49 -03:00
2026-08-24 14:19:20 -03:00
#include <atomic>
#include <thread>
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_connect_disconnect_peer ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
std :: string fakePeer = "12D3KooWInvalidPeerForTest" ;
std :: vector < std :: string > fakeAddrs = { "/ip4/127.0.0.1/tcp/9999" };
2026-02-18 16:38:02 -03:00
2026-06-19 11:34:48 -03:00
LOGOS_ASSERT_FALSE ( plugin . connectPeer ( fakePeer , fakeAddrs , - 1 ). success );
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . disconnectPeer ( fakePeer ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 12:04:18 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_peer_info ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 12:04:18 -03:00
2026-05-07 14:34:51 -04:00
auto res = plugin . peerInfo ();
LOGOS_ASSERT_TRUE ( res . success );
2026-02-18 12:04:18 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( res . value [ "peerId" ]. get < std :: string > (). empty ());
2026-02-18 12:04:18 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 12:04:18 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_connected_peers ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 17:21:48 -03:00
2026-06-12 10:20:35 -03:00
auto res = plugin . connectedPeers ( 0 );
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( res . success );
2026-02-18 17:21:48 -03:00
2026-05-07 14:34:51 -04:00
auto peers = res . value ;
LOGOS_ASSERT_TRUE ( peers . is_array ());
LOGOS_ASSERT_EQ ( peers . size (), size_t ( 0 ));
2026-02-18 17:21:48 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 12:04:18 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_dial ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 17:21:48 -03:00
2026-05-07 14:34:51 -04:00
std :: string fakePeer = "12D3KooWInvalidPeerForTest" ;
std :: string proto = "/test/1.0.0" ;
2026-02-18 17:21:48 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . dial ( fakePeer , proto ). success );
2026-02-18 17:21:48 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 12:04:18 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_public_key ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
LOGOS_ASSERT_TRUE ( plugin . publicKey (). success );
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 12:04:18 -03:00
2026-07-31 15:23:05 +02:00
LOGOS_TEST ( sync_new_private_key ) {
Libp2pModuleImpl plugin ;
2026-07-31 14:35:59 -03:00
auto res = plugin . newPrivateKey ( "ed25519" );
2026-07-31 15:23:05 +02:00
LOGOS_ASSERT_TRUE ( res . success );
LOGOS_ASSERT_TRUE ( res . value . is_string ());
LOGOS_ASSERT_FALSE ( res . value . get < std :: string > (). empty ());
}
2026-07-31 14:35:59 -03:00
LOGOS_TEST ( sync_new_private_key_unknown_scheme ) {
Libp2pModuleImpl plugin ;
// An unknown name is rejected by name, not silently mapped onto a scheme.
auto res = plugin . newPrivateKey ( "ed25519 " );
LOGOS_ASSERT_FALSE ( res . success );
LOGOS_ASSERT_FALSE ( res . error . empty ());
}
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_close ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 12:04:18 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . streamClose ( fakeStreamId ). success );
2026-02-18 12:04:18 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 12:04:18 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_close_with_eof ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-17 14:05:49 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . streamCloseWithEOF ( fakeStreamId ). success );
2026-02-23 11:37:43 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_release ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . streamRelease ( fakeStreamId ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_read_exactly ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
size_t len = 16 ;
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . streamReadExactly ( fakeStreamId , len ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_read_lp ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
size_t maxSize = 4096 ;
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_FALSE ( plugin . streamReadLp ( fakeStreamId , maxSize ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_write ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
2026-05-07 14:34:51 -04:00
std :: string data = "hello-stream" ;
LOGOS_ASSERT_FALSE ( plugin . streamWrite ( fakeStreamId , data ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_stream_write_lp ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
uint64_t fakeStreamId = 1234 ;
2026-05-07 14:34:51 -04:00
std :: string data = "hello-stream-lp" ;
LOGOS_ASSERT_FALSE ( plugin . streamWriteLp ( fakeStreamId , data ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_gossipsub_subscribe_publish ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
std :: string topic = "sync-topic" ;
std :: string msg = "sync-gossipsub-msg" ;
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . gossipsubSubscribe ( topic ). success );
LOGOS_ASSERT_TRUE ( plugin . gossipsubPublish ( topic , msg ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_gossipsub_unsubscribe ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
std :: string topic = "sync-topic" ;
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . gossipsubSubscribe ( topic ). success );
LOGOS_ASSERT_TRUE ( plugin . gossipsubUnsubscribe ( topic ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_kad_get_put_value ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
std :: string key = "sync-test-key" ;
std :: string value = "sync-hello-world" ;
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . kadPutValue ( key , value ). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
auto res = plugin . kadGetValue ( key , 1 );
LOGOS_ASSERT_TRUE ( res . success );
2026-06-25 10:10:16 -03:00
LOGOS_ASSERT_TRUE ( base64Decode ( res . value . get < std :: string > ()) == value );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-18 16:38:02 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_key_to_cid_and_providers ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
std :: string key = "sync-provider-test-key" ;
std :: string value = "sync-provider-test-value" ;
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
auto res = plugin . toCid ( key );
LOGOS_ASSERT_TRUE ( res . success );
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
std :: string cid = res . value . get < std :: string > ();
LOGOS_ASSERT_FALSE ( cid . empty ());
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . kadPutValue ( key , value ). success );
LOGOS_ASSERT_TRUE ( plugin . kadAddProvider ( cid ). success );
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
auto provRes = plugin . kadGetProviders ( cid );
LOGOS_ASSERT_TRUE ( provRes . success );
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
auto providers = provRes . value ;
LOGOS_ASSERT_TRUE ( providers . is_array ());
LOGOS_ASSERT_EQ ( providers . size (), size_t ( 0 ));
2026-03-02 15:08:33 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-03-02 15:08:33 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_kad_find_node ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-18 16:38:02 -03:00
2026-05-07 14:34:51 -04:00
std :: string fakePeer = "12D3KooWInvalidPeerForSyncTest" ;
LOGOS_ASSERT_FALSE ( plugin . kadFindNode ( fakePeer ). success );
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-17 14:05:49 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_kad_provide_lifecycle ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ;
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
std :: string key = "sync-providing-key" ;
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
auto res = plugin . toCid ( key );
LOGOS_ASSERT_TRUE ( res . success );
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
std :: string cid = res . value . get < std :: string > ();
LOGOS_ASSERT_FALSE ( cid . empty ());
2026-02-18 17:21:48 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . kadStartProviding ( cid ). success );
LOGOS_ASSERT_TRUE ( plugin . kadStopProviding ( cid ). success );
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-02-17 14:05:49 -03:00
2026-05-07 08:01:35 -04:00
LOGOS_TEST ( sync_kad_random_records ) {
2026-05-07 14:34:51 -04:00
Libp2pModuleImpl plugin ( Libp2pModuleOptions { . mountServiceDiscovery = true });
LOGOS_ASSERT_TRUE ( plugin . start (). success );
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
auto res = plugin . kadGetRandomRecords ();
LOGOS_ASSERT_TRUE ( res . success );
LOGOS_ASSERT_TRUE ( res . value . is_array ());
2026-02-17 14:05:49 -03:00
2026-05-07 14:34:51 -04:00
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
2026-05-07 08:01:35 -04:00
}
2026-08-24 14:19:20 -03:00
LOGOS_TEST ( sync_stop_without_a_context_is_rejected ) {
Libp2pModuleImpl plugin ;
auto res = plugin . stop ();
LOGOS_ASSERT_FALSE ( res . success );
LOGOS_ASSERT_TRUE ( res . error == "No libp2p context" );
}
// A reader on another thread while start() installs the context: every call sees either no context or a fully installed one, and TSAN sees no race on the pointer.
LOGOS_TEST ( sync_reader_races_context_create ) {
Libp2pModuleImpl plugin ;
std :: atomic < bool > reading { false };
std :: atomic < bool > done { false };
std :: atomic < bool > unexpectedError { false };
std :: thread reader ([ & ] {
reading . store ( true , std :: memory_order_release );
while ( ! done . load ( std :: memory_order_relaxed )) {
auto res = plugin . peerInfo ();
if ( ! res . success && res . error != "No libp2p context" &&
res . error . rfind ( "Failed to get peer info" , 0 ) != 0 ) {
unexpectedError . store ( true , std :: memory_order_relaxed );
}
}
});
// The reader must be inside its loop before the create publishes the pointer, or there is no race to observe.
while ( ! reading . load ( std :: memory_order_acquire )) {
std :: this_thread :: yield ();
}
LOGOS_ASSERT_TRUE ( plugin . start (). success );
done . store ( true , std :: memory_order_relaxed );
reader . join ();
LOGOS_ASSERT_FALSE ( unexpectedError . load ());
// The hammering left a usable context behind, not one the race half-installed.
LOGOS_ASSERT_TRUE ( plugin . peerInfo (). success );
LOGOS_ASSERT_TRUE ( plugin . stop (). success );
}