diff --git a/CMakeLists.txt b/CMakeLists.txt index 3da1ac2a6..3215d3275 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -619,6 +619,7 @@ set(TEST_SRC test/test_llarp_dns.cpp test/test_llarp_dnsd.cpp test/test_llarp_encrypted_frame.cpp + test/test_llarp_router.cpp test/test_llarp_router_contact.cpp test/util/test_llarp_util_aligned.cpp test/util/test_llarp_util_bencode.cpp diff --git a/llarp/crypto.cpp b/llarp/crypto.cpp index 7be3d2ede..4c49583a6 100644 --- a/llarp/crypto.cpp +++ b/llarp/crypto.cpp @@ -26,7 +26,9 @@ namespace llarp std::ifstream f; f.open(fname, std::ios::binary); if(!f.is_open()) + { return false; + } size_t sz = 0; f.seekg(0, std::ios::end); sz = f.tellg(); @@ -41,7 +43,9 @@ namespace llarp byte_t tmp[128]; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); if(sz > sizeof(tmp)) + { return false; + } f.read((char*)tmp, sz); return BDecode(&buf); } @@ -52,7 +56,9 @@ namespace llarp byte_t tmp[128]; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); if(!BEncode(&buf)) + { return false; + } std::ofstream f; f.open(fname, std::ios::binary); diff --git a/test/test_llarp_router.cpp b/test/test_llarp_router.cpp new file mode 100644 index 000000000..0dde08de1 --- /dev/null +++ b/test/test_llarp_router.cpp @@ -0,0 +1,123 @@ + +#include +#include + +#include +#include + +#include + +std::string +randFilename() +{ + static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz"; + + std::random_device rd; + std::uniform_int_distribution< size_t > dist{0, sizeof(alphabet) - 2}; + + std::string filename; + for(size_t i = 0; i < 5; ++i) + { + filename.push_back(alphabet[dist(rd)]); + } + + filename.push_back('.'); + + for(size_t i = 0; i < 5; ++i) + { + filename.push_back(alphabet[dist(rd)]); + } + + return filename; +} + +struct FileGuard +{ + const fs::path &p; + + explicit FileGuard(const fs::path &_p) : p(_p) + { + } + + ~FileGuard() + { + if(fs::exists(fs::status(p))) + { + fs::remove(p); + } + } +}; + +using FindOrCreateFunc = std::function< bool(llarp::Crypto *, const fs::path &, + llarp::SecretKey &) >; + +struct FindOrCreate : public ::testing::TestWithParam< FindOrCreateFunc > +{ + FindOrCreate() : crypto(llarp::Crypto::sodium{}) + { + } + + llarp::Crypto crypto; +}; + +// Concerns +// - file missing +// - file empty +// - happy path + +TEST_P(FindOrCreate, find_file_missing) +{ + // File missing. Should create a new file + llarp::SecretKey key; + fs::path p = randFilename(); + ASSERT_FALSE(fs::exists(fs::status(p))); + + FileGuard guard(p); + + ASSERT_TRUE(GetParam()(&crypto, p, key)); + ASSERT_TRUE(fs::exists(fs::status(p))); + ASSERT_FALSE(key.IsZero()); +} + +TEST_P(FindOrCreate, find_file_empty) +{ + // File empty. + llarp::SecretKey key; + fs::path p = randFilename(); + ASSERT_FALSE(fs::exists(fs::status(p))); + + std::fstream f; + f.open(p.string(), std::ios::out); + f.close(); + + FileGuard guard(p); + + ASSERT_FALSE(GetParam()(&crypto, p, key)); + // Verify we didn't delete an invalid file + ASSERT_TRUE(fs::exists(fs::status(p))); +} + +TEST_P(FindOrCreate, happy_path) +{ + // happy path. + llarp::SecretKey key; + fs::path p = randFilename(); + ASSERT_FALSE(fs::exists(fs::status(p))); + + std::ofstream f; + f.open(p.string(), std::ios::out); + std::fill_n(std::ostream_iterator< byte_t >(f), key.size(), 0x20); + f.close(); + + FileGuard guard(p); + + ASSERT_TRUE(GetParam()(&crypto, p, key)); + // Verify we didn't delete the file + ASSERT_TRUE(fs::exists(fs::status(p))); +} + +FindOrCreateFunc findOrCreateFunc[] = {llarp_findOrCreateEncryption, + llarp_findOrCreateIdentity}; + +INSTANTIATE_TEST_CASE_P(TestRouter, FindOrCreate, + ::testing::ValuesIn(findOrCreateFunc));