blob: 789eefbe33849890ec64889dbb7b5ee982a076dd [file] [log] [blame]
Kun Yi91beea62018-11-26 15:23:14 -08001#include "handler_unittest.hpp"
2
Kun Yi8ca234e2019-03-04 10:14:45 -08003#include "fake_sys_file.hpp"
4
5#include <google/protobuf/message_lite.h>
6#include <google/protobuf/text_format.h>
7
Kun Yi64dc05c2018-12-19 13:19:03 -08008#include <algorithm>
Kun Yi8ca234e2019-03-04 10:14:45 -08009#include <boost/endian/arithmetic.hpp>
Kun Yi64dc05c2018-12-19 13:19:03 -080010#include <memory>
11#include <string>
12#include <vector>
13
Kun Yi8ca234e2019-03-04 10:14:45 -080014#include "binaryblob.pb.h"
15
Kun Yic83d2fa2019-04-03 18:40:19 -070016#include <gtest/gtest.h>
17
Kun Yi68c81142018-12-18 11:17:14 -080018using ::testing::_;
Kun Yi64dc05c2018-12-19 13:19:03 -080019using ::testing::AtLeast;
20using ::testing::ElementsAreArray;
21using ::testing::IsEmpty;
Kun Yi68c81142018-12-18 11:17:14 -080022using ::testing::Return;
23using ::testing::StrEq;
24using ::testing::StrNe;
Kun Yi64dc05c2018-12-19 13:19:03 -080025using ::testing::UnorderedElementsAreArray;
26
Kun Yi68c81142018-12-18 11:17:14 -080027using namespace std::string_literals;
28using namespace binstore;
29
Kun Yi91beea62018-11-26 15:23:14 -080030namespace blobs
31{
32
Kun Yi68c81142018-12-18 11:17:14 -080033class BinaryStoreBlobHandlerBasicTest : public BinaryStoreBlobHandlerTest
34{
35 protected:
36 static inline std::string basicTestBaseId = "/test/"s;
37 static inline std::string basicTestBlobId = "/test/blob0"s;
Kun Yi64dc05c2018-12-19 13:19:03 -080038
39 static const std::vector<std::string> basicTestBaseIdList;
Kun Yi68c81142018-12-18 11:17:14 -080040 static inline std::string basicTestInvalidBlobId = "/invalid/blob0"s;
Kun Yi64dc05c2018-12-19 13:19:03 -080041
42 void addAllBaseIds()
43 {
44 for (size_t i = 0; i < basicTestBaseIdList.size(); ++i)
45 {
46 auto store = defaultMockStore(basicTestBaseIdList[i]);
47
48 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
49
50 handler.addNewBinaryStore(std::move(store));
51 }
52 }
Kun Yi68c81142018-12-18 11:17:14 -080053};
54
Kun Yi64dc05c2018-12-19 13:19:03 -080055const std::vector<std::string>
56 BinaryStoreBlobHandlerBasicTest::basicTestBaseIdList = {
57 BinaryStoreBlobHandlerBasicTest::basicTestBaseId, "/another/"s,
58 "/null\0/"s};
59
Kun Yi68c81142018-12-18 11:17:14 -080060TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobZeroStoreFail)
61{
62 // Cannot handle since there is no store. Shouldn't crash.
63 EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
64}
65
Kun Yi64dc05c2018-12-19 13:19:03 -080066TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobChecksName)
Kun Yi91beea62018-11-26 15:23:14 -080067{
Kun Yi64dc05c2018-12-19 13:19:03 -080068 auto store = defaultMockStore(basicTestBaseId);
Kun Yi68c81142018-12-18 11:17:14 -080069
Kun Yi64dc05c2018-12-19 13:19:03 -080070 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
71
72 handler.addNewBinaryStore(std::move(store));
Kun Yi68c81142018-12-18 11:17:14 -080073
Kun Yi91beea62018-11-26 15:23:14 -080074 // Verify canHandleBlob checks and returns false on an invalid name.
Kun Yi68c81142018-12-18 11:17:14 -080075 EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
Kun Yi68c81142018-12-18 11:17:14 -080076 // Verify canHandleBlob return true for a blob id that it can handle
Kun Yi68c81142018-12-18 11:17:14 -080077 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
78}
79
Kun Yi64dc05c2018-12-19 13:19:03 -080080TEST_F(BinaryStoreBlobHandlerBasicTest, GetBlobIdEqualsConcatenationsOfBaseIds)
Kun Yi68c81142018-12-18 11:17:14 -080081{
Kun Yi64dc05c2018-12-19 13:19:03 -080082 addAllBaseIds();
Kun Yi68c81142018-12-18 11:17:14 -080083
Kun Yi64dc05c2018-12-19 13:19:03 -080084 // When there is no other blob id, ids are just base ids (might be
85 // re-ordered).
86 EXPECT_THAT(handler.getBlobIds(),
87 UnorderedElementsAreArray(basicTestBaseIdList));
Kun Yi68c81142018-12-18 11:17:14 -080088}
89
Kun Yi64dc05c2018-12-19 13:19:03 -080090TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobInvalidNames)
Kun Yi68c81142018-12-18 11:17:14 -080091{
Kun Yi64dc05c2018-12-19 13:19:03 -080092 addAllBaseIds();
Kun Yi68c81142018-12-18 11:17:14 -080093
Kun Yi64dc05c2018-12-19 13:19:03 -080094 const std::vector<std::string> invalidNames = {
95 basicTestInvalidBlobId,
96 "/"s,
97 "//"s,
98 "/test"s, // Cannot handle the base path
99 "/test/"s,
100 "/test/this/blob"s, // Cannot handle nested path
101 };
Kun Yi68c81142018-12-18 11:17:14 -0800102
Kun Yi64dc05c2018-12-19 13:19:03 -0800103 // Unary helper for algorithm
104 auto canHandle = [this](const std::string& blobId) {
105 return handler.canHandleBlob(blobId);
106 };
Kun Yi68c81142018-12-18 11:17:14 -0800107
Kun Yi64dc05c2018-12-19 13:19:03 -0800108 EXPECT_TRUE(
109 std::none_of(invalidNames.cbegin(), invalidNames.cend(), canHandle));
110}
111
112TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobValidNames)
113{
114 addAllBaseIds();
115
116 const std::vector<std::string> validNames = {
117 basicTestBlobId, "/test/test"s, "/test/xyz.abc"s,
118 "/another/blob"s, "/null\0/\0\0zer\0\0"s,
119 };
120
121 // Unary helper for algorithm
122 auto canHandle = [this](const std::string& blobId) {
123 return handler.canHandleBlob(blobId);
124 };
125
126 // Verify canHandleBlob can handle a valid blob under the path.
127 EXPECT_TRUE(std::all_of(validNames.cbegin(), validNames.cend(), canHandle));
Kun Yi91beea62018-11-26 15:23:14 -0800128}
129
Kun Yic0adbc32018-12-18 22:35:29 -0800130TEST_F(BinaryStoreBlobHandlerBasicTest, DeleteReturnsWhatStoreReturns)
131{
Kun Yi64dc05c2018-12-19 13:19:03 -0800132 auto store = defaultMockStore(basicTestBaseId);
Kun Yic0adbc32018-12-18 22:35:29 -0800133
Kun Yi64dc05c2018-12-19 13:19:03 -0800134 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
135 EXPECT_CALL(*store, deleteBlob(StrEq(basicTestBlobId)))
Kun Yic0adbc32018-12-18 22:35:29 -0800136 .WillOnce(Return(false))
137 .WillOnce(Return(true));
Kun Yi64dc05c2018-12-19 13:19:03 -0800138 handler.addNewBinaryStore(std::move(store));
139
140 // Unary helper for algorithm
141 auto canHandle = [this](const std::string& blobId) {
142 return handler.canHandleBlob(blobId);
143 };
Kun Yic0adbc32018-12-18 22:35:29 -0800144
145 // Verify canHandleBlob return true for a blob id that it can handle
Kun Yi64dc05c2018-12-19 13:19:03 -0800146 EXPECT_FALSE(canHandle(basicTestInvalidBlobId));
147 EXPECT_TRUE(canHandle(basicTestBlobId));
Kun Yic0adbc32018-12-18 22:35:29 -0800148 EXPECT_FALSE(handler.deleteBlob(basicTestInvalidBlobId));
149 EXPECT_FALSE(handler.deleteBlob(basicTestBlobId));
150 EXPECT_TRUE(handler.deleteBlob(basicTestBlobId));
151}
152
Kun Yi8ca234e2019-03-04 10:14:45 -0800153TEST_F(BinaryStoreBlobHandlerBasicTest, StaleDataIsClearedDuringCreation)
154{
155 using namespace google::protobuf;
156
157 auto basicTestStaleBlobStr =
158 R"(blob_base_id: "/stale/"
159 blobs {
160 blob_id: "/stale/blob"
161 })";
162
163 // Create sysfile containing a valid but stale blob
164 const std::string staleBaseId = "/stale/"s;
165 const std::string staleBlobId = "/stale/blob"s;
166 binaryblobproto::BinaryBlobBase staleBlob;
167 EXPECT_TRUE(TextFormat::ParseFromString(basicTestStaleBlobStr, &staleBlob));
168
169 // Serialize to string stored in the fakeSysFile
170 auto staleBlobData = staleBlob.SerializeAsString();
171 boost::endian::little_uint64_t sizeLE = staleBlobData.size();
Patrick Venture3fd960d2020-07-09 08:41:33 -0700172 std::string commitData(reinterpret_cast<const char*>(sizeLE.data()),
173 sizeof(sizeLE));
Kun Yi8ca234e2019-03-04 10:14:45 -0800174 commitData += staleBlobData;
175
176 std::vector<std::string> expectedIdList = {basicTestBaseId};
177
178 handler.addNewBinaryStore(BinaryStore::createFromConfig(
Patrick Venturee496b2b2020-07-09 13:49:05 -0700179 basicTestBaseId, std::make_unique<FakeSysFile>(commitData)));
Kun Yi8ca234e2019-03-04 10:14:45 -0800180 EXPECT_FALSE(handler.canHandleBlob(staleBlobId));
181 EXPECT_EQ(handler.getBlobIds(), expectedIdList);
182}
183
Kun Yic83d2fa2019-04-03 18:40:19 -0700184TEST_F(BinaryStoreBlobHandlerBasicTest, CreatingFromEmptySysfile)
185{
186 const std::string emptyData;
187 EXPECT_NO_THROW(handler.addNewBinaryStore(BinaryStore::createFromConfig(
Patrick Venturee496b2b2020-07-09 13:49:05 -0700188 basicTestBaseId, std::make_unique<FakeSysFile>(emptyData))));
Kun Yic83d2fa2019-04-03 18:40:19 -0700189 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
190}
191
192TEST_F(BinaryStoreBlobHandlerBasicTest, CreatingFromJunkData)
193{
194 boost::endian::little_uint64_t tooLarge = 0xffffffffffffffffull;
Patrick Venture3fd960d2020-07-09 08:41:33 -0700195 const std::string junkDataWithLargeSize(
196 reinterpret_cast<const char*>(tooLarge.data()), sizeof(tooLarge));
Kun Yic83d2fa2019-04-03 18:40:19 -0700197 EXPECT_GE(tooLarge, junkDataWithLargeSize.max_size());
198
199 EXPECT_NO_THROW(handler.addNewBinaryStore(BinaryStore::createFromConfig(
Patrick Venturee496b2b2020-07-09 13:49:05 -0700200 basicTestBaseId,
201 std::make_unique<FakeSysFile>(junkDataWithLargeSize))));
Kun Yic83d2fa2019-04-03 18:40:19 -0700202
203 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
204}
205
Kun Yi91beea62018-11-26 15:23:14 -0800206} // namespace blobs