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 }