1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright 2017 Couchbase, Inc
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 * Unit tests for the StoredValue class.
24 #include "hash_table.h"
26 #include "stored_value_factories.h"
27 #include "tests/module_tests/test_helpers.h"
29 #include <gtest/gtest.h>
32 * Test fixture for StoredValue tests. Type-parameterized to test both
33 * StoredValue and OrderedStoredValue.
35 template <typename Factory>
36 class ValueTest : public ::testing::Test {
41 ht(stats, std::make_unique<Factory>(stats), /*size*/ 47, /*locks*/ 1),
42 item(make_item(0, makeStoredDocKey("key"), "value")) {
45 void SetUp() override {
46 // Create an initial stored value for testing - key length (3) and
48 sv = factory(item, {});
51 /// Returns the number of bytes in the Fixed part of StoredValue
52 static size_t getFixedSize() {
53 return sizeof(typename Factory::value_type);
56 /// Allow testing access to StoredValue::getRequiredStorage
57 static size_t public_getRequiredStorage(const Item& item) {
58 return Factory::value_type::getRequiredStorage(item);
66 StoredValue::UniquePtr sv;
69 using ValueFactories =
70 ::testing::Types<StoredValueFactory, OrderedStoredValueFactory>;
71 TYPED_TEST_CASE(ValueTest, ValueFactories);
73 // Check that the size calculation methods return the expected sizes.
75 TYPED_TEST(ValueTest, getObjectSize) {
76 // Check the size are as expected: Fixed size of (Ordered)StoredValue, plus
78 // for 'key', 1 byte for length of key and 1 byte for StoredDocKey
80 EXPECT_EQ(this->getFixedSize() + /*key*/ 3 + /*len*/ 1 +
82 this->sv->getObjectSize());
85 TYPED_TEST(ValueTest, metaDataSize) {
86 // Check metadata size reports correctly.
87 EXPECT_EQ(this->getFixedSize() + /*key*/ 3 + /*len*/ 1 +
89 this->sv->metaDataSize());
92 TYPED_TEST(ValueTest, valuelen) {
93 // Check valuelen reports correctly.
94 EXPECT_EQ(/*value length*/ 5 + /*extmeta*/ 2, this->sv->valuelen())
95 << "valuelen() expected to be sum of raw value length + extended "
99 TYPED_TEST(ValueTest, valuelenDeletedWithValue) {
100 // Check valuelen reports correctly for a StoredValue just marked delete
101 // (with xattrs deleted items can have value)
102 this->sv->markDeleted();
103 EXPECT_EQ(/*value length*/ 5 + /*extmeta*/ 2, this->sv->valuelen())
104 << "valuelen() expected to be sum of raw value length + extended "
105 "meta as we want to keep deleted body";
108 TYPED_TEST(ValueTest, valuelenDeletedWithoutValue) {
109 // Check valuelen reports correctly for a StoredValue logically delete
111 EXPECT_EQ(0, this->sv->valuelen())
112 << "valuelen() expected to be 0 as we do not want to keep deleted "
116 TYPED_TEST(ValueTest, size) {
117 // Check size reports correctly.
118 EXPECT_EQ(this->getFixedSize() + /*key*/ 3 + /*len*/ 1 +
119 /*namespace*/ 1 + /*valuelen*/ 5 + /*extmeta*/ 2,
123 TYPED_TEST(ValueTest, getRequiredStorage) {
124 EXPECT_EQ(this->sv->getObjectSize(),
125 this->public_getRequiredStorage(this->item))
126 << "Actual object size doesn't match what getRequiredStorage "
130 /// Check that StoredValue / OrderedStoredValue don't unexpectedly change in
131 /// size (we've carefully crafted them to be as efficient as possible).
132 TEST(StoredValueTest, expectedSize) {
133 EXPECT_EQ(56, sizeof(StoredValue))
134 << "Unexpected change in StoredValue fixed size";
135 auto item = make_item(0, makeStoredDocKey("k"), "v");
136 EXPECT_EQ(59, StoredValue::getRequiredStorage(item))
137 << "Unexpected change in StoredValue storage size for item: "
141 TEST(OrderedStoredValueTest, expectedSize) {
142 EXPECT_EQ(72, sizeof(OrderedStoredValue))
143 << "Unexpected change in OrderedStoredValue fixed size";
144 auto item = make_item(0, makeStoredDocKey("k"), "v");
145 EXPECT_EQ(75, OrderedStoredValue::getRequiredStorage(item))
146 << "Unexpected change in OrderedStoredValue storage size for item: "