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 #ifdef USE_RD_KERNEL
16 #include "distributeddb_storage_rd_single_ver_natural_store_testcase.h"
17 
18 #include "generic_single_ver_kv_entry.h"
19 #include "runtime_context.h"
20 #include "time_helper.h"
21 
22 using namespace DistributedDB;
23 using namespace DistributedDBUnitTest;
24 
25 namespace {
26     const int MAX_TEST_KEY_SIZE = 1024;     // 1K
27     const int MAX_TEST_VAL_SIZE = 4194304; // 4M
28 }
29 
30 /**
31   * @tc.name: SyncDatabaseOperate001
32   * @tc.desc: To test the function of inserting data of the local device in the synchronization database.
33   * @tc.type: FUNC
34   * @tc.require: AR000CCPOM
35   * @tc.author: huangboxin
36   */
SyncDatabaseOperate001(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection)37 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::SyncDatabaseOperate001(RdSingleVerNaturalStore *&store,
38     RdSingleVerNaturalStoreConnection *&connection)
39 {
40     IOption option;
41     option.dataType = IOption::SYNC_DATA;
42     DataBaseCommonPutOperate(store, connection, option);
43 }
44 
45 /**
46   * @tc.name: SyncDatabaseOperate003
47   * @tc.desc: test the delete operation in sync database.
48   * @tc.type: FUNC
49   * @tc.require: AR000CCPOM
50   * @tc.author: huangboxin
51   */
SyncDatabaseOperate003(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection)52 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::SyncDatabaseOperate003(RdSingleVerNaturalStore *&store,
53     RdSingleVerNaturalStoreConnection *&connection)
54 {
55     IOption option;
56     option.dataType = IOption::SYNC_DATA;
57     DataBaseCommonDeleteOperate(store, connection, option);
58 }
59 
60 /**
61   * @tc.name: SyncDatabaseOperate005
62   * @tc.desc: test the reading for sync database.
63   * @tc.type: FUNC
64   * @tc.require: AR000CCPOM
65   * @tc.author: huangboxin
66   */
SyncDatabaseOperate005(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection)67 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::SyncDatabaseOperate005(RdSingleVerNaturalStore *&store,
68     RdSingleVerNaturalStoreConnection *&connection)
69 {
70     IOption option;
71     option.dataType = IOption::SYNC_DATA;
72     DataBaseCommonGetOperate(store, connection, option);
73 }
74 
75 /**
76   * @tc.name: SyncDatabaseOperate006
77   * @tc.desc: test the get entries for sync database
78   * @tc.type: FUNC
79   * @tc.require: AR000CCPOM
80   * @tc.author: huangboxin
81   */
SyncDatabaseOperate006(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection)82 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::SyncDatabaseOperate006(RdSingleVerNaturalStore *&store,
83     RdSingleVerNaturalStoreConnection *&connection)
84 {
85     IOption option;
86     option.dataType = IOption::SYNC_DATA;
87 
88     /**
89      * @tc.steps: step2/3/4. Set Ioption to synchronous data.
90      * Insert the data of key=keyPrefix + 'a', value1.
91      * Insert the data of key=keyPrefix + 'c', value2.
92      * Insert the data of key length=keyPrefix length - 1, value3.
93      * @tc.expected: step2/3/4. Return E_NOT_FOUND.
94      */
95     Key key1;
96     DistributedDBToolsUnitTest::GetRandomKeyValue(key1, 30); // 30 as random size
97     Key key2 = key1;
98     key2.push_back('C');
99     Key key3 = key1;
100     key3.pop_back();
101     Value value1;
102     DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 84); // 84 as random size
103     Value value2;
104     DistributedDBToolsUnitTest::GetRandomKeyValue(value2, 101); // 101 as random size
105     Value value3;
106     DistributedDBToolsUnitTest::GetRandomKeyValue(value3, 37); // 37 as random size
107     EXPECT_EQ(connection->Put(option, key1, value1), E_OK);
108     EXPECT_EQ(connection->Put(option, key2, value2), E_OK);
109     EXPECT_EQ(connection->Put(option, key3, value3), E_OK);
110 
111     /**
112      * @tc.steps: step5. Obtain all data whose prefixKey is keyPrefix.
113      * @tc.expected: step5. Return OK. The number of obtained data records is 2.
114      */
115     std::vector<Entry> entriesRead;
116     EXPECT_EQ(connection->GetEntries(option, key1, entriesRead), E_OK);
117     EXPECT_EQ(entriesRead.size(), 2UL);
118 
119     /**
120      * @tc.steps: step6. Obtain all data whose prefixKey is empty.
121      * @tc.expected: step6. Return OK. The number of obtained data records is 3.
122      */
123     entriesRead.clear();
124     Key emptyKey;
125     EXPECT_EQ(connection->GetEntries(option, emptyKey, entriesRead), E_OK);
126     EXPECT_EQ(entriesRead.size(), 3UL);
127 
128     /**
129      * @tc.steps: step7. Obtain all data whose prefixKey is keyPrefix.
130      * @tc.expected: step7. Return -E_NOT_SUPPORT.
131      */
132     option.dataType = IOption::LOCAL_DATA;
133     EXPECT_EQ(connection->GetEntries(option, emptyKey, entriesRead), -E_NOT_SUPPORT);
134 }
135 
136 // @Real query sync-DATA table by key, judge is exist.
IsSqlinteExistKey(const std::vector<SyncData> & vecSyncData,const std::vector<uint8_t> & key)137 bool DistributedDBStorageRdSingleVerNaturalStoreTestCase::IsSqlinteExistKey(const std::vector<SyncData> &vecSyncData,
138     const std::vector<uint8_t> &key)
139 {
140     for (const auto &iter : vecSyncData) {
141         if (key == iter.key) {
142             return true;
143         }
144     }
145     return false;
146 }
147 
DataBaseCommonPutOperate(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection,IOption option)148 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::DataBaseCommonPutOperate(RdSingleVerNaturalStore *&store,
149     RdSingleVerNaturalStoreConnection *&connection, IOption option)
150 {
151     Key key1;
152     Value value1;
153 
154     /**
155      * @tc.steps: step1/2. Set Ioption to the local data and insert a record of key1 and value1.
156      * @tc.expected: step1/2. Return OK.
157      */
158     DistributedDBToolsUnitTest::GetRandomKeyValue(key1);
159     DistributedDBToolsUnitTest::GetRandomKeyValue(value1);
160     EXPECT_EQ(connection->Put(option, key1, value1), E_OK);
161 
162     /**
163      * @tc.steps: step3. Set Ioption to the local data and obtain the value of key1.
164      *  Check whether the value is the same as the value of value1.
165      * @tc.expected: step3. The obtained value and value2 are the same.
166      */
167     Value valueRead;
168     EXPECT_EQ(connection->Get(option, key1, valueRead), E_OK);
169     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value1), true);
170     Value value2;
171     DistributedDBToolsUnitTest::GetRandomKeyValue(value2, static_cast<int>(value1.size() + 3)); // 3 more for diff
172 
173     /**
174      * @tc.steps: step4. Ioption Set this parameter to the local data. Insert key1.
175      *  The value cannot be empty. value2(!=value1)
176      * @tc.expected: step4. Return OK.
177      */
178     EXPECT_EQ(connection->Put(option, key1, value2), E_OK);
179 
180     /**
181      * @tc.steps: step5. Set Ioption to the local data, GetMetaData to obtain the value of key1,
182      *  and check whether the value is the same as the value of value2.
183      * @tc.expected: step5. The obtained value and value2 are the same.
184      */
185     EXPECT_EQ(connection->Get(option, key1, valueRead), E_OK);
186     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value2), true);
187 
188     /**
189      * @tc.steps: step6. The Ioption parameter is set to the local data.
190      *  The data record whose key is empty and value is not empty is inserted.
191      * @tc.expected: step6. Return E_INVALID_DATA.
192      */
193     Key emptyKey;
194     Value emptyValue;
195     EXPECT_EQ(connection->Put(option, emptyKey, value1), -E_INVALID_ARGS);
196 
197     /**
198      * @tc.steps: step7. Set Ioption to the local data, insert data
199      *  whose key2(!=key1) is not empty, and value is empty.
200      * @tc.expected: step7. Return E_OK
201      */
202     Key key2;
203     DistributedDBToolsUnitTest::GetRandomKeyValue(key2, static_cast<int>(key1.size() + 1));
204     EXPECT_EQ(connection->Put(option, key2, emptyValue), E_OK);
205 
206     /**
207      * @tc.steps: step8. Set option to local data, obtain the value of key2,
208      *  and check whether the value is empty.
209      * @tc.expected: step8. Return E_OK.
210      */
211     EXPECT_EQ(connection->Get(option, key2, valueRead), E_OK);
212 
213     /**
214      * @tc.steps: step9. Ioption Set the local data.
215      *  Insert the data whose key size is 1024 and value size is 4Mb + 1.
216      * @tc.expected: step9. Return OK.
217      */
218     Key sizeKey;
219     Value sizeValue;
220     DistributedDBToolsUnitTest::GetRandomKeyValue(sizeKey, MAX_TEST_KEY_SIZE);
221     DistributedDBToolsUnitTest::GetRandomKeyValue(sizeValue, MAX_TEST_VAL_SIZE + 1);
222     EXPECT_EQ(connection->Put(option, sizeKey, sizeValue), -E_INVALID_ARGS);
223     EXPECT_EQ(connection->Get(option, sizeKey, valueRead), -E_NOT_FOUND);
224 
225     /**
226      * @tc.steps: step10/11. Set Ioption to the local data and insert data items
227      *  whose value is greater than 4Mb or key is bigger than 1Kb
228      * @tc.expected: step10/11. Return E_INVALID_ARGS.
229      */
230     sizeKey.push_back(std::rand()); // random size
231     EXPECT_EQ(connection->Put(option, sizeKey, sizeValue), -E_INVALID_ARGS);
232     sizeKey.pop_back();
233     sizeValue.push_back(174); // 174 as random size
234     EXPECT_EQ(connection->Put(option, sizeKey, sizeValue), -E_INVALID_ARGS);
235 }
236 
DataBaseCommonDeleteOperate(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection,IOption option)237 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::DataBaseCommonDeleteOperate(RdSingleVerNaturalStore *&store,
238     RdSingleVerNaturalStoreConnection *&connection, IOption option)
239 {
240     /**
241      * @tc.steps: step2. Set Ioption to the local data and delete the data whose key is key1 (empty).
242      * @tc.expected: step2. Return E_INVALID_ARGS.
243      */
244     Key key1;
245     EXPECT_EQ(connection->Delete(option, key1), -E_INVALID_ARGS);
246     DistributedDBToolsUnitTest::GetRandomKeyValue(key1, MAX_TEST_KEY_SIZE + 1);
247     EXPECT_EQ(connection->Delete(option, key1), -E_INVALID_ARGS);
248     DistributedDBToolsUnitTest::GetRandomKeyValue(key1);
249     EXPECT_EQ(connection->Delete(option, key1), E_OK);
250 
251     /**
252      * @tc.steps: step3. Set Ioption to the local data, insert non-null key1, and non-null value1 data.
253      * @tc.expected: step3. Return E_OK.
254      */
255     Value value1;
256     DistributedDBToolsUnitTest::GetRandomKeyValue(value1);
257     EXPECT_EQ(connection->Put(option, key1, value1), E_OK);
258 
259     /**
260      * @tc.steps: step4. Set Ioption to the local data, obtain the value of key1,
261      *  and check whether the value is the same as that of value1.
262      * @tc.expected: step4. Return E_OK. The obtained value is the same as the value of value1.
263      */
264     Value valueRead;
265     EXPECT_EQ(connection->Get(option, key1, valueRead), E_OK);
266     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value1), true);
267 
268     /**
269      * @tc.steps: step5. Set Ioption to the local data and delete the data whose key is key1.
270      * @tc.expected: step5. Return E_OK.
271      */
272     EXPECT_EQ(connection->Delete(option, key1), E_OK);
273 
274     /**
275      * @tc.steps: step5. Set Ioption to the local data and obtain the value of Key1.
276      * @tc.expected: step5. Return E_NOT_FOUND.
277      */
278     EXPECT_EQ(connection->Get(option, key1, valueRead), -E_NOT_FOUND);
279 }
280 
DataBaseCommonGetOperate(RdSingleVerNaturalStore * & store,RdSingleVerNaturalStoreConnection * & connection,IOption option)281 void DistributedDBStorageRdSingleVerNaturalStoreTestCase::DataBaseCommonGetOperate(RdSingleVerNaturalStore *&store,
282     RdSingleVerNaturalStoreConnection *&connection, IOption option)
283 {
284     /**
285      * @tc.steps: step2. Set Ioption to the local data and delete the data whose key is key1 (empty).
286      * @tc.expected: step2. Return E_INVALID_ARGS.
287      */
288     Key key1;
289     Value valueRead;
290     // empty key
291     EXPECT_EQ(connection->Get(option, key1, valueRead), -E_INVALID_ARGS);
292 
293     // invalid key
294     DistributedDBToolsUnitTest::GetRandomKeyValue(key1, MAX_TEST_KEY_SIZE + 1);
295     EXPECT_EQ(connection->Get(option, key1, valueRead), -E_INVALID_ARGS);
296 
297     // non-exist key
298     DistributedDBToolsUnitTest::GetRandomKeyValue(key1, MAX_TEST_KEY_SIZE);
299     EXPECT_EQ(connection->Get(option, key1, valueRead), -E_NOT_FOUND);
300 
301     /**
302      * @tc.steps: step3. Set Ioption to the local data, insert non-null key1, and non-null value1 data.
303      * @tc.expected: step3. Return E_OK.
304      */
305     Value value1;
306     DistributedDBToolsUnitTest::GetRandomKeyValue(value1);
307     EXPECT_EQ(connection->Put(option, key1, value1), E_OK);
308 
309     /**
310      * @tc.steps: step4. Set Ioption to the local data, obtain the value of key1,
311      *  and check whether the value is the same as that of value1.
312      * @tc.expected: step4. Return E_OK. The obtained value is the same as the value of value1.
313      */
314     EXPECT_EQ(connection->Get(option, key1, valueRead), E_OK);
315     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value1), true);
316 
317     Key key2;
318     DistributedDBToolsUnitTest::GetRandomKeyValue(key2);
319     EXPECT_EQ(connection->Get(option, key2, valueRead), -E_NOT_FOUND);
320 
321     /**
322      * @tc.steps: step5. Set Ioption to the local data and obtain the value data of Key1.
323      *  Check whether the value is the same as the value of value2.
324      * @tc.expected: step4. Return E_OK, and the value is the same as the value of value2.
325      */
326     Value value2;
327     DistributedDBToolsUnitTest::GetRandomKeyValue(value2, value1.size() + 1);
328     EXPECT_EQ(connection->Put(option, key1, value2), E_OK);
329 
330     /**
331      * @tc.steps: step5. The Ioption is set to the local.
332      *  The data of the key1 and value2(!=value1) is inserted.
333      * @tc.expected: step4. Return E_OK.
334      */
335     EXPECT_EQ(connection->Get(option, key1, valueRead), E_OK);
336     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead, value2), true);
337 }
338 #endif // USE_RD_KERNEL