| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- // Copyright (c) Meta Platforms, Inc. and affiliates.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #include "db/wide/wide_column_serialization.h"
- #include "db/wide/wide_columns_helper.h"
- #include "test_util/testharness.h"
- #include "util/coding.h"
- namespace ROCKSDB_NAMESPACE {
- TEST(WideColumnSerializationTest, Construct) {
- constexpr char foo[] = "foo";
- constexpr char bar[] = "bar";
- const std::string foo_str(foo);
- const std::string bar_str(bar);
- const Slice foo_slice(foo_str);
- const Slice bar_slice(bar_str);
- {
- WideColumn column(foo, bar);
- ASSERT_EQ(column.name(), foo);
- ASSERT_EQ(column.value(), bar);
- }
- {
- WideColumn column(foo_str, bar);
- ASSERT_EQ(column.name(), foo_str);
- ASSERT_EQ(column.value(), bar);
- }
- {
- WideColumn column(foo_slice, bar);
- ASSERT_EQ(column.name(), foo_slice);
- ASSERT_EQ(column.value(), bar);
- }
- {
- WideColumn column(foo, bar_str);
- ASSERT_EQ(column.name(), foo);
- ASSERT_EQ(column.value(), bar_str);
- }
- {
- WideColumn column(foo_str, bar_str);
- ASSERT_EQ(column.name(), foo_str);
- ASSERT_EQ(column.value(), bar_str);
- }
- {
- WideColumn column(foo_slice, bar_str);
- ASSERT_EQ(column.name(), foo_slice);
- ASSERT_EQ(column.value(), bar_str);
- }
- {
- WideColumn column(foo, bar_slice);
- ASSERT_EQ(column.name(), foo);
- ASSERT_EQ(column.value(), bar_slice);
- }
- {
- WideColumn column(foo_str, bar_slice);
- ASSERT_EQ(column.name(), foo_str);
- ASSERT_EQ(column.value(), bar_slice);
- }
- {
- WideColumn column(foo_slice, bar_slice);
- ASSERT_EQ(column.name(), foo_slice);
- ASSERT_EQ(column.value(), bar_slice);
- }
- {
- constexpr char foo_name[] = "foo_name";
- constexpr char bar_value[] = "bar_value";
- WideColumn column(std::piecewise_construct,
- std::forward_as_tuple(foo_name, sizeof(foo) - 1),
- std::forward_as_tuple(bar_value, sizeof(bar) - 1));
- ASSERT_EQ(column.name(), foo);
- ASSERT_EQ(column.value(), bar);
- }
- }
- TEST(WideColumnSerializationTest, SerializeDeserialize) {
- WideColumns columns{{"foo", "bar"}, {"hello", "world"}};
- std::string output;
- ASSERT_OK(WideColumnSerialization::Serialize(columns, output));
- Slice input(output);
- WideColumns deserialized_columns;
- ASSERT_OK(WideColumnSerialization::Deserialize(input, deserialized_columns));
- ASSERT_EQ(columns, deserialized_columns);
- {
- const auto it = WideColumnsHelper::Find(deserialized_columns.cbegin(),
- deserialized_columns.cend(), "foo");
- ASSERT_NE(it, deserialized_columns.cend());
- ASSERT_EQ(*it, deserialized_columns.front());
- }
- {
- const auto it = WideColumnsHelper::Find(
- deserialized_columns.cbegin(), deserialized_columns.cend(), "hello");
- ASSERT_NE(it, deserialized_columns.cend());
- ASSERT_EQ(*it, deserialized_columns.back());
- }
- {
- const auto it = WideColumnsHelper::Find(
- deserialized_columns.cbegin(), deserialized_columns.cend(), "fubar");
- ASSERT_EQ(it, deserialized_columns.cend());
- }
- {
- const auto it = WideColumnsHelper::Find(
- deserialized_columns.cbegin(), deserialized_columns.cend(), "snafu");
- ASSERT_EQ(it, deserialized_columns.cend());
- }
- }
- TEST(WideColumnSerializationTest, SerializeDuplicateError) {
- WideColumns columns{{"foo", "bar"}, {"foo", "baz"}};
- std::string output;
- ASSERT_TRUE(
- WideColumnSerialization::Serialize(columns, output).IsCorruption());
- }
- TEST(WideColumnSerializationTest, SerializeOutOfOrderError) {
- WideColumns columns{{"hello", "world"}, {"foo", "bar"}};
- std::string output;
- ASSERT_TRUE(
- WideColumnSerialization::Serialize(columns, output).IsCorruption());
- }
- TEST(WideColumnSerializationTest, DeserializeVersionError) {
- // Can't decode version
- std::string buf;
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "version"));
- }
- TEST(WideColumnSerializationTest, DeserializeUnsupportedVersion) {
- // Unsupported version
- constexpr uint32_t future_version = 1000;
- std::string buf;
- PutVarint32(&buf, future_version);
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsNotSupported());
- ASSERT_TRUE(std::strstr(s.getState(), "version"));
- }
- TEST(WideColumnSerializationTest, DeserializeNumberOfColumnsError) {
- // Can't decode number of columns
- std::string buf;
- PutVarint32(&buf, WideColumnSerialization::kCurrentVersion);
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "number"));
- }
- TEST(WideColumnSerializationTest, DeserializeColumnsError) {
- std::string buf;
- PutVarint32(&buf, WideColumnSerialization::kCurrentVersion);
- constexpr uint32_t num_columns = 2;
- PutVarint32(&buf, num_columns);
- // Can't decode the first column name
- {
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "name"));
- }
- constexpr char first_column_name[] = "foo";
- PutLengthPrefixedSlice(&buf, first_column_name);
- // Can't decode the size of the first column value
- {
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "value size"));
- }
- constexpr uint32_t first_value_size = 16;
- PutVarint32(&buf, first_value_size);
- // Can't decode the second column name
- {
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "name"));
- }
- constexpr char second_column_name[] = "hello";
- PutLengthPrefixedSlice(&buf, second_column_name);
- // Can't decode the size of the second column value
- {
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "value size"));
- }
- constexpr uint32_t second_value_size = 64;
- PutVarint32(&buf, second_value_size);
- // Can't decode the payload of the first column
- {
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "payload"));
- }
- buf.append(first_value_size, '0');
- // Can't decode the payload of the second column
- {
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "payload"));
- }
- buf.append(second_value_size, 'x');
- // Success
- {
- Slice input(buf);
- WideColumns columns;
- ASSERT_OK(WideColumnSerialization::Deserialize(input, columns));
- }
- }
- TEST(WideColumnSerializationTest, DeserializeColumnsOutOfOrder) {
- std::string buf;
- PutVarint32(&buf, WideColumnSerialization::kCurrentVersion);
- constexpr uint32_t num_columns = 2;
- PutVarint32(&buf, num_columns);
- constexpr char first_column_name[] = "b";
- PutLengthPrefixedSlice(&buf, first_column_name);
- constexpr uint32_t first_value_size = 16;
- PutVarint32(&buf, first_value_size);
- constexpr char second_column_name[] = "a";
- PutLengthPrefixedSlice(&buf, second_column_name);
- Slice input(buf);
- WideColumns columns;
- const Status s = WideColumnSerialization::Deserialize(input, columns);
- ASSERT_TRUE(s.IsCorruption());
- ASSERT_TRUE(std::strstr(s.getState(), "order"));
- }
- } // namespace ROCKSDB_NAMESPACE
- int main(int argc, char** argv) {
- ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
- }
|