get rid of the rest of gtest/gmock

pull/1561/head
Jeff Becker 3 years ago
parent ece91e87fc
commit 60bfdacc23
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

3
.gitmodules vendored

@ -1,9 +1,6 @@
[submodule "external/nlohmann"]
path = external/nlohmann
url = https://github.com/nlohmann/json.git
[submodule "external/googletest"]
path = external/googletest
url = https://github.com/google/googletest.git
[submodule "external/cxxopts"]
path = external/cxxopts
url = https://github.com/jarro2783/cxxopts.git

@ -309,7 +309,6 @@ if(SUBMODULE_CHECK)
message(STATUS "Checking submodules")
check_submodule(external/nlohmann)
check_submodule(external/googletest)
check_submodule(external/cxxopts)
check_submodule(external/ghc-filesystem)
check_submodule(external/date)
@ -322,9 +321,6 @@ endif()
if(WITH_HIVE)
add_subdirectory(external/pybind11 EXCLUDE_FROM_ALL)
endif()
if(WITH_TESTS)
add_subdirectory(external/googletest EXCLUDE_FROM_ALL)
endif()
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(external/nlohmann EXCLUDE_FROM_ALL)

@ -1 +0,0 @@
Subproject commit 703bd9caab50b139428cea1aaff9974ebee5742e

@ -21,13 +21,6 @@ add_executable(catchAll
crypto/test_llarp_crypto_types.cpp
crypto/test_llarp_crypto.cpp
crypto/test_llarp_key_manager.cpp
dht/test_llarp_dht_bucket.cpp
dht/test_llarp_dht_explorenetworkjob.cpp
dht/test_llarp_dht_kademlia.cpp
dht/test_llarp_dht_key.cpp
dht/test_llarp_dht_node.cpp
dht/test_llarp_dht_tx.cpp
dht/test_llarp_dht_txowner.cpp
dns/test_llarp_dns_dns.cpp
exit/test_llarp_exit_context.cpp
iwp/test_iwp_session.cpp
@ -59,7 +52,7 @@ add_executable(catchAll
test_llarp_encrypted_frame.cpp
test_llarp_router_contact.cpp)
target_link_libraries(catchAll PUBLIC gmock liblokinet Catch2::Catch2)
target_link_libraries(catchAll PUBLIC liblokinet Catch2::Catch2)
target_include_directories(catchAll PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
if(WIN32)

@ -1,8 +1,6 @@
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
#include <gmock/gmock.h>
#include <util/logging/logger.hpp>
#ifdef _WIN32
@ -25,9 +23,7 @@ startWinsock()
int
main(int argc, char* argv[])
{
llarp::LogSilencer shutup;
::testing::InitGoogleMock(&argc, argv);
llarp::LogSilencer shutup{};
#ifdef _WIN32
if (startWinsock())

@ -1,77 +0,0 @@
#ifndef TEST_LLARP_CRYPTO_MOCK_CRYPTO
#define TEST_LLARP_CRYPTO_MOCK_CRYPTO
#include <crypto/crypto.hpp>
#include <gmock/gmock.h>
namespace llarp
{
namespace test
{
struct MockCrypto : public Crypto
{
MOCK_METHOD3(
maybe_decrypt_name,
std::optional<AlignedBuffer<32>>(std::string_view, llarp::SymmNonce, std::string_view));
MOCK_METHOD3(xchacha20, bool(const llarp_buffer_t&, const SharedSecret&, const TunnelNonce&));
MOCK_METHOD4(
xchacha20_alt,
bool(const llarp_buffer_t&, const llarp_buffer_t&, const SharedSecret&, const byte_t*));
MOCK_METHOD4(
dh_client, bool(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&));
MOCK_METHOD4(
dh_server, bool(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&));
MOCK_METHOD4(
transport_dh_client,
bool(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&));
MOCK_METHOD4(
transport_dh_server,
bool(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&));
MOCK_METHOD2(hash, bool(byte_t*, const llarp_buffer_t&));
MOCK_METHOD2(shorthash, bool(ShortHash&, const llarp_buffer_t&));
MOCK_METHOD3(hmac, bool(byte_t*, const llarp_buffer_t&, const SharedSecret&));
MOCK_METHOD4(derive_subkey, bool(PubKey&, const PubKey&, uint64_t, const AlignedBuffer<32>*));
MOCK_METHOD4(
derive_subkey_private,
bool(PrivateKey&, const SecretKey&, uint64_t, const AlignedBuffer<32>*));
MOCK_METHOD(bool, sign, (Signature&, const SecretKey&, const llarp_buffer_t&));
MOCK_METHOD(bool, sign, (Signature&, const PrivateKey&, const llarp_buffer_t&));
MOCK_METHOD3(verify, bool(const PubKey&, const llarp_buffer_t&, const Signature&));
MOCK_METHOD2(seed_to_secretkey, bool(llarp::SecretKey&, const llarp::IdentitySecret&));
MOCK_METHOD1(randomize, void(const llarp_buffer_t&));
MOCK_METHOD2(randbytes, void(byte_t*, size_t));
MOCK_METHOD1(identity_keygen, void(SecretKey&));
MOCK_METHOD1(encryption_keygen, void(SecretKey&));
MOCK_METHOD1(pqe_keygen, void(PQKeyPair&));
MOCK_METHOD3(pqe_decrypt, bool(const PQCipherBlock&, SharedSecret&, const byte_t*));
MOCK_METHOD3(pqe_encrypt, bool(PQCipherBlock&, SharedSecret&, const PQPubKey&));
MOCK_METHOD1(check_identity_privkey, bool(const SecretKey&));
};
} // namespace test
} // namespace llarp
#endif

@ -12,7 +12,6 @@
#include <catch2/catch.hpp>
using namespace ::llarp;
using namespace ::testing;
struct KeyManagerTest : public test::LlarpTest<llarp::sodium::CryptoLibSodium>
{

@ -1,142 +0,0 @@
#ifndef TEST_LLARP_DHT_MOCK_CONTEXT
#define TEST_LLARP_DHT_MOCK_CONTEXT
#include <dht/context.hpp>
#include <gmock/gmock.h>
namespace llarp
{
namespace test
{
struct MockContext : public dht::AbstractContext
{
MOCK_CONST_METHOD1(StoreRC, void(const RouterContact));
MOCK_METHOD2(LookupRouter, bool(const RouterID&, RouterLookupHandler));
MOCK_METHOD5(
LookupRouterRecursive,
void(
const RouterID&,
const dht::Key_t&,
uint64_t,
const dht::Key_t&,
RouterLookupHandler));
MOCK_METHOD6(
LookupIntroSetRelayed,
void(
const dht::Key_t&,
const dht::Key_t&,
uint64_t,
const dht::Key_t&,
uint64_t,
service::EncryptedIntroSetLookupHandler));
MOCK_METHOD5(
LookupIntroSetDirect,
void(
const dht::Key_t&,
const dht::Key_t&,
uint64_t,
const dht::Key_t&,
service::EncryptedIntroSetLookupHandler));
MOCK_CONST_METHOD1(HasRouterLookup, bool(const RouterID& target));
MOCK_METHOD4(
LookupRouterForPath,
void(
const RouterID& target,
uint64_t txid,
const PathID_t& path,
const dht::Key_t& askpeer));
MOCK_METHOD5(
LookupIntroSetForPath,
void(const dht::Key_t&, uint64_t, const PathID_t&, const dht::Key_t&, uint64_t));
MOCK_METHOD3(DHTSendTo, void(const RouterID&, dht::IMessage*, bool));
MOCK_METHOD4(
HandleExploritoryRouterLookup,
bool(
const dht::Key_t& requester,
uint64_t txid,
const RouterID& target,
std::vector<std::unique_ptr<dht::IMessage>>& reply));
MOCK_METHOD5(
LookupRouterRelayed,
void(
const dht::Key_t& requester,
uint64_t txid,
const dht::Key_t& target,
bool recursive,
std::vector<std::unique_ptr<dht::IMessage>>& replies));
MOCK_METHOD2(RelayRequestForPath, bool(const PathID_t& localPath, const dht::IMessage& msg));
MOCK_CONST_METHOD2(GetRCFromNodeDB, bool(const dht::Key_t& k, RouterContact& rc));
MOCK_METHOD5(
PropagateIntroSetTo,
void(
const dht::Key_t& source,
uint64_t sourceTX,
const service::EncryptedIntroSet& introset,
const dht::Key_t& peer,
uint64_t relayOrder));
MOCK_METHOD5(
PropagateLocalIntroSet,
void(
const PathID_t& source,
uint64_t sourceTX,
const service::EncryptedIntroSet& introset,
const dht::Key_t& peer,
uint64_t relayOrder));
MOCK_METHOD2(Init, void(const dht::Key_t&, AbstractRouter*));
MOCK_CONST_METHOD1(
GetIntroSetByLocation,
std::optional<llarp::service::EncryptedIntroSet>(const llarp::dht::Key_t&));
MOCK_CONST_METHOD0(ExtractStatus, util::StatusObject());
MOCK_CONST_METHOD0(Now, llarp_time_t());
MOCK_METHOD1(ExploreNetworkVia, void(const dht::Key_t& peer));
MOCK_CONST_METHOD0(GetRouter, llarp::AbstractRouter*());
MOCK_CONST_METHOD0(OurKey, const dht::Key_t&());
MOCK_CONST_METHOD0(pendingIntrosetLookups, const PendingIntrosetLookups&());
MOCK_METHOD0(pendingIntrosetLookups, PendingIntrosetLookups&());
MOCK_METHOD0(pendingRouterLookups, PendingRouterLookups&());
MOCK_CONST_METHOD0(pendingRouterLookups, const PendingRouterLookups&());
MOCK_METHOD0(pendingExploreLookups, PendingExploreLookups&());
MOCK_CONST_METHOD0(pendingExploreLookups, const PendingExploreLookups&());
MOCK_METHOD0(services, dht::Bucket<dht::ISNode>*());
MOCK_CONST_METHOD0(AllowTransit, const bool&());
MOCK_METHOD0(AllowTransit, bool&());
MOCK_CONST_METHOD0(Nodes, dht::Bucket<dht::RCNode>*());
MOCK_METHOD1(PutRCNodeAsync, void(const dht::RCNode& val));
MOCK_METHOD1(DelRCNodeAsync, void(const dht::Key_t& val));
MOCK_METHOD2(FloodRCLater, void(const dht::Key_t, const RouterContact));
};
} // namespace test
} // namespace llarp
#endif

@ -1,369 +0,0 @@
#include <dht/bucket.hpp>
#include <dht/key.hpp>
#include <dht/node.hpp>
#include <catch2/catch.hpp>
using Key_t = llarp::dht::Key_t;
using Value_t = llarp::dht::RCNode;
using Bucket_t = llarp::dht::Bucket<Value_t>;
class TestDhtBucket
{
public:
TestDhtBucket() : randInt(0)
{
us.Fill(16);
nodes = std::make_unique<Bucket_t>(us, [&]() { return randInt++; });
size_t numNodes = 10;
byte_t fill = 1;
while (numNodes)
{
Value_t n;
n.ID.Fill(fill);
nodes->PutNode(n);
--numNodes;
++fill;
}
}
uint64_t randInt;
llarp::dht::Key_t us;
std::unique_ptr<Bucket_t> nodes;
};
TEST_CASE_METHOD(TestDhtBucket, "Simple cycle", "[dht]")
{
// Empty the current bucket.
nodes->Clear();
// Create a simple value, and add it to the bucket.
Value_t val;
val.ID.Fill(1);
nodes->PutNode(val);
// Verify the value is in the bucket
REQUIRE(nodes->HasNode(val.ID));
REQUIRE(1u == nodes->size());
// Verify after deletion, the value is no longer in the bucket
nodes->DelNode(val.ID);
REQUIRE_FALSE(nodes->HasNode(val.ID));
// Verify deleting again succeeds;
nodes->DelNode(val.ID);
REQUIRE_FALSE(nodes->HasNode(val.ID));
}
TEST_CASE_METHOD(TestDhtBucket, "get_random_node_excluding")
{
// Empty the current bucket.
nodes->Clear();
// We expect not to find anything
Key_t result;
std::set<Key_t> excludeSet;
REQUIRE_FALSE(nodes->GetRandomNodeExcluding(result, excludeSet));
// Create a simple value.
Value_t val;
val.ID.Fill(1);
// Add the simple value to the exclude set
excludeSet.insert(val.ID);
REQUIRE_FALSE(nodes->GetRandomNodeExcluding(result, excludeSet));
// Add the simple value to the bucket
nodes->PutNode(val);
REQUIRE_FALSE(nodes->GetRandomNodeExcluding(result, excludeSet));
excludeSet.clear();
REQUIRE(nodes->GetRandomNodeExcluding(result, excludeSet));
REQUIRE(val.ID == result);
// Add an element to the exclude set which isn't the bucket.
Key_t other;
other.Fill(0xff);
excludeSet.insert(other);
REQUIRE(nodes->GetRandomNodeExcluding(result, excludeSet));
REQUIRE(val.ID == result);
// Add a node which is in both bucket and excludeSet
Value_t nextVal;
nextVal.ID.Fill(0xAA);
excludeSet.insert(nextVal.ID);
nodes->PutNode(nextVal);
REQUIRE(nodes->GetRandomNodeExcluding(result, excludeSet));
REQUIRE(val.ID == result);
// Clear the excludeSet - we should still have 2 nodes in the bucket
excludeSet.clear();
randInt = 0;
REQUIRE(nodes->GetRandomNodeExcluding(result, excludeSet));
REQUIRE(val.ID == result);
// Set the random value to be 1, we should get the other node.
randInt = 1;
REQUIRE(nodes->GetRandomNodeExcluding(result, excludeSet));
REQUIRE(nextVal.ID == result);
// Set the random value to be 100, we should get the first node.
randInt = 100;
REQUIRE(nodes->GetRandomNodeExcluding(result, excludeSet));
REQUIRE(val.ID == result);
}
TEST_CASE_METHOD(TestDhtBucket, "find_closest", "[dht]")
{
// Empty the current bucket.
nodes->Clear();
// We expect not to find anything
Key_t target;
target.Fill(0xF0);
Key_t result;
REQUIRE_FALSE(nodes->FindClosest(target, result));
// Add a node to the bucket
Value_t first;
first.ID.Zero();
nodes->PutNode(first);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(result == first.ID);
// Add another node to the bucket, closer to the target
Value_t second;
second.ID.Fill(0x10);
nodes->PutNode(second);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(result == second.ID);
// Add a third node to the bucket, closer to the target
Value_t third;
third.ID.Fill(0x20);
nodes->PutNode(third);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(result == third.ID);
// Add a fourth node to the bucket, greater than the target
Value_t fourth;
fourth.ID.Fill(0xF1);
nodes->PutNode(fourth);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(result == fourth.ID);
// Add a fifth node to the bucket, equal to the target
Value_t fifth;
fifth.ID.Fill(0xF0);
nodes->PutNode(fifth);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(result == fifth.ID);
}
TEST_CASE_METHOD(TestDhtBucket, "get_many_random", "[dht]")
{
// Empty the current bucket.
nodes->Clear();
// Verify behaviour with empty node set
std::set<Key_t> result;
REQUIRE_FALSE(nodes->GetManyRandom(result, 0));
REQUIRE_FALSE(nodes->GetManyRandom(result, 1));
// Add 5 nodes to the bucket
std::set<Value_t> curValues;
std::set<Key_t> curKeys;
for (byte_t i = 0x00; i < 0x05; ++i)
{
Value_t v;
v.ID.Fill(i);
REQUIRE(curKeys.insert(v.ID).second);
nodes->PutNode(v);
}
// Fetching more than the current size fails
REQUIRE(5u == nodes->size());
REQUIRE_FALSE(nodes->GetManyRandom(result, nodes->size() + 1));
// Fetching the current size succeeds
REQUIRE(nodes->GetManyRandom(result, nodes->size()));
REQUIRE(curKeys == result);
// Fetching a subset succeeds.
// Note we hack this by "fixing" the random number generator
result.clear();
REQUIRE(nodes->GetManyRandom(result, 1u));
REQUIRE(1u == result.size());
REQUIRE(*curKeys.begin() == *result.begin());
randInt = 0;
result.clear();
REQUIRE(nodes->GetManyRandom(result, nodes->size() - 1));
REQUIRE(nodes->size() - 1 == result.size());
REQUIRE(std::set<Key_t>(++curKeys.rbegin(), curKeys.rend()) == result);
}
TEST_CASE_METHOD(TestDhtBucket, "find_close_excluding", "[dht]")
{
// Empty the current bucket.
nodes->Clear();
Key_t target;
target.Zero();
std::set<Key_t> exclude;
Key_t result;
// Empty node + exclude set fails
REQUIRE_FALSE(nodes->FindCloseExcluding(target, result, exclude));
Value_t first;
first.ID.Fill(0xF0);
exclude.insert(first.ID);
// Empty nodes fails
REQUIRE_FALSE(nodes->FindCloseExcluding(target, result, exclude));
// Nodes and exclude set match
nodes->PutNode(first);
REQUIRE_FALSE(nodes->FindCloseExcluding(target, result, exclude));
// Exclude set empty
exclude.clear();
REQUIRE(nodes->FindCloseExcluding(target, result, exclude));
result = first.ID;
Value_t second;
second.ID.Fill(0x01);
nodes->PutNode(second);
REQUIRE(nodes->FindCloseExcluding(target, result, exclude));
result = second.ID;
exclude.insert(second.ID);
REQUIRE(nodes->FindCloseExcluding(target, result, exclude));
result = first.ID;
}
TEST_CASE_METHOD(TestDhtBucket, "find_many_near_excluding", "[dht]")
{
// Empty the current bucket.
nodes->Clear();
Key_t target;
target.Zero();
std::set<Key_t> exclude;
std::set<Key_t> result;
// Empty node + exclude set, with size 0 succeeds
REQUIRE(nodes->GetManyNearExcluding(target, result, 0, exclude));
REQUIRE(0u == result.size());
// Empty node + exclude set fails
REQUIRE_FALSE(nodes->GetManyNearExcluding(target, result, 1, exclude));
Value_t first;
first.ID.Fill(0xF0);
exclude.insert(first.ID);
// Empty nodes fails
REQUIRE_FALSE(nodes->GetManyNearExcluding(target, result, 1, exclude));
// Nodes and exclude set match
nodes->PutNode(first);
REQUIRE_FALSE(nodes->GetManyNearExcluding(target, result, 1, exclude));
// Single node succeeds
exclude.clear();
REQUIRE(nodes->GetManyNearExcluding(target, result, 1, exclude));
REQUIRE(result == std::set<Key_t>({first.ID}));
// Trying to grab 2 nodes from a 1 node set fails
result.clear();
REQUIRE_FALSE(nodes->GetManyNearExcluding(target, result, 2, exclude));
// two nodes finds closest
Value_t second;
second.ID.Fill(0x01);
nodes->PutNode(second);
result.clear();
REQUIRE(nodes->GetManyNearExcluding(target, result, 1, exclude));
REQUIRE(result == std::set<Key_t>({second.ID}));
// 3 nodes finds 2 closest
Value_t third;
third.ID.Fill(0x02);
nodes->PutNode(third);
result.clear();
REQUIRE(nodes->GetManyNearExcluding(target, result, 2, exclude));
REQUIRE(result == std::set<Key_t>({second.ID, third.ID}));
// 4 nodes, one in exclude set finds 2 closest
Value_t fourth;
fourth.ID.Fill(0x03);
nodes->PutNode(fourth);
exclude.insert(third.ID);
result.clear();
REQUIRE(nodes->GetManyNearExcluding(target, result, 2, exclude));
REQUIRE(result == std::set<Key_t>({second.ID, fourth.ID}));
}
TEST_CASE_METHOD(TestDhtBucket, "Bucket: FindClosest", "[dht]")
{
llarp::dht::Key_t result;
llarp::dht::Key_t target;
target.Fill(5);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(target == result);
const llarp::dht::Key_t oldResult = result;
target.Fill(0xf5);
REQUIRE(nodes->FindClosest(target, result));
REQUIRE(oldResult == result);
}
TEST_CASE_METHOD(TestDhtBucket, "Bucket: randomized 1000", "[dht]")
{
size_t moreNodes = 100;
while (moreNodes--)
{
llarp::dht::RCNode n;
n.ID.Fill(randInt);
randInt++;
nodes->PutNode(n);
}
const size_t count = 1000;
size_t left = count;
while (left--)
{
llarp::dht::Key_t result;
llarp::dht::Key_t target;
target.Randomize();
const llarp::dht::Key_t expect = target;
REQUIRE(nodes->FindClosest(target, result));
if (target == result)
{
REQUIRE((result ^ target) >= (expect ^ target));
REQUIRE((result ^ target) == (expect ^ target));
REQUIRE((result ^ target) == (expect ^ target));
}
else
{
Key_t dist = (result ^ target);
Key_t oldDist = (expect ^ target);
REQUIRE((result ^ target) != (expect ^ target));
INFO(dist << ">=" << oldDist << "iteration=" << (count - left));
REQUIRE((result ^ target) >= (expect ^ target));
REQUIRE((result ^ target) != (expect ^ target));
}
}
}

@ -1,97 +0,0 @@
#include <dht/explorenetworkjob.hpp>
#include <dht/messages/findrouter.hpp>
#include <dht/mock_context.hpp>
#include <test_util.hpp>
#include <gmock/gmock.h>
#include <catch2/catch.hpp>
using namespace llarp;
using namespace ::testing;
using test::makeBuf;
struct TestDhtExploreNetworkJob
{
RouterID peer;
test::MockContext context;
dht::ExploreNetworkJob exploreNetworkJob;
TestDhtExploreNetworkJob() : peer(makeBuf<RouterID>(0x01)), exploreNetworkJob(peer, &context)
{}
~TestDhtExploreNetworkJob()
{
CHECK(Mock::VerifyAndClearExpectations(&context));
}
};
TEST_CASE_METHOD(TestDhtExploreNetworkJob, "validate", "[dht]")
{
const RouterID other = makeBuf<RouterID>(0x02);
REQUIRE(exploreNetworkJob.Validate(other));
}
TEST_CASE_METHOD(TestDhtExploreNetworkJob, "start", "[dht]")
{
// Verify input arguments are passed correctly.
// The actual logic is inside the `dht::AbstractContext` implementation.
const auto txKey = makeBuf<dht::Key_t>(0x02);
uint64_t txId = 4;
dht::TXOwner txOwner(txKey, txId);
// clang-format off
EXPECT_CALL(context, DHTSendTo(
Eq(txKey.as_array()),
WhenDynamicCastTo< dht::FindRouterMessage* >(NotNull()),
true)
).Times(1);
// clang-format off
REQUIRE_NOTHROW(exploreNetworkJob.Start(txOwner));
}
// TODO: sections?
TEST_CASE_METHOD(TestDhtExploreNetworkJob, "send_reply", "[dht]")
{
// Concerns:
// - Empty collection
// - Lookup router fails (returns false)
// - Number of calls matches collection size
{
exploreNetworkJob.valuesFound.clear();
EXPECT_CALL(context, LookupRouter(_, _)).Times(0);
EXPECT_CALL(context, GetRouter()).WillOnce(Return(nullptr));
REQUIRE_NOTHROW(exploreNetworkJob.SendReply());
}
{
exploreNetworkJob.valuesFound.clear();
exploreNetworkJob.valuesFound.push_back(makeBuf<RouterID>(0x00));
exploreNetworkJob.valuesFound.push_back(makeBuf<RouterID>(0x01));
exploreNetworkJob.valuesFound.push_back(makeBuf<RouterID>(0x02));
EXPECT_CALL(context, GetRouter()).WillOnce(Return(nullptr));
EXPECT_CALL(context, LookupRouter(Ne(makeBuf<RouterID>(0x01)), _)).Times(2).WillRepeatedly(Return(true));
EXPECT_CALL(context, LookupRouter(Eq(makeBuf<RouterID>(0x01)), _)).WillOnce(Return(false));
REQUIRE_NOTHROW(exploreNetworkJob.SendReply());
}
{
exploreNetworkJob.valuesFound.clear();
exploreNetworkJob.valuesFound.push_back(makeBuf<RouterID>(0x00));
exploreNetworkJob.valuesFound.push_back(makeBuf<RouterID>(0x01));
exploreNetworkJob.valuesFound.push_back(makeBuf<RouterID>(0x02));
EXPECT_CALL(context, GetRouter()).WillOnce(Return(nullptr));
EXPECT_CALL(context, LookupRouter(_, _)).Times(3).WillRepeatedly(Return(true));
REQUIRE_NOTHROW(exploreNetworkJob.SendReply());
}
}

@ -1,78 +0,0 @@
#include <dht/kademlia.hpp>
#include <catch2/catch.hpp>
using llarp::dht::Key_t;
using Array = std::array<byte_t, Key_t::SIZE>;
struct XorMetricData
{
Array us;
Array left;
Array right;
bool result;
XorMetricData(const Array& u, const Array& l, const Array& r, bool res)
: us(u), left(l), right(r), result(res)
{}
};
std::ostream&
operator<<(std::ostream& stream, const XorMetricData& x)
{
stream << int(x.us[0]) << " " << int(x.left[0]) << " " << int(x.right[0]) << " " << std::boolalpha
<< x.result;
return stream;
}
std::vector<XorMetricData>
makeData()
{
std::vector<XorMetricData> result;
Array zero;
zero.fill(0);
Array one;
one.fill(1);
Array two;
two.fill(2);
Array three;
three.fill(3);
result.emplace_back(zero, zero, zero, false);
result.emplace_back(zero, zero, one, true);
result.emplace_back(zero, zero, two, true);
result.emplace_back(zero, one, zero, false);
result.emplace_back(zero, one, one, false);
result.emplace_back(zero, one, two, true);
result.emplace_back(zero, two, zero, false);
result.emplace_back(zero, two, one, false);
result.emplace_back(zero, two, two, false);
result.emplace_back(one, zero, zero, false);
result.emplace_back(one, zero, one, false);
result.emplace_back(one, zero, two, true);
result.emplace_back(one, one, zero, true);
result.emplace_back(one, one, one, false);
result.emplace_back(one, one, two, true);
result.emplace_back(one, two, zero, false);
result.emplace_back(one, two, one, false);
result.emplace_back(one, two, two, false);
result.emplace_back(two, zero, zero, false);
result.emplace_back(two, zero, one, true);
result.emplace_back(two, zero, two, false);
result.emplace_back(two, one, zero, false);
result.emplace_back(two, one, one, false);
result.emplace_back(two, one, two, false);
result.emplace_back(two, two, zero, true);
result.emplace_back(two, two, one, true);
result.emplace_back(two, two, two, false);
return result;
}
TEST_CASE("XorMetric", "[dht]")
{
auto d = GENERATE(from_range(makeData()));
REQUIRE(llarp::dht::XorMetric{Key_t{d.us}}(Key_t{d.left}, Key_t{d.right}) == d.result);
}

@ -1,109 +0,0 @@
#include <catch2/catch.hpp>
#include <dht/key.hpp>
using namespace llarp;
using Array = std::array<byte_t, dht::Key_t::SIZE>;
static constexpr Array emptyArray{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
static constexpr Array fullArray{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
static constexpr Array seqArray{{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}};
std::vector<Array> data{emptyArray, fullArray, seqArray};
TEST_CASE("DHT key constructor", "[dht]")
{
auto d = GENERATE(from_range(data));
dht::Key_t a(d);
dht::Key_t b(d.data());
dht::Key_t c;
REQUIRE(a == b);
if (a.IsZero())
{
REQUIRE(a == c);
}
else
{
REQUIRE(a != c);
}
}
TEST_CASE("DHT key ==", "[dht]")
{
REQUIRE(dht::Key_t(emptyArray) == dht::Key_t(emptyArray));
REQUIRE(dht::Key_t(fullArray) == dht::Key_t(fullArray));
REQUIRE(dht::Key_t(seqArray) == dht::Key_t(seqArray));
}
TEST_CASE("DHT key !=", "[dht]")
{
REQUIRE(dht::Key_t(emptyArray) != dht::Key_t(fullArray));
REQUIRE(dht::Key_t(emptyArray) != dht::Key_t(seqArray));
REQUIRE(dht::Key_t(fullArray) != dht::Key_t(seqArray));
}
TEST_CASE("DHT key <", "[dht]")
{
REQUIRE(dht::Key_t(emptyArray) < dht::Key_t(fullArray));
REQUIRE(dht::Key_t(emptyArray) < dht::Key_t(seqArray));
REQUIRE(dht::Key_t(seqArray) < dht::Key_t(fullArray));
}
TEST_CASE("DHT key >", "[dht]")
{
REQUIRE(dht::Key_t(fullArray) > dht::Key_t(emptyArray));
REQUIRE(dht::Key_t(seqArray) > dht::Key_t(emptyArray));
REQUIRE(dht::Key_t(fullArray) > dht::Key_t(seqArray));
}
TEST_CASE("DHT key ^", "[dht]")
{
REQUIRE(dht::Key_t(emptyArray) == (dht::Key_t(emptyArray) ^ dht::Key_t(emptyArray)));
REQUIRE(dht::Key_t(seqArray) == (dht::Key_t(emptyArray) ^ dht::Key_t(seqArray)));
REQUIRE(dht::Key_t(fullArray) == (dht::Key_t(emptyArray) ^ dht::Key_t(fullArray)));
REQUIRE(dht::Key_t(emptyArray) == (dht::Key_t(fullArray) ^ dht::Key_t(fullArray)));
REQUIRE(dht::Key_t(emptyArray) == (dht::Key_t(seqArray) ^ dht::Key_t(seqArray)));
Array xorResult;
std::iota(xorResult.rbegin(), xorResult.rend(), 0xE0);
REQUIRE(dht::Key_t(xorResult) == (dht::Key_t(seqArray) ^ dht::Key_t(fullArray)));
}
TEST_CASE("DHT key: test bucket operators", "[dht]")
{
dht::Key_t zero;
dht::Key_t one;
dht::Key_t three;
zero.Zero();
one.Fill(1);
three.Fill(3);
REQUIRE(zero < one);
REQUIRE(zero < three);
REQUIRE_FALSE(zero > one);
REQUIRE_FALSE(zero > three);
REQUIRE(zero != three);
REQUIRE_FALSE(zero == three);
REQUIRE((zero ^ one) == one);
REQUIRE(one < three);
REQUIRE(three > one);
REQUIRE(one != three);
REQUIRE_FALSE(one == three);
REQUIRE((one ^ three) == (three ^ one));
}

@ -1,106 +0,0 @@
#include <dht/node.hpp>
#include <test_util.hpp>
#include <catch2/catch.hpp>
using namespace llarp;
using test::makeBuf;
TEST_CASE("dht::RCNode construct", "[dht]")
{
dht::RCNode node;
REQUIRE(node.ID.IsZero());
node.ID.Fill(0xCA);
node.rc.last_updated = 101s;
dht::RCNode other{node};
REQUIRE(node.ID == other.ID);
REQUIRE(node.rc == other.rc);
RouterContact contact;
contact.pubkey.Randomize();
dht::RCNode fromContact{contact};
REQUIRE(fromContact.ID.as_array() == contact.pubkey.as_array());
}
TEST_CASE("dht::RCNode <", "[dht]")
{
dht::RCNode one;
dht::RCNode two;
dht::RCNode three;
dht::RCNode eqThree;
one.rc.last_updated = 1s;
two.rc.last_updated = 2s;
three.rc.last_updated = 3s;
eqThree.rc.last_updated = 3s;
// LT cases
REQUIRE(one < two);
REQUIRE(one < three);
REQUIRE(one < eqThree);
REQUIRE(two < three);
REQUIRE(two < eqThree);
// !LT cases
REQUIRE(!(one < one));
REQUIRE(!(two < one));
REQUIRE(!(two < two));
REQUIRE(!(three < one));
REQUIRE(!(three < two));
REQUIRE(!(three < three));
REQUIRE(!(three < eqThree));
}
TEST_CASE("dht::ISNode construct", "[dht]")
{
dht::ISNode node;
REQUIRE(node.ID.IsZero());
node.ID.Fill(0xCA);
node.introset.derivedSigningKey.Fill(0xDB);
dht::ISNode other{node};
REQUIRE(node.ID == other.ID);
REQUIRE(node.introset == other.introset);
service::EncryptedIntroSet introSet;
introSet.derivedSigningKey.Randomize();
dht::ISNode fromIntro{introSet};
REQUIRE(fromIntro.ID.as_array() == introSet.derivedSigningKey);
}
TEST_CASE("dht::ISNode <", "[dht]")
{
dht::ISNode one;
dht::ISNode two;
dht::ISNode three;
dht::ISNode eqThree;
one.introset.signedAt = 1s;
two.introset.signedAt = 2s;
three.introset.signedAt = 3s;
eqThree.introset.signedAt = 3s;
// LT cases
REQUIRE(one < two);
REQUIRE(one < three);
REQUIRE(one < eqThree);
REQUIRE(two < three);
REQUIRE(two < eqThree);
// !LT cases
REQUIRE(!(one < one));
REQUIRE(!(two < one));
REQUIRE(!(two < two));
REQUIRE(!(three < one));
REQUIRE(!(three < two));
REQUIRE(!(three < three));
REQUIRE(!(three < eqThree));
}

@ -1,107 +0,0 @@
#include <dht/tx.hpp>
#include <service/tag.hpp>
#include <test_util.hpp>
#include <catch2/catch.hpp>
#include <gmock/gmock.h>
using namespace llarp;
using namespace ::testing;
using llarp::test::makeBuf;
using Val_t = llarp::service::Tag;
// Mock implementation of TX.
struct TestTx : public dht::TX<dht::Key_t, Val_t>
{
TestTx(const dht::TXOwner& asker, const dht::Key_t& k, dht::AbstractContext* p)
: dht::TX<dht::Key_t, Val_t>(asker, k, p)
{}
MOCK_CONST_METHOD1(Validate, bool(const Val_t&));
MOCK_METHOD1(Start, void(const dht::TXOwner&));
MOCK_METHOD0(SendReply, void());
};
struct TestDhtTx
{
dht::TXOwner asker;
dht::Key_t m_key;
TestTx tx;
TestDhtTx() : tx(asker, m_key, nullptr)
{}
~TestDhtTx()
{
CHECK(Mock::VerifyAndClearExpectations(&tx));
}
};
// TODO: sections?
TEST_CASE_METHOD(TestDhtTx, "on_found", "[dht]")
{
// Concerns
// - Validate returns true
// - Repeated call on success
// - Validate returns false
// - Repeated call on failure
// - Repeated call on success after failure
const auto key = makeBuf<dht::Key_t>(0x00);
Val_t val("good value");
// Validate returns true
{
EXPECT_CALL(tx, Validate(val)).WillOnce(Return(true));
tx.OnFound(key, val);
REQUIRE(tx.peersAsked.count(key) > 0);
REQUIRE_THAT(tx.valuesFound, Catch::VectorContains(val));
}
// Repeated call on success
{
EXPECT_CALL(tx, Validate(val)).WillOnce(Return(true));
tx.OnFound(key, val);
REQUIRE(tx.peersAsked.count(key) > 0);
REQUIRE_THAT(tx.valuesFound, Catch::VectorContains(val));
}
const auto key1 = makeBuf<dht::Key_t>(0x01);
Val_t badVal("bad value");
// Validate returns false
{
EXPECT_CALL(tx, Validate(badVal)).WillOnce(Return(false));
tx.OnFound(key1, badVal);
REQUIRE(tx.peersAsked.count(key1) > 0);
REQUIRE_THAT(tx.valuesFound, !Catch::VectorContains(badVal));
}
// Repeated call on failure
{
EXPECT_CALL(tx, Validate(badVal)).WillOnce(Return(false));
tx.OnFound(key1, badVal);
REQUIRE(tx.peersAsked.count(key1) > 0);
REQUIRE_THAT(tx.valuesFound, !Catch::VectorContains(badVal));
}
// Repeated call on success after failure
{
EXPECT_CALL(tx, Validate(badVal)).WillOnce(Return(true));
tx.OnFound(key1, badVal);
REQUIRE(tx.peersAsked.count(key1) > 0);
REQUIRE_THAT(tx.valuesFound, Catch::VectorContains(badVal));
}
}

@ -1,106 +0,0 @@
#include <dht/txowner.hpp>
#include <catch2/catch.hpp>
namespace
{
using llarp::dht::Key_t;
using llarp::dht::TXOwner;
struct TxOwnerData
{
Key_t node;
uint64_t id;
size_t expectedHash;
TxOwnerData(const Key_t& k, uint64_t i, size_t h) : node(k), id(i), expectedHash(h)
{}
};
TEST_CASE("TxOwner default construct", "[dht]")
{
TXOwner dc;
REQUIRE(dc.node.IsZero());
REQUIRE(0u == dc.txid);
REQUIRE(0u == TXOwner::Hash()(dc));
}
std::vector<TxOwnerData>
makeData()
{
std::vector<TxOwnerData> result;
Key_t zero;
zero.Zero();
Key_t one;
one.Fill(0x01);
Key_t two;
two.Fill(0x02);
uint64_t max = std::numeric_limits<uint64_t>::max();
result.emplace_back(zero, 0, 0ull);
result.emplace_back(zero, 1, 1ull);
result.emplace_back(one, 0, 144680345676153346ull);
result.emplace_back(one, 1, 144680345676153347ull);
result.emplace_back(two, 0, 289360691352306692ull);
result.emplace_back(two, 2, 289360691352306694ull);
result.emplace_back(zero, max, 18446744073709551615ull);
result.emplace_back(one, max, 18302063728033398269ull);
result.emplace_back(two, max, 18157383382357244923ull);
return result;
}
TEST_CASE("TxOwner hash", "[dht]")
{
// test single interactions (constructor and hash)
auto d = GENERATE(from_range(makeData()));
TXOwner constructor(d.node, d.id);
REQUIRE(d.expectedHash == TXOwner::Hash()(constructor));
}
struct TxOwnerCmpData
{
TXOwner lhs;
TXOwner rhs;
bool equal;
bool less;
TxOwnerCmpData(const TXOwner& l, const TXOwner& r, bool e, bool ls)
: lhs(l), rhs(r), equal(e), less(ls)
{}
};
std::vector<TxOwnerCmpData>
makeCmpData()
{
std::vector<TxOwnerCmpData> result;
Key_t zero;
zero.Fill(0x00);
Key_t one;
one.Fill(0x01);
Key_t two;
two.Fill(0x02);
result.emplace_back(TXOwner(zero, 0), TXOwner(zero, 0), true, false);
result.emplace_back(TXOwner(one, 0), TXOwner(one, 0), true, false);
result.emplace_back(TXOwner(two, 0), TXOwner(two, 0), true, false);
result.emplace_back(TXOwner(zero, 0), TXOwner(one, 0), false, true);
result.emplace_back(TXOwner(two, 0), TXOwner(one, 0), false, false);
return result;
}
TEST_CASE("TxOwner ops", "[dht]")
{
// test single interactions (constructor and hash)
auto d = GENERATE(from_range(makeCmpData()));
REQUIRE((d.lhs == d.rhs) == d.equal);
REQUIRE((d.lhs < d.rhs) == d.less);
}
} // namespace

@ -1,36 +1,30 @@
#ifndef LLARP_TEST
#define LLARP_TEST
#pragma once
#include <crypto/mock_crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <catch2/catch.hpp>
#include <gmock/gmock.h>
namespace llarp
namespace llarp::test
{
namespace test
template <typename CryptoImpl = llarp::sodium::CryptoLibSodium>
class LlarpTest
{
template <typename CryptoImpl = MockCrypto>
class LlarpTest
protected:
CryptoImpl m_crypto;
CryptoManager cm;
LlarpTest() : cm(&m_crypto)
{
protected:
CryptoImpl m_crypto;
CryptoManager cm;
static_assert(std::is_base_of<Crypto, CryptoImpl>::value, "");
}
LlarpTest() : cm(&m_crypto)
{
static_assert(std::is_base_of<Crypto, CryptoImpl>::value, "");
}
~LlarpTest()
{}
};
~LlarpTest()
{}
};
template <>
inline LlarpTest<llarp::sodium::CryptoLibSodium>::~LlarpTest()
{
template <>
inline LlarpTest<MockCrypto>::~LlarpTest()
{
CHECK(::testing::Mock::VerifyAndClearExpectations(&m_crypto));
}
} // namespace test
} // namespace llarp
#endif
}

@ -1,37 +0,0 @@
#include <gtest/gtest.h>
#include <util/logging/logger.hpp>
#ifdef _WIN32
#include <winsock2.h>
int
startWinsock()
{
WSADATA wsockd;
int err;
err = ::WSAStartup(MAKEWORD(2, 2), &wsockd);
if (err)
{
perror("Failed to start Windows Sockets");
return err;
}
return 0;
}
#endif
int
main(int argc, char** argv)
{
llarp::LogSilencer shutup;
#ifdef _WIN32
if (startWinsock())
return -1;
#endif
::testing::InitGoogleTest(&argc, argv);
int r = RUN_ALL_TESTS();
#ifdef _WIN32
WSACleanup();
#endif
return r;
}

@ -2,14 +2,10 @@
#include <crypto/crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <crypto/mock_crypto.hpp>
#include <llarp_test.hpp>
#include <gmock/gmock.h>
#include <catch2/catch.hpp>
using namespace ::testing;
using namespace ::llarp;
using namespace ::llarp::test;
@ -23,16 +19,15 @@ fill(Signature& s)
TEST_CASE_METHOD(LlarpTest<>, "Sign-verify")
{
SecretKey alice;
EXPECT_CALL(m_crypto, sign(_, alice, _)).WillOnce(DoAll(WithArg<0>(Invoke(&fill)), Return(true)));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ObtainExitMessage msg;
msg.Z.Zero();
SecretKey alice{};
CryptoManager::instance()->identity_keygen(alice);
REQUIRE(not alice.IsZero());
ObtainExitMessage msg{};
msg.S = randint();
msg.T = randint();
CHECK(msg.Sign(alice));
CHECK(msg.Verify());
CHECK(msg.I == PubKey(seckey_topublic(alice)));
CHECK(msg.I == PubKey{seckey_topublic(alice)});
CHECK(msg.version == LLARP_PROTO_VERSION);
CHECK_FALSE(msg.Z.IsZero());
}

@ -10,7 +10,6 @@
#include <catch2/catch.hpp>
using namespace ::llarp;
using namespace ::testing;
using EncryptedFrame = EncryptedFrame;
using SecretKey = SecretKey;
@ -25,9 +24,9 @@ class FrameTest : public test::LlarpTest<>
TEST_CASE_METHOD(FrameTest, "Frame crypto")
{
EncryptedFrame f(256);
EncryptedFrame f{256};
f.Fill(0);
LRCR record;
LRCR record{};
record.nextHop.Fill(1);
record.tunnelNonce.Fill(2);
record.rxid.Fill(3);
@ -38,19 +37,11 @@ TEST_CASE_METHOD(FrameTest, "Frame crypto")
REQUIRE(record.BEncode(buf));
EXPECT_CALL(m_crypto, randbytes(_, _)).WillOnce(Invoke(&test::randbytes_impl));
EXPECT_CALL(m_crypto, dh_client(_, _, alice, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, xchacha20(_, _, _)).Times(2).WillRepeatedly(Return(true));
EXPECT_CALL(m_crypto, hmac(_, _, _)).Times(2).WillRepeatedly(Return(true));
// rewind buffer
buf->cur = buf->base + EncryptedFrameOverheadSize;
// encrypt to alice
REQUIRE(f.EncryptInPlace(alice, bob.toPublic()));
EXPECT_CALL(m_crypto, dh_server(_, _, _, _)).WillOnce(Return(true));
// decrypt from alice
REQUIRE(f.DecryptInPlace(bob));

Loading…
Cancel
Save