blob: 31ccdc65ecc4f6c547628a24b32f87d3dadf3840 [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 Yi68c81142018-12-18 11:17:14 -080016using ::testing::_;
Kun Yi64dc05c2018-12-19 13:19:03 -080017using ::testing::AtLeast;
18using ::testing::ElementsAreArray;
19using ::testing::IsEmpty;
Kun Yi68c81142018-12-18 11:17:14 -080020using ::testing::Return;
21using ::testing::StrEq;
22using ::testing::StrNe;
Kun Yi64dc05c2018-12-19 13:19:03 -080023using ::testing::UnorderedElementsAreArray;
24
Kun Yi68c81142018-12-18 11:17:14 -080025using namespace std::string_literals;
26using namespace binstore;
27
Kun Yi91beea62018-11-26 15:23:14 -080028namespace blobs
29{
30
Kun Yi68c81142018-12-18 11:17:14 -080031class BinaryStoreBlobHandlerBasicTest : public BinaryStoreBlobHandlerTest
32{
33 protected:
34 static inline std::string basicTestBaseId = "/test/"s;
35 static inline std::string basicTestBlobId = "/test/blob0"s;
Kun Yi64dc05c2018-12-19 13:19:03 -080036
37 static const std::vector<std::string> basicTestBaseIdList;
Kun Yi68c81142018-12-18 11:17:14 -080038 static inline std::string basicTestInvalidBlobId = "/invalid/blob0"s;
Kun Yi64dc05c2018-12-19 13:19:03 -080039
40 void addAllBaseIds()
41 {
42 for (size_t i = 0; i < basicTestBaseIdList.size(); ++i)
43 {
44 auto store = defaultMockStore(basicTestBaseIdList[i]);
45
46 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
47
48 handler.addNewBinaryStore(std::move(store));
49 }
50 }
Kun Yi68c81142018-12-18 11:17:14 -080051};
52
Kun Yi64dc05c2018-12-19 13:19:03 -080053const std::vector<std::string>
54 BinaryStoreBlobHandlerBasicTest::basicTestBaseIdList = {
55 BinaryStoreBlobHandlerBasicTest::basicTestBaseId, "/another/"s,
56 "/null\0/"s};
57
Kun Yi68c81142018-12-18 11:17:14 -080058TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobZeroStoreFail)
59{
60 // Cannot handle since there is no store. Shouldn't crash.
61 EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
62}
63
Kun Yi64dc05c2018-12-19 13:19:03 -080064TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobChecksName)
Kun Yi91beea62018-11-26 15:23:14 -080065{
Kun Yi64dc05c2018-12-19 13:19:03 -080066 auto store = defaultMockStore(basicTestBaseId);
Kun Yi68c81142018-12-18 11:17:14 -080067
Kun Yi64dc05c2018-12-19 13:19:03 -080068 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
69
70 handler.addNewBinaryStore(std::move(store));
Kun Yi68c81142018-12-18 11:17:14 -080071
Kun Yi91beea62018-11-26 15:23:14 -080072 // Verify canHandleBlob checks and returns false on an invalid name.
Kun Yi68c81142018-12-18 11:17:14 -080073 EXPECT_FALSE(handler.canHandleBlob(basicTestInvalidBlobId));
Kun Yi68c81142018-12-18 11:17:14 -080074 // Verify canHandleBlob return true for a blob id that it can handle
Kun Yi68c81142018-12-18 11:17:14 -080075 EXPECT_TRUE(handler.canHandleBlob(basicTestBlobId));
76}
77
Kun Yi64dc05c2018-12-19 13:19:03 -080078TEST_F(BinaryStoreBlobHandlerBasicTest, GetBlobIdEqualsConcatenationsOfBaseIds)
Kun Yi68c81142018-12-18 11:17:14 -080079{
Kun Yi64dc05c2018-12-19 13:19:03 -080080 addAllBaseIds();
Kun Yi68c81142018-12-18 11:17:14 -080081
Kun Yi64dc05c2018-12-19 13:19:03 -080082 // When there is no other blob id, ids are just base ids (might be
83 // re-ordered).
84 EXPECT_THAT(handler.getBlobIds(),
85 UnorderedElementsAreArray(basicTestBaseIdList));
Kun Yi68c81142018-12-18 11:17:14 -080086}
87
Kun Yi64dc05c2018-12-19 13:19:03 -080088TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobInvalidNames)
Kun Yi68c81142018-12-18 11:17:14 -080089{
Kun Yi64dc05c2018-12-19 13:19:03 -080090 addAllBaseIds();
Kun Yi68c81142018-12-18 11:17:14 -080091
Kun Yi64dc05c2018-12-19 13:19:03 -080092 const std::vector<std::string> invalidNames = {
93 basicTestInvalidBlobId,
94 "/"s,
95 "//"s,
96 "/test"s, // Cannot handle the base path
97 "/test/"s,
98 "/test/this/blob"s, // Cannot handle nested path
99 };
Kun Yi68c81142018-12-18 11:17:14 -0800100
Kun Yi64dc05c2018-12-19 13:19:03 -0800101 // Unary helper for algorithm
102 auto canHandle = [this](const std::string& blobId) {
103 return handler.canHandleBlob(blobId);
104 };
Kun Yi68c81142018-12-18 11:17:14 -0800105
Kun Yi64dc05c2018-12-19 13:19:03 -0800106 EXPECT_TRUE(
107 std::none_of(invalidNames.cbegin(), invalidNames.cend(), canHandle));
108}
109
110TEST_F(BinaryStoreBlobHandlerBasicTest, CanHandleBlobValidNames)
111{
112 addAllBaseIds();
113
114 const std::vector<std::string> validNames = {
115 basicTestBlobId, "/test/test"s, "/test/xyz.abc"s,
116 "/another/blob"s, "/null\0/\0\0zer\0\0"s,
117 };
118
119 // Unary helper for algorithm
120 auto canHandle = [this](const std::string& blobId) {
121 return handler.canHandleBlob(blobId);
122 };
123
124 // Verify canHandleBlob can handle a valid blob under the path.
125 EXPECT_TRUE(std::all_of(validNames.cbegin(), validNames.cend(), canHandle));
Kun Yi91beea62018-11-26 15:23:14 -0800126}
127
Kun Yic0adbc32018-12-18 22:35:29 -0800128TEST_F(BinaryStoreBlobHandlerBasicTest, DeleteReturnsWhatStoreReturns)
129{
Kun Yi64dc05c2018-12-19 13:19:03 -0800130 auto store = defaultMockStore(basicTestBaseId);
Kun Yic0adbc32018-12-18 22:35:29 -0800131
Kun Yi64dc05c2018-12-19 13:19:03 -0800132 EXPECT_CALL(*store, getBaseBlobId()).Times(AtLeast(1));
133 EXPECT_CALL(*store, deleteBlob(StrEq(basicTestBlobId)))
Kun Yic0adbc32018-12-18 22:35:29 -0800134 .WillOnce(Return(false))
135 .WillOnce(Return(true));
Kun Yi64dc05c2018-12-19 13:19:03 -0800136 handler.addNewBinaryStore(std::move(store));
137
138 // Unary helper for algorithm
139 auto canHandle = [this](const std::string& blobId) {
140 return handler.canHandleBlob(blobId);
141 };
Kun Yic0adbc32018-12-18 22:35:29 -0800142
143 // Verify canHandleBlob return true for a blob id that it can handle
Kun Yi64dc05c2018-12-19 13:19:03 -0800144 EXPECT_FALSE(canHandle(basicTestInvalidBlobId));
145 EXPECT_TRUE(canHandle(basicTestBlobId));
Kun Yic0adbc32018-12-18 22:35:29 -0800146 EXPECT_FALSE(handler.deleteBlob(basicTestInvalidBlobId));
147 EXPECT_FALSE(handler.deleteBlob(basicTestBlobId));
148 EXPECT_TRUE(handler.deleteBlob(basicTestBlobId));
149}
150
Kun Yi8ca234e2019-03-04 10:14:45 -0800151TEST_F(BinaryStoreBlobHandlerBasicTest, StaleDataIsClearedDuringCreation)
152{
153 using namespace google::protobuf;
154
155 auto basicTestStaleBlobStr =
156 R"(blob_base_id: "/stale/"
157 blobs {
158 blob_id: "/stale/blob"
159 })";
160
161 // Create sysfile containing a valid but stale blob
162 const std::string staleBaseId = "/stale/"s;
163 const std::string staleBlobId = "/stale/blob"s;
164 binaryblobproto::BinaryBlobBase staleBlob;
165 EXPECT_TRUE(TextFormat::ParseFromString(basicTestStaleBlobStr, &staleBlob));
166
167 // Serialize to string stored in the fakeSysFile
168 auto staleBlobData = staleBlob.SerializeAsString();
169 boost::endian::little_uint64_t sizeLE = staleBlobData.size();
170 std::string commitData(sizeLE.data(), sizeof(sizeLE));
171 commitData += staleBlobData;
172
173 std::vector<std::string> expectedIdList = {basicTestBaseId};
174
175 handler.addNewBinaryStore(BinaryStore::createFromConfig(
176 basicTestBaseId, std::make_unique<FakeSysFile>(commitData), 0));
177 EXPECT_FALSE(handler.canHandleBlob(staleBlobId));
178 EXPECT_EQ(handler.getBlobIds(), expectedIdList);
179}
180
Kun Yi91beea62018-11-26 15:23:14 -0800181} // namespace blobs