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 #ifndef OMIT_ENCRYPT
16 #include <gtest/gtest.h>
17 #include <fcntl.h>
18 
19 #include "db_common.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "platform_specific.h"
22 #include "process_communicator_test_stub.h"
23 #include "process_system_api_adapter_impl.h"
24 
25 using namespace std;
26 using namespace testing::ext;
27 using namespace DistributedDB;
28 using namespace DistributedDBUnitTest;
29 
30 namespace {
31     // define some variables to init a KvStoreDelegateManager object.
32     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
33     string g_testDir;
34     KvStoreConfig g_config;
35     std::string g_exportFileDir;
36     std::vector<std::string> g_junkFilesList;
37 
38     // define the g_kvNbDelegateCallback, used to get some information when open a kv store.
39     DBStatus g_kvDelegateStatus = INVALID_ARGS;
40     KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
41     KvStoreNbDelegate *g_kvNbDelegatePtrWithoutPasswd = nullptr;
42 
43 #ifndef OMIT_MULTI_VER
44     KvStoreDelegate *g_kvDelegatePtr = nullptr;
45     KvStoreDelegate *g_kvDelegatePtrWithoutPasswd = nullptr;
46     // the type of g_kvDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
47     auto g_kvDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
48         placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvDelegatePtr));
49     KvStoreDelegate::Option g_option;
50 #endif // OMIT_MULTI_VER
51 
52     const size_t MAX_PASSWD_SIZE = 128;
53     // define the g_valueCallback, used to query a value object data from the kvdb.
54     DBStatus g_valueStatus = INVALID_ARGS;
55     Value g_value;
56 
57     CipherPassword g_passwd1;
58     CipherPassword g_passwd2;
59     CipherPassword g_passwd3;
60     CipherPassword g_passwd4;
61     // the type of g_valueCallback is function<void(DBStatus, Value)>
62     auto g_valueCallback = bind(&DistributedDBToolsUnitTest::ValueCallback,
63         placeholders::_1, placeholders::_2, std::ref(g_valueStatus), std::ref(g_value));
64 
65     // the type of g_kvNbDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
66     auto g_kvNbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, placeholders::_1,
67         placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvNbDelegatePtr));
68 
RemoveJunkFile(const std::vector<std::string> & fileList)69     void RemoveJunkFile(const std::vector<std::string> &fileList)
70     {
71         for (auto &junkFile : fileList) {
72             std::ifstream file(junkFile);
73             if (file) {
74                 file.close();
75                 int result = remove(junkFile.c_str());
76                 if (result < 0) {
77                     LOGE("failed to delete the db file:%d", errno);
78                 }
79             }
80         }
81         return;
82     }
83 }
84 
85 class DistributedDBInterfacesImportAndExportTest : public testing::Test {
86 public:
87     static void SetUpTestCase(void);
88     static void TearDownTestCase(void);
89     void SetUp();
90     void TearDown();
91 };
92 
SetUpTestCase(void)93 void DistributedDBInterfacesImportAndExportTest::SetUpTestCase(void)
94 {
95     g_mgr.SetProcessLabel("6666", "8888");
96     g_mgr.SetProcessCommunicator(std::make_shared<ProcessCommunicatorTestStub>());
97     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
98     g_config.dataDir = g_testDir;
99     g_mgr.SetKvStoreConfig(g_config);
100 
101     g_exportFileDir = g_testDir + "/ExportDir";
102     OS::MakeDBDirectory(g_exportFileDir);
103     vector<uint8_t> passwdBuffer1(5, 1);  // 5 and 1 as random password.
104     int errCode = g_passwd1.SetValue(passwdBuffer1.data(), passwdBuffer1.size());
105     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
106     vector<uint8_t> passwdBuffer2(5, 2);  // 5 and 2 as random password.
107     errCode = g_passwd2.SetValue(passwdBuffer2.data(), passwdBuffer2.size());
108     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
109     vector<uint8_t> passwdBuffer3(5, 3);  // 5 and 3 as random password.
110     errCode = g_passwd3.SetValue(passwdBuffer3.data(), passwdBuffer3.size());
111     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
112     vector<uint8_t> passwdBuffer4(5, 4);  // 5 and 4 as random password.
113     errCode = g_passwd4.SetValue(passwdBuffer4.data(), passwdBuffer4.size());
114     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
115 }
116 
TearDownTestCase(void)117 void DistributedDBInterfacesImportAndExportTest::TearDownTestCase(void)
118 {
119     OS::RemoveDBDirectory(g_exportFileDir);
120     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
121         LOGE("rm test db files error!");
122     }
123     RuntimeContext::GetInstance()->StopTaskPool(); // wait for all thread exit
124 }
125 
SetUp(void)126 void DistributedDBInterfacesImportAndExportTest::SetUp(void)
127 {
128     DistributedDBToolsUnitTest::PrintTestCaseInfo();
129     g_junkFilesList.clear();
130     g_kvDelegateStatus = INVALID_ARGS;
131     g_kvNbDelegatePtr = nullptr;
132 #ifndef OMIT_MULTI_VER
133     g_kvDelegatePtr = nullptr;
134 #endif // OMIT_MULTI_VER
135 }
136 
TearDown(void)137 void DistributedDBInterfacesImportAndExportTest::TearDown(void)
138 {
139     RemoveJunkFile(g_junkFilesList);
140 }
141 
142 /**
143   * @tc.name: NormalExport001
144   * @tc.desc: The data of the current version of the board is exported and the package file is single.
145   * @tc.type: FUNC
146   * @tc.require: AR000D4879
147   * @tc.author: sunpeng
148   */
149 HWTEST_F(DistributedDBInterfacesImportAndExportTest, NormalExport001, TestSize.Level1)
150 {
151     /**
152      * @tc.steps: step1. Pre-create folder dir
153      */
154     std::string singleExportFileName = g_exportFileDir + "/singleNormalExport001.$$";
155     std::string singleStoreId = "distributed_ExportSingle_001";
156     KvStoreNbDelegate::Option option = {true, false, false};
157     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
158     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
159     EXPECT_TRUE(g_kvDelegateStatus == OK);
160 
161     /**
162      * @tc.steps: step2. Specify the path to export the non-encrypted board database.
163      * @tc.expected: step2. Returns OK
164      */
165     CipherPassword passwd;
166     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
167 #ifndef OMIT_MULTI_VER
168     std::string mulitExportFileName = g_exportFileDir + "/mulitNormalExport001.$$";
169     std::string multiStoreId = "distributed_ExportMulit_001";
170     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
171     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
172     EXPECT_TRUE(g_kvDelegateStatus == OK);
173 
174     /**
175      * @tc.steps: step3. Specify the path to export the multi-version non-encrypted database.
176      * @tc.expected: step3. Returns OK
177      */
178     EXPECT_EQ(g_kvDelegatePtr->Export(mulitExportFileName, passwd), OK);
179 
180     // clear resource
181     g_junkFilesList.push_back(mulitExportFileName);
182     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
183     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
184 #endif // OMIT_MULTI_VER
185     g_junkFilesList.push_back(singleExportFileName);
186     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
187     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
188 }
189 
190 /**
191   * @tc.name: UndisturbedlSingleExport001
192   * @tc.desc: Check that the export action is an independent transaction.
193   * @tc.type: FUNC
194   * @tc.require: AR000D4879
195   * @tc.author: sunpeng
196   */
197 HWTEST_F(DistributedDBInterfacesImportAndExportTest, UndisturbedlSingleExport001, TestSize.Level1)
198 {
199     std::string singleStoreId = "distributed_ExportSingle_002";
200     KvStoreNbDelegate::Option option = {true, false, false};
201     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
202     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
203     EXPECT_TRUE(g_kvDelegateStatus == OK);
204 
205     /**
206      * @tc.steps: step1. Three known data records are preset in the board database.
207      */
208     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
209     g_kvNbDelegatePtr->Put(KEY_2, VALUE_2);
210     g_kvNbDelegatePtr->Put(KEY_3, VALUE_3);
211 
212     /**
213      * @tc.steps: step2. Execute the export action.
214      */
215     std::string singleExportFileName = g_exportFileDir + "/UndisturbedlSingleExport001.$$";
216     CipherPassword passwd;
217     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
218 
219     /**
220      * @tc.steps: step3. Insert multiple new data records into the database.
221      */
222     g_kvNbDelegatePtr->Put(KEY_4, VALUE_4);
223     g_kvNbDelegatePtr->Put(KEY_5, VALUE_5);
224 
225     /**
226      * @tc.steps: step4.  Import backup data.
227      * @tc.expected: step4. Returns OK.
228      */
229     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
230 
231     /**
232      * @tc.steps: step5. Check whether the imported data is the preset content in step 1.
233      * @tc.expected: step5. Three preset data records are found.
234      */
235     Value readValue;
236     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_1, readValue), OK);
237     EXPECT_EQ(readValue, VALUE_1);
238     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_2, readValue), OK);
239     EXPECT_EQ(readValue, VALUE_2);
240     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_3, readValue), OK);
241     EXPECT_EQ(readValue, VALUE_3);
242 
243     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_4, readValue), NOT_FOUND);
244     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_5, readValue), NOT_FOUND);
245 
246     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
247     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
248     g_junkFilesList.push_back(singleExportFileName);
249 }
250 
251 #ifndef OMIT_MULTI_VER
GetSnapshotUnitTest(KvStoreDelegate * & kvDelegatePtr,KvStoreSnapshotDelegate * & snapshotDelegatePtr)252 static void GetSnapshotUnitTest(KvStoreDelegate *&kvDelegatePtr, KvStoreSnapshotDelegate *&snapshotDelegatePtr)
253 {
254     DBStatus snapshotDelegateStatus = INVALID_ARGS;
255     auto snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
256         placeholders::_1, placeholders::_2, std::ref(snapshotDelegateStatus), std::ref(snapshotDelegatePtr));
257 
258     kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallback);
259     EXPECT_TRUE(snapshotDelegateStatus == OK);
260     ASSERT_TRUE(snapshotDelegatePtr != nullptr);
261 }
262 
263 /**
264   * @tc.name: UndisturbedlMultiExport001
265   * @tc.desc: Check that the export action is an independent transaction.
266   * @tc.type: FUNC
267   * @tc.require: AR000D4879
268   * @tc.author: sunpeng
269   */
270 HWTEST_F(DistributedDBInterfacesImportAndExportTest, UndisturbedlMultiExport001, TestSize.Level1)
271 {
272     std::string multiStoreId = "distributed_Exportmulit_001";
273     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
274     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
275     EXPECT_TRUE(g_kvDelegateStatus == OK);
276 
277     /**
278      * @tc.steps: step1. Three known data records are preset in the board database.
279      */
280     g_kvDelegatePtr->Put(KEY_1, VALUE_1);
281     g_kvDelegatePtr->Put(KEY_2, VALUE_2);
282     g_kvDelegatePtr->Put(KEY_3, VALUE_3);
283 
284     /**
285      * @tc.steps: step2. Execute the export action.
286      */
287     std::string mulitExportFileName = g_exportFileDir + "/UndisturbedlMultiExport001.$$";
288     CipherPassword passwd;
289     EXPECT_EQ(g_kvDelegatePtr->Export(mulitExportFileName, passwd), OK);
290 
291     /**
292      * @tc.steps: step3. Insert multiple new data records into the database.
293      */
294     g_kvDelegatePtr->Put(KEY_4, VALUE_4);
295     g_kvDelegatePtr->Put(KEY_5, VALUE_5);
296 
297     /**
298      * @tc.steps: step4.  Import backup data.
299      * @tc.expected: step4. Returns OK.
300      */
301     EXPECT_EQ(g_kvDelegatePtr->Import(mulitExportFileName, passwd), OK);
302 
303     KvStoreSnapshotDelegate *snapshotDelegatePtr = nullptr;
304     GetSnapshotUnitTest(g_kvDelegatePtr, snapshotDelegatePtr);
305     ASSERT_TRUE(snapshotDelegatePtr != nullptr);
306 
307     /**
308      * @tc.steps: step5. Check whether the imported data is the preset content in step 1.
309      * @tc.expected: step5. Three preset data records are found.
310      */
311     snapshotDelegatePtr->Get(KEY_1, g_valueCallback);
312     EXPECT_EQ(g_valueStatus, OK);
313     EXPECT_EQ(g_value, VALUE_1);
314     snapshotDelegatePtr->Get(KEY_2, g_valueCallback);
315     EXPECT_EQ(g_valueStatus, OK);
316     EXPECT_EQ(g_value, VALUE_2);
317     snapshotDelegatePtr->Get(KEY_3, g_valueCallback);
318     EXPECT_EQ(g_valueStatus, OK);
319     EXPECT_EQ(g_value, VALUE_3);
320 
321     snapshotDelegatePtr->Get(KEY_4, g_valueCallback);
322     EXPECT_EQ(g_valueStatus, NOT_FOUND);
323     snapshotDelegatePtr->Get(KEY_5, g_valueCallback);
324     EXPECT_EQ(g_valueStatus, NOT_FOUND);
325 
326     EXPECT_TRUE(g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotDelegatePtr) == OK);
327     snapshotDelegatePtr = nullptr;
328 
329     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
330     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
331     g_junkFilesList.push_back(mulitExportFileName);
332 }
333 #endif // OMIT_MULTI_VER
334 
335 /**
336   * @tc.name: ExportParameterCheck001
337   * @tc.desc: Check the verification of abnormal interface parameters.
338   * @tc.type: FUNC
339   * @tc.require: AR000D4879
340   * @tc.author: sunpeng
341   */
342 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ExportParameterCheck001, TestSize.Level1)
343 {
344     std::string singleStoreId = "distributed_ExportSingle_003";
345     KvStoreNbDelegate::Option option = {true, false, false};
346     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
347     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
348     EXPECT_TRUE(g_kvDelegateStatus == OK);
349 
350     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
351 
352     /**
353      * @tc.steps: step1. The filePath path does not exist.
354      * @tc.expected: step1. Return INVALID_ARGS.
355      */
356     std::string invalidFileName = g_exportFileDir + "/tempNotCreated/" + "/ExportParameterCheck001.$$";
357     CipherPassword passwd;
358     EXPECT_EQ(g_kvNbDelegatePtr->Export(invalidFileName, passwd), INVALID_ARGS);
359 
360     /**
361      * @tc.steps: step2. Password length MAX_PASSWD_SIZE + 1
362      * @tc.expected: step2. Return INVALID_ARGS.
363      */
364     vector<uint8_t> passwdBuffer(MAX_PASSWD_SIZE + 1, MAX_PASSWD_SIZE);
365     int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
366     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OVERSIZE);
367     /**
368      * @tc.steps: step3. Password length MAX_PASSWD_SIZE
369      * @tc.expected: step3. Return OK.
370      */
371     passwdBuffer.resize(MAX_PASSWD_SIZE, MAX_PASSWD_SIZE);
372     errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
373     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
374     std::string singleExportFileName = g_exportFileDir + "/ExportParameterCheck001.$$";
375     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
376     // Check export FILE_ALREADY_EXISTED
377     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), FILE_ALREADY_EXISTED);
378 
379     /**
380      * @tc.steps: step4. Delete the database.
381      */
382     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
383     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
384 
385     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
386     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
387     EXPECT_TRUE(g_kvDelegateStatus == OK);
388 
389     /**
390      * @tc.steps: step5. Use the password to import the file again,
391      * @tc.expected: step5. Return OK.
392      */
393     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
394     Value readValue;
395     g_kvNbDelegatePtr->Get(KEY_1, readValue);
396     EXPECT_EQ(readValue, VALUE_1);
397 
398     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
399     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
400     g_junkFilesList.push_back(singleExportFileName);
401 }
402 
403 #ifndef OMIT_MULTI_VER
404 /**
405   * @tc.name: ExportParameterCheck002
406   * @tc.desc: Check the verification of abnormal interface parameters.
407   * @tc.type: FUNC
408   * @tc.require: AR000D4879
409   * @tc.author: sunpeng
410   */
411 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ExportParameterCheck002, TestSize.Level1)
412 {
413     std::string multiStoreId = "distributed_ExportMulti_003";
414     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
415     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
416     EXPECT_TRUE(g_kvDelegateStatus == OK);
417 
418     g_kvDelegatePtr->Put(KEY_1, VALUE_1);
419 
420     /**
421      * @tc.steps: step1. The filePath path does not exist.
422      * @tc.expected: step1. Return INVALID_ARGS.
423      */
424     std::string invalidExportFileName = g_exportFileDir + "/tempNotCreated/" + "/ExportParameterCheck002.$$";
425     CipherPassword passwd;
426     EXPECT_EQ(g_kvDelegatePtr->Export(invalidExportFileName, passwd), INVALID_ARGS);
427 
428     /**
429      * @tc.steps: step2. Password length MAX_PASSWD_SIZE + 1
430      * @tc.expected: step2. Return INVALID_ARGS.
431      */
432     vector<uint8_t> passwdBuffer(MAX_PASSWD_SIZE + 1, MAX_PASSWD_SIZE);
433     int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
434     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OVERSIZE);
435     /**
436      * @tc.steps: step3. Password length MAX_PASSWD_SIZE
437      * @tc.expected: step3. Return OK.
438      */
439     passwdBuffer.resize(MAX_PASSWD_SIZE, MAX_PASSWD_SIZE);
440     errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
441     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
442     std::string multiExportFileName = g_exportFileDir + "/ExportParameterCheck002.$$";
443     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileName, passwd), OK);
444     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileName, passwd), FILE_ALREADY_EXISTED); // Check export INVALID_FILE
445 
446     /**
447      * @tc.steps: step4. Delete the database.
448      */
449     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
450     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
451 
452     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
453     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
454     EXPECT_TRUE(g_kvDelegateStatus == OK);
455 
456     /**
457      * @tc.steps: step5. Use the password to import the file again,
458      * @tc.expected: step5. Return OK.
459      */
460     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, passwd), OK);
461 
462     KvStoreSnapshotDelegate *snapshotDelegatePtr = nullptr;
463     GetSnapshotUnitTest(g_kvDelegatePtr, snapshotDelegatePtr);
464     ASSERT_TRUE(snapshotDelegatePtr != nullptr);
465 
466     snapshotDelegatePtr->Get(KEY_1, g_valueCallback);
467     EXPECT_EQ(g_valueStatus, OK);
468     EXPECT_EQ(g_value, VALUE_1);
469 
470     EXPECT_TRUE(g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotDelegatePtr) == OK);
471     snapshotDelegatePtr = nullptr;
472 
473     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
474     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
475     g_junkFilesList.push_back(multiExportFileName);
476 }
477 #endif // OMIT_MULTI_VER
478 
479 /**
480   * @tc.name: NormalImport001
481   * @tc.desc: Normal import capability for single version, parameter verification capability
482   * @tc.type: FUNC
483   * @tc.require: AR000D487A
484   * @tc.author: sunpeng
485   */
486 HWTEST_F(DistributedDBInterfacesImportAndExportTest, NormalImport001, TestSize.Level1)
487 {
488     std::string singleExportFileName = g_exportFileDir + "/NormalImport001.$$";
489     std::string singleStoreId = "distributed_Importmulti_001";
490     KvStoreNbDelegate::Option option = {true, false, false};
491     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
492     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
493     EXPECT_TRUE(g_kvDelegateStatus == OK);
494     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
495 
496     CipherPassword passwd;
497     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
498 
499     /**
500      * @tc.steps: step1. Import the invalid path.
501      * @tc.expected: step1. Return INVALID_ARGS.
502      */
503     std::string invalidPath = g_exportFileDir + "sdad" + "/NormalImport001.$$";
504     EXPECT_EQ(g_kvNbDelegatePtr->Import(invalidPath, passwd), INVALID_ARGS);
505 
506     /**
507      * @tc.steps: step2. Import an authorized path with an incorrect password.
508      * @tc.expected: step2. Return INVALID_FILE.
509      */
510     vector<uint8_t> passwdBuffer(MAX_PASSWD_SIZE, MAX_PASSWD_SIZE);
511     int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
512     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
513     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), INVALID_FILE);
514 
515     /**
516      * @tc.steps: step3. Import a permission path without a password.
517      * @tc.expected: step3. Return OK.
518      */
519     errCode = passwd.Clear();
520     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
521     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
522 
523     /**
524      * @tc.steps: step4. Check whether the data is the same as the backup database.
525      * @tc.expected: step4. Same database data.
526      */
527     Value readValue;
528     g_kvNbDelegatePtr->Get(KEY_1, readValue);
529     EXPECT_EQ(readValue, VALUE_1);
530 
531     // clear resource
532     g_junkFilesList.push_back(singleExportFileName);
533     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
534     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
535 }
536 
537 #ifndef OMIT_MULTI_VER
538 /**
539   * @tc.name: NormalImport002
540   * @tc.desc: Normal import capability for multi version, parameter verification capability
541   * @tc.type: FUNC
542   * @tc.require: AR000D487A
543   * @tc.author: sunpeng
544   */
545 HWTEST_F(DistributedDBInterfacesImportAndExportTest, NormalImport002, TestSize.Level1)
546 {
547     std::string multiExportFileName = g_exportFileDir + "/NormalImport002.$$";
548     std::string multiStoreId = "distributed_ImportSingle_002";
549     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
550     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
551     EXPECT_TRUE(g_kvDelegateStatus == OK);
552     g_kvDelegatePtr->Put(KEY_1, VALUE_1);
553 
554     CipherPassword passwd;
555     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileName, passwd), OK);
556 
557     /**
558      * @tc.steps: step1. Import the invalid path.
559      * @tc.expected: step1. Return INVALID_ARGS.
560      */
561     std::string invalidPath = g_exportFileDir + "sdad" + "/NormalImport002.$$";
562     EXPECT_EQ(g_kvDelegatePtr->Import(invalidPath, passwd), INVALID_ARGS);
563 
564     /**
565      * @tc.steps: step2. Import an authorized path with an incorrect password.
566      * @tc.expected: step2. Return INVALID_FILE.
567      */
568     vector<uint8_t> passwdBuffer(MAX_PASSWD_SIZE, MAX_PASSWD_SIZE);
569     int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
570     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
571     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, passwd), INVALID_FILE);
572 
573     g_kvDelegatePtr->Delete(KEY_1);
574     /**
575      * @tc.steps: step3. Import a permission path without a password.
576      * @tc.expected: step3. Return OK.
577      */
578     errCode = passwd.Clear();
579     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
580     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, passwd), OK);
581 
582     KvStoreSnapshotDelegate *snapshotDelegatePtr = nullptr;
583     GetSnapshotUnitTest(g_kvDelegatePtr, snapshotDelegatePtr);
584     ASSERT_TRUE(snapshotDelegatePtr != nullptr);
585 
586     /**
587      * @tc.steps: step4. Check whether the data is the same as the backup database.
588      * @tc.expected: step4. Same database data.
589      */
590     snapshotDelegatePtr->Get(KEY_1, g_valueCallback);
591     EXPECT_EQ(g_valueStatus, OK);
592     EXPECT_EQ(g_value, VALUE_1);
593 
594     EXPECT_TRUE(g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotDelegatePtr) == OK);
595     snapshotDelegatePtr = nullptr;
596 
597     // clear resource
598     g_junkFilesList.push_back(multiExportFileName);
599     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
600     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
601 }
602 #endif // OMIT_MULTI_VER
603 
604 /**
605   * @tc.name: ExceptionFileImport001
606   * @tc.desc: Normal import capability for single version, parameter verification capability
607   * @tc.type: FUNC
608   * @tc.require: AR000D487A
609   * @tc.author: sunpeng
610   */
611 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ExceptionFileImport001, TestSize.Level1)
612 {
613     std::string singleExportFileName = g_exportFileDir + "/ExceptionFileImport001.$$";
614     std::string singleStoreId = "distributed_ImportExceptionsigle_001";
615     KvStoreNbDelegate::Option option = {true, false, false};
616     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
617     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
618     EXPECT_TRUE(g_kvDelegateStatus == OK);
619     g_kvNbDelegatePtr->Put(KEY_2, VALUE_2);
620 
621     CipherPassword passwd;
622     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
623 
624     /**
625      * @tc.steps: step1. Repeat import backup file to same database.
626      * @tc.expected: step1. Return OK.
627      */
628     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
629     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
630 
631     /**
632      * @tc.steps: step2. Change the name of file1 to file2.
633      */
634     std::string newSingleExportFileName = g_exportFileDir + "/newExceptionFileImport001.$$";
635     EXPECT_EQ(rename(singleExportFileName.c_str(), newSingleExportFileName.c_str()), 0);
636 
637     /**
638      * @tc.steps: step3. Import file1 into the database.
639      * @tc.expected: step3. Return INVALID_FILE.
640      */
641     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), INVALID_FILE);
642 
643     /**
644      * @tc.steps: step4. Import file2 into the database.
645      * @tc.expected: step4. Return INVALID_FILE.
646      */
647     EXPECT_EQ(g_kvNbDelegatePtr->Import(newSingleExportFileName, passwd), OK);
648 
649     // clear resource
650     g_junkFilesList.push_back(singleExportFileName);
651     g_junkFilesList.push_back(newSingleExportFileName);
652     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
653     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
654 }
655 
656 #ifndef OMIT_MULTI_VER
657 /**
658   * @tc.name: ExceptionFileImport002
659   * @tc.desc: Normal import capability for multi version, parameter verification capability
660   * @tc.type: FUNC
661   * @tc.require: AR000D487A
662   * @tc.author: sunpeng
663   */
664 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ExceptionFileImport002, TestSize.Level1)
665 {
666     std::string multiExportFileName = g_exportFileDir + "/ExceptionFileImport002.$$";
667     std::string multiStoreId = "distributed_ImportExceptionMulti_001";
668     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
669     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
670     EXPECT_TRUE(g_kvDelegateStatus == OK);
671     g_kvDelegatePtr->Put(KEY_1, VALUE_1);
672 
673     CipherPassword passwd;
674     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileName, passwd), OK);
675 
676     /**
677      * @tc.steps: step1. Import the backup file that has been tampered with to the multi-version database.
678      * @tc.expected: step1. Return INVALID_FILE.
679      */
680     EXPECT_EQ(DistributedDBToolsUnitTest::ModifyDatabaseFile(multiExportFileName), 0);
681     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, passwd), INVALID_FILE);
682 
683     // clear resource
684     g_junkFilesList.push_back(multiExportFileName);
685     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
686     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
687 }
688 
689 /**
690   * @tc.name: ExceptionFileImport003
691   * @tc.desc: The data of the current version of the board is exported and the package file is single.
692   * @tc.type: FUNC
693   * @tc.require: AR000D487A
694   * @tc.author: sunpeng
695   */
696 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ExceptionFileImport003, TestSize.Level1)
697 {
698     std::string singleExportFileName = g_exportFileDir + "/singleExceptionFileImport003.$$";
699     std::string singleStoreId = "distributed_ExportSingle_001";
700     KvStoreNbDelegate::Option option = {true, false, false};
701     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
702     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
703     EXPECT_TRUE(g_kvDelegateStatus == OK);
704 
705     CipherPassword passwd;
706     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
707 
708     std::string mulitExportFileName = g_exportFileDir + "/mulitExceptionFileImport003.$$";
709     std::string multiStoreId = "distributed_ExportMulit_001";
710     g_mgr.GetKvStore(multiStoreId, g_option, g_kvDelegateCallback);
711     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
712     EXPECT_TRUE(g_kvDelegateStatus == OK);
713     EXPECT_EQ(g_kvDelegatePtr->Export(mulitExportFileName, passwd), OK);
714 
715     /**
716      * @tc.steps: step1. Use the single ver import interface. The file path is a multi-version backup file.
717      * @tc.expected: step1. Return INVALID_FILE.
718      */
719     EXPECT_EQ(g_kvNbDelegatePtr->Import(mulitExportFileName, passwd), INVALID_FILE);
720 
721     /**
722      * @tc.steps: step2.  Use the single ver import interface. The file path is a single-version backup file.
723      * @tc.expected: step2. Return OK.
724      */
725     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
726 
727     /**
728      * @tc.steps: step3.  Use the multi-version import interface. The file path is a single-version backup file.
729      * @tc.expected: step3. Return INVALID_FILE.
730      */
731     EXPECT_EQ(g_kvDelegatePtr->Import(singleExportFileName, passwd), INVALID_FILE);
732 
733     /**
734      * @tc.steps: step4.  Use the multi-version import interface. The file path is a multi-version backup file.
735      * @tc.expected: step4. Return INVALID_FILE.
736      */
737     EXPECT_EQ(g_kvDelegatePtr->Import(mulitExportFileName, passwd), OK);
738 
739     // clear resource
740     g_junkFilesList.push_back(singleExportFileName);
741     g_junkFilesList.push_back(mulitExportFileName);
742     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
743     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
744     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
745     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
746 }
747 #endif // OMIT_MULTI_VER
748 
749 /**
750   * @tc.name: ExceptionFileImport004
751   * @tc.desc: The data of the current version of the board is exported and the package file is single.
752   * @tc.type: FUNC
753   * @tc.require: AR000D487A
754   * @tc.author: sunpeng
755   */
756 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ExceptionFileImport004, TestSize.Level1)
757 {
758     std::string singleExportFileName = g_exportFileDir + "/singleExceptionFileImport004.$$";
759     std::string singleStoreId = "distributed_ExportSingle_004";
760     KvStoreNbDelegate::Option option = {true, false, true, CipherType::DEFAULT, g_passwd1};
761     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
762     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
763     ASSERT_TRUE(g_kvDelegateStatus == OK);
764 
765     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, g_passwd2), OK);
766 
767     std::string mulitExportFileName = g_exportFileDir + "/mulitExceptionFileImport004.$$";
768     std::string multiStoreId = "distributed_ExportMulit_004";
769 #ifndef OMIT_MULTI_VER
770     KvStoreDelegate::Option multiOption = {true, false, true, CipherType::DEFAULT, g_passwd1};
771     g_mgr.GetKvStore(multiStoreId, multiOption, g_kvDelegateCallback);
772     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
773     EXPECT_EQ(g_kvDelegateStatus, OK);
774     EXPECT_EQ(g_kvDelegatePtr->Export(mulitExportFileName, g_passwd2), OK);
775 #endif // OMIT_MULTI_VER
776     /**
777      * @tc.steps: step1. Use the diff passwd, try to import database.
778      */
779     CipherPassword passwd;
780     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), INVALID_FILE);
781     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, g_passwd1), INVALID_FILE);
782     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, g_passwd2), OK);
783 #ifndef OMIT_MULTI_VER
784     EXPECT_EQ(g_kvDelegatePtr->Import(mulitExportFileName, passwd), INVALID_FILE);
785     EXPECT_EQ(g_kvDelegatePtr->Import(mulitExportFileName, g_passwd1), INVALID_FILE);
786     EXPECT_EQ(g_kvDelegatePtr->Import(mulitExportFileName, g_passwd2), OK);
787 
788     // clear resource
789     g_junkFilesList.push_back(mulitExportFileName);
790     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
791     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
792 #endif // OMIT_MULTI_VER
793     g_junkFilesList.push_back(singleExportFileName);
794     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
795     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
796 }
797 
TryDbForPasswordIndependence001()798 static void TryDbForPasswordIndependence001()
799 {
800     std::string singleStoreIdNoPasswd = "distributed_ExportSingle_005";
801     std::string singleStoreId = "distributed_ExportSingle_006";
802 
803     /**
804      * @tc.steps: step4. Run the p3 command to open the database db1.
805      * @tc.expected: step4. Return ERROR.
806      */
807     KvStoreNbDelegate::Option option = {true, false, true, CipherType::DEFAULT, g_passwd3};
808     g_mgr.GetKvStore(singleStoreIdNoPasswd, option, g_kvNbDelegateCallback);
809     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
810     EXPECT_NE(g_kvDelegateStatus, OK);
811 
812     /**
813      * @tc.steps: step5. Run the p4 command to open the database db2.
814      * @tc.expected: step5. Return ERROR.
815      */
816     option = {true, false, true, CipherType::DEFAULT, g_passwd4};
817     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
818     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
819     ASSERT_TRUE(g_kvDelegateStatus != OK);
820 
821     /**
822      * @tc.steps: step6. Open the db1 directly.
823      * @tc.expected: step6. Return OK.
824      */
825     option = {true, false, false, CipherType::DEFAULT, g_passwd3};
826     g_mgr.GetKvStore(singleStoreIdNoPasswd, option, g_kvNbDelegateCallback);
827     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
828     ASSERT_TRUE(g_kvDelegateStatus == OK);
829     g_kvNbDelegatePtrWithoutPasswd = g_kvNbDelegatePtr;
830 
831     /**
832      * @tc.steps: step7. Open the db1 directly
833      * @tc.expected: step7. Return ERROR.
834      */
835     option = {true, false, false, CipherType::DEFAULT, g_passwd3};
836     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
837     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
838     ASSERT_TRUE(g_kvDelegateStatus != OK);
839 
840     /**
841      * @tc.steps: step8. Run the p2 command to open the db2 file.
842      * @tc.expected: step8. Return ERROR.
843      */
844     option = {true, false, true, CipherType::DEFAULT, g_passwd2};
845     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
846     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
847     ASSERT_TRUE(g_kvDelegateStatus == OK);
848 }
849 
850 /**
851   * @tc.name: PasswordIndependence001
852   * @tc.desc: The data of the current version of the board is exported and the package file is single.
853   * @tc.type: FUNC
854   * @tc.require: AR000D487B
855   * @tc.author: sunpeng
856   */
857 HWTEST_F(DistributedDBInterfacesImportAndExportTest, PasswordIndependence001, TestSize.Level1)
858 {
859     /**
860      * @tc.steps: step1. Back up a single database db1 No password backup password p3
861      */
862     std::string singleExportFileNameNoPasswd = g_exportFileDir + "/singleNoPasswdIndependence001.$$";
863     std::string singleStoreIdNoPasswd = "distributed_ExportSingle_005";
864     KvStoreNbDelegate::Option option = {true, false, false};
865     g_mgr.GetKvStore(singleStoreIdNoPasswd, option, g_kvNbDelegateCallback);
866     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
867     EXPECT_TRUE(g_kvDelegateStatus == OK);
868     g_kvNbDelegatePtrWithoutPasswd = g_kvNbDelegatePtr;
869 
870     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileNameNoPasswd, g_passwd3), OK);
871 
872     /**
873      * @tc.steps: step2. Back up the database of the single version db2 Password p2 Backup file password p4
874      */
875     std::string singleExportFileName = g_exportFileDir + "/singleIndependence001.$$";
876     std::string singleStoreId = "distributed_ExportSingle_006";
877     option = {true, false, true, CipherType::DEFAULT, g_passwd2};
878     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
879     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
880     ASSERT_TRUE(g_kvDelegateStatus == OK);
881 
882     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, g_passwd4), OK);
883 
884     /**
885      * @tc.steps: step3. Recover the backup file.
886      */
887     EXPECT_EQ(g_kvNbDelegatePtrWithoutPasswd->Import(singleExportFileNameNoPasswd, g_passwd3), OK);
888     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, g_passwd4), OK);
889 
890     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtrWithoutPasswd), OK);
891     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
892 
893     (void)TryDbForPasswordIndependence001();
894 
895     // clear resource
896     g_junkFilesList.push_back(singleExportFileName);
897     g_junkFilesList.push_back(singleExportFileNameNoPasswd);
898     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
899     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
900     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtrWithoutPasswd), OK);
901     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreIdNoPasswd), OK);
902 }
903 
904 #ifndef OMIT_MULTI_VER
TryDbForPasswordIndependence002()905 static void TryDbForPasswordIndependence002()
906 {
907     std::string multiStoreIdNoPasswd = "distributed_ExportMulti_007";
908     std::string multiStoreId = "distributed_ExportMulti_008";
909 
910     KvStoreDelegate::Option option = {true, false, true, CipherType::DEFAULT, g_passwd3};
911     g_mgr.GetKvStore(multiStoreIdNoPasswd, option, g_kvDelegateCallback);
912     ASSERT_TRUE(g_kvDelegatePtr == nullptr);
913     ASSERT_TRUE(g_kvDelegateStatus != OK);
914 
915     option = {true, false, true, CipherType::DEFAULT, g_passwd4};
916     g_mgr.GetKvStore(multiStoreId, option, g_kvDelegateCallback);
917     ASSERT_TRUE(g_kvDelegatePtr == nullptr);
918     ASSERT_TRUE(g_kvDelegateStatus != OK);
919 
920     option = {true, false, false, CipherType::DEFAULT, g_passwd3};
921     g_mgr.GetKvStore(multiStoreIdNoPasswd, option, g_kvDelegateCallback);
922     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
923     ASSERT_TRUE(g_kvDelegateStatus == OK);
924     g_kvDelegatePtrWithoutPasswd = g_kvDelegatePtr;
925 
926     option = {true, false, false, CipherType::DEFAULT, g_passwd3};
927     g_mgr.GetKvStore(multiStoreId, option, g_kvDelegateCallback);
928     ASSERT_TRUE(g_kvDelegatePtr == nullptr);
929     ASSERT_TRUE(g_kvDelegateStatus != OK);
930 
931     option = {true, false, true, CipherType::DEFAULT, g_passwd2};
932     g_mgr.GetKvStore(multiStoreId, option, g_kvDelegateCallback);
933     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
934     ASSERT_TRUE(g_kvDelegateStatus == OK);
935 }
936 
937 /**
938   * @tc.name: PasswordIndependence002
939   * @tc.desc: The data of the current version of the board is exported and the package file is single.
940   * @tc.type: FUNC
941   * @tc.require: AR000D487B
942   * @tc.author: sunpeng
943   */
944 HWTEST_F(DistributedDBInterfacesImportAndExportTest, PasswordIndependence002, TestSize.Level1)
945 {
946     /**
947      * @tc.steps: step1. Back up a single database db1 No password backup password p3
948      */
949     std::string multiExportFileNameNoPasswd = g_exportFileDir + "/multiNoPasswdIndependence001.$$";
950     std::string multiStoreIdNoPasswd = "distributed_ExportMulti_007";
951     KvStoreDelegate::Option option;
952     g_mgr.GetKvStore(multiStoreIdNoPasswd, option, g_kvDelegateCallback);
953     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
954     EXPECT_TRUE(g_kvDelegateStatus == OK);
955     g_kvDelegatePtrWithoutPasswd = g_kvDelegatePtr;
956 
957     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileNameNoPasswd, g_passwd3), OK);
958 
959     /**
960      * @tc.steps: step2. Back up the database of the single version db2 Password p2 Backup file password p4
961      */
962     std::string multiExportFileName = g_exportFileDir + "/multiIndependence001.$$";
963     std::string multiStoreId = "distributed_ExportMulti_008";
964     option = {true, false, true, CipherType::DEFAULT, g_passwd2};
965     g_mgr.GetKvStore(multiStoreId, option, g_kvDelegateCallback);
966     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
967     ASSERT_TRUE(g_kvDelegateStatus == OK);
968 
969     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileName, g_passwd4), OK);
970 
971     /**
972      * @tc.steps: step3. Recover the backup file.
973      */
974     EXPECT_EQ(g_kvDelegatePtrWithoutPasswd->Import(multiExportFileNameNoPasswd, g_passwd3), OK);
975     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, g_passwd4), OK);
976 
977     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtrWithoutPasswd), OK);
978     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
979 
980     /**
981      * @tc.steps: step4. Try diff passwd.
982      */
983     (void)TryDbForPasswordIndependence002();
984 
985     // clear resource
986     g_junkFilesList.push_back(multiExportFileName);
987     g_junkFilesList.push_back(multiExportFileNameNoPasswd);
988     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
989     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
990     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtrWithoutPasswd), OK);
991     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreIdNoPasswd), OK);
992 }
993 #endif // OMIT_MULTI_VER
994 
995 /**
996   * @tc.name: PasswordIndependence002
997   * @tc.desc: The data of the current version of the board is exported and the package file is single.
998   * @tc.type: FUNC
999   * @tc.require: AR000D487B
1000   * @tc.author: sunpeng
1001   */
1002 HWTEST_F(DistributedDBInterfacesImportAndExportTest, PasswordIndependence003, TestSize.Level1)
1003 {
1004     /**
1005      * @tc.steps: step1. Back up the (passwd1) encryption single-version (passwd2) database.
1006      */
1007     std::string singleExportFileName = g_exportFileDir + "/singleIndependence003.$$";
1008     std::string singleStoreId = "distributed_ExportSingle_009";
1009     KvStoreNbDelegate::Option option = {true, false, true, CipherType::DEFAULT, g_passwd2};
1010     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
1011     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1012     ASSERT_TRUE(g_kvDelegateStatus == OK);
1013 
1014     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, g_passwd1), OK);
1015 
1016     /**
1017      * @tc.steps: step2. Rekey The password by passwd3
1018      */
1019     g_kvNbDelegatePtr->Rekey(g_passwd3);
1020 
1021     /**
1022      * @tc.steps: step3. Import the database using passwd3.
1023      * @tc.expected: step3. Return INVALID_FILE.
1024      */
1025     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, g_passwd3), INVALID_FILE);
1026 
1027     /**
1028      * @tc.steps: step4. Import the database using passwd1.
1029      * @tc.expected: step4. Return OK.
1030      */
1031     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, g_passwd1), OK);
1032 
1033 #ifndef OMIT_MULTI_VER
1034     /**
1035      * @tc.steps: step5. Repeat step 1 - 4.
1036      */
1037     std::string multiExportFileName = g_exportFileDir + "/multiIndependence003.$$";
1038     std::string multiStoreId = "distributed_ExportMulti_010";
1039     KvStoreDelegate::Option multiOption = {true, false, true, CipherType::DEFAULT, g_passwd2};
1040     g_mgr.GetKvStore(multiStoreId, multiOption, g_kvDelegateCallback);
1041     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
1042     ASSERT_TRUE(g_kvDelegateStatus == OK);
1043 
1044     EXPECT_EQ(g_kvDelegatePtr->Export(multiExportFileName, g_passwd1), OK);
1045 
1046     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, g_passwd3), INVALID_FILE);
1047     EXPECT_EQ(g_kvDelegatePtr->Import(multiExportFileName, g_passwd1), OK);
1048 
1049     // clear resource
1050     g_junkFilesList.push_back(multiExportFileName);
1051     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
1052     EXPECT_EQ(g_mgr.DeleteKvStore(multiStoreId), OK);
1053 #endif // OMIT_MULTI_VER
1054     g_junkFilesList.push_back(singleExportFileName);
1055     remove(singleExportFileName.c_str());
1056     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1057     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
1058 }
1059 
1060 /**
1061   * @tc.name: SeparaDbExportAndImport
1062   * @tc.desc: Import and export after Separate database.
1063   * @tc.type: FUNC
1064   * @tc.require: AR000D487B
1065   * @tc.author: sunpeng
1066   */
1067 HWTEST_F(DistributedDBInterfacesImportAndExportTest, SeparaDbExportAndImport, TestSize.Level1)
1068 {
1069     std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
1070     EXPECT_TRUE(adapter != nullptr);
1071     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(adapter);
1072 
1073     std::string singleExportFileName = g_exportFileDir + "/SeparaDbExportAndImport.$$";
1074     std::string singleStoreId = "distributed_ExportSingle_010";
1075     KvStoreNbDelegate::Option option = {true, false, false};
1076     SecurityOption secOption{SecurityLabel::S3, SecurityFlag::SECE};
1077     option.secOption = secOption;
1078 
1079     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
1080     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1081     EXPECT_EQ(g_kvDelegateStatus, OK);
1082 
1083     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
1084 
1085     CipherPassword passwd;
1086     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
1087 
1088     g_kvNbDelegatePtr->Put(KEY_2, VALUE_2);
1089 
1090     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleExportFileName, passwd), OK);
1091     Value valueRead;
1092     g_kvNbDelegatePtr->Get(KEY_2, valueRead);
1093     EXPECT_EQ(valueRead, Value());
1094     g_kvNbDelegatePtr->Get(KEY_1, valueRead);
1095     EXPECT_EQ(valueRead, VALUE_1);
1096     g_kvNbDelegatePtr->Put(KEY_3, VALUE_3);
1097 
1098     EXPECT_EQ(g_kvNbDelegatePtr->Rekey(g_passwd1), OK);
1099     g_kvNbDelegatePtr->Get(KEY_3, valueRead);
1100     EXPECT_EQ(valueRead, VALUE_3);
1101 
1102     // clear resource
1103     g_junkFilesList.push_back(singleExportFileName);
1104 
1105     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1106     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
1107     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
1108 
1109     option.passwd = g_passwd1;
1110     option.isEncryptedDb = true;
1111     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
1112     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1113     EXPECT_EQ(g_kvDelegateStatus, OK);
1114 
1115     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1116     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
1117 }
1118 
1119 /**
1120   * @tc.name: SeparaDbExportAndImport
1121   * @tc.desc: Import and export after Separate database.
1122   * @tc.type: FUNC
1123   * @tc.require: AR000D487B
1124   * @tc.author: sunpeng
1125   */
1126 HWTEST_F(DistributedDBInterfacesImportAndExportTest, SeparaDbNoPasswdRekey, TestSize.Level1)
1127 {
1128     std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
1129     EXPECT_TRUE(adapter != nullptr);
1130     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(adapter);
1131 
1132     KvStoreNbDelegate::Option option = {true, false, true};
1133     SecurityOption secOption{SecurityLabel::S3, SecurityFlag::SECE};
1134     option.secOption = secOption;
1135     option.passwd = g_passwd1;
1136     g_mgr.GetKvStore("SeparaDbNoPasswdRekey", option, g_kvNbDelegateCallback);
1137     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1138 
1139     EXPECT_EQ(g_kvDelegateStatus, OK);
1140     EXPECT_EQ(g_kvNbDelegatePtr->Rekey(g_passwd2), OK);
1141 
1142     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1143     option.passwd = g_passwd2;
1144     g_mgr.GetKvStore("SeparaDbNoPasswdRekey", option, g_kvNbDelegateCallback);
1145     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1146 
1147     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1148     EXPECT_EQ(g_mgr.DeleteKvStore("SeparaDbNoPasswdRekey"), OK);
1149 }
1150 
1151 /**
1152   * @tc.name: ForceExportTest001
1153   * @tc.desc: Force export to an existing file.
1154   * @tc.type: FUNC
1155   * @tc.require:
1156   * @tc.author: lianhuix
1157   */
1158 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ForceExportTest001, TestSize.Level1)
1159 {
1160     KvStoreNbDelegate::Option option = {true, false, false};
1161     g_mgr.GetKvStore("ForceExportTest001", option, g_kvNbDelegateCallback);
1162     EXPECT_EQ(g_kvDelegateStatus, OK);
1163     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1164 
1165     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
1166 
1167     CipherPassword passwd;
1168     std::string exportFileName = g_exportFileDir + "ForceExportTest001.back";
1169 
1170     int fd = open(exportFileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP));
1171     ASSERT_TRUE(fd >= 0);
1172     std::string text = "Hello world.";
1173     write(fd, text.c_str(), text.length());
1174     close(fd);
1175 
1176     chmod(exportFileName.c_str(), S_IRWXU);
1177     EXPECT_EQ(g_kvNbDelegatePtr->Export(exportFileName, passwd, true), OK);
1178 
1179     uint32_t filePermission = 0;
1180     struct stat fileStat;
1181     EXPECT_EQ(stat(exportFileName.c_str(), &fileStat), 0);
1182     filePermission = fileStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
1183     EXPECT_EQ(filePermission, static_cast<uint32_t>(S_IRWXU));
1184 
1185     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1186     g_kvNbDelegatePtr = nullptr;
1187     EXPECT_EQ(g_mgr.DeleteKvStore("ForceExportTest001"), OK);
1188 
1189     g_mgr.GetKvStore(STORE_ID_1, option, g_kvNbDelegateCallback);
1190     EXPECT_EQ(g_kvDelegateStatus, OK);
1191     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1192 
1193     EXPECT_EQ(g_kvNbDelegatePtr->Import(exportFileName, passwd), OK);
1194     Value val;
1195     g_kvNbDelegatePtr->Get(KEY_1, val);
1196     EXPECT_EQ(val, VALUE_1);
1197 
1198     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1199     g_kvNbDelegatePtr = nullptr;
1200     EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID_1), OK);
1201 }
1202 
1203 /**
1204   * @tc.name: ImportWithTimeChange001
1205   * @tc.desc: Import DB after time changed.
1206   * @tc.type: FUNC
1207   * @tc.require:
1208   * @tc.author: lianhuix
1209   */
1210 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ImportWithTimeChange001, TestSize.Level1)
1211 {
1212     KvStoreNbDelegate::Option option = {true, false, false};
1213     std::string storeId = "ImportWithTimeChange001";
1214     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
1215     EXPECT_EQ(g_kvDelegateStatus, OK);
1216     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1217 
1218     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
1219 
1220     // fake entry timestamp
1221     std::string origId = USER_ID + "-" + APP_ID + "-" + storeId;
1222     std::string identifier = DBCommon::TransferHashString(origId);
1223     std::string hexDir = DBCommon::TransferStringToHex(identifier);
1224     std::string dbPath = g_testDir + "/" + hexDir + "/single_ver/main/gen_natural_store.db";
1225     sqlite3 *db = RelationalTestUtils::CreateDataBase(dbPath);
1226     ASSERT_NE(db, nullptr);
1227     std::string fakeSql = "UPDATE sync_data SET timestamp = 3270281552768731970, w_timestamp = 3270281552768731970";
1228     EXPECT_EQ(RelationalTestUtils::ExecSql(db, fakeSql), E_OK);
1229     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1230     db = nullptr;
1231 
1232     // prepare import file with timestamp later then current
1233     CipherPassword passwd;
1234     std::string exportFileName = g_exportFileDir + storeId + ".back";
1235     EXPECT_EQ(g_kvNbDelegatePtr->Export(exportFileName, passwd, true), OK);
1236 
1237     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1238     g_kvNbDelegatePtr = nullptr;
1239     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
1240 
1241     // import
1242     g_mgr.GetKvStore(STORE_ID_1, option, g_kvNbDelegateCallback);
1243     EXPECT_EQ(g_kvDelegateStatus, OK);
1244     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1245 
1246     EXPECT_EQ(g_kvNbDelegatePtr->Import(exportFileName, passwd), OK);
1247 
1248     // check crud normal
1249     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY_1), OK);
1250     Value val;
1251     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_1, val), NOT_FOUND);
1252 
1253     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_2), OK);
1254     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_2, val), OK);
1255 
1256     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1257     g_kvNbDelegatePtr = nullptr;
1258     EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID_1), OK);
1259 }
1260 
1261 /**
1262   * @tc.name: abortHandle001
1263   * @tc.desc: Intercept obtaining new write handles during Import.
1264   * @tc.type: FUNC
1265   * @tc.require:
1266   * @tc.author: bty
1267   */
1268 HWTEST_F(DistributedDBInterfacesImportAndExportTest, abortHandle001, TestSize.Level1)
1269 {
1270     std::string singleStoreId = "ExportAbortHandle_001";
1271     KvStoreNbDelegate::Option option = {true, false, false};
1272     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
1273     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1274     EXPECT_TRUE(g_kvDelegateStatus == OK);
1275 
1276     /**
1277      * @tc.steps: step1. Init data for export.
1278      */
1279     std::string str(1024, 'k');
1280     Value value(str.begin(), str.end());
1281     for (int i = 0; i < 1000; ++i) {
1282         Key key;
1283         DBCommon::StringToVector(std::to_string(i), key);
1284         g_kvNbDelegatePtr->Put(key, value);
1285     }
1286 
1287     /**
1288      * @tc.steps: step2. Execute the export action.
1289      */
1290     std::string singleExportFileName = g_exportFileDir + "/UnExportAbortHandle001.$$";
1291     CipherPassword passwd;
1292     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleExportFileName, passwd), OK);
1293 
1294     /**
1295      * @tc.steps: step3. Multi threads to occupy write handles.
1296      */
1297     for (int i = 0; i < 10; ++i) { // 10 is run times
1298         vector<thread> threads;
__anon906019a80202() 1299         threads.emplace_back(thread([&]() {
1300             g_kvNbDelegatePtr->CheckIntegrity();
1301         }));
1302         threads.emplace_back(&KvStoreNbDelegate::Import, g_kvNbDelegatePtr, singleExportFileName, passwd);
__anon906019a80302() 1303         threads.emplace_back(thread([&i]() {
1304             std::this_thread::sleep_for(std::chrono::milliseconds(i));
1305             g_kvNbDelegatePtr->CheckIntegrity();
1306         }));
1307         for (auto &th: threads) {
1308             th.join();
1309         }
1310     }
1311     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1312     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
1313     g_junkFilesList.push_back(singleExportFileName);
1314 }
1315 
1316 /**
1317   * @tc.name: ImportTest001
1318   * @tc.desc: Verify that it will allow to import backup file again during it is importing.
1319   * @tc.type: FUNC
1320   * @tc.require:
1321   * @tc.author: chenguoliang
1322   */
1323 HWTEST_F(DistributedDBInterfacesImportAndExportTest, ImportTest001, TestSize.Level1)
1324 {
1325     /**
1326      * @tc.steps: step1. Pre-create folder dir
1327      */
1328     std::string singleFileName = g_exportFileDir + "/ImportTest001.$$";
1329     std::string singleStoreId = "distributed_ImportSingle_001";
1330     KvStoreNbDelegate::Option option = {true, false, false};
1331     g_mgr.GetKvStore(singleStoreId, option, g_kvNbDelegateCallback);
1332 
1333     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1334     EXPECT_TRUE(g_kvDelegateStatus == OK);
1335 
1336     /**
1337      * @tc.steps: step2. Specify the path to export the non-encrypted board database.
1338      * @tc.expected: step2. Returns OK
1339      */
1340     CipherPassword passwd;
1341     EXPECT_EQ(g_kvNbDelegatePtr->Export(singleFileName, passwd), OK);
1342 
1343     /**
1344      * @tc.steps: step3. start subthread to import the backup file.
1345      * @tc.expected: step3. start successfully.
1346      */
1347     std::atomic<bool> readyFlag(false);
1348     readyFlag.store(false);
1349     std::condition_variable backupVar;
__anon906019a80402() 1350     thread subThread([&singleFileName, &passwd, &readyFlag, &backupVar]() {
1351         EXPECT_EQ(g_kvNbDelegatePtr->Import(singleFileName, passwd), OK);
1352         readyFlag.store(true);
1353         backupVar.notify_one();
1354     });
1355     subThread.detach();
1356 
1357     /**
1358      * @tc.steps: step4. import the backup file during the subthread is importing with empty password.
1359      * @tc.expected: step4. import successfully and return OK.
1360      */
1361     const static int millsecondsPerSecond = 1000;
1362     std::this_thread::sleep_for(std::chrono::microseconds(millsecondsPerSecond));
1363     EXPECT_EQ(g_kvNbDelegatePtr->Import(singleFileName, passwd), OK);
1364 
1365     std::mutex rekeyMtx;
1366     std::unique_lock<std::mutex> lck(rekeyMtx);
__anon906019a80502null1367     backupVar.wait(lck, [&]{ return readyFlag.load(); });
1368 
1369     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1370     EXPECT_EQ(g_mgr.DeleteKvStore(singleStoreId), OK);
1371 }
1372 #endif // OMIT_ENCRYPT
1373