updated build system
This commit is contained in:
@@ -67,6 +67,54 @@ TEST(utils_encrypting_reader, read_file_data) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader, read_file_data_using_argon2id) {
|
||||
const auto token = std::string("moose");
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
auto &source_file = test::create_random_file(
|
||||
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file);
|
||||
if (source_file) {
|
||||
utils::encryption::encrypting_reader reader(
|
||||
"test.dat", source_file.get_path(), get_stop_requested, token, cfg);
|
||||
|
||||
std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr;
|
||||
EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function(
|
||||
reinterpret_cast<char *>(hdr.data()), hdr.size(),
|
||||
1U, &reader));
|
||||
EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg));
|
||||
// EXPECT_EQ(cfg, reader.get_kdf_config().value());
|
||||
|
||||
for (std::uint8_t i = 0U; i < 8U; i++) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size());
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
ASSERT_EQ(
|
||||
buffer.size() / 2U,
|
||||
utils::encryption::encrypting_reader::reader_function(
|
||||
reinterpret_cast<char *>(&buffer[(buffer.size() / 2U) * j]),
|
||||
buffer.size() / 2U, 1U, &reader));
|
||||
}
|
||||
|
||||
data_buffer decrypted_data;
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(
|
||||
token, *reader.get_kdf_config(), buffer, decrypted_data));
|
||||
|
||||
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||
decrypted_data.size());
|
||||
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file.read(
|
||||
file_data,
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size() * i,
|
||||
&bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks) {
|
||||
const auto token = std::string("moose");
|
||||
auto &source_file = test::create_random_file(
|
||||
@@ -114,6 +162,63 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader,
|
||||
read_file_data_in_multiple_chunks_using_argon2id) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
const auto token = std::string("moose");
|
||||
auto &source_file = test::create_random_file(
|
||||
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file);
|
||||
if (source_file) {
|
||||
utils::encryption::encrypting_reader reader(
|
||||
"test.dat", source_file.get_path(), get_stop_requested, token, cfg);
|
||||
|
||||
std::array<std::uint8_t, utils::encryption::kdf_config::size()> hdr;
|
||||
EXPECT_EQ(hdr.size(), utils::encryption::encrypting_reader::reader_function(
|
||||
reinterpret_cast<char *>(hdr.data()), hdr.size(),
|
||||
1U, &reader));
|
||||
EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, cfg));
|
||||
// EXPECT_EQ(cfg, reader.get_kdf_config().value());
|
||||
|
||||
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size() *
|
||||
2U);
|
||||
EXPECT_EQ(buffer.size(),
|
||||
utils::encryption::encrypting_reader::reader_function(
|
||||
reinterpret_cast<char *>(buffer.data()), buffer.size(), 1U,
|
||||
&reader));
|
||||
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
data_buffer decrypted_data;
|
||||
const auto offset = (j * (buffer.size() / 2U));
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(
|
||||
token, *reader.get_kdf_config(),
|
||||
data_buffer(
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(offset)),
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(
|
||||
offset + (buffer.size() / 2U)))),
|
||||
decrypted_data));
|
||||
|
||||
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||
decrypted_data.size());
|
||||
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file.read(
|
||||
file_data,
|
||||
(utils::encryption::encrypting_reader::get_data_chunk_size() * i) +
|
||||
(j *
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size()),
|
||||
&bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader, read_file_data_as_stream) {
|
||||
const auto token = std::string("moose");
|
||||
auto &source_file = test::create_random_file(
|
||||
@@ -166,6 +271,62 @@ TEST(utils_encrypting_reader, read_file_data_as_stream) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader, read_file_data_as_stream_using_argon2id) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
const auto token = std::string("moose");
|
||||
auto &source_file = test::create_random_file(
|
||||
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file);
|
||||
if (source_file) {
|
||||
utils::encryption::encrypting_reader reader(
|
||||
"test.dat", source_file.get_path(), get_stop_requested, token, cfg);
|
||||
auto io_stream = reader.create_iostream();
|
||||
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
EXPECT_EQ(reader.get_total_size(),
|
||||
static_cast<std::uint64_t>(io_stream->tellg()));
|
||||
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
|
||||
for (std::uint8_t i = 0U; i < 8U; i++) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size());
|
||||
EXPECT_FALSE(
|
||||
io_stream
|
||||
->seekg(static_cast<std::streamoff>(
|
||||
i * buffer.size() + utils::encryption::kdf_config::size()))
|
||||
.fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
EXPECT_FALSE(
|
||||
io_stream
|
||||
->read(
|
||||
reinterpret_cast<char *>(&buffer[(buffer.size() / 2U) * j]),
|
||||
static_cast<std::streamsize>(buffer.size()) / 2U)
|
||||
.fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
}
|
||||
|
||||
data_buffer decrypted_data;
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(
|
||||
token, *reader.get_kdf_config(), buffer, decrypted_data));
|
||||
|
||||
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||
decrypted_data.size());
|
||||
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file.read(
|
||||
file_data,
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size() * i,
|
||||
&bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks_as_stream) {
|
||||
const auto token = std::string("moose");
|
||||
auto &source_file = test::create_random_file(
|
||||
@@ -220,6 +381,69 @@ TEST(utils_encrypting_reader, read_file_data_in_multiple_chunks_as_stream) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encrypting_reader,
|
||||
read_file_data_in_multiple_chunks_as_stream_using_argon2id) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
const auto token = std::string("moose");
|
||||
auto &source_file = test::create_random_file(
|
||||
8u * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file);
|
||||
if (source_file) {
|
||||
utils::encryption::encrypting_reader reader(
|
||||
"test.dat", source_file.get_path(), get_stop_requested, token, cfg);
|
||||
auto io_stream = reader.create_iostream();
|
||||
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
EXPECT_EQ(reader.get_total_size(),
|
||||
static_cast<std::uint64_t>(io_stream->tellg()));
|
||||
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
|
||||
EXPECT_FALSE(io_stream
|
||||
->seekg(static_cast<std::streamoff>(
|
||||
utils::encryption::kdf_config::size()))
|
||||
.fail());
|
||||
|
||||
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size() *
|
||||
2U);
|
||||
EXPECT_FALSE(io_stream
|
||||
->read(reinterpret_cast<char *>(buffer.data()),
|
||||
static_cast<std::streamsize>(buffer.size()))
|
||||
.fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
data_buffer decrypted_data;
|
||||
const auto offset = (j * (buffer.size() / 2U));
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(
|
||||
token, *reader.get_kdf_config(),
|
||||
data_buffer(
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(offset)),
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(
|
||||
offset + (buffer.size() / 2U)))),
|
||||
decrypted_data));
|
||||
|
||||
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||
decrypted_data.size());
|
||||
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file.read(
|
||||
file_data,
|
||||
(utils::encryption::encrypting_reader::get_data_chunk_size() * i) +
|
||||
(j *
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size()),
|
||||
&bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace repertory
|
||||
|
||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||
|
144
support/test/src/utils/encryption_kdf_config_test.cpp
Normal file
144
support/test/src/utils/encryption_kdf_config_test.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "test.hpp"
|
||||
|
||||
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||
|
||||
namespace repertory {
|
||||
TEST(utils_encryption_kdf_config, can_construct_using_default_constructor) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
EXPECT_EQ(utils::encryption::kdf_config::repertory_magic, cfg.magic);
|
||||
EXPECT_EQ(utils::encryption::kdf_version::v1, cfg.version);
|
||||
EXPECT_EQ(utils::encryption::kdf_type::argon2id, cfg.kdf);
|
||||
EXPECT_EQ(utils::encryption::memlimit_level::level3, cfg.memlimit);
|
||||
EXPECT_EQ(utils::encryption::opslimit_level::level2, cfg.opslimit);
|
||||
EXPECT_EQ(utils::encryption::kdf_config::salt_t{}, cfg.salt);
|
||||
EXPECT_EQ(0U, cfg.checksum);
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, can_generate_salt) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.generate_salt();
|
||||
EXPECT_NE(utils::encryption::kdf_config::salt_t{}, cfg.salt);
|
||||
|
||||
auto orig_salt = cfg.salt;
|
||||
cfg.generate_salt();
|
||||
EXPECT_NE(orig_salt, cfg.salt);
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, can_generate_checksum) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
EXPECT_EQ(8853559678329530327ULL, cfg.generate_checksum());
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, generate_salt_calculates_checksum) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.generate_salt();
|
||||
|
||||
EXPECT_NE(0U, cfg.checksum);
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, can_create_header_and_restore) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.generate_salt();
|
||||
auto hdr = cfg.to_header();
|
||||
|
||||
EXPECT_EQ(utils::encryption::kdf_config::size(), hdr.size());
|
||||
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_TRUE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
auto restored_hdr = restored_cfg.to_header();
|
||||
|
||||
EXPECT_EQ(hdr, restored_hdr);
|
||||
EXPECT_EQ(cfg.magic, restored_cfg.magic);
|
||||
EXPECT_EQ(cfg.version, restored_cfg.version);
|
||||
EXPECT_EQ(cfg.kdf, restored_cfg.kdf);
|
||||
EXPECT_EQ(cfg.memlimit, restored_cfg.memlimit);
|
||||
EXPECT_EQ(cfg.opslimit, restored_cfg.opslimit);
|
||||
EXPECT_EQ(cfg.salt, restored_cfg.salt);
|
||||
EXPECT_EQ(cfg.checksum, restored_cfg.checksum);
|
||||
EXPECT_EQ(cfg, restored_cfg);
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, header_restore_fails_if_magic_is_invalid) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.magic = 0x11;
|
||||
cfg.generate_salt();
|
||||
|
||||
auto hdr = cfg.to_header();
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, header_restore_fails_if_version_is_invalid) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.version = static_cast<utils::encryption::kdf_version>(0x11);
|
||||
cfg.generate_salt();
|
||||
|
||||
auto hdr = cfg.to_header();
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, header_restore_fails_if_kdf_is_invalid) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.kdf = static_cast<utils::encryption::kdf_type>(0x11);
|
||||
cfg.generate_salt();
|
||||
|
||||
auto hdr = cfg.to_header();
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, header_restore_fails_if_memlimit_is_invalid) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.memlimit = static_cast<utils::encryption::memlimit_level>(0x11);
|
||||
cfg.generate_salt();
|
||||
|
||||
auto hdr = cfg.to_header();
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, header_restore_fails_if_opslimit_is_invalid) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.opslimit = static_cast<utils::encryption::opslimit_level>(0x11);
|
||||
cfg.generate_salt();
|
||||
|
||||
auto hdr = cfg.to_header();
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
}
|
||||
|
||||
TEST(utils_encryption_kdf_config, header_restore_fails_if_salt_is_invalid) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
cfg.generate_salt();
|
||||
cfg.salt = utils::encryption::kdf_config::salt_t{};
|
||||
|
||||
auto hdr = cfg.to_header();
|
||||
utils::encryption::kdf_config restored_cfg;
|
||||
EXPECT_FALSE(utils::encryption::kdf_config::from_header(hdr, restored_cfg));
|
||||
}
|
||||
} // namespace repertory
|
||||
|
||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
@@ -24,6 +24,10 @@
|
||||
#if defined(PROJECT_ENABLE_LIBSODIUM)
|
||||
|
||||
namespace {
|
||||
#if defined(PROJECT_ENABLE_BOOST)
|
||||
const std::string buffer = "cow moose dog chicken";
|
||||
#endif // defined(PROJECT_ENABLE_BOOST)
|
||||
|
||||
const auto get_stop_requested = []() -> bool { return false; };
|
||||
} // namespace
|
||||
|
||||
@@ -32,24 +36,21 @@ static constexpr std::string_view token{"moose"};
|
||||
static constexpr std::wstring_view token_w{L"moose"};
|
||||
|
||||
TEST(utils_encryption, generate_key) {
|
||||
auto key1 =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
auto key1 = utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
EXPECT_STREQ(
|
||||
"ab4a0b004e824962913f7c0f79582b6ec7a3b8726426ca61d1a0a28ce5049e96",
|
||||
utils::collection::to_hex_string(key1).c_str());
|
||||
|
||||
auto key2 =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>("moose");
|
||||
auto key3 =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>("moose");
|
||||
auto key2 = utils::encryption::generate_key<utils::hash::hash_256_t>("moose");
|
||||
auto key3 = utils::encryption::generate_key<utils::hash::hash_256_t>("moose");
|
||||
EXPECT_EQ(key2, key3);
|
||||
|
||||
auto key4 =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>("moose2");
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>("moose2");
|
||||
EXPECT_NE(key2, key4);
|
||||
|
||||
auto key1_w =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token_w);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w);
|
||||
EXPECT_NE(key1, key1_w);
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ(
|
||||
@@ -62,34 +63,33 @@ TEST(utils_encryption, generate_key) {
|
||||
#endif
|
||||
|
||||
auto key2_w =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(L"moose");
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(L"moose");
|
||||
auto key3_w =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(L"moose");
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(L"moose");
|
||||
EXPECT_EQ(key2_w, key3_w);
|
||||
EXPECT_NE(key2_w, key2);
|
||||
EXPECT_NE(key3_w, key3);
|
||||
|
||||
auto key4_w =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(L"moose2");
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(L"moose2");
|
||||
EXPECT_NE(key2_w, key4_w);
|
||||
EXPECT_NE(key4_w, key4);
|
||||
}
|
||||
|
||||
TEST(utils_encryption, generate_key_default_hasher_is_blake2b_256) {
|
||||
auto key1 =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
auto key2 = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
auto key1 = utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
auto key2 = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
token, [](auto &&data, auto &&size) -> auto {
|
||||
return utils::encryption::create_hash_blake2b_256(
|
||||
return utils::hash::create_hash_blake2b_256(
|
||||
std::string_view(reinterpret_cast<const char *>(data), size));
|
||||
});
|
||||
EXPECT_EQ(key1, key2);
|
||||
|
||||
auto key1_w =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token_w);
|
||||
auto key2_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w);
|
||||
auto key2_w = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
token_w, [](auto &&data, auto &&size) -> auto {
|
||||
return utils::encryption::create_hash_blake2b_256(std::wstring_view(
|
||||
return utils::hash::create_hash_blake2b_256(std::wstring_view(
|
||||
reinterpret_cast<const wchar_t *>(data), size / sizeof(wchar_t)));
|
||||
});
|
||||
EXPECT_EQ(key1_w, key2_w);
|
||||
@@ -99,22 +99,22 @@ TEST(utils_encryption, generate_key_default_hasher_is_blake2b_256) {
|
||||
}
|
||||
|
||||
TEST(utils_encryption, generate_key_with_hasher) {
|
||||
auto key1 = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
token, utils::encryption::blake2b_256_hasher);
|
||||
auto key1 = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
token, utils::hash::blake2b_256_hasher);
|
||||
EXPECT_STREQ(
|
||||
"ab4a0b004e824962913f7c0f79582b6ec7a3b8726426ca61d1a0a28ce5049e96",
|
||||
utils::collection::to_hex_string(key1).c_str());
|
||||
|
||||
auto key2 = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
token, utils::encryption::sha256_hasher);
|
||||
auto key2 = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
token, utils::hash::sha256_hasher);
|
||||
EXPECT_NE(key1, key2);
|
||||
|
||||
EXPECT_STREQ(
|
||||
"182072537ada59e4d6b18034a80302ebae935f66adbdf0f271d3d36309c2d481",
|
||||
utils::collection::to_hex_string(key2).c_str());
|
||||
|
||||
auto key1_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
token_w, utils::encryption::blake2b_256_hasher);
|
||||
auto key1_w = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
token_w, utils::hash::blake2b_256_hasher);
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ(
|
||||
L"4f5eb2a2ab34e3777b230465283923080b9ba59311e74058ccd74185131d11fe",
|
||||
@@ -125,8 +125,8 @@ TEST(utils_encryption, generate_key_with_hasher) {
|
||||
utils::collection::to_hex_wstring(key1_w).c_str());
|
||||
#endif
|
||||
|
||||
auto key2_w = utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
token_w, utils::encryption::sha256_hasher);
|
||||
auto key2_w = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
token_w, utils::hash::sha256_hasher);
|
||||
EXPECT_NE(key1_w, key2_w);
|
||||
|
||||
#if defined(_WIN32)
|
||||
@@ -144,7 +144,69 @@ TEST(utils_encryption, generate_key_with_hasher) {
|
||||
}
|
||||
|
||||
#if defined(PROJECT_ENABLE_BOOST)
|
||||
static const std::string buffer = "cow moose dog chicken";
|
||||
TEST(utils_encryption, generate_argon2id_key) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
{
|
||||
auto key1 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg);
|
||||
|
||||
auto key2 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg);
|
||||
EXPECT_NE(key1, key2);
|
||||
|
||||
auto key3 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg);
|
||||
EXPECT_NE(key3, key1);
|
||||
|
||||
auto key4 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg);
|
||||
EXPECT_NE(key4, key2);
|
||||
|
||||
EXPECT_NE(key3, key4);
|
||||
}
|
||||
|
||||
{
|
||||
auto key1 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w, cfg);
|
||||
|
||||
auto key2 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w, cfg);
|
||||
EXPECT_NE(key1, key2);
|
||||
|
||||
auto key3 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w, cfg);
|
||||
EXPECT_NE(key3, key1);
|
||||
|
||||
auto key4 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w, cfg);
|
||||
EXPECT_NE(key4, key2);
|
||||
|
||||
EXPECT_NE(key3, key4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encryption, recreate_argon2id_key) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
{
|
||||
auto key1 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg);
|
||||
|
||||
auto key2 =
|
||||
utils::encryption::recreate_key<utils::hash::hash_256_t>(token, cfg);
|
||||
EXPECT_EQ(key1, key2);
|
||||
}
|
||||
|
||||
{
|
||||
auto key1 =
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token_w, cfg);
|
||||
|
||||
auto key2 =
|
||||
utils::encryption::recreate_key<utils::hash::hash_256_t>(token_w, cfg);
|
||||
EXPECT_EQ(key1, key2);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_encrypted_result(const data_buffer &result) {
|
||||
EXPECT_EQ(buffer.size() + utils::encryption::encryption_header_size,
|
||||
@@ -155,6 +217,17 @@ static void test_encrypted_result(const data_buffer &result) {
|
||||
EXPECT_STREQ(buffer.c_str(), data.c_str());
|
||||
}
|
||||
|
||||
static void
|
||||
test_encrypted_result_using_argon2id(const data_buffer &result,
|
||||
const utils::encryption::kdf_config &cfg) {
|
||||
EXPECT_EQ(buffer.size() + utils::encryption::encryption_header_size,
|
||||
result.size());
|
||||
std::string data;
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(token, cfg, result, data));
|
||||
EXPECT_EQ(buffer.size(), data.size());
|
||||
EXPECT_STREQ(buffer.c_str(), data.c_str());
|
||||
}
|
||||
|
||||
TEST(utils_encryption, encrypt_data_buffer) {
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(token, buffer, result);
|
||||
@@ -163,7 +236,7 @@ TEST(utils_encryption, encrypt_data_buffer) {
|
||||
|
||||
TEST(utils_encryption, encrypt_data_buffer_with_key) {
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(key, buffer, result);
|
||||
test_encrypted_result(result);
|
||||
@@ -179,7 +252,7 @@ TEST(utils_encryption, encrypt_data_pointer) {
|
||||
|
||||
TEST(utils_encryption, encrypt_data_pointer_with_key) {
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(
|
||||
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
||||
@@ -189,7 +262,7 @@ TEST(utils_encryption, encrypt_data_pointer_with_key) {
|
||||
|
||||
TEST(utils_encryption, decrypt_data_pointer) {
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(
|
||||
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
||||
@@ -205,7 +278,7 @@ TEST(utils_encryption, decrypt_data_pointer) {
|
||||
|
||||
TEST(utils_encryption, decrypt_data_buffer_with_key) {
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(
|
||||
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
||||
@@ -220,7 +293,7 @@ TEST(utils_encryption, decrypt_data_buffer_with_key) {
|
||||
|
||||
TEST(utils_encryption, decrypt_data_pointer_with_key) {
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(
|
||||
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
||||
@@ -236,7 +309,7 @@ TEST(utils_encryption, decrypt_data_pointer_with_key) {
|
||||
|
||||
TEST(utils_encryption, decryption_failure) {
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(token);
|
||||
utils::encryption::generate_key<utils::hash::hash_256_t>(token);
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(
|
||||
key, reinterpret_cast<const unsigned char *>(buffer.data()),
|
||||
@@ -280,6 +353,28 @@ TEST(utils_encryption, decrypt_file_path) {
|
||||
EXPECT_STREQ("/moose/cow/test.dat", file_path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_encryption, encrypt_data_buffer_using_argon2id) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(token, cfg, buffer, result);
|
||||
test_encrypted_result_using_argon2id(result, cfg);
|
||||
}
|
||||
|
||||
TEST(utils_encryption, encrypt_data_pointer_using_argon2id) {
|
||||
utils::encryption::kdf_config cfg;
|
||||
|
||||
data_buffer result;
|
||||
utils::encryption::encrypt_data(
|
||||
token, cfg, reinterpret_cast<const unsigned char *>(buffer.data()),
|
||||
buffer.size(), result);
|
||||
test_encrypted_result_using_argon2id(result, cfg);
|
||||
}
|
||||
|
||||
// TEST(utils_encryption, decrypt_file_name_using_argon2id) {}
|
||||
|
||||
// TEST(utils_encryption, decrypt_file_path_using_argon2id) {}
|
||||
#endif // defined(PROJECT_ENABLE_BOOST)
|
||||
} // namespace repertory
|
||||
|
||||
|
@@ -25,34 +25,31 @@
|
||||
|
||||
namespace repertory {
|
||||
TEST(utils_hash, hash_type_sizes) {
|
||||
EXPECT_EQ(32U, utils::encryption::hash_256_t{}.size());
|
||||
EXPECT_EQ(48U, utils::encryption::hash_384_t{}.size());
|
||||
EXPECT_EQ(64U, utils::encryption::hash_512_t{}.size());
|
||||
EXPECT_EQ(32U, utils::hash::hash_256_t{}.size());
|
||||
EXPECT_EQ(48U, utils::hash::hash_384_t{}.size());
|
||||
EXPECT_EQ(64U, utils::hash::hash_512_t{}.size());
|
||||
}
|
||||
|
||||
TEST(utils_hash, default_hasher_is_blake2b) {
|
||||
EXPECT_EQ(
|
||||
&utils::encryption::blake2b_256_hasher,
|
||||
&utils::encryption::default_create_hash<utils::encryption::hash_256_t>());
|
||||
EXPECT_EQ(&utils::hash::blake2b_256_hasher,
|
||||
&utils::hash::default_create_hash<utils::hash::hash_256_t>());
|
||||
|
||||
EXPECT_EQ(
|
||||
&utils::encryption::blake2b_384_hasher,
|
||||
&utils::encryption::default_create_hash<utils::encryption::hash_384_t>());
|
||||
EXPECT_EQ(&utils::hash::blake2b_384_hasher,
|
||||
&utils::hash::default_create_hash<utils::hash::hash_384_t>());
|
||||
|
||||
EXPECT_EQ(
|
||||
&utils::encryption::blake2b_512_hasher,
|
||||
&utils::encryption::default_create_hash<utils::encryption::hash_512_t>());
|
||||
EXPECT_EQ(&utils::hash::blake2b_512_hasher,
|
||||
&utils::hash::default_create_hash<utils::hash::hash_512_t>());
|
||||
}
|
||||
|
||||
TEST(utils_hash, blake2b_256) {
|
||||
auto hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_256("a"));
|
||||
utils::hash::create_hash_blake2b_256("a"));
|
||||
EXPECT_STREQ(
|
||||
"8928aae63c84d87ea098564d1e03ad813f107add474e56aedd286349c0c03ea4",
|
||||
hash.c_str());
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_256(L"a"));
|
||||
utils::hash::create_hash_blake2b_256(L"a"));
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ(
|
||||
"d2373b17cd8a8e19e39f52fa4905a274f93805fbb8bb4c7f3cb4b2cd6708ec8a",
|
||||
@@ -64,7 +61,7 @@ TEST(utils_hash, blake2b_256) {
|
||||
#endif
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_256({1U}));
|
||||
utils::hash::create_hash_blake2b_256({1U}));
|
||||
EXPECT_STREQ(
|
||||
"ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25",
|
||||
hash.c_str());
|
||||
@@ -72,13 +69,13 @@ TEST(utils_hash, blake2b_256) {
|
||||
|
||||
TEST(utils_hash, blake2b_384) {
|
||||
auto hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_384("a"));
|
||||
utils::hash::create_hash_blake2b_384("a"));
|
||||
EXPECT_STREQ("7d40de16ff771d4595bf70cbda0c4ea0a066a6046fa73d34471cd4d93d827d7"
|
||||
"c94c29399c50de86983af1ec61d5dcef0",
|
||||
hash.c_str());
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_384(L"a"));
|
||||
utils::hash::create_hash_blake2b_384(L"a"));
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ("637fe31d1e955760ef31043d525d9321826a778ddbe82fcde45a98394241380"
|
||||
"96675e2f87e36b53ab223a7fd254198fd",
|
||||
@@ -90,7 +87,7 @@ TEST(utils_hash, blake2b_384) {
|
||||
#endif
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_384({1U}));
|
||||
utils::hash::create_hash_blake2b_384({1U}));
|
||||
EXPECT_STREQ("42cfe875d08d816538103b906bb0b05202e0b09c4e981680c1110684fc7845b"
|
||||
"c91c178fa167afcc445490644b2bf5f5b",
|
||||
hash.c_str());
|
||||
@@ -98,14 +95,14 @@ TEST(utils_hash, blake2b_384) {
|
||||
|
||||
TEST(utils_hash, blake2b_512) {
|
||||
auto hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_512("a"));
|
||||
utils::hash::create_hash_blake2b_512("a"));
|
||||
EXPECT_STREQ(
|
||||
"333fcb4ee1aa7c115355ec66ceac917c8bfd815bf7587d325aec1864edd24e34d5abe2c6"
|
||||
"b1b5ee3face62fed78dbef802f2a85cb91d455a8f5249d330853cb3c",
|
||||
hash.c_str());
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_512(L"a"));
|
||||
utils::hash::create_hash_blake2b_512(L"a"));
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ(
|
||||
"05970b95468b0b1941066ff189091493e73859ce41cde5ad08118e93ea1d81a57a144296"
|
||||
@@ -119,7 +116,7 @@ TEST(utils_hash, blake2b_512) {
|
||||
#endif
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_blake2b_512({1U}));
|
||||
utils::hash::create_hash_blake2b_512({1U}));
|
||||
EXPECT_STREQ(
|
||||
"9545ba37b230d8a2e716c4707586542780815b7c4088edcb9af6a9452d50f32474d5ba9a"
|
||||
"ab52a67aca864ef2696981c2eadf49020416136afd838fb048d21653",
|
||||
@@ -127,14 +124,14 @@ TEST(utils_hash, blake2b_512) {
|
||||
}
|
||||
|
||||
TEST(utils_hash, sha256) {
|
||||
auto hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_sha256("a"));
|
||||
auto hash =
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_sha256("a"));
|
||||
EXPECT_STREQ(
|
||||
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
|
||||
hash.c_str());
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_sha256(L"a"));
|
||||
hash =
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_sha256(L"a"));
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ(
|
||||
"ffe9aaeaa2a2d5048174df0b80599ef0197ec024c4b051bc9860cff58ef7f9f3",
|
||||
@@ -145,23 +142,23 @@ TEST(utils_hash, sha256) {
|
||||
hash.c_str());
|
||||
#endif
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_sha256({1U}));
|
||||
hash =
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_sha256({1U}));
|
||||
EXPECT_STREQ(
|
||||
"4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
|
||||
hash.c_str());
|
||||
}
|
||||
|
||||
TEST(utils_hash, sha512) {
|
||||
auto hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_sha512("a"));
|
||||
auto hash =
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_sha512("a"));
|
||||
EXPECT_STREQ(
|
||||
"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c65"
|
||||
"2bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75",
|
||||
hash.c_str());
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_sha512(L"a"));
|
||||
hash =
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_sha512(L"a"));
|
||||
#if defined(_WIN32)
|
||||
EXPECT_STREQ(
|
||||
"5c2ca3d50f46ece6066c53bd1a490cbe5f72d2738ae9417332e91e5c3f75205c639d71a9"
|
||||
@@ -174,8 +171,8 @@ TEST(utils_hash, sha512) {
|
||||
hash.c_str());
|
||||
#endif
|
||||
|
||||
hash = utils::collection::to_hex_string(
|
||||
utils::encryption::create_hash_sha512({1U}));
|
||||
hash =
|
||||
utils::collection::to_hex_string(utils::hash::create_hash_sha512({1U}));
|
||||
EXPECT_STREQ(
|
||||
"7b54b66836c1fbdd13d2441d9e1434dc62ca677fb68f5fe66a464baadecdbd00576f8d6b"
|
||||
"5ac3bcc80844b7d50b1cc6603444bbe7cfcf8fc0aa1ee3c636d9e339",
|
||||
|
253
support/test/src/utils/ttl_cache_test.cpp
Normal file
253
support/test/src/utils/ttl_cache_test.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "test.hpp"
|
||||
|
||||
namespace repertory {
|
||||
TEST(utils_ttl_cache, can_construct_cache) {
|
||||
utils::ttl_cache<std::uint8_t> cache;
|
||||
EXPECT_EQ(utils::ttl_cache<std::uint8_t>::default_expiration,
|
||||
cache.get_ttl());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_construct_cache_with_ttl) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(1000U));
|
||||
EXPECT_EQ(std::chrono::milliseconds(1000U), cache.get_ttl());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_change_ttl) {
|
||||
utils::ttl_cache<std::uint8_t> cache;
|
||||
cache.set_ttl(std::chrono::milliseconds(1000U));
|
||||
EXPECT_EQ(std::chrono::milliseconds(1000U), cache.get_ttl());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_set_and_get) {
|
||||
utils::ttl_cache<std::uint8_t> cache;
|
||||
cache.set("/test", 21U);
|
||||
auto data = cache.get("/test");
|
||||
ASSERT_NE(nullptr, data.get());
|
||||
|
||||
EXPECT_EQ(21U, data->load());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, get_returns_nullptr_for_api_path_not_in_cache) {
|
||||
utils::ttl_cache<std::uint8_t> cache;
|
||||
auto data = cache.get("/test");
|
||||
ASSERT_EQ(nullptr, data.get());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, set_and_get_returns_value_and_refreshes_ttl) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(1000U));
|
||||
|
||||
cache.set("/test", 7U);
|
||||
auto data = cache.get("/test");
|
||||
{
|
||||
EXPECT_TRUE(cache.contains("/test"));
|
||||
ASSERT_NE(data, nullptr);
|
||||
EXPECT_EQ(7U, data->load());
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200U));
|
||||
{
|
||||
EXPECT_TRUE(cache.contains("/test"));
|
||||
auto data2 = cache.get("/test");
|
||||
ASSERT_NE(data2, nullptr);
|
||||
ASSERT_EQ(data.get(), data2.get());
|
||||
EXPECT_EQ(7U, data2->load());
|
||||
}
|
||||
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(800U));
|
||||
cache.purge_expired();
|
||||
|
||||
auto data3 = cache.get("/test");
|
||||
EXPECT_TRUE(cache.contains("/test"));
|
||||
|
||||
ASSERT_NE(data3, nullptr);
|
||||
ASSERT_EQ(data.get(), data3.get());
|
||||
EXPECT_EQ(7U, data3->load());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, entry_expires_without_refresh) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(50U));
|
||||
cache.set("/test", 42U);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(51U));
|
||||
cache.purge_expired();
|
||||
EXPECT_FALSE(cache.contains("/test"));
|
||||
|
||||
auto data = cache.get("/test");
|
||||
EXPECT_EQ(nullptr, data.get());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_erase) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(50U));
|
||||
cache.set("/test", 42U);
|
||||
cache.erase("/test");
|
||||
|
||||
EXPECT_FALSE(cache.contains("/test"));
|
||||
auto data = cache.get("/test");
|
||||
EXPECT_EQ(nullptr, data.get());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_clear) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(50U));
|
||||
|
||||
cache.set("/test", 42U);
|
||||
cache.set("/test2", 42U);
|
||||
EXPECT_TRUE(cache.contains("/test"));
|
||||
EXPECT_TRUE(cache.contains("/test2"));
|
||||
cache.clear();
|
||||
|
||||
{
|
||||
EXPECT_FALSE(cache.contains("/test"));
|
||||
auto data = cache.get("/test");
|
||||
EXPECT_EQ(nullptr, data.get());
|
||||
}
|
||||
|
||||
{
|
||||
EXPECT_FALSE(cache.contains("/test2"));
|
||||
auto data = cache.get("/test2");
|
||||
EXPECT_EQ(nullptr, data.get());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_handle_concurrent_access) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(5000U));
|
||||
|
||||
std::atomic<bool> start{false};
|
||||
std::thread writer([&] {
|
||||
while (not start.load()) {
|
||||
}
|
||||
for (std::uint8_t ttl = 0U; ttl < 100U; ++ttl) {
|
||||
cache.set("/key", ttl);
|
||||
std::this_thread::yield();
|
||||
}
|
||||
});
|
||||
|
||||
std::thread reader([&] {
|
||||
while (not start.load()) {
|
||||
}
|
||||
for (std::uint8_t ttl = 0U; ttl < 100U; ++ttl) {
|
||||
auto data = cache.get("/key");
|
||||
if (data) {
|
||||
(void)data->load();
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
});
|
||||
|
||||
start = true;
|
||||
writer.join();
|
||||
reader.join();
|
||||
|
||||
auto data = cache.get("/key");
|
||||
ASSERT_NE(data, nullptr);
|
||||
(void)data->load();
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_handle_custom_atomic) {
|
||||
utils::ttl_cache<std::string, utils::atomic> cache(
|
||||
std::chrono::milliseconds(5000U));
|
||||
cache.set("/test", "test");
|
||||
auto data = cache.get("/test");
|
||||
ASSERT_NE(nullptr, data.get());
|
||||
EXPECT_STREQ("test", data->load().c_str());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, get_renews_after_ttl_if_purge_expired_is_not_called) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(50U));
|
||||
cache.set("/test", 9U);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(75U));
|
||||
|
||||
auto data = cache.get("/test");
|
||||
ASSERT_NE(nullptr, data.get());
|
||||
EXPECT_EQ(9U, data->load());
|
||||
|
||||
cache.purge_expired();
|
||||
EXPECT_TRUE(cache.contains("/test"));
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_update_data) {
|
||||
utils::ttl_cache<std::uint8_t> cache;
|
||||
|
||||
cache.set("/test", 1U);
|
||||
auto data = cache.get("/test");
|
||||
ASSERT_NE(nullptr, data.get());
|
||||
EXPECT_EQ(1U, data->load());
|
||||
|
||||
cache.set("/test", 2U);
|
||||
auto data2 = cache.get("/test");
|
||||
ASSERT_NE(nullptr, data2.get());
|
||||
EXPECT_EQ(data.get(), data2.get());
|
||||
EXPECT_EQ(2U, data2->load());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, purge_expired_removes_only_expired_entries) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(1000U));
|
||||
cache.set("/test1", 1U);
|
||||
cache.set("/test2", 2U);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500U));
|
||||
auto data = cache.get("/test2");
|
||||
ASSERT_NE(data, nullptr);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(501U));
|
||||
cache.purge_expired();
|
||||
|
||||
EXPECT_FALSE(cache.contains("/test1"));
|
||||
EXPECT_TRUE(cache.contains("/test2"));
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, can_handle_non_existing_items_without_failure) {
|
||||
utils::ttl_cache<std::uint8_t> cache;
|
||||
cache.set("/exists", 5U);
|
||||
EXPECT_TRUE(cache.contains("/exists"));
|
||||
|
||||
cache.erase("/not_found");
|
||||
EXPECT_TRUE(cache.contains("/exists"));
|
||||
|
||||
auto data = cache.get("/exists");
|
||||
ASSERT_NE(nullptr, data.get());
|
||||
EXPECT_EQ(5U, data->load());
|
||||
}
|
||||
|
||||
TEST(utils_ttl_cache, changing_ttl_affects_only_future_expirations) {
|
||||
utils::ttl_cache<std::uint8_t> cache(std::chrono::milliseconds(1000U));
|
||||
cache.set("/test", 11U);
|
||||
|
||||
cache.set_ttl(std::chrono::milliseconds(100U));
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200U));
|
||||
cache.purge_expired();
|
||||
EXPECT_TRUE(cache.contains("/test"));
|
||||
|
||||
auto data = cache.get("/test");
|
||||
ASSERT_NE(nullptr, data.get());
|
||||
EXPECT_EQ(11U, data->load());
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200U));
|
||||
cache.purge_expired();
|
||||
EXPECT_FALSE(cache.contains("/test"));
|
||||
}
|
||||
} // namespace repertory
|
Reference in New Issue
Block a user