• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <gtest/gtest.h>
17 
18 #include "db_common.h"
19 #include "distributeddb_storage_single_ver_natural_store_testcase.h"
20 #include "process_system_api_adapter_impl.h"
21 #include "single_ver_utils.h"
22 #include "storage_engine_manager.h"
23 #include "virtual_sqlite_storage_engine.h"
24 
25 using namespace testing::ext;
26 using namespace DistributedDB;
27 using namespace DistributedDBUnitTest;
28 using namespace std;
29 
30 namespace {
31     string g_testDir;
32     string g_databaseName;
33     string g_identifier;
34     string g_cacheDir;
35     KvDBProperties g_property;
36 
37     SQLiteSingleVerNaturalStore *g_store = nullptr;
38     SQLiteSingleVerNaturalStoreConnection *g_connection = nullptr;
39 
40     const char * const ADD_SYNC = "ALTER TABLE sync_data ADD column version INT";
41     const char * const INSERT_SQL = "INSERT INTO sync_data VALUES('a', 'b', 1, 2, '', '', 'efdef', 100 , 1, 0, 0);";
42     const int SQL_STATE_ERR = -1;
43 
CopyCacheDb()44     void CopyCacheDb()
45     {
46         EXPECT_EQ(DBCommon::CopyFile(g_testDir + g_databaseName, g_cacheDir), E_OK);
47         EXPECT_EQ(DBCommon::CopyFile(g_testDir + g_databaseName + "-wal", g_cacheDir + "-wal"), E_OK);
48     }
49 
GetStorageEngine(SQLiteSingleVerStorageEngine * & storageEngine)50     void GetStorageEngine(SQLiteSingleVerStorageEngine *&storageEngine)
51     {
52         int errCode;
53         storageEngine =
54             static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
55         EXPECT_EQ(errCode, E_OK);
56     }
57 
PrepareEnv()58     void PrepareEnv()
59     {
60         sqlite3 *db;
61         ASSERT_TRUE(sqlite3_open_v2((g_testDir + g_databaseName).c_str(),
62             &db, SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr) == SQLITE_OK);
63         ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, ADD_SYNC) == E_OK);
64         ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, INSERT_SQL) == E_OK);
65         sqlite3_close_v2(db);
66     }
67 
GetProperties(bool isMem,const SecurityOption & option,bool createIfNecessary)68     OpenDbProperties GetProperties(bool isMem, const SecurityOption &option, bool createIfNecessary)
69     {
70         OpenDbProperties properties;
71         properties.uri = DistributedDB::GetDatabasePath(g_property);
72         properties.createIfNecessary = createIfNecessary;
73         properties.subdir = DistributedDB::GetSubDirPath(g_property);
74         properties.isMemDb = isMem;
75         properties.securityOpt = option;
76         return properties;
77     }
78 
InitVirtualEngine(const std::shared_ptr<DistributedDB::VirtualSingleVerStorageEngine> & engine,bool isMem,const SecurityOption & option,bool createIfNecessary,const StorageEngineAttr & poolSize)79     int InitVirtualEngine(const std::shared_ptr<DistributedDB::VirtualSingleVerStorageEngine> &engine,
80         bool isMem, const SecurityOption &option, bool createIfNecessary, const StorageEngineAttr &poolSize)
81     {
82         auto properties = GetProperties(isMem, option, createIfNecessary);
83         return engine->InitSQLiteStorageEngine(poolSize, properties, "");
84     }
85 
GetVirtualEngineWithSecurity(uint32_t maxRead,bool isMem,const SecurityOption & option,bool createIfNecessary)86     std::pair<int, std::shared_ptr<DistributedDB::VirtualSingleVerStorageEngine>> GetVirtualEngineWithSecurity(
87         uint32_t maxRead, bool isMem, const SecurityOption &option, bool createIfNecessary)
88     {
89         std::pair<int, std::shared_ptr<DistributedDB::VirtualSingleVerStorageEngine>> res;
90         auto &[errCode, engine] = res;
91         engine = std::make_shared<DistributedDB::VirtualSingleVerStorageEngine>();
92         StorageEngineAttr poolSize = {1, 1, 1, maxRead}; // at most 1 write.
93         errCode = InitVirtualEngine(engine, isMem, option, createIfNecessary, poolSize);
94         return res;
95     }
96 
GetVirtualEngine(uint32_t maxRead=1,bool isMem=false,bool createIfNecessary=false)97     std::pair<int, std::shared_ptr<DistributedDB::VirtualSingleVerStorageEngine>> GetVirtualEngine(uint32_t maxRead = 1,
98         bool isMem = false, bool createIfNecessary = false)
99     {
100         return GetVirtualEngineWithSecurity(maxRead, isMem, {}, createIfNecessary);
101     }
102 }
103 
104 class DistributedDBStorageSQLiteSingleVerStorageEngineTest : public testing::Test {
105 public:
106     static void SetUpTestCase(void);
107     static void TearDownTestCase(void);
108     void SetUp();
109     void TearDown();
110 };
111 
SetUpTestCase(void)112 void DistributedDBStorageSQLiteSingleVerStorageEngineTest::SetUpTestCase(void)
113 {
114     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
115     LOGI("DistributedDBStorageSQLiteSingleVerStorageEngineTest dir is %s", g_testDir.c_str());
116     std::string oriIdentifier = APP_ID + "-" + USER_ID + "-" + "TestGeneralNBStorageEngine";
117     std::string identifier = DBCommon::TransferHashString(oriIdentifier);
118     g_identifier = DBCommon::TransferStringToHex(identifier);
119 
120     g_databaseName = "/" + g_identifier + "/" + DBConstant::SINGLE_SUB_DIR + "/" + DBConstant::MAINDB_DIR + "/" +
121         DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
122     g_property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
123     g_property.SetStringProp(KvDBProperties::STORE_ID, "TestGeneralNBStorageEngine");
124     g_property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, g_identifier);
125     g_property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
126     g_cacheDir = g_testDir + "/" + g_identifier + "/" + DBConstant::SINGLE_SUB_DIR +
127         "/" + DBConstant::CACHEDB_DIR + "/" + DBConstant::SINGLE_VER_CACHE_STORE + DBConstant::DB_EXTENSION;
128 }
129 
TearDownTestCase(void)130 void DistributedDBStorageSQLiteSingleVerStorageEngineTest::TearDownTestCase(void)
131 {
132     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir + "/" + g_identifier + "/" + DBConstant::SINGLE_SUB_DIR);
133 }
134 
SetUp(void)135 void DistributedDBStorageSQLiteSingleVerStorageEngineTest::SetUp(void)
136 {
137     DistributedDBToolsUnitTest::PrintTestCaseInfo();
138     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir + "/" + g_identifier + "/" + DBConstant::SINGLE_SUB_DIR);
139     g_store = new (std::nothrow) SQLiteSingleVerNaturalStore;
140     ASSERT_NE(g_store, nullptr);
141     ASSERT_EQ(g_store->Open(g_property), E_OK);
142 
143     int erroCode = E_OK;
144     g_connection = static_cast<SQLiteSingleVerNaturalStoreConnection *>(g_store->GetDBConnection(erroCode));
145     ASSERT_NE(g_connection, nullptr);
146     RefObject::DecObjRef(g_store);
147     EXPECT_EQ(erroCode, E_OK);
148 }
149 
TearDown(void)150 void DistributedDBStorageSQLiteSingleVerStorageEngineTest::TearDown(void)
151 {
152     if (g_connection != nullptr) {
153         g_connection->Close();
154         g_connection = nullptr;
155     }
156     g_store = nullptr;
157     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
158 }
159 
160 /**
161   * @tc.name: DataTest001
162   * @tc.desc: Change engine state, execute migrate
163   * @tc.type: FUNC
164   * @tc.require:
165   * @tc.author: bty
166   */
167 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, DataTest001, TestSize.Level1)
168 {
169     SQLiteSingleVerStorageEngine *storageEngine = nullptr;
170     GetStorageEngine(storageEngine);
171     ASSERT_NE(storageEngine, nullptr);
172     CopyCacheDb();
173 
174     storageEngine->SetEngineState(EngineState::ENGINE_BUSY);
175     EXPECT_EQ(storageEngine->ExecuteMigrate(), -E_BUSY);
176     storageEngine->SetEngineState(EngineState::ATTACHING);
177     EXPECT_EQ(storageEngine->ExecuteMigrate(), -E_NOT_SUPPORT);
178     storageEngine->SetEngineState(EngineState::MAINDB);
179     EXPECT_EQ(storageEngine->ExecuteMigrate(), SQL_STATE_ERR);
180     storageEngine->SetEngineState(EngineState::CACHEDB);
181     EXPECT_EQ(storageEngine->ExecuteMigrate(), SQL_STATE_ERR);
182     storageEngine->Release();
183     storageEngine = nullptr;
184 }
185 
186 /**
187   * @tc.name: DataTest002
188   * @tc.desc: Alter table, Change engine state, execute migrate
189   * @tc.type: FUNC
190   * @tc.require:
191   * @tc.author: bty
192   */
193 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, DataTest002, TestSize.Level1)
194 {
195     sqlite3 *db;
196     ASSERT_TRUE(sqlite3_open_v2((g_testDir + g_databaseName).c_str(),
197         &db, SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr) == SQLITE_OK);
198     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, ADD_SYNC) == E_OK);
199     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, INSERT_SQL) == E_OK);
200     sqlite3_close_v2(db);
201     CopyCacheDb();
202     SQLiteSingleVerStorageEngine *storageEngine = nullptr;
203     GetStorageEngine(storageEngine);
204     ASSERT_NE(storageEngine, nullptr);
205     storageEngine->SetEngineState(EngineState::CACHEDB);
206     EXPECT_EQ(storageEngine->ExecuteMigrate(), -E_BUSY);
207     storageEngine->Release();
208     storageEngine = nullptr;
209 }
210 
211 /**
212   * @tc.name: DataTest003
213   * @tc.desc: Test invalid SQLiteSingleVerNaturalStore and invalid SQLiteSingleVerNaturalStoreConnection
214   * @tc.type: FUNC
215   * @tc.require:
216   * @tc.author: caihaoting
217   */
218 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, DataTest003, TestSize.Level0)
219 {
220     /**
221      * @tc.steps::step1. init invalid SQLiteSingleVerNaturalStore and invalid SQLiteSingleVerNaturalStoreConnection
222      * @tc.expected: step1. return OK.
223      */
224     SQLiteSingleVerNaturalStore *invalidStore = nullptr;
225     SQLiteSingleVerNaturalStoreConnection *invalidConnection = nullptr;
226     ASSERT_EQ(invalidStore, nullptr);
227     invalidConnection = new (std::nothrow) SQLiteSingleVerNaturalStoreConnection(invalidStore);
228     ASSERT_NE(invalidConnection, nullptr);
229     /**
230      * @tc.steps:step2. test RegisterObserver with invalid SQLiteSingleVerNaturalStore
231      * @tc.expected: step2. return -E_INVALID_CONNECTION.
232      */
233     int errCode = E_OK;
234     Key key;
235     key.push_back('a');
__anonda3673ce0202(const KvDBCommitNotifyData &data) 236     KvDBObserverAction func = [&](const KvDBCommitNotifyData &data) {};
237     invalidConnection->RegisterObserver(
238         static_cast<unsigned int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT), key, func,
239         errCode);
240     EXPECT_EQ(errCode, -E_INVALID_CONNECTION);
241     /**
242      * @tc.steps:step3. test UnRegisterObserver with invalid SQLiteSingleVerNaturalStore
243      * @tc.expected: step3. return -E_INVALID_CONNECTION.
244      */
245     auto observerHandle = g_connection->RegisterObserver(
246         static_cast<unsigned int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT), key, func,
247         errCode);
248     EXPECT_EQ(errCode, E_OK);
249     errCode = invalidConnection->UnRegisterObserver(observerHandle);
250     EXPECT_EQ(errCode, -E_INVALID_CONNECTION);
251     /**
252      * @tc.steps:step4. test GetSecurityOption with invalid SQLiteSingleVerNaturalStore
253      * @tc.expected: step4. return -E_INVALID_CONNECTION.
254      */
255     int securityLabel = NOT_SET;
256     int securityFlag = ECE;
257     errCode = invalidConnection->GetSecurityOption(securityLabel, securityFlag);
258     EXPECT_EQ(errCode, -E_INVALID_CONNECTION);
259     /**
260      * @tc.steps:step5. test Close with invalid SQLiteSingleVerNaturalStore
261      * @tc.expected: step5. return -E_INVALID_CONNECTION.
262      */
263     errCode = invalidConnection->Close();
264     EXPECT_EQ(errCode, -E_INVALID_CONNECTION);
265     /**
266      * @tc.steps:step6. delete invalid SQLiteSingleVerNaturalStoreConnection
267      * @tc.expected: step6. return OK.
268      */
269     delete invalidConnection;
270     invalidConnection = nullptr;
271     ASSERT_EQ(invalidConnection, nullptr);
272 }
273 
274 /**
275   * @tc.name: ExecutorTest001
276   * @tc.desc: Test find executor after disable engine
277   * @tc.type: FUNC
278   * @tc.require:
279   * @tc.author: zqq
280   */
281 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest001, TestSize.Level0)
282 {
283     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
284     SQLiteSingleVerStorageEngine *storageEngine = nullptr;
285     GetStorageEngine(storageEngine);
286     ASSERT_NE(storageEngine, nullptr);
287     EXPECT_EQ(storageEngine->TryToDisable(false), E_OK);
288     int errCode = E_OK;
289     EXPECT_EQ(storageEngine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode), nullptr);
290     storageEngine->Release();
291     storageEngine = nullptr;
292 }
293 
294 /**
295   * @tc.name: ExecutorTest002
296   * @tc.desc: Test find executor success
297   * @tc.type: FUNC
298   * @tc.require:
299   * @tc.author: zqq
300   */
301 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest002, TestSize.Level0)
302 {
303     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
304     SQLiteSingleVerStorageEngine *storageEngine = nullptr;
305     GetStorageEngine(storageEngine);
306     int errCode = E_OK;
307     auto executor1 = storageEngine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
308     EXPECT_NE(executor1, nullptr);
309     auto executor2 = storageEngine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
310     EXPECT_NE(executor2, nullptr);
311     storageEngine->Recycle(executor1);
312     storageEngine->Recycle(executor2);
313     EXPECT_EQ(storageEngine->FindExecutor(false, OperatePerm::DISABLE_PERM, errCode), nullptr);
314     storageEngine->Release();
315     storageEngine = nullptr;
316 }
317 
318 /**
319   * @tc.name: ExecutorTest003
320   * @tc.desc: Test find executor abnormal
321   * @tc.type: FUNC
322   * @tc.require:
323   * @tc.author: zqq
324   */
325 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest003, TestSize.Level0)
326 {
327     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
328     auto [errCode, engine] = GetVirtualEngine();
329     ASSERT_EQ(errCode, E_OK);
330     auto executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
331     EXPECT_NE(executor1, nullptr);
332     auto executor2 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
333     EXPECT_EQ(executor2, nullptr);
334     engine->Recycle(executor1);
335     engine->Release();
336 }
337 
338 /**
339   * @tc.name: ExecutorTest004
340   * @tc.desc: Test find executor abnormal
341   * @tc.type: FUNC
342   * @tc.require:
343   * @tc.author: zqq
344   */
345 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest004, TestSize.Level0)
346 {
347     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
348     auto [errCode, engine] = GetVirtualEngine(3); // max read is 3
349     ASSERT_EQ(errCode, E_OK);
__anonda3673ce0302(bool, StorageExecutor *&handle) 350     auto mockFunc = [](bool, StorageExecutor *&handle) {
351         handle = nullptr;
352         return -E_EKEYREVOKED;
353     };
354     auto executor0 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
355     EXPECT_NE(executor0, nullptr);
356     /**
357      * @tc.steps:step1. create new handle with mock func
358      * @tc.expected: step1. create failed.
359      */
360     engine->ForkNewExecutorMethod(mockFunc);
361     auto executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
362     EXPECT_EQ(executor1, nullptr);
363     EXPECT_EQ(errCode, -E_BUSY);
364     /**
365      * @tc.steps:step2. create new handle with normal func
366      * @tc.expected: step2. create ok.
367      */
368     engine->ForkNewExecutorMethod(nullptr);
369     executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
370     EXPECT_NE(executor1, nullptr);
371     /**
372      * @tc.steps:step3. create new handle with mock func
373      * @tc.expected: step3. create failed.
374      */
__anonda3673ce0402(bool, StorageExecutor *&handle) 375     engine->ForkNewExecutorMethod([](bool, StorageExecutor *&handle) {
376         handle = nullptr;
377         return -E_BUSY;
378     });
379     auto executor2 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
380     EXPECT_EQ(executor2, nullptr);
381     engine->Recycle(executor1);
382     engine->Recycle(executor0);
383     engine->Release();
384 }
385 
386 /**
387   * @tc.name: ExecutorTest005
388   * @tc.desc: Test find executor abnormal
389   * @tc.type: FUNC
390   * @tc.require:
391   * @tc.author: zqq
392   */
393 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest005, TestSize.Level0)
394 {
395     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
396     auto [errCode, engine] = GetVirtualEngine(2); // max read is 2
397     ASSERT_EQ(errCode, E_OK);
398     engine->SetEnhance(true);
399     /**
400      * @tc.steps:step1. create new handle without mock func
401      * @tc.expected: step1. create ok.
402      */
403     auto executor0 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
404     EXPECT_NE(executor0, nullptr);
405     /**
406      * @tc.steps:step2. create new handle with mock func, mock func will release executor
407      * @tc.expected: step2. create fail.
408      */
__anonda3673ce0502(bool, StorageExecutor *&handle) 409     engine->ForkNewExecutorMethod([executor = executor0, enginePtr = engine](bool, StorageExecutor *&handle) {
410         StorageExecutor *executorPtr = executor;
411         enginePtr->Recycle(executorPtr);
412         handle = nullptr;
413         return -E_EKEYREVOKED;
414     });
415     auto executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 0);
416     EXPECT_EQ(executor1, nullptr);
417     engine->Release();
418     engine->ForkNewExecutorMethod(nullptr);
419 }
420 
421 /**
422   * @tc.name: ExecutorTest006
423   * @tc.desc: Test find executor abnormal when get executor timeout and operate abort
424   * @tc.type: FUNC
425   * @tc.require:
426   * @tc.author: zqq
427   */
428 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest006, TestSize.Level4)
429 {
430     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
431     auto [errCode, engine] = GetVirtualEngine(1); // max read is 1
432     ASSERT_EQ(errCode, E_OK);
433     /**
434      * @tc.steps:step1. create new handle
435      * @tc.expected: step1. create ok.
436      */
437     auto executor0 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
438     EXPECT_NE(executor0, nullptr);
439     /**
440      * @tc.steps:step2. create new handle again
441      * @tc.expected: step2. create failed by timeout.
442      */
443     auto executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 1); // max wait 1s
444     EXPECT_EQ(executor1, nullptr);
445     /**
446      * @tc.steps:step3. create new handle again and async mark operate abort
447      * @tc.expected: step3. create failed by operate abort.
448      */
__anonda3673ce0602() 449     std::thread t([enginePtr = engine]() {
450         std::this_thread::sleep_for(std::chrono::seconds(1));
451         enginePtr->Abort();
452     });
453     executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode, false, 5); // max wait 5s
454     EXPECT_EQ(executor1, nullptr);
455     t.join();
456     engine->Recycle(executor0);
457     engine->Release();
458 }
459 
460 /**
461   * @tc.name: ExecutorTest007
462   * @tc.desc: Test diff executor pool will not recycle others pool's executor
463   * @tc.type: FUNC
464   * @tc.require:
465   * @tc.author: zqq
466   */
467 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest007, TestSize.Level0)
468 {
469     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
470     auto [errCode, engine1] = GetVirtualEngine(1); // max read is 1
471     ASSERT_EQ(errCode, E_OK);
472     auto [ret, engine2] = GetVirtualEngine(1); // max read is 1
473     ASSERT_EQ(ret, E_OK);
474     /**
475      * @tc.steps:step1. create new handle
476      * @tc.expected: step1. create ok.
477      */
478     auto executor1 = engine1->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
479     EXPECT_NE(executor1, nullptr);
480     /**
481      * @tc.steps:step2. create new handle
482      * @tc.expected: step2. create ok.
483      */
484     auto tmp = executor1;
485     engine2->Recycle(tmp);
486     engine1->Recycle(executor1);
487     EXPECT_EQ(executor1, nullptr);
488     engine1->Release();
489     engine2->Release();
490 }
491 
492 /**
493   * @tc.name: ExecutorTest008
494   * @tc.desc: Test mem executor pool
495   * @tc.type: FUNC
496   * @tc.require:
497   * @tc.author: zqq
498   */
499 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest008, TestSize.Level0)
500 {
501     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
502     auto [errCode, engine1] = GetVirtualEngine(1, true); // max read is 1
503     /**
504      * @tc.steps:step1. create new handle
505      * @tc.expected: step1. create ok.
506      */
507     auto executor1 = engine1->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
508     EXPECT_NE(executor1, nullptr);
509     engine1->Recycle(executor1);
510     engine1->CallSetSQL({});
511     engine1->Release();
512 }
513 
514 /**
515   * @tc.name: ExecutorTest009
516   * @tc.desc: Test cache executor pool
517   * @tc.type: FUNC
518   * @tc.require:
519   * @tc.author: zqq
520   */
521 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest009, TestSize.Level0)
522 {
523     auto systemApi = std::make_shared<ProcessSystemApiAdapterImpl>();
524     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(systemApi);
525     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
526     SecurityOption option = {S3, SECE};
527     auto [errCode, engine] = GetVirtualEngineWithSecurity(2, false, option, true); // max read is 2
528     /**
529      * @tc.steps:step1. create new handle
530      * @tc.expected: step1. create ok.
531      */
532     auto executor1 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
533     EXPECT_NE(executor1, nullptr);
534     /**
535      * @tc.steps:step2. create new handle with fork open main failed
536      * @tc.expected: step2. create failed because of read handle was not allowed.
537      */
__anonda3673ce0702(bool, sqlite3 *&db, OpenDbProperties &) 538     engine->ForkOpenMainDatabaseMethod([executor1, enginePtr = engine](bool, sqlite3 *&db, OpenDbProperties &) {
539         StorageExecutor *executor = executor1;
540         enginePtr->Recycle(executor);
541         db = nullptr;
542         return -E_EKEYREVOKED;
543     });
544     auto executor2 = engine->FindExecutor(false, OperatePerm::NORMAL_PERM, errCode);
545     EXPECT_EQ(executor2, nullptr);
546     engine->ForkOpenMainDatabaseMethod(nullptr);
547     engine->Recycle(executor2);
548     engine->Release();
549 }
550 
551 /**
552   * @tc.name: ExecutorTest010
553   * @tc.desc: Test cache executor pool
554   * @tc.type: FUNC
555   * @tc.require:
556   * @tc.author: zqq
557   */
558 HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, ExecutorTest010, TestSize.Level0)
559 {
560     auto systemApi = std::make_shared<ProcessSystemApiAdapterImpl>();
561     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(systemApi);
562     ASSERT_NO_FATAL_FAILURE(PrepareEnv());
563     CopyCacheDb();
564     SecurityOption option = {S3, SECE};
565     auto [errCode, engine] = GetVirtualEngineWithSecurity(2, false, option, true); // max read is 2
566     ASSERT_EQ(errCode, E_OK);
567     /**
568      * @tc.steps:step1. create new handle with create if necessary
569      * @tc.expected: step1. create ok.
570      */
571     auto properties = GetProperties(false, option, true);
572     auto [ret, handle] = engine->GetCacheHandle(properties);
573     EXPECT_EQ(ret, E_OK);
574     if (handle != nullptr) {
575         EXPECT_EQ(sqlite3_close_v2(handle), SQLITE_OK);
576     }
577     /**
578      * @tc.steps:step2. create new handle without create if necessary
579      * @tc.expected: step2. create ok.
580      */
581     properties = GetProperties(false, option, false);
582     std::tie(ret, handle) = engine->GetCacheHandle(properties);
583     EXPECT_EQ(ret, E_OK);
584     if (handle != nullptr) {
585         EXPECT_EQ(sqlite3_close_v2(handle), SQLITE_OK);
586     }
587     /**
588      * @tc.steps:step3. create new handle without create if necessary and dir was removed
589      * @tc.expected: step3. create failed.
590      */
591     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
592     properties.createIfNecessary = false;
593     std::tie(ret, handle) = engine->GetCacheHandle(properties);
594     EXPECT_EQ(ret, -E_INVALID_DB);
595     engine->Release();
596 }