From c5d0e2c245ec2441e40567e3fd011499096ec84b Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 13 Dec 2014 11:59:48 +0100 Subject: [PATCH] Add Key::ToBinary, Key::FromBinary and more test cases for Key --- .../inmemory/InMemoryBlockStore.cpp | 4 +- .../ondisk/OnDiskBlockStore.cpp | 4 +- .../testfake/FakeBlockStore.cpp | 4 +- src/blockstore/utils/Key.cpp | 12 +- src/blockstore/utils/Key.h | 5 +- .../helpers/BlockStoreWithRandomKeysTest.cpp | 2 +- src/test/blockstore/utils/KeyTest.cpp | 124 +++++++++++++++--- 7 files changed, 126 insertions(+), 29 deletions(-) diff --git a/src/blockstore/implementations/inmemory/InMemoryBlockStore.cpp b/src/blockstore/implementations/inmemory/InMemoryBlockStore.cpp index 566a9894..e635c163 100644 --- a/src/blockstore/implementations/inmemory/InMemoryBlockStore.cpp +++ b/src/blockstore/implementations/inmemory/InMemoryBlockStore.cpp @@ -14,7 +14,7 @@ InMemoryBlockStore::InMemoryBlockStore() : _blocks() {} unique_ptr InMemoryBlockStore::create(const Key &key, size_t size) { - auto insert_result = _blocks.emplace(key.AsString(), size); + auto insert_result = _blocks.emplace(key.ToString(), size); if (!insert_result.second) { return nullptr; @@ -27,7 +27,7 @@ unique_ptr InMemoryBlockStore::create(const Key &key, size_t size) { unique_ptr InMemoryBlockStore::load(const Key &key) { //Return a pointer to the stored InMemoryBlock try { - return make_unique(_blocks.at(key.AsString())); + return make_unique(_blocks.at(key.ToString())); } catch (const std::out_of_range &e) { return nullptr; } diff --git a/src/blockstore/implementations/ondisk/OnDiskBlockStore.cpp b/src/blockstore/implementations/ondisk/OnDiskBlockStore.cpp index 8af6c10d..e6057959 100644 --- a/src/blockstore/implementations/ondisk/OnDiskBlockStore.cpp +++ b/src/blockstore/implementations/ondisk/OnDiskBlockStore.cpp @@ -16,7 +16,7 @@ OnDiskBlockStore::OnDiskBlockStore(const boost::filesystem::path &rootdir) : _rootdir(rootdir) {} unique_ptr OnDiskBlockStore::create(const Key &key, size_t size) { - auto file_path = _rootdir / key.AsString(); + auto file_path = _rootdir / key.ToString(); auto block = OnDiskBlock::CreateOnDisk(file_path, size); if (!block) { @@ -26,7 +26,7 @@ unique_ptr OnDiskBlockStore::create(const Key &key, size_t size) { } unique_ptr OnDiskBlockStore::load(const Key &key) { - auto file_path = _rootdir / key.AsString(); + auto file_path = _rootdir / key.ToString(); return OnDiskBlock::LoadFromDisk(file_path); } diff --git a/src/blockstore/implementations/testfake/FakeBlockStore.cpp b/src/blockstore/implementations/testfake/FakeBlockStore.cpp index 2d7cc306..4b839164 100644 --- a/src/blockstore/implementations/testfake/FakeBlockStore.cpp +++ b/src/blockstore/implementations/testfake/FakeBlockStore.cpp @@ -15,7 +15,7 @@ FakeBlockStore::FakeBlockStore() : _blocks(), _used_dataregions_for_blocks() {} unique_ptr FakeBlockStore::create(const Key &key, size_t size) { - auto insert_result = _blocks.emplace(key.AsString(), size); + auto insert_result = _blocks.emplace(key.ToString(), size); insert_result.first->second.FillWithZeroes(); if (!insert_result.second) { @@ -28,7 +28,7 @@ unique_ptr FakeBlockStore::create(const Key &key, size_t size) { unique_ptr FakeBlockStore::load(const Key &key) { //Return a copy of the stored data - string key_string = key.AsString(); + string key_string = key.ToString(); try { return makeFakeBlockFromData(key_string, _blocks.at(key_string)); } catch (const std::out_of_range &e) { diff --git a/src/blockstore/utils/Key.cpp b/src/blockstore/utils/Key.cpp index 18ac49b8..ef3959a5 100644 --- a/src/blockstore/utils/Key.cpp +++ b/src/blockstore/utils/Key.cpp @@ -44,7 +44,7 @@ Key Key::FromString(const std::string &key) { return result; } -string Key::AsString() const { +string Key::ToString() const { string result; ArraySource(_key, KEYLENGTH_BINARY, true, new HexEncoder(new StringSink(result)) @@ -65,4 +65,14 @@ bool operator!=(const Key &lhs, const Key &rhs) { return !operator==(lhs, rhs); } +void Key::ToBinary(void *target) const { + std::memcpy(target, _key, KEYLENGTH_BINARY); +} + +Key Key::FromBinary(void *source) { + Key result; + std::memcpy(result._key, source, KEYLENGTH_BINARY); + return result; +} + } diff --git a/src/blockstore/utils/Key.h b/src/blockstore/utils/Key.h index 3441dc8a..7b091e41 100644 --- a/src/blockstore/utils/Key.h +++ b/src/blockstore/utils/Key.h @@ -18,7 +18,10 @@ public: static Key CreateRandomKey(); static Key FromString(const std::string &key); - std::string AsString() const; + std::string ToString() const; + + static Key FromBinary(void *source); + void ToBinary(void *target) const; const unsigned char *data() const; diff --git a/src/test/blockstore/interface/helpers/BlockStoreWithRandomKeysTest.cpp b/src/test/blockstore/interface/helpers/BlockStoreWithRandomKeysTest.cpp index 45835c5d..13ccfc3b 100644 --- a/src/test/blockstore/interface/helpers/BlockStoreWithRandomKeysTest.cpp +++ b/src/test/blockstore/interface/helpers/BlockStoreWithRandomKeysTest.cpp @@ -58,7 +58,7 @@ TEST_F(BlockStoreWithRandomKeysTest, SizeIsPassedThrough1024) { TEST_F(BlockStoreWithRandomKeysTest, KeyHasCorrectSize) { EXPECT_CALL(blockStoreMock, do_create(_, _)).WillOnce(Invoke([](const Key &key, size_t) { - EXPECT_EQ(Key::KEYLENGTH_STRING, key.AsString().size()); + EXPECT_EQ(Key::KEYLENGTH_STRING, key.ToString().size()); return new BlockMock; })); diff --git a/src/test/blockstore/utils/KeyTest.cpp b/src/test/blockstore/utils/KeyTest.cpp index 5366939b..34927057 100644 --- a/src/test/blockstore/utils/KeyTest.cpp +++ b/src/test/blockstore/utils/KeyTest.cpp @@ -1,6 +1,8 @@ #include "gtest/gtest.h" #include +#include "blockstore/utils/Data.h" +#include "test/testutils/DataBlockFixture.h" using ::testing::Test; @@ -10,73 +12,155 @@ using namespace blockstore; class KeyTest: public Test { public: - const string KEY1_DATA = "1491BB4932A389EE14BC7090AC772972"; - const string KEY2_DATA = "272EE5517627CFA147A971A8E6E747E0"; + //TODO Use parametrized tests + const string KEY1_AS_STRING = "1491BB4932A389EE14BC7090AC772972"; + const string KEY2_AS_STRING = "272EE5517627CFA147A971A8E6E747E0"; + + const DataBlockFixture KEY3_AS_BINARY; + const DataBlockFixture KEY4_AS_BINARY; + + KeyTest() : KEY3_AS_BINARY(Key::KEYLENGTH_BINARY, 1), KEY4_AS_BINARY(Key::KEYLENGTH_BINARY, 2) {} }; +#define EXPECT_DATA_EQ(expected, actual) { \ + EXPECT_EQ(expected.size(), actual.size()); \ + EXPECT_EQ(0, std::memcmp(expected.data(), actual.data(), expected.size())); \ +} \ + TEST_F(KeyTest, CanGenerateRandomKeysWithoutCrashing) { Key result = Key::CreateRandomKey(); } TEST_F(KeyTest, CreatedRandomKeysHaveCorrectLength) { - auto key = Key::CreateRandomKey(); - EXPECT_EQ(Key::KEYLENGTH_STRING, key.AsString().size()); + Key key = Key::CreateRandomKey(); + EXPECT_EQ(Key::KEYLENGTH_STRING, key.ToString().size()); } TEST_F(KeyTest, EqualsTrue) { - auto key1_1 = Key::FromString(KEY1_DATA); - auto key1_2 = Key::FromString(KEY1_DATA); + Key key1_1 = Key::FromString(KEY1_AS_STRING); + Key key1_2 = Key::FromString(KEY1_AS_STRING); EXPECT_TRUE(key1_1 == key1_2); EXPECT_TRUE(key1_2 == key1_1); } TEST_F(KeyTest, EqualsFalse) { - auto key1_1 = Key::FromString(KEY1_DATA); - auto key2_1 = Key::FromString(KEY2_DATA); + Key key1_1 = Key::FromString(KEY1_AS_STRING); + Key key2_1 = Key::FromString(KEY2_AS_STRING); EXPECT_FALSE(key1_1 == key2_1); EXPECT_FALSE(key2_1 == key1_1); } TEST_F(KeyTest, NotEqualsFalse) { - auto key1_1 = Key::FromString(KEY1_DATA); - auto key1_2 = Key::FromString(KEY1_DATA); + Key key1_1 = Key::FromString(KEY1_AS_STRING); + Key key1_2 = Key::FromString(KEY1_AS_STRING); EXPECT_FALSE(key1_1 != key1_2); EXPECT_FALSE(key1_2 != key1_1); } TEST_F(KeyTest, NotEqualsTrue) { - auto key1_1 = Key::FromString(KEY1_DATA); - auto key2_1 = Key::FromString(KEY2_DATA); + Key key1_1 = Key::FromString(KEY1_AS_STRING); + Key key2_1 = Key::FromString(KEY2_AS_STRING); EXPECT_TRUE(key1_1 != key2_1); EXPECT_TRUE(key2_1 != key1_1); } TEST_F(KeyTest, FromAndToString1) { - auto key = Key::FromString(KEY1_DATA); - EXPECT_EQ(KEY1_DATA, key.AsString()); + Key key = Key::FromString(KEY1_AS_STRING); + EXPECT_EQ(KEY1_AS_STRING, key.ToString()); } TEST_F(KeyTest, FromAndToString2) { - auto key = Key::FromString(KEY2_DATA); - EXPECT_EQ(KEY2_DATA, key.AsString()); + Key key = Key::FromString(KEY2_AS_STRING); + EXPECT_EQ(KEY2_AS_STRING, key.ToString()); } TEST_F(KeyTest, ToAndFromString1) { - auto key = Key::FromString(KEY1_DATA); - auto key2 = Key::FromString(key.AsString()); + Key key = Key::FromString(KEY1_AS_STRING); + Key key2 = Key::FromString(key.ToString()); EXPECT_EQ(key, key2); } TEST_F(KeyTest, ToAndFromString2) { - auto key = Key::FromString(KEY2_DATA); - auto key2 = Key::FromString(key.AsString()); + Key key = Key::FromString(KEY2_AS_STRING); + Key key2 = Key::FromString(key.ToString()); EXPECT_EQ(key, key2); } +TEST_F(KeyTest, FromAndToBinary1) { + Key key = Key::FromBinary((uint8_t*)KEY3_AS_BINARY.data()); + Data keydata(Key::KEYLENGTH_BINARY); + key.ToBinary(keydata.data()); + EXPECT_DATA_EQ(KEY3_AS_BINARY, keydata); +} + +TEST_F(KeyTest, FromAndToBinary2) { + Key key = Key::FromBinary((uint8_t*)KEY4_AS_BINARY.data()); + Data keydata(Key::KEYLENGTH_BINARY); + key.ToBinary(keydata.data()); + EXPECT_DATA_EQ(KEY4_AS_BINARY, keydata); +} + +TEST_F(KeyTest, ToAndFromBinary1) { + Key key = Key::FromBinary((uint8_t*)KEY3_AS_BINARY.data()); + Data stored(Key::KEYLENGTH_BINARY); + key.ToBinary(stored.data()); + Key loaded = Key::FromBinary(stored.data()); + EXPECT_EQ(key, loaded); +} + +TEST_F(KeyTest, ToAndFromBinary2) { + Key key = Key::FromBinary((uint8_t*)KEY4_AS_BINARY.data()); + Data stored(Key::KEYLENGTH_BINARY); + key.ToBinary(stored.data()); + Key loaded = Key::FromBinary(stored.data()); + EXPECT_EQ(key, loaded); +} + +TEST_F(KeyTest, CopyConstructor1) { + Key key = Key::FromString(KEY1_AS_STRING); + Key copy(key); + EXPECT_EQ(key, copy); +} + +TEST_F(KeyTest, CopyConstructor2) { + Key key = Key::FromString(KEY2_AS_STRING); + Key copy(key); + EXPECT_EQ(key, copy); +} + +TEST_F(KeyTest, CopyConstructorDoesntChangeSource) { + Key key1 = Key::FromString(KEY1_AS_STRING); + Key key2(key1); + EXPECT_EQ(KEY1_AS_STRING, key1.ToString()); +} + +TEST_F(KeyTest, IsEqualAfterAssignment1) { + Key key1 = Key::FromString(KEY1_AS_STRING); + Key key2 = Key::FromString(KEY2_AS_STRING); + EXPECT_NE(key1, key2); + key2 = key1; + EXPECT_EQ(key1, key2); +} + +TEST_F(KeyTest, IsEqualAfterAssignment2) { + Key key1 = Key::FromString(KEY2_AS_STRING); + Key key2 = Key::FromString(KEY1_AS_STRING); + EXPECT_NE(key1, key2); + key2 = key1; + EXPECT_EQ(key1, key2); +} + +TEST_F(KeyTest, AssignmentDoesntChangeSource) { + Key key1 = Key::FromString(KEY1_AS_STRING); + Key key2 = Key::FromString(KEY2_AS_STRING); + key2 = key1; + EXPECT_EQ(KEY1_AS_STRING, key1.ToString()); +} + // This tests that a Key object is very lightweight // (we will often pass keys around) TEST_F(KeyTest, KeyIsLightweightObject) {