• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef OMIT_JSON
17 #include <functional>
18 #include <gtest/gtest.h>
19 #include <string>
20 
21 #include "distributeddb_tools_unit_test.h"
22 #include "kv_store_delegate_manager.h"
23 #include "kv_store_nb_delegate.h"
24 #include "query.h"
25 
26 using namespace testing::ext;
27 using namespace DistributedDB;
28 using namespace DistributedDBUnitTest;
29 
30 namespace {
31     const std::string VALID_SCHEMA_STRICT_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\","
32         "\"SCHEMA_MODE\":\"STRICT\","
33         "\"SCHEMA_DEFINE\":{"
34             "\"field_name1\":\"BOOL\","
35             "\"field_name2\":\"INTEGER, NOT NULL\""
36         "},"
37         "\"SCHEMA_INDEXES\":[\"$.field_name1\"]}";
38     const std::string VALID_SCHEMA_COMPA_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\","
39         "\"SCHEMA_MODE\":\"COMPATIBLE\","
40         "\"SCHEMA_DEFINE\":{"
41             "\"field_name1\":\"BOOL\","
42             "\"field_name2\":\"INTEGER, NOT NULL\""
43         "},"
44         "\"SCHEMA_INDEXES\":[\"$.field_name1\"]}";
45     // define some variables to init a KvStoreDelegateManager object.
46     KvStoreDelegateManager g_mgr("app0", "user0");
47     std::string g_testDir;
48     KvStoreConfig g_config;
49     std::string g_storeName = "schema_put_test";
50 
51     // define the g_kvNbDelegateCallback, used to get some information when open a kv store.
52     DBStatus g_kvDelegateStatus = INVALID_ARGS;
53     KvStoreNbDelegate *g_kvStore = nullptr;
54     CipherPassword g_passwd;
55     KvStoreNbDelegate::Option g_strictOpt = {true, false, false, CipherType::DEFAULT, g_passwd,
56         VALID_SCHEMA_STRICT_DEFINE};
57     KvStoreNbDelegate::Option g_compOpt = {true, false, false, CipherType::DEFAULT, g_passwd,
58         VALID_SCHEMA_COMPA_DEFINE};
59 
KvStoreNbDelegateCallback(DBStatus statusSrc,KvStoreNbDelegate * kvStoreSrc,DBStatus * statusDst,KvStoreNbDelegate ** kvStoreDst)60     void KvStoreNbDelegateCallback(
61         DBStatus statusSrc, KvStoreNbDelegate* kvStoreSrc, DBStatus* statusDst, KvStoreNbDelegate** kvStoreDst)
62     {
63         *statusDst = statusSrc;
64         *kvStoreDst = kvStoreSrc;
65     }
66 
67     // the type of g_kvNbDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
68     auto g_kvNbDelegateCallback = std::bind(&KvStoreNbDelegateCallback, std::placeholders::_1,
69         std::placeholders::_2, &g_kvDelegateStatus, &g_kvStore);
70 
CheckPutSchemaData(KvStoreNbDelegate * kvStore)71     void CheckPutSchemaData(KvStoreNbDelegate *kvStore)
72     {
73         ASSERT_NE(kvStore, nullptr);
74         Key key;
75         DistributedDBToolsUnitTest::GetRandomKeyValue(key);
76         /**
77          * @tc.steps:step1. Put one data whose value has less fields than the schema(less value is not null).
78          * @tc.expected: step1. return CONSTRAIN_VIOLATION.
79          */
80         std::string lessData = "{\"field_name1\":true}";
81         Value value(lessData.begin(), lessData.end());
82         EXPECT_EQ(g_kvStore->Put(key, value), CONSTRAIN_VIOLATION);
83 
84         /**
85          * @tc.steps:step2. Put one data whose value has different type with the schema.
86          * @tc.expected: step2. return INVALID_FIELD_TYPE.
87          */
88         std::string typeDiffData = "{\"field_name1\":30,\"field_name2\":10}";
89         value.assign(typeDiffData.begin(), typeDiffData.end());
90         EXPECT_EQ(kvStore->Put(key, value), INVALID_FIELD_TYPE);
91 
92         /**
93          * @tc.steps:step3. Put one data whose value has constrain violation with the schema.
94          * @tc.expected: step3. return CONSTRAIN_VIOLATION.
95          */
96         std::string constrainDiffData = "{\"field_name1\":false,\"field_name2\":null}";
97         value.assign(constrainDiffData.begin(), constrainDiffData.end());
98         EXPECT_EQ(kvStore->Put(key, value), CONSTRAIN_VIOLATION);
99 
100         /**
101          * @tc.steps:step4. Put one data whose value has invalid json.
102          * @tc.expected: step4. return INVALID_FORMAT.
103          */
104         std::string invalidJsonData = "{\"field_name1\":false,\"field_name2\":10";
105         value.assign(invalidJsonData.begin(), invalidJsonData.end());
106         EXPECT_EQ(kvStore->Put(key, value), INVALID_FORMAT);
107 
108         /**
109          * @tc.steps:step5. Put one data whose value is empty.
110          * @tc.expected: step5. return INVALID_FORMAT.
111          */
112         value.clear();
113         EXPECT_EQ(kvStore->Put(key, value), INVALID_FORMAT);
114 
115         /**
116          * @tc.steps:step6. Put one data whose value is match with the schema.
117          * @tc.expected: step6. return INVALID_FORMAT.
118          */
119         std::string validJsonData = "{\"field_name1\":false,\"field_name2\":10}";
120         value.assign(validJsonData.begin(), validJsonData.end());
121         EXPECT_EQ(kvStore->Put(key, value), OK);
122     }
123 
CheckPutBatchSchemaData(KvStoreNbDelegate * kvStore)124     void CheckPutBatchSchemaData(KvStoreNbDelegate *kvStore)
125     {
126         ASSERT_NE(kvStore, nullptr);
127         /**
128          * @tc.steps:step1. Put the batch data, one data is invalid.
129          * @tc.expected: step1. return INVALID_FORMAT.
130          */
131         Key key;
132         DistributedDBToolsUnitTest::GetRandomKeyValue(key);
133         std::string invalidData = "{\"field_name1\":true, \"field_name2\":null}";
134         Value value(invalidData.begin(), invalidData.end());
135         std::vector<Entry> entries;
136         entries.push_back({key, value});
137 
138         DistributedDBToolsUnitTest::GetRandomKeyValue(key);
139         std::string validData = "{\"field_name1\":true, \"field_name2\":0}";
140         value.assign(validData.begin(), validData.end());
141         entries.push_back({key, value});
142 
143         EXPECT_NE(kvStore->PutBatch(entries), INVALID_FORMAT);
144 
145         entries.clear();
146         entries.push_back({key, value});
147 
148         /**
149          * @tc.steps:step2. Put the batch data, both valid.
150          * @tc.expected: step2. return OK.
151          */
152         DistributedDBToolsUnitTest::GetRandomKeyValue(key);
153         validData = "{\"field_name1\":null, \"field_name2\":30}";
154         value.assign(validData.begin(), validData.end());
155         entries.push_back({key, value});
156 
157         EXPECT_EQ(kvStore->PutBatch(entries), OK);
158     }
159 }
160 class DistributedDBInterfacesNBDelegateSchemaPutTest : public testing::Test {
161 public:
162     static void SetUpTestCase(void);
163     static void TearDownTestCase(void);
164     void SetUp();
165     void TearDown();
166 };
167 
SetUpTestCase(void)168 void DistributedDBInterfacesNBDelegateSchemaPutTest::SetUpTestCase(void)
169 {
170     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
171     g_config.dataDir = g_testDir;
172     g_mgr.SetKvStoreConfig(g_config);
173 }
174 
TearDownTestCase(void)175 void DistributedDBInterfacesNBDelegateSchemaPutTest::TearDownTestCase(void)
176 {
177     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
178         LOGE("rm test db files error!");
179     }
180 }
181 
SetUp(void)182 void DistributedDBInterfacesNBDelegateSchemaPutTest::SetUp(void)
183 {
184     DistributedDBToolsUnitTest::PrintTestCaseInfo();
185 }
186 
TearDown(void)187 void DistributedDBInterfacesNBDelegateSchemaPutTest::TearDown(void)
188 {
189     EXPECT_EQ(g_mgr.CloseKvStore(g_kvStore), OK);
190     EXPECT_EQ(g_mgr.DeleteKvStore(g_storeName), OK);
191     g_kvStore = nullptr;
192     g_kvDelegateStatus = INVALID_ARGS;
193 }
194 
195 /**
196   * @tc.name: PutValueStrictSchemaCheck001
197   * @tc.desc: Check the value in the strict schema mode.
198   * @tc.type: FUNC
199   * @tc.require: AR000DR9K5
200   * @tc.author: wangbingquan
201   */
202 HWTEST_F(DistributedDBInterfacesNBDelegateSchemaPutTest, PutValueStrictSchemaCheck001, TestSize.Level1)
203 {
204     g_mgr.GetKvStore(g_storeName, g_strictOpt, g_kvNbDelegateCallback);
205     ASSERT_TRUE(g_kvStore != nullptr);
206     EXPECT_TRUE(g_kvDelegateStatus == OK);
207 
208     /**
209      * @tc.steps:step1. Put one data whose value has more fields than the schema.
210      * @tc.expected: step1. return INVALID_VALUE_FIELDS.
211      */
212     Key key;
213     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
214     std::string moreData = "{\"field_name1\":true,\"field_name2\":10,\"field_name3\":10}";
215     Value value(moreData.begin(), moreData.end());
216     EXPECT_EQ(g_kvStore->Put(key, value), INVALID_VALUE_FIELDS);
217 
218     /**
219      * @tc.steps:step2. Put one data whose value has diff fields than the schema.
220      * @tc.expected: step2. return INVALID_VALUE_FIELDS.
221      */
222     std::string diffData = "{\"field_name2\":10,\"field_name3\":10}";
223     Value value1(diffData.begin(), diffData.end());
224     EXPECT_EQ(g_kvStore->Put(key, value1), INVALID_VALUE_FIELDS);
225 
226     std::string filedDiffData = "{\"field_name1\":true,\"field_name3\":10}";
227     value.assign(filedDiffData.begin(), filedDiffData.end());
228     EXPECT_EQ(g_kvStore->Put(key, value), INVALID_VALUE_FIELDS);
229 
230     /**
231      * @tc.steps:step3. Put the data whose value is mismatch with the schema.
232      * @tc.expected: step3. return not OK.
233      */
234     CheckPutSchemaData(g_kvStore);
235     CheckPutBatchSchemaData(g_kvStore);
236 }
237 
238 /**
239   * @tc.name: PutValueReadOnlyCheck001
240   * @tc.desc: Test writing the data into the no-schema kvStore which has schema originally.
241   * @tc.type: FUNC
242   * @tc.require: AR000DR9K5
243   * @tc.author: wangbingquan
244   */
245 HWTEST_F(DistributedDBInterfacesNBDelegateSchemaPutTest, PutValueCompaSchemaCheck001, TestSize.Level1)
246 {
247     g_mgr.GetKvStore(g_storeName, g_compOpt, g_kvNbDelegateCallback);
248     ASSERT_TRUE(g_kvStore != nullptr);
249     EXPECT_TRUE(g_kvDelegateStatus == OK);
250     /**
251      * @tc.steps:step1. Put one data whose value has more fields than the schema.
252      * @tc.expected: step1. return OK.
253      */
254     Key key;
255     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
256     std::string moreData = "{\"field_name1\":true,\"field_name2\":10,\"field_name3\":10}";
257     Value value(moreData.begin(), moreData.end());
258     EXPECT_EQ(g_kvStore->Put(key, value), OK);
259 
260 
261     /**
262      * @tc.steps:step2. Put one data whose value has different fields with the schema(less value is not null).
263      * @tc.expected: step2. return CONSTRAIN_VIOLATION.
264      */
265     std::string filedDiffData = "{\"field_name1\":true,\"field_name3\":10}";
266     value.assign(filedDiffData.begin(), filedDiffData.end());
267     EXPECT_EQ(g_kvStore->Put(key, value), CONSTRAIN_VIOLATION);
268 
269     /**
270      * @tc.steps:step2. Put the data whose value is mismatch with the schema.
271      * @tc.expected: step2. return not OK.
272      */
273     CheckPutSchemaData(g_kvStore);
274     CheckPutBatchSchemaData(g_kvStore);
275 }
276 
277 /**
278   * @tc.name: PutValueReadOnlyCheck001
279   * @tc.desc: Test writing the data into the no-schema kvStore which has schema originally.
280   * @tc.type: FUNC
281   * @tc.require: AR000DR9K5
282   * @tc.author: wangbingquan
283   */
284 HWTEST_F(DistributedDBInterfacesNBDelegateSchemaPutTest, PutValueReadOnlyCheck001, TestSize.Level1)
285 {
286     /**
287      * @tc.steps:step1. Open the kv store with valid schema, and close it.
288      */
289     g_mgr.GetKvStore(g_storeName, g_compOpt, g_kvNbDelegateCallback);
290     ASSERT_TRUE(g_kvStore != nullptr);
291     EXPECT_TRUE(g_kvDelegateStatus == OK);
292     EXPECT_EQ(g_mgr.CloseKvStore(g_kvStore), OK);
293     /**
294      * @tc.steps:step2. Open the kv store with no schema.
295      * @tc.expected: step2. return OK.
296      */
297     DistributedDB::KvStoreNbDelegate::Option option = g_compOpt;
298     option.schema.clear();
299     g_mgr.GetKvStore(g_storeName, option, g_kvNbDelegateCallback);
300     ASSERT_TRUE(g_kvStore != nullptr);
301     EXPECT_TRUE(g_kvDelegateStatus == OK);
302     /**
303      * @tc.steps:step3. Put the data.
304      * @tc.expected: step3. return READ_ONLY.
305      */
306     Key key;
307     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
308     std::string valueData = "{\"field_name1\":true,\"field_name2\":20}";
309     Value value(valueData.begin(), valueData.end());
310     EXPECT_EQ(g_kvStore->Put(key, value), READ_ONLY);
311 }
312 
313 /**
314   * @tc.name: QueryDeleted001
315   * @tc.desc: Test the query in the deleted scene.
316   * @tc.type: FUNC
317   * @tc.require: AR000DR9K5
318   * @tc.author: wangbingquan
319   */
320 HWTEST_F(DistributedDBInterfacesNBDelegateSchemaPutTest, QueryDeleted001, TestSize.Level1)
321 {
322     g_mgr.GetKvStore(g_storeName, g_strictOpt, g_kvNbDelegateCallback);
323     ASSERT_TRUE(g_kvStore != nullptr);
324     EXPECT_TRUE(g_kvDelegateStatus == OK);
325 
326     /**
327      * @tc.steps:step1. Put 2 schema data.
328      * @tc.expected: step1. return OK.
329      */
330     Key key1;
331     std::string valueData = "{\"field_name1\":true,\"field_name2\":1}";
332     Value value(valueData.begin(), valueData.end());
333     DistributedDBToolsUnitTest::GetRandomKeyValue(key1);
334     EXPECT_EQ(g_kvStore->Put(key1, value), OK);
335 
336     Key key2;
337     valueData = "{\"field_name1\":true,\"field_name2\":2}";
338     value.assign(valueData.begin(), valueData.end());
339     DistributedDBToolsUnitTest::GetRandomKeyValue(key2);
340     EXPECT_EQ(g_kvStore->Put(key2, value), OK);
341 
342     /**
343      * @tc.steps:step2. Get the data through the query condition where the field value is 1.
344      * @tc.expected: step2. GetEntries return OK, and the data num is 1.
345      */
346     std::vector<Entry> entries;
347     KvStoreResultSet *resultSet = nullptr;
348     Query query = Query::Select().EqualTo("$.field_name2", 1);
349     EXPECT_EQ(g_kvStore->GetEntries(query, entries), OK);
350     EXPECT_EQ(g_kvStore->GetEntries(query, resultSet), OK);
351     ASSERT_NE(resultSet, nullptr);
352     EXPECT_EQ(resultSet->GetCount(), 1);
353     int count = 0;
354     EXPECT_EQ(g_kvStore->GetCount(query, count), OK);
355     EXPECT_EQ(count, 1);
356     EXPECT_EQ(g_kvStore->CloseResultSet(resultSet), OK);
357 
358     /**
359      * @tc.steps:step3. Delete the data whose field value is 1.
360      */
361     EXPECT_EQ(g_kvStore->Delete(key1), OK);
362 
363     /**
364      * @tc.steps:step4. Get the data whose field value is 1.
365      * @tc.expected: step4. GetEntries return NOT_FOUND, and the data num is 0.
366      */
367     EXPECT_EQ(g_kvStore->GetEntries(query, entries), NOT_FOUND);
368     EXPECT_EQ(g_kvStore->GetCount(query, count), NOT_FOUND);
369     EXPECT_EQ(g_kvStore->GetEntries(query, resultSet), OK);
370     ASSERT_NE(resultSet, nullptr);
371     EXPECT_EQ(resultSet->GetCount(), 0);
372     EXPECT_EQ(g_kvStore->CloseResultSet(resultSet), OK);
373 }
374 #endif