1 /*
2 * Copyright (c) 2025 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 #define LOG_TAG "RdbPerfStatTest"
17 #include <gtest/gtest.h>
18
19 #include <functional>
20 #include <string>
21 #include <thread>
22
23 #include "block_data.h"
24 #include "rdb_errno.h"
25 #include "rdb_helper.h"
26 #include "rdb_open_callback.h"
27 #include "rdb_store_manager.h"
28 #include "rdb_types.h"
29 #include "logger.h"
30 #include "rdb_platform.h"
31 #include "rdb_perfStat.h"
32
33 using namespace testing::ext;
34 using namespace OHOS::NativeRdb;
35 using namespace OHOS::DistributedRdb;
36 using namespace OHOS::Rdb;
37
38 class PerfStatObserver : public SqlObserver {
39 public:
~PerfStatObserver()40 virtual ~PerfStatObserver()
41 {
42 }
43 void OnStatistic(const SqlExecutionInfo &info);
44 void SetBlockData(std::shared_ptr<OHOS::BlockData<bool>> block);
45 SqlExecutionInfo perfInfo_;
46 private:
47 std::shared_ptr<OHOS::BlockData<bool>> block_;
48 };
49
50 class RdbPerfStatTest : public testing::Test {
51 public:
52 static void SetUpTestCase(void);
53 static void TearDownTestCase(void);
54 void SetUp();
55 void TearDown();
56
57 static const std::string databasePath;
58 static std::shared_ptr<RdbStore> CreateRDB(int version);
59 static std::shared_ptr<RdbStore> store;
60 static std::shared_ptr<PerfStatObserver> sqlObserver_;
61 };
62
63 const std::string RdbPerfStatTest::databasePath = "/data/test/perfStat.db";
64 std::shared_ptr<RdbStore> RdbPerfStatTest::store = nullptr;
65 std::shared_ptr<PerfStatObserver> RdbPerfStatTest::sqlObserver_ = nullptr;
SetUpTestCase(void)66 void RdbPerfStatTest::SetUpTestCase(void)
67 {
68 RdbHelper::DeleteRdbStore(databasePath);
69 store = CreateRDB(1);
70 if (sqlObserver_ == nullptr) {
71 sqlObserver_ = std::make_shared<PerfStatObserver>();
72 }
73 }
74
TearDownTestCase(void)75 void RdbPerfStatTest::TearDownTestCase(void)
76 {
77 store = nullptr;
78 RdbHelper::DeleteRdbStore(databasePath);
79 }
80
SetUp()81 void RdbPerfStatTest::SetUp()
82 {
83 }
84
TearDown()85 void RdbPerfStatTest::TearDown()
86 {
87 }
88
89 class PerfStatCallback : public RdbOpenCallback {
90 public:
91 int OnCreate(RdbStore &store) override;
92 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
93 };
94
OnCreate(RdbStore & store)95 int PerfStatCallback::OnCreate(RdbStore &store)
96 {
97 return E_OK;
98 }
99
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)100 int PerfStatCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
101 {
102 return E_OK;
103 }
104
OnStatistic(const PerfStatObserver::SqlExecutionInfo & info)105 void PerfStatObserver::OnStatistic(const PerfStatObserver::SqlExecutionInfo &info)
106 {
107 perfInfo_ = info;
108 if (block_) {
109 block_->SetValue(true);
110 }
111 }
112
SetBlockData(std::shared_ptr<OHOS::BlockData<bool>> block)113 void PerfStatObserver::SetBlockData(std::shared_ptr<OHOS::BlockData<bool>> block)
114 {
115 block_ = block;
116 }
117
CreateRDB(int version)118 std::shared_ptr<RdbStore> RdbPerfStatTest::CreateRDB(int version)
119 {
120 RdbStoreConfig config(RdbPerfStatTest::databasePath);
121 config.SetBundleName("subscribe_test");
122 config.SetArea(0);
123 config.SetCreateNecessary(true);
124 config.SetDistributedType(RDB_DEVICE_COLLABORATION);
125 config.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel::S1);
126 PerfStatCallback helper;
127 int errCode = E_OK;
128 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, version, helper, errCode);
129 if (store == nullptr) {
130 return nullptr;
131 }
132 constexpr const char *createTableTest = "CREATE TABLE IF NOT EXISTS perfStat_test "
133 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
134 "name TEXT NOT NULL, age INTEGER)";
135 store->ExecuteSql(createTableTest);
136 return store;
137 }
138
139 /**
140 * @tc.name: RdbPerfStat001
141 * @tc.desc: test perfStat observer
142 * @tc.type: FUNC
143 */
144 HWTEST_F(RdbPerfStatTest, RdbPerfStat001, TestSize.Level1)
145 {
146 ASSERT_NE(store, nullptr) << "store is null";
147 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
148 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
149 EXPECT_EQ(status, E_OK);
150 ValuesBucket values;
151 int64_t id;
152 values.PutInt("id", 1);
153 values.PutString("name", std::string("zhangsan"));
154 values.PutInt("age", 18); // 18 is random age
155 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
156 sqlObserver_->SetBlockData(block);
157 status = store->Insert(id, "perfStat_test", values);
158 EXPECT_EQ(status, E_OK);
159 EXPECT_EQ(id, 1);
160 EXPECT_TRUE(block->GetValue());
161 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
162 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
163 EXPECT_EQ(status, E_OK);
164 }
165
166 /**
167 * @tc.name: RdbPerfStat002
168 * @tc.desc: test perfStat observer
169 * @tc.type: FUNC
170 */
171 HWTEST_F(RdbPerfStatTest, RdbPerfStat002, TestSize.Level1)
172 {
173 ASSERT_NE(store, nullptr) << "store is null";
174 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
175 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
176 EXPECT_EQ(status, E_OK);
177 int id;
178 ValuesBucket values;
179 values.PutString("name", std::string("zhangsan_update2"));
180 values.PutInt("age", 20); // 20 is random age
181 AbsRdbPredicates predicates("perfStat_test");
182 predicates.EqualTo("id", 1);
183 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
184 sqlObserver_->SetBlockData(block);
185 status = store->Update(id, values, predicates);
186 EXPECT_EQ(status, E_OK);
187 EXPECT_EQ(id, 1);
188 EXPECT_TRUE(block->GetValue());
189 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
190 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
191 EXPECT_EQ(status, E_OK);
192 }
193
194 /**
195 * @tc.name: RdbPerfStat003
196 * @tc.desc: test perfStat observer
197 * @tc.type: FUNC
198 */
199 HWTEST_F(RdbPerfStatTest, RdbPerfStat003, TestSize.Level1)
200 {
201 ASSERT_NE(store, nullptr) << "store is null";
202 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
203 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
204 EXPECT_EQ(status, E_OK);
205 int id;
206 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
207 sqlObserver_->SetBlockData(block);
208 status = store->Delete(id, "perfStat_test", "id = ?", std::vector<std::string>{ "1" });
209 EXPECT_EQ(status, E_OK);
210 EXPECT_EQ(id, 1);
211 EXPECT_TRUE(block->GetValue());
212 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
213 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
214 EXPECT_EQ(status, E_OK);
215 }
216
217 /**
218 * @tc.name: RdbPerfStat004
219 * @tc.desc: test perfStat observer
220 * @tc.type: FUNC
221
222 */
223 HWTEST_F(RdbPerfStatTest, RdbPerfStat004, TestSize.Level1)
224 {
225 int num = 3;
226 ASSERT_NE(store, nullptr) << "store is null";
227 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
228 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
229 int64_t id;
230 std::vector<ValuesBucket> values;
231 for (int i = 0; i < num; i++) {
232 ValuesBucket value;
233 value.PutInt("id", i);
234 value.PutString("name", std::string("zhangsan"));
235 value.PutInt("age", 18); // 18 is random age
236 values.push_back(value);
237 }
238 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
239 sqlObserver_->SetBlockData(block);
240 status = store->BatchInsert(id, "perfStat_test", values);
241 EXPECT_EQ(status, E_OK);
242 EXPECT_EQ(id, num);
243 EXPECT_TRUE(block->GetValue());
244 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
245 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
246 EXPECT_EQ(status, E_OK);
247 }
248
249 /**
250 * @tc.name: RdbPerfStat005
251 * @tc.desc: test perfStat observer
252 * @tc.type: FUNC
253 * @tc.require:
254 * @tc.author:
255 */
256 HWTEST_F(RdbPerfStatTest, RdbPerfStat005, TestSize.Level1)
257 {
258 ASSERT_NE(store, nullptr) << "store is null";
259 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
260 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
261 EXPECT_EQ(status, E_OK);
262 constexpr const char *createTableTest = "CREATE TABLE IF NOT EXISTS perfStat_test2 "
263 "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
264 "name TEXT NOT NULL, age INTEGER)";
265 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
266 sqlObserver_->SetBlockData(block);
267 status = store->ExecuteSql(createTableTest);
268 EXPECT_TRUE(block->GetValue());
269 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
270 EXPECT_EQ(sqlObserver_->perfInfo_.sql_[0], createTableTest);
271 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
272 EXPECT_EQ(status, E_OK);
273 }
274
275 /**
276 * @tc.name: RdbPerfStat006
277 * @tc.desc: test perfStat observer
278 * @tc.type: FUNC
279 * @tc.require:
280 * @tc.author:
281 */
282 HWTEST_F(RdbPerfStatTest, RdbPerfStat006, TestSize.Level1)
283 {
284 ASSERT_NE(store, nullptr) << "store is null";
285 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
286 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
287 EXPECT_EQ(status, E_OK);
288 constexpr const char *pargmaTest = "PRAGMA quick_check";
289 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
290 sqlObserver_->SetBlockData(block);
291 store->Execute(pargmaTest);
292 EXPECT_TRUE(block->GetValue());
293 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
294 EXPECT_EQ(sqlObserver_->perfInfo_.sql_[0], pargmaTest);
295 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
296 EXPECT_EQ(status, E_OK);
297 }
298
299 /**
300 * @tc.name: RdbPerfStat007
301 * @tc.desc: test perfStat observer
302 * @tc.type: FUNC
303 * @tc.require:
304 * @tc.author:
305 */
306 HWTEST_F(RdbPerfStatTest, RdbPerfStat007, TestSize.Level1)
307 {
308 ASSERT_NE(store, nullptr) << "store is null";
309 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
310 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
311 EXPECT_EQ(status, E_OK);
312 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
313 sqlObserver_->SetBlockData(block);
314 std::shared_ptr<ResultSet> resultSet = store->QueryByStep("SELECT * FROM perfStat_test");
315 ASSERT_NE(resultSet, nullptr);
316 EXPECT_TRUE(block->GetValue());
317 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
318 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
319 EXPECT_EQ(status, E_OK);
320 }
321
322 /**
323 * @tc.name: RdbPerfStat008
324 * @tc.desc: test perfStat observer
325 * @tc.type: FUNC
326 * @tc.require:
327 * @tc.author:
328 */
329 HWTEST_F(RdbPerfStatTest, RdbPerfStat008, TestSize.Level1)
330 {
331 ASSERT_NE(store, nullptr) << "store is null";
332 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
333
334 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
335 EXPECT_EQ(status, E_OK);
336 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
337 sqlObserver_->SetBlockData(block);
338 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM perfStat_test");
339 ASSERT_NE(resultSet, nullptr);
340 EXPECT_TRUE(block->GetValue());
341 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
342 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
343 EXPECT_EQ(status, E_OK);
344 }
345
346 /**
347 * @tc.name: RdbPerfStat009
348 * @tc.desc: test perfStat observer
349 * @tc.type: FUNC
350 */
351 HWTEST_F(RdbPerfStatTest, RdbPerfStat009, TestSize.Level1)
352 {
353 ASSERT_NE(store, nullptr) << "store is null";
354 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
355
356 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
357 EXPECT_EQ(status, E_OK);
358 AbsRdbPredicates predicates("perfStat_test");
359 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
360 sqlObserver_->SetBlockData(block);
361 std::shared_ptr<ResultSet> resultSet = store->Query(predicates);
362 ASSERT_NE(resultSet, nullptr);
363 EXPECT_TRUE(block->GetValue());
364 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 1);
365 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
366 EXPECT_EQ(status, E_OK);
367 }
368
369 /**
370 * @tc.name: RdbPerfStat010
371 * @tc.desc: test perfStat observer
372 * @tc.type: FUNC
373 */
374 HWTEST_F(RdbPerfStatTest, RdbPerfStat010, TestSize.Level1)
375 {
376 ASSERT_NE(store, nullptr) << "store is null";
377 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
378
379 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
380 EXPECT_EQ(status, E_OK);
381
382 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
383 sqlObserver_->SetBlockData(block);
384 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
385 EXPECT_EQ(ret, E_OK);
386 ASSERT_NE(transaction, nullptr);
387
388 ValuesBucket value;
389 value.PutString("name", std::string("zhangsan"));
390 value.PutInt("age", 18); // 18 is random age
391
392 auto result = transaction->Insert("perfStat_test", value);
393 EXPECT_EQ(result.first, E_OK);
394 ret = transaction->Commit();
395 EXPECT_EQ(ret, E_OK);
396 EXPECT_TRUE(block->GetValue());
397 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 3);
398 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
399 EXPECT_EQ(status, E_OK);
400 }
401
402 /**
403 * @tc.name: RdbPerfStat011
404 * @tc.desc: test perfStat observer
405 * @tc.type: FUNC
406 */
407 HWTEST_F(RdbPerfStatTest, RdbPerfStat011, TestSize.Level1)
408 {
409 ASSERT_NE(store, nullptr) << "store is null";
410 ASSERT_NE(sqlObserver_, nullptr) << "observer is null";
411
412 auto status = PerfStat::Subscribe(databasePath, sqlObserver_);
413 EXPECT_EQ(status, E_OK);
414
415 std::shared_ptr<OHOS::BlockData<bool>> block = std::make_shared<OHOS::BlockData<bool>>(3, false);
416 sqlObserver_->SetBlockData(block);
417 auto [ret, transaction] = store->CreateTransaction(Transaction::DEFERRED);
418 EXPECT_EQ(ret, E_OK);
419 ASSERT_NE(transaction, nullptr);
420 int num = 3;
421 std::vector<ValuesBucket> values;
422 for (int i = 0; i < num; i++) {
423 ValuesBucket value;
424 value.PutInt("id", i);
425 value.PutString("name", std::string("zhangsan"));
426 value.PutInt("age", 18); // 18 is random age
427 values.push_back(value);
428 }
429 auto result = transaction->BatchInsert("perfStat_test", values);
430 EXPECT_EQ(result.first, E_OK);
431 ret = transaction->Commit();
432 EXPECT_EQ(ret, E_OK);
433 EXPECT_TRUE(block->GetValue());
434 EXPECT_EQ(sqlObserver_->perfInfo_.sql_.size(), 3);
435 status = PerfStat::Unsubscribe(databasePath, sqlObserver_);
436 EXPECT_EQ(status, E_OK);
437 }
438