blob: 37b16b1404f5980eda8a907e8b1faf337885ba80 [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;
Kun Yi68c81142018-12-18 11:17:14 -080020using ::testing::Return;
21using ::testing::StrEq;
Kun Yi64dc05c2018-12-19 13:19:03 -080022using ::testing::UnorderedElementsAreArray;
23
Kun Yi68c81142018-12-18 11:17:14 -080024using namespace std::string_literals;
25using namespace binstore;
26
Kun Yi91beea62018-11-26 15:23:14 -080027namespace blobs
28{
29
Kun Yi68c81142018-12-18 11:17:14 -080030class BinaryStoreBlobHandlerBasicTest : public BinaryStoreBlobHandlerTest
31{
32 protected:
Patrick Venturec3abe752020-08-14 09:17:51 -070033 static inline char basicTestBaseId[] = "/test/";
34 static inline char basicTestBlobId[] = "/test/blob0";
Kun Yi64dc05c2018-12-19 13:19:03 -080035
36 static const std::vector<std::string> basicTestBaseIdList;
Patrick Venturec3abe752020-08-14 09:17:51 -070037 static inline char basicTestInvalidBlobId[] = "/invalid/blob0";
Kun Yi64dc05c2018-12-19 13:19:03 -080038
39 void addAllBaseIds()
40 {
41 for (size_t i = 0; i < basicTestBaseIdList.size(); ++i)
42 {
43 auto store = defaultMockStore(basicTestBaseIdList[i]);
44
45 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
46
47 handler.addNewBinaryStore(std::move(store));
48 }
49 }
Kun Yi68c81142018-12-18 11:17:14 -080050};
51
Kun Yi64dc05c2018-12-19 13:19:03 -080052const std::vector<std::string>
53 BinaryStoreBlobHandlerBasicTest::basicTestBaseIdList = {
54 BinaryStoreBlobHandlerBasicTest::basicTestBaseId, "/another/"s,
55 "/null\0/"s};
56
Kun Yi68c81142018-12-18 11:17:14 -080057TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobZeroStoreFail)
58{
59 // Cannot handle since there is no store. Shouldn't crash.
60 EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
61}
62
Kun Yi64dc05c2018-12-19 13:19:03 -080063TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobChecksName)
Kun Yi91beea62018-11-26 15:23:14 -080064{
Kun Yi64dc05c2018-12-19 13:19:03 -080065 auto store = defaultMockStore(basicTestBaseId);
Kun Yi68c81142018-12-18 11:17:14 -080066
Kun Yi64dc05c2018-12-19 13:19:03 -080067 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
68
69 handler.addNewBinaryStore(std::move(store));
Kun Yi68c81142018-12-18 11:17:14 -080070
Kun Yi91beea62018-11-26 15:23:14 -080071 // Verify canHandleBlob checks and returns false on an invalid name.
Kun Yi68c81142018-12-18 11:17:14 -080072 EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
Kun Yi68c81142018-12-18 11:17:14 -080073 // Verify canHandleBlob return true for a blob id that it can handle
Kun Yi68c81142018-12-18 11:17:14 -080074 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
75}
76
Kun Yi64dc05c2018-12-19 13:19:03 -080077TEST_F(BinaryStoreBlobHandlerBasicTest, GetBlobIdEqualsConcatenationsOfBaseIds)
Kun Yi68c81142018-12-18 11:17:14 -080078{
Kun Yi64dc05c2018-12-19 13:19:03 -080079 addAllBaseIds();
Kun Yi68c81142018-12-18 11:17:14 -080080
Kun Yi64dc05c2018-12-19 13:19:03 -080081 // When there is no other blob id, ids are just base ids (might be
82 // re-ordered).
83 EXPECT_THAT(handler.getBlobIds(),
84 UnorderedElementsAreArray(basicTestBaseIdList));
Kun Yi68c81142018-12-18 11:17:14 -080085}
86
Kun Yi64dc05c2018-12-19 13:19:03 -080087TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobInvalidNames)
Kun Yi68c81142018-12-18 11:17:14 -080088{
Kun Yi64dc05c2018-12-19 13:19:03 -080089 addAllBaseIds();
Kun Yi68c81142018-12-18 11:17:14 -080090
Kun Yi64dc05c2018-12-19 13:19:03 -080091 const std::vector<std::string> invalidNames = {
92 basicTestInvalidBlobId,
93 "/"s,
94 "//"s,
95 "/test"s, // Cannot handle the base path
96 "/test/"s,
97 "/test/this/blob"s, // Cannot handle nested path
98 };
Kun Yi68c81142018-12-18 11:17:14 -080099
Kun Yi64dc05c2018-12-19 13:19:03 -0800100 // Unary helper for algorithm
101 auto canHandle = [this](const std::string& blobId) {
102 return handler.canHandleBlob(blobId);
103 };
Kun Yi68c81142018-12-18 11:17:14 -0800104
Kun Yi64dc05c2018-12-19 13:19:03 -0800105 EXPECT_TRUE(
106 std::none_of(invalidNames.cbegin(), invalidNames.cend(), canHandle));
107}
108
109TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobValidNames)
110{
111 addAllBaseIds();
112
113 const std::vector<std::string> validNames = {
114 basicTestBlobId, "/test/test"s, "/test/xyz.abc"s,
115 "/another/blob"s, "/null\0/\0\0zer\0\0"s,
116 };
117
118 // Unary helper for algorithm
119 auto canHandle = [this](const std::string& blobId) {
120 return handler.canHandleBlob(blobId);
121 };
122
123 // Verify canHandleBlob can handle a valid blob under the path.
124 EXPECT_TRUE(std::all_of(validNames.cbegin(), validNames.cend(), canHandle));
Kun Yi91beea62018-11-26 15:23:14 -0800125}
126
Kun Yic0adbc32018-12-18 22:35:29 -0800127TEST_F(BinaryStoreBlobHandlerBasicTest, DeleteReturnsWhatStoreReturns)
128{
Kun Yi64dc05c2018-12-19 13:19:03 -0800129 auto store = defaultMockStore(basicTestBaseId);
Kun Yic0adbc32018-12-18 22:35:29 -0800130
Kun Yi64dc05c2018-12-19 13:19:03 -0800131 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
132 EXPECT_CALL(*store, deleteBlob(StrEq(basicTestBlobId)))
Kun Yic0adbc32018-12-18 22:35:29 -0800133 .WillOnce(Return(false))
134 .WillOnce(Return(true));
Kun Yi64dc05c2018-12-19 13:19:03 -0800135 handler.addNewBinaryStore(std::move(store));
136
137 // Unary helper for algorithm
138 auto canHandle = [this](const std::string& blobId) {
139 return handler.canHandleBlob(blobId);
140 };
Kun Yic0adbc32018-12-18 22:35:29 -0800141
142 // Verify canHandleBlob return true for a blob id that it can handle
Kun Yi64dc05c2018-12-19 13:19:03 -0800143 EXPECT_FALSE(canHandle(basicTestInvalidBlobId));
144 EXPECT_TRUE(canHandle(basicTestBlobId));
Kun Yic0adbc32018-12-18 22:35:29 -0800145 EXPECT_FALSE(handler.deleteBlob(basicTestInvalidBlobId));
146 EXPECT_FALSE(handler.deleteBlob(basicTestBlobId));
147 EXPECT_TRUE(handler.deleteBlob(basicTestBlobId));
148}
149
Kun Yi8ca234e2019-03-04 10:14:45 -0800150TEST_F(BinaryStoreBlobHandlerBasicTest, StaleDataIsClearedDuringCreation)
151{
152 using namespace google::protobuf;
153
154 auto basicTestStaleBlobStr =
155 R"(blob_base_id: "/stale/"
156 blobs {
157 blob_id: "/stale/blob"
158 })";
159
160 // Create sysfile containing a valid but stale blob
Kun Yi8ca234e2019-03-04 10:14:45 -0800161 const std::string staleBlobId = "/stale/blob"s;
162 binaryblobproto::BinaryBlobBase staleBlob;
163 EXPECT_TRUE(TextFormat::ParseFromString(basicTestStaleBlobStr, &staleBlob));
164
165 // Serialize to string stored in the fakeSysFile
166 auto staleBlobData = staleBlob.SerializeAsString();
167 boost::endian::little_uint64_t sizeLE = staleBlobData.size();
Patrick Venture3fd960d2020-07-09 08:41:33 -0700168 std::string commitData(reinterpret_cast<const char*>(sizeLE.data()),
169 sizeof(sizeLE));
Kun Yi8ca234e2019-03-04 10:14:45 -0800170 commitData += staleBlobData;
171
172 std::vector<std::string> expectedIdList = {basicTestBaseId};
173
174 handler.addNewBinaryStore(BinaryStore::createFromConfig(
Patrick Venturee496b2b2020-07-09 13:49:05 -0700175 basicTestBaseId, std::make_unique<FakeSysFile>(commitData)));
Kun Yi8ca234e2019-03-04 10:14:45 -0800176 EXPECT_FALSE(handler.canHandleBlob(staleBlobId));
177 EXPECT_EQ(handler.getBlobIds(), expectedIdList);
178}
179
Kun Yic83d2fa2019-04-03 18:40:19 -0700180TEST_F(BinaryStoreBlobHandlerBasicTest, CreatingFromEmptySysfile)
181{
182 const std::string emptyData;
183 EXPECT_NO_THROW(handler.addNewBinaryStore(BinaryStore::createFromConfig(
Patrick Venturee496b2b2020-07-09 13:49:05 -0700184 basicTestBaseId, std::make_unique<FakeSysFile>(emptyData))));
Kun Yic83d2fa2019-04-03 18:40:19 -0700185 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
186}
187
188TEST_F(BinaryStoreBlobHandlerBasicTest, CreatingFromJunkData)
189{
190 boost::endian::little_uint64_t tooLarge = 0xffffffffffffffffull;
Patrick Venture3fd960d2020-07-09 08:41:33 -0700191 const std::string junkDataWithLargeSize(
192 reinterpret_cast<const char*>(tooLarge.data()), sizeof(tooLarge));
Kun Yic83d2fa2019-04-03 18:40:19 -0700193 EXPECT_GE(tooLarge, junkDataWithLargeSize.max_size());
194
195 EXPECT_NO_THROW(handler.addNewBinaryStore(BinaryStore::createFromConfig(
Patrick Venturee496b2b2020-07-09 13:49:05 -0700196 basicTestBaseId,
197 std::make_unique<FakeSysFile>(junkDataWithLargeSize))));
Kun Yic83d2fa2019-04-03 18:40:19 -0700198
199 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
200}
201
Kun Yi91beea62018-11-26 15:23:14 -0800202} // namespace blobs