• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <gtest/gtest.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <string>
19 #include <chrono>
20 #include "accesstoken_kit.h"
21 #include "common.h"
22 #include "rdb_errno.h"
23 #include "relational_store.h"
24 #include "relational_store_error_code.h"
25 #include "relational_store_impl.h"
26 #include "token_setproc.h"
27 
28 using namespace testing::ext;
29 using namespace OHOS::NativeRdb;
30 using namespace OHOS::Security::AccessToken;
31 using namespace OHOS::RdbNdk;
32 
33 static constexpr int64_t BASE_COUNT = 1000; // loop times
34 static constexpr int64_t RDB_INSERT_BASELINE = 3000;
35 static constexpr int64_t RDB_UPDATE_BASELINE = 3000;
36 static constexpr int64_t TRANS_INSERT_BASELINE = 3000;
37 static constexpr int64_t TRANS_UPDATE_BASELINE = 3000;
38 static constexpr int64_t RDB_ATTACH_BASELINE = 6000; // attach and detach two interfaces together.
39 
40 class RdbPerformanceTest : public testing::Test {
41 public:
42     static void SetUpTestCase(void);
43     static void TearDownTestCase(void);
44     void SetUp();
45     void TearDown();
InitRdbConfig()46     static void InitRdbConfig()
47     {
48         config_.dataBaseDir = RDB_TEST_PATH;
49         config_.storeName = "rdb_store_test.db";
50         config_.bundleName = "com.ohos.example.distributedndk";
51         config_.moduleName = "";
52         config_.securityLevel = OH_Rdb_SecurityLevel::S1;
53         config_.isEncrypt = false;
54         config_.selfSize = sizeof(OH_Rdb_Config);
55         config_.area = RDB_SECURITY_AREA_EL1;
56     }
57     static OH_Rdb_Config config_;
58     static void MockHap(void);
59 };
60 
61 static OH_Rdb_Store *g_performanStore = nullptr;
62 static OH_RDB_TransOptions *g_options = nullptr;
63 OH_Rdb_Config RdbPerformanceTest::config_ = { 0 };
64 
MockHap(void)65 void RdbPerformanceTest::MockHap(void)
66 {
67     HapInfoParams info = {
68         .userID = 100,
69         .bundleName = "com.example.distributed",
70         .instIndex = 0,
71         .appIDDesc = "com.example.distributed"
72     };
73     PermissionDef infoManagerTestPermDef = {
74         .permissionName = "ohos.permission.test",
75         .bundleName = "com.example.distributed",
76         .grantMode = 1,
77         .availableLevel = APL_NORMAL,
78         .label = "label",
79         .labelId = 1,
80         .description = "open the door",
81         .descriptionId = 1
82     };
83     PermissionStateFull infoManagerTestState = {
84         .permissionName = "ohos.permission.test",
85         .isGeneral = true,
86         .resDeviceID = { "local" },
87         .grantStatus = { PermissionState::PERMISSION_GRANTED },
88         .grantFlags = { 1 }
89     };
90     HapPolicyParams policy = {
91         .apl = APL_NORMAL,
92         .domain = "test.domain",
93         .permList = { infoManagerTestPermDef },
94         .permStateList = { infoManagerTestState }
95     };
96     AccessTokenKit::AllocHapToken(info, policy);
97 }
98 
SetUpTestCase(void)99 void RdbPerformanceTest::SetUpTestCase(void)
100 {
101     MockHap();
102     InitRdbConfig();
103     // 0770 is permission
104     mkdir(config_.dataBaseDir, 0770);
105     int errCode = 0;
106     g_performanStore = OH_Rdb_GetOrOpen(&config_, &errCode);
107     EXPECT_NE(g_performanStore, NULL);
108 
109     g_options = OH_RdbTrans_CreateOptions();
110     EXPECT_NE(g_options, nullptr);
111     int ret = OH_RdbTransOption_SetType(g_options, RDB_TRANS_BUTT);
112     EXPECT_EQ(ret, RDB_E_INVALID_ARGS);
113     ret = OH_RdbTransOption_SetType(g_options, RDB_TRANS_DEFERRED);
114     EXPECT_EQ(ret, RDB_OK);
115 }
116 
TearDownTestCase(void)117 void RdbPerformanceTest::TearDownTestCase(void)
118 {
119     int errCode = OH_Rdb_CloseStore(g_performanStore);
120     EXPECT_EQ(errCode, 0);
121     errCode = OH_Rdb_DeleteStore(&config_);
122     EXPECT_EQ(errCode, 0);
123 
124     OH_RdbTrans_DestroyOptions(g_options);
125     g_options = nullptr;
126 }
127 
SetUp(void)128 void RdbPerformanceTest::SetUp(void)
129 {
130     char createTableSql[] = "CREATE TABLE store_test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, data2 INTEGER, "
131         "data3 FLOAT, data4 BLOB, data5 TEXT);";
132     int errCode = OH_Rdb_Execute(g_performanStore, createTableSql);
133     EXPECT_EQ(errCode, 0);
134 
135     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
136     valueBucket->putInt64(valueBucket, "id", 1);
137     valueBucket->putText(valueBucket, "data1", "zhangSan");
138     // 12800 test value.
139     valueBucket->putInt64(valueBucket, "data2", 12800);
140     // 100.1 test value.
141     valueBucket->putReal(valueBucket, "data3", 100.1);
142     uint8_t arr[] = { 1, 2, 3, 4, 5 };
143     int len = sizeof(arr) / sizeof(arr[0]);
144     valueBucket->putBlob(valueBucket, "data4", arr, len);
145     valueBucket->putText(valueBucket, "data5", "ABCDEFG");
146     errCode = OH_Rdb_Insert(g_performanStore, "store_test", valueBucket);
147     EXPECT_EQ(errCode, 1);
148 
149     char querySql[] = "SELECT * FROM store_test";
150     OH_Cursor *cursor = OH_Rdb_ExecuteQuery(g_performanStore, querySql);
151 
152     int rowCount = 0;
153     cursor->getRowCount(cursor, &rowCount);
154     EXPECT_EQ(rowCount, 1);
155     cursor->destroy(cursor);
156     valueBucket->destroy(valueBucket);
157 }
158 
TearDown(void)159 void RdbPerformanceTest::TearDown(void)
160 {
161     char dropTableSql[] = "DROP TABLE IF EXISTS store_test";
162     int errCode = OH_Rdb_Execute(g_performanStore, dropTableSql);
163     EXPECT_EQ(errCode, 0);
164 }
165 
166 /* *
167  * @tc.name: Trans_InsertWithConflictResolution_test_001
168  * @tc.desc: test OH_RdbTrans_InsertWithConflictResolution interface performance.
169  * @tc.type: FUNC
170  */
171 HWTEST_F(RdbPerformanceTest, Trans_InsertWithConflictResolution_test_001, TestSize.Level1)
172 {
173     OH_Rdb_Transaction *trans = nullptr;
174     const char *table = "store_test";
175     int ret = OH_Rdb_CreateTransaction(g_performanStore, g_options, &trans);
176     EXPECT_EQ(ret, RDB_OK);
177     EXPECT_NE(trans, nullptr);
178 
179     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
180     valueBucket->putText(valueBucket, "data1", "test_name4");
181     // init is data2 is 14800
182     valueBucket->putInt64(valueBucket, "data2", 14800);
183     // init is data2 is 300.1
184     valueBucket->putReal(valueBucket, "data3", 300.1);
185     valueBucket->putText(valueBucket, "data5", "ABCDEFGHI");
186     int64_t rowId = -1;
187 
188     auto now = std::chrono::system_clock::now().time_since_epoch();
189     int64_t start = std::chrono::duration_cast<std::chrono::microseconds>(now).count();
190 
191     for (int i = 0; i < BASE_COUNT; i++) {
192         ret = OH_RdbTrans_InsertWithConflictResolution(trans, table, valueBucket, RDB_CONFLICT_ROLLBACK, &rowId);
193         EXPECT_EQ(ret, RDB_OK);
194     }
195 
196     now = std::chrono::system_clock::now().time_since_epoch();
197     int64_t summaryTime = (std::chrono::duration_cast<std::chrono::microseconds>(now).count() - start);
198     int64_t averageTime = summaryTime / BASE_COUNT;
199 
200     EXPECT_LE(averageTime, RDB_INSERT_BASELINE);
201 
202     valueBucket->destroy(valueBucket);
203     ret = OH_RdbTrans_Destroy(trans);
204     EXPECT_EQ(ret, RDB_OK);
205 }
206 
207 /* *
208  * @tc.name: Trans_UpdateWithConflictResolution_test_002
209  * @tc.desc: test OH_RdbTrans_UpdateWithConflictResolution interface performance.
210  * @tc.type: FUNC
211  */
212 HWTEST_F(RdbPerformanceTest, Trans_UpdateWithConflictResolution_test_002, TestSize.Level1)
213 {
214     OH_Rdb_Transaction *trans = nullptr;
215     const char *table = "store_test";
216     int ret = OH_Rdb_CreateTransaction(g_performanStore, g_options, &trans);
217     EXPECT_EQ(ret, RDB_OK);
218     EXPECT_NE(trans, nullptr);
219 
220     // new row
221     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
222     valueBucket->putText(valueBucket, "data1", "liSi");
223     // init data2 value is 13800
224     valueBucket->putInt64(valueBucket, "data2", 13800);
225     // init data3 value is 200.1
226     valueBucket->putReal(valueBucket, "data3", 200.1);
227     valueBucket->putNull(valueBucket, "data5");
228 
229     // create predicates
230     OH_Predicates *predicates = OH_Rdb_CreatePredicates(table);
231     // create match data
232     OH_VObject *valueObject = OH_Rdb_CreateValueObject();
233     const char *data1Value = "zhangSan";
234     valueObject->putText(valueObject, data1Value);
235     predicates->equalTo(predicates, "data1", valueObject);
236 
237     // update
238     int64_t changes = -1;
239     auto now = std::chrono::system_clock::now().time_since_epoch();
240     int64_t start = std::chrono::duration_cast<std::chrono::microseconds>(now).count();
241 
242     for (int i = 0; i < BASE_COUNT; i++) {
243         ret = OH_RdbTrans_UpdateWithConflictResolution(trans, valueBucket, predicates, RDB_CONFLICT_REPLACE, &changes);
244         EXPECT_EQ(ret, RDB_OK);
245     }
246 
247     now = std::chrono::system_clock::now().time_since_epoch();
248     int64_t summaryTime = (std::chrono::duration_cast<std::chrono::microseconds>(now).count() - start);
249     int64_t averageTime = summaryTime / BASE_COUNT;
250 
251     EXPECT_LE(averageTime, RDB_UPDATE_BASELINE);
252 
253     // destroy
254     valueObject->destroy(valueObject);
255     valueBucket->destroy(valueBucket);
256     ret = OH_RdbTrans_Destroy(trans);
257     EXPECT_EQ(ret, RDB_OK);
258 }
259 
260 /* *
261  * @tc.name: RDB_InsertWithConflictResolution_test_003
262  * @tc.desc: test OH_Rdb_InsertWithConflictResolution interface performance.
263  * @tc.type: FUNC
264  */
265 HWTEST_F(RdbPerformanceTest, RDB_InsertWithConflictResolution_test_003, TestSize.Level1)
266 {
267     int ret = 0;
268     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
269     valueBucket->putText(valueBucket, "data1", "liSi");
270     valueBucket->putInt64(valueBucket, "data2", 13800);
271     valueBucket->putReal(valueBucket, "data3", 200.1);
272     valueBucket->putText(valueBucket, "data5", "ABCDEFGH");
273     int64_t rowId = 0;
274 
275     auto now = std::chrono::system_clock::now().time_since_epoch();
276     int64_t start = std::chrono::duration_cast<std::chrono::microseconds>(now).count();
277 
278     for (int i = 0; i < BASE_COUNT; i++) {
279         ret = OH_Rdb_InsertWithConflictResolution(g_performanStore, "store_test", valueBucket, RDB_CONFLICT_ROLLBACK,
280             &rowId);
281         EXPECT_EQ(ret, RDB_OK);
282     }
283 
284     now = std::chrono::system_clock::now().time_since_epoch();
285     int64_t summaryTime = (std::chrono::duration_cast<std::chrono::microseconds>(now).count() - start);
286     int64_t averageTime = summaryTime / BASE_COUNT;
287 
288     EXPECT_LE(averageTime, TRANS_INSERT_BASELINE);
289 
290     valueBucket->destroy(valueBucket);
291 }
292 
293 /* *
294  * @tc.name: RDB_UpdateWithConflictResolution_test_004
295  * @tc.desc: test OH_Rdb_UpdateWithConflictResolution interface performance.
296  * @tc.type: FUNC
297  */
298 HWTEST_F(RdbPerformanceTest, RDB_UpdateWithConflictResolution_test_004, TestSize.Level1)
299 {
300     int ret = 0;
301     OH_Predicates *predicates = OH_Rdb_CreatePredicates("store_test");
302     EXPECT_NE(predicates, NULL);
303 
304     OH_VObject *valueObject = OH_Rdb_CreateValueObject();
305     EXPECT_NE(valueObject, NULL);
306     const char *data1Value = "zhangSan";
307     valueObject->putText(valueObject, data1Value);
308 
309     predicates->equalTo(predicates, "data1", valueObject);
310 
311     OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
312     EXPECT_NE(valueBucket, NULL);
313     valueBucket->putText(valueBucket, "data1", "liSi");
314     valueBucket->putInt64(valueBucket, "data2", 13800);
315     valueBucket->putReal(valueBucket, "data3", 200.1);
316     valueBucket->putNull(valueBucket, "data5");
317 
318     int64_t chgs = 0;
319     auto now = std::chrono::system_clock::now().time_since_epoch();
320     int64_t start = std::chrono::duration_cast<std::chrono::microseconds>(now).count();
321 
322     for (int i = 0; i < BASE_COUNT; i++) {
323         ret = OH_Rdb_UpdateWithConflictResolution(g_performanStore, valueBucket, predicates, RDB_CONFLICT_ROLLBACK,
324             &chgs);
325         EXPECT_EQ(ret, RDB_OK);
326     }
327 
328     now = std::chrono::system_clock::now().time_since_epoch();
329     int64_t summaryTime = (std::chrono::duration_cast<std::chrono::microseconds>(now).count() - start);
330     int64_t averageTime = summaryTime / BASE_COUNT;
331 
332     EXPECT_LE(averageTime, TRANS_UPDATE_BASELINE);
333 
334     valueObject->destroy(valueObject);
335     valueBucket->destroy(valueBucket);
336     predicates->destroy(predicates);
337 }
338 
339 /* *
340  * @tc.name: RDB_AttachAndDetach_test_005
341  * @tc.desc: Normal testCase of OH_Rdb_InsertWithConflictResolution errcode.
342  * @tc.type: FUNC
343  */
344 HWTEST_F(RdbPerformanceTest, RDB_AttachAndDetach_test_005, TestSize.Level1)
345 {
346     auto attachConfig = OH_Rdb_CreateConfig();
347     ASSERT_NE(attachConfig, nullptr);
348     OH_Rdb_SetDatabaseDir(attachConfig, RDB_TEST_PATH);
349     OH_Rdb_SetStoreName(attachConfig, "rdb_attach_store_test.db");
350     OH_Rdb_SetBundleName(attachConfig, "com.ohos.example.distributedndk");
351     OH_Rdb_SetEncrypted(attachConfig, false);
352     OH_Rdb_SetSecurityLevel(attachConfig, OH_Rdb_SecurityLevel::S1);
353     OH_Rdb_SetArea(attachConfig, RDB_SECURITY_AREA_EL1);
354 
355     int errCode = 0;
356     auto tmpStore = OH_Rdb_CreateOrOpen(attachConfig, &errCode);
357     EXPECT_NE(tmpStore, NULL);
358     OH_Rdb_CloseStore(tmpStore);
359 
360     size_t attachedNumber = 0;
361     auto now = std::chrono::system_clock::now().time_since_epoch();
362     int64_t start = std::chrono::duration_cast<std::chrono::microseconds>(now).count();
363     for (int i = 0; i < BASE_COUNT; i++) {
364         auto ret = OH_Rdb_Attach(g_performanStore, attachConfig, "rdb_attach_test", 3, &attachedNumber);
365         EXPECT_EQ(ret, RDB_OK);
366 
367         ret = OH_Rdb_Detach(g_performanStore, "rdb_attach_test", 3, &attachedNumber);
368         EXPECT_EQ(ret, RDB_OK);
369     }
370 
371     now = std::chrono::system_clock::now().time_since_epoch();
372     int64_t summaryTime = (std::chrono::duration_cast<std::chrono::microseconds>(now).count() - start);
373     int64_t averageTime = summaryTime / BASE_COUNT;
374 
375     EXPECT_LE(averageTime, RDB_ATTACH_BASELINE);
376 }