1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "distributed_kv_data_manager.h"
17 #include "gtest/gtest.h"
18 #include "kv_utils.h"
19 #include "kvstore_datashare_bridge.h"
20 #include "store_errno.h"
21 #include "result_set_bridge.h"
22 #include "kvstore_result_set.h"
23 #include "types.h"
24
25 namespace {
26 using namespace testing::ext;
27 using namespace OHOS::DistributedKv;
28 using namespace OHOS::DataShare;
29 class BridgeWriter final : public ResultSetBridge::Writer {
30 public:
31 int AllocRow() override;
32 int Write(uint32_t column) override;
33 int Write(uint32_t column, int64_t value) override;
34 int Write(uint32_t column, double value) override;
35 int Write(uint32_t column, const uint8_t *value, size_t size) override;
36 int Write(uint32_t column, const char *value, size_t size) override;
37 void SetAllocRowStatue(int status);
38 Key GetKey() const;
39 Key GetValue() const;
40
41 private:
42 int allocStatus_ = E_OK;
43 std::vector<uint8_t> key_;
44 std::vector<uint8_t> value_;
45 };
46
SetAllocRowStatue(int status)47 void BridgeWriter::SetAllocRowStatue(int status)
48 {
49 allocStatus_ = status;
50 }
51
GetKey() const52 Key BridgeWriter::GetKey() const
53 {
54 return key_;
55 }
56
GetValue() const57 Value BridgeWriter::GetValue() const
58 {
59 return value_;
60 }
61
AllocRow()62 int BridgeWriter::AllocRow()
63 {
64 return allocStatus_;
65 }
66
Write(uint32_t column)67 int BridgeWriter::Write(uint32_t column)
68 {
69 return E_OK;
70 }
71
Write(uint32_t column,int64_t value)72 int BridgeWriter::Write(uint32_t column, int64_t value)
73 {
74 return E_OK;
75 }
76
Write(uint32_t column,double value)77 int BridgeWriter::Write(uint32_t column, double value)
78 {
79 return E_OK;
80 }
81
Write(uint32_t column,const uint8_t * value,size_t size)82 int BridgeWriter::Write(uint32_t column, const uint8_t *value, size_t size)
83 {
84 return E_OK;
85 }
86
Write(uint32_t column,const char * value,size_t size)87 int BridgeWriter::Write(uint32_t column, const char *value, size_t size)
88 {
89 if (column < 0 || column > 1 || value == nullptr) {
90 return E_ERROR;
91 }
92 auto vec = std::vector<uint8_t>(value, value + size - 1);
93 if (column == 0) {
94 key_.insert(key_.end(), vec.begin(), vec.end());
95 } else {
96 value_.insert(value_.end(), vec.begin(), vec.end());
97 }
98 return E_OK;
99 }
100
101 class KvstoreDatashareBridgeTest : public testing::Test {
102 public:
103 static void SetUpTestCase(void);
104 static void TearDownTestCase(void);
SetUp()105 void SetUp() {}
TearDown()106 void TearDown() {}
107
108 protected:
109 static DistributedKvDataManager manager;
110 static std::shared_ptr<SingleKvStore> singleKvStore;
111 };
112 std::shared_ptr<SingleKvStore> KvstoreDatashareBridgeTest::singleKvStore = nullptr;
113 DistributedKvDataManager KvstoreDatashareBridgeTest::manager;
114 static constexpr int32_t INVALID_COUNT = -1;
115 static constexpr const char *VALID_SCHEMA_STRICT_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\","
116 "\"SCHEMA_MODE\":\"STRICT\","
117 "\"SCHEMA_SKIPSIZE\":0,"
118 "\"SCHEMA_DEFINE\":{"
119 "\"age\":\"INTEGER, NOT NULL\""
120 "},"
121 "\"SCHEMA_INDEXES\":[\"$.age\"]}";
122
SetUpTestCase(void)123 void KvstoreDatashareBridgeTest::SetUpTestCase(void)
124 {
125 Options options = { .createIfMissing = true, .encrypt = false, .autoSync = false,
126 .kvStoreType = KvStoreType::SINGLE_VERSION, .schema = VALID_SCHEMA_STRICT_DEFINE };
127 options.area = EL1;
128 options.securityLevel = S1;
129 options.baseDir = std::string("/data/service/el1/public/database/KvstoreDatashareBridgeTest");
130 AppId appId = { "KvstoreDatashareBridgeTest" };
131 StoreId storeId = { "test_single" };
132 mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
133 manager.DeleteKvStore(appId, storeId, options.baseDir);
134 manager.GetSingleKvStore(options, appId, storeId, singleKvStore);
135 EXPECT_NE(singleKvStore, nullptr);
136 singleKvStore->Put("test_key_1", "{\"age\":1}");
137 singleKvStore->Put("test_key_2", "{\"age\":2}");
138 singleKvStore->Put("test_key_3", "{\"age\":3}");
139 singleKvStore->Put("data_share", "{\"age\":4}");
140 }
141
TearDownTestCase(void)142 void KvstoreDatashareBridgeTest::TearDownTestCase(void)
143 {
144 manager.DeleteKvStore({"KvstoreDatashareBridgeTest"}, {"test_single"},
145 "/data/service/el1/public/database/KvstoreDatashareBridgeTest");
146 (void) remove("/data/service/el1/public/database/KvstoreDatashareBridgeTest/key");
147 (void) remove("/data/service/el1/public/database/KvstoreDatashareBridgeTest/kvdb");
148 (void) remove("/data/service/el1/public/database/KvstoreDatashareBridgeTest");
149 }
150
151 /**
152 * @tc.name:ToDataShareResult
153 * @tc.desc: get row count, the kvStore resultSet is nullptr
154 * @tc.type: FUNC
155 * @tc.require:
156 * @tc.author: zuojiangjiang
157 */
158 HWTEST_F(KvstoreDatashareBridgeTest, GetRowCountByInvalidBridge, TestSize.Level0)
159 {
160 auto bridge = std::make_shared<KvStoreDataShareBridge>(nullptr);
161 int32_t count;
162 auto result = bridge->GetRowCount(count);
163 EXPECT_EQ(result, E_ERROR);
164 EXPECT_EQ(count, INVALID_COUNT);
165 std::vector<std::string> columnNames;
166 result = bridge->GetAllColumnNames(columnNames);
167 EXPECT_FALSE(columnNames.empty());
168 EXPECT_EQ(result, E_OK);
169 }
170
171 /**
172 * @tc.name:ToDataShareResultSet
173 * @tc.desc: kvStore resultSet to dataShare resultSet, the former has invalid predicate
174 * @tc.type: FUNC
175 * @tc.require:
176 * @tc.author: zuojiangjiang
177 */
178 HWTEST_F(KvstoreDatashareBridgeTest, KvStoreResultSetToDataShareResultSetAbnormal, TestSize.Level0)
179 {
180 std::shared_ptr<KvStoreResultSet> resultSet = nullptr;
181 DataQuery query;
182 query.KeyPrefix("key");
183 singleKvStore->GetResultSet(query, resultSet);
184 EXPECT_NE(resultSet, nullptr);
185 auto bridge = KvUtils::ToResultSetBridge(resultSet);
186 int32_t count;
187 auto result = bridge->GetRowCount(count);
188 EXPECT_EQ(result, E_OK);
189 EXPECT_EQ(count, 0);
190 }
191
192 /**
193 * @tc.name:ToDataShareResultSet
194 * @tc.desc: kvStore resultSet to dataShare resultSet, the former has valid predicate
195 * @tc.type: FUNC
196 * @tc.require:
197 * @tc.author: zuojiangjiang
198 */
199 HWTEST_F(KvstoreDatashareBridgeTest, KvStoreResultSetToDataShareResultSetNormal, TestSize.Level0)
200 {
201 DataQuery query;
202 query.KeyPrefix("test");
203 std::shared_ptr<KvStoreResultSet> resultSet = nullptr;
204 singleKvStore->GetResultSet(query, resultSet);
205 EXPECT_NE(resultSet, nullptr);
206 auto bridge = KvUtils::ToResultSetBridge(resultSet);
207 int32_t count;
208 auto result = bridge->GetRowCount(count);
209 EXPECT_EQ(result, E_OK);
210 EXPECT_EQ(count, 3);
211 count = -1;
212 bridge->GetRowCount(count);
213 EXPECT_EQ(count, 3);
214 }
215
216 /**
217 * @tc.name:BridgeOnGo
218 * @tc.desc: bridge on go, the input parameter is invalid
219 * @tc.type: FUNC
220 * @tc.require:
221 * @tc.author: zuojiangjiang
222 */
223 HWTEST_F(KvstoreDatashareBridgeTest, BridgeOnGoAbnormal, TestSize.Level0)
224 {
225 DataQuery query;
226 query.KeyPrefix("test");
227 std::shared_ptr<KvStoreResultSet> resultSet = nullptr;
228 singleKvStore->GetResultSet(query, resultSet);
229 EXPECT_NE(resultSet, nullptr);
230 auto bridge = KvUtils::ToResultSetBridge(resultSet);
231 int32_t start = -1;
232 int32_t target = 0;
233 BridgeWriter writer;
234 EXPECT_EQ(bridge->OnGo(start, target, writer), -1);
235 EXPECT_TRUE(writer.GetKey().Empty());
236 EXPECT_TRUE(writer.GetValue().Empty());
237 start = 0;
238 target = -1;
239 EXPECT_EQ(bridge->OnGo(start, target, writer), -1);
240 EXPECT_TRUE(writer.GetKey().Empty());
241 EXPECT_TRUE(writer.GetValue().Empty());
242 start = 1;
243 target = 0;
244 EXPECT_EQ(bridge->OnGo(start, target, writer), -1);
245 EXPECT_TRUE(writer.GetKey().Empty());
246 EXPECT_TRUE(writer.GetValue().Empty());
247 start = 1;
248 target = 3;
249 EXPECT_EQ(bridge->OnGo(start, target, writer), -1);
250 EXPECT_TRUE(writer.GetKey().Empty());
251 EXPECT_TRUE(writer.GetValue().Empty());
252 }
253
254 /**
255 * @tc.name:BridgeOnGo
256 * @tc.desc: bridge on go, the input parameter is valid
257 * @tc.type: FUNC
258 * @tc.require:
259 * @tc.author: zuojiangjiang
260 */
261 HWTEST_F(KvstoreDatashareBridgeTest, BridgeOnGoNormal, TestSize.Level0)
262 {
263 DataQuery query;
264 query.KeyPrefix("test");
265 std::shared_ptr<KvStoreResultSet> resultSet = nullptr;
266 singleKvStore->GetResultSet(query, resultSet);
267 EXPECT_NE(resultSet, nullptr);
268 auto bridge = KvUtils::ToResultSetBridge(resultSet);
269 int start = 0;
270 int target = 2;
271 BridgeWriter writer;
272 writer.SetAllocRowStatue(E_ERROR);
273 EXPECT_EQ(bridge->OnGo(start, target, writer), -1);
274 EXPECT_TRUE(writer.GetKey().Empty());
275 EXPECT_TRUE(writer.GetValue().Empty());
276 writer.SetAllocRowStatue(E_OK);
277 EXPECT_EQ(bridge->OnGo(start, target, writer), target);
278 size_t keySize = 0;
279 size_t valueSize = 0;
280 for (auto i = start; i <= target; i++) {
281 resultSet->MoveToPosition(i);
282 Entry entry;
283 resultSet->GetEntry(entry);
284 keySize += entry.key.Size();
285 valueSize += entry.value.Size();
286 }
287 EXPECT_EQ(writer.GetKey().Size(), keySize);
288 EXPECT_EQ(writer.GetValue().Size(), valueSize);
289 }
290 } // namespace
291