1 /*
2 * Copyright (C) 2021-2022 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 <unistd.h>
17
18 #include "accesstoken_kit.h"
19 #include "datashare_helper.h"
20 #include "datashare_log.h"
21 #include "datashare_values_bucket.h"
22 #include "hap_token_info.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "token_setproc.h"
26
27 namespace OHOS {
28 namespace DataShare {
29 using namespace testing::ext;
30 using namespace OHOS::Security::AccessToken;
31 constexpr int STORAGE_MANAGER_MANAGER_ID = 5003;
32 std::string DATA_SHARE_URI = "datashare:///com.acts.datasharetest";
33 std::string SLIENT_ACCESS_URI = "datashare:///com.acts.datasharetest?Proxy=true";
34 std::string USER_URI = "datashare:///com.acts.datasharetest/entry/DB00/user?Proxy=true";
35 std::string BOOK_URI = "datashare:///com.acts.datasharetest/entry/DB00/book?Proxy=true";
36 std::string TBL_STU_NAME = "name";
37 std::string TBL_STU_AGE = "age";
38 std::shared_ptr<DataShare::DataShareHelper> g_slientAccessHelper;
39
40 class JoinTest : public testing::Test {
41 public:
42 static void SetUpTestCase(void);
43 static void TearDownTestCase(void);
44 void SetUp();
45 void TearDown();
46 static void InsertUserDates();
47 static void InsertBookDates();
48 int ResultSize(std::shared_ptr<DataShareResultSet> &resultSet);
49 };
50
CreateDataShareHelper(int32_t systemAbilityId,std::string uri)51 std::shared_ptr<DataShare::DataShareHelper> CreateDataShareHelper(int32_t systemAbilityId, std::string uri)
52 {
53 LOG_INFO("CreateDataShareHelper start");
54 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
55 if (saManager == nullptr) {
56 LOG_ERROR("GetSystemAbilityManager get samgr failed.");
57 return nullptr;
58 }
59 auto remoteObj = saManager->GetSystemAbility(systemAbilityId);
60 if (remoteObj == nullptr) {
61 LOG_ERROR("GetSystemAbility service failed.");
62 return nullptr;
63 }
64 return DataShare::DataShareHelper::Creator(remoteObj, uri);
65 }
66
SetUpTestCase(void)67 void JoinTest::SetUpTestCase(void)
68 {
69 LOG_INFO("SetUpTestCase invoked");
70 auto dataShareHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, DATA_SHARE_URI);
71 ASSERT_TRUE(dataShareHelper != nullptr);
72 int sleepTime = 3;
73 sleep(sleepTime);
74
75 HapInfoParams info = {
76 .userID = 100,
77 .bundleName = "ohos.datashareclienttest.demo",
78 .instIndex = 0,
79 .appIDDesc = "ohos.datashareclienttest.demo" };
80 HapPolicyParams policy = { .apl = APL_NORMAL,
81 .domain = "test.domain",
82 .permList = { { .permissionName = "ohos.permission.test",
83 .bundleName = "ohos.datashareclienttest.demo",
84 .grantMode = 1,
85 .availableLevel = APL_NORMAL,
86 .label = "label",
87 .labelId = 1,
88 .description = "ohos.datashareclienttest.demo",
89 .descriptionId = 1 }
90 },
91 .permStateList = {
92 {
93 .permissionName = "ohos.permission.test",
94 .isGeneral = true,
95 .resDeviceID = { "local" },
96 .grantStatus = { PermissionState::PERMISSION_GRANTED },
97 .grantFlags = { 1 }
98 }
99 }
100 };
101 AccessTokenKit::AllocHapToken(info, policy);
102 auto testTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(
103 info.userID, info.bundleName, info.instIndex);
104 SetSelfTokenID(testTokenId);
105
106 g_slientAccessHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID, SLIENT_ACCESS_URI);
107 ASSERT_TRUE(g_slientAccessHelper != nullptr);
108 JoinTest::InsertUserDates();
109 JoinTest::InsertBookDates();
110 LOG_INFO("SetUpTestCase end");
111 }
112
TearDownTestCase(void)113 void JoinTest::TearDownTestCase(void)
114 {
115 auto tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.datashareclienttest.demo", 0);
116 AccessTokenKit::DeleteToken(tokenId);
117 g_slientAccessHelper = nullptr;
118 }
119
SetUp(void)120 void JoinTest::SetUp(void) {}
TearDown(void)121 void JoinTest::TearDown(void) {}
122
InsertUserDates()123 void JoinTest::InsertUserDates()
124 {
125 LOG_INFO("JoinTest::InsertUserDates start");
126 DataShare::DataShareValuesBucket values;
127
128 values.Put("userId", 1);
129 values.Put("firstName", "Zhang");
130 values.Put("lastName", "San");
131 values.Put("age", 29);
132 values.Put("balance", 100.51);
133 Uri userUri (USER_URI);
134 g_slientAccessHelper->Insert(userUri, values);
135
136 values.Clear();
137 values.Put("userId", 2);
138 values.Put("firstName", "Li");
139 values.Put("lastName", "Si");
140 values.Put("age", 30);
141 values.Put("balance", 200.51);
142 g_slientAccessHelper->Insert(userUri, values);
143
144 values.Clear();
145 values.Put("userId", 3);
146 values.Put("firstName", std::string("Wang"));
147 values.Put("lastName", std::string("Wu"));
148 values.Put("age", 30);
149 values.Put("balance", 300.51);
150 g_slientAccessHelper->Insert(userUri, values);
151
152 values.Clear();
153 values.Put("userId", 4);
154 values.Put("firstName", "Sun");
155 values.Put("lastName", "Liu");
156 values.Put("age", 31);
157 values.Put("balance", 400.51);
158 g_slientAccessHelper->Insert(userUri, values);
159
160 values.Clear();
161 values.Put("userId", 5);
162 values.Put("firstName", "Ma");
163 values.Put("lastName", "Qi");
164 values.Put("age", 32);
165 values.Put("balance", 500.51);
166 g_slientAccessHelper->Insert(userUri, values);
167 LOG_INFO("JoinTest::InsertUserDates ends");
168 }
169
InsertBookDates()170 void JoinTest::InsertBookDates()
171 {
172 LOG_INFO("JoinTest::InsertBookDates start");
173 DataShare::DataShareValuesBucket values;
174
175 values.Put("id", 1);
176 values.Put("name", "SanGuo");
177 values.Put("userId", 1);
178 Uri bookUri (BOOK_URI);
179 g_slientAccessHelper->Insert(bookUri, values);
180
181 values.Clear();
182 values.Put("id", 2);
183 values.Put("name", "XiYouJi");
184 values.Put("userId", 2);
185 g_slientAccessHelper->Insert(bookUri, values);
186
187 values.Clear();
188 values.Put("id", 3);
189 values.Put("name", "ShuiHuZhuan");
190 values.Put("userId", 3);
191 g_slientAccessHelper->Insert(bookUri, values);
192 LOG_INFO("JoinTest::InsertBookDates end");
193 }
194
ResultSize(std::shared_ptr<DataShareResultSet> & resultSet)195 int JoinTest::ResultSize(std::shared_ptr<DataShareResultSet> &resultSet)
196 {
197 if (resultSet->GoToFirstRow() != E_OK) {
198 return 0;
199 }
200 int count = 1;
201 while (resultSet->GoToNextRow() == E_OK) {
202 count++;
203 }
204 return count;
205 }
206
207 /**
208 * @tc.name: Join_CrossJoin_001
209 * @tc.desc: Verify cross join operation returns correct results
210 * @tc.type: FUNC
211 * @tc.require: None
212 * @tc.precon: None
213 * @tc.step:
214 1. Create cross join predicate with "user.userId = book.userId" condition
215 2. Execute query on user table with join predicate
216 3. Verify row count is 3
217 4. Check first row data matches expected values
218 * @tc.experct:
219 1. Query returns 3 rows
220 2. First row contains correct user and book data for userId = 1
221 */
222 HWTEST_F(JoinTest, Join_CrossJoin_001, TestSize.Level0)
223 {
224 auto helper = g_slientAccessHelper;
225 DataShare::DataSharePredicates predicates;
226 std::vector<std::string> clauses;
227 clauses.push_back("user.userId = book.userId");
228 predicates.CrossJoin("book")->On(clauses);
229
230 std::vector<std::string> columns;
231 Uri userUri (USER_URI);
232 auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns);
233 int rowCount;
234 resultSet->GetRowCount(rowCount);
235 EXPECT_EQ(3, rowCount);
236
237 EXPECT_EQ(E_OK, resultSet->GoToFirstRow());
238 int userId;
239 EXPECT_EQ(E_OK, resultSet->GetInt(0, userId));
240 EXPECT_EQ(1, userId);
241
242 std::string firstName;
243 EXPECT_EQ(E_OK, resultSet->GetString(1, firstName));
244 EXPECT_EQ("Zhang", firstName);
245
246 std::string lastName;
247 EXPECT_EQ(E_OK, resultSet->GetString(2, lastName));
248 EXPECT_EQ("San", lastName);
249
250 int age;
251 EXPECT_EQ(E_OK, resultSet->GetInt(3, age));
252 EXPECT_EQ(29, age);
253
254 double balance;
255 EXPECT_EQ(E_OK, resultSet->GetDouble(4, balance));
256 EXPECT_EQ(100.51, balance);
257
258 int id;
259 EXPECT_EQ(E_OK, resultSet->GetInt(5, id));
260 EXPECT_EQ(1, id);
261
262 std::string name;
263 EXPECT_EQ(E_OK, resultSet->GetString(6, name));
264 EXPECT_EQ("SanGuo", name);
265
266 int userId_1;
267 EXPECT_EQ(E_OK, resultSet->GetInt(7, userId_1));
268 EXPECT_EQ(1, userId_1);
269 }
270
271 /**
272 * @tc.name: Join_InnerJoin_001
273 * @tc.require: None
274 * @tc.desc: Verify inner join with filter returns correct single result
275 * @tc.type: FUNC
276 * @tc.precon: None
277 * @tc.step:
278 1. Create inner join predicate with "user.userId = book.userId" condition
279 2. Add filter for book.name = "SanGuo"
280 3. Execute query on user table with join predicate
281 4. Verify row count is 1
282 5. Check row data matches expected values for "SanGuo" book
283 * @tc.experct:
284 1. Query returns 1 row
285 2. Row contains correct user and book data for "SanGuo" book
286 */
287 HWTEST_F(JoinTest, Join_InnerJoin_001, TestSize.Level0)
288 {
289 auto helper = g_slientAccessHelper;
290 DataShare::DataSharePredicates predicates;
291 std::vector<std::string> clauses;
292 clauses.push_back("user.userId = book.userId");
293 predicates.InnerJoin("book")->On(clauses)->EqualTo("book.name", "SanGuo");
294
295 std::vector<std::string> columns;
296 Uri userUri (USER_URI);
297 auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns);
298
299 int rowCount;
300 resultSet->GetRowCount(rowCount);
301 EXPECT_EQ(1, rowCount);
302 EXPECT_EQ(E_OK, resultSet->GoToFirstRow());
303
304 int userId;
305 EXPECT_EQ(E_OK, resultSet->GetInt(0, userId));
306 EXPECT_EQ(1, userId);
307
308 std::string firstName;
309 EXPECT_EQ(E_OK, resultSet->GetString(1, firstName));
310 EXPECT_EQ("Zhang", firstName);
311
312 std::string lastName;
313 EXPECT_EQ(E_OK, resultSet->GetString(2, lastName));
314 EXPECT_EQ("San", lastName);
315
316 int age;
317 EXPECT_EQ(E_OK, resultSet->GetInt(3, age));
318 EXPECT_EQ(29, age);
319
320 double balance;
321 EXPECT_EQ(E_OK, resultSet->GetDouble(4, balance));
322 EXPECT_EQ(100.51, balance);
323
324 int id;
325 EXPECT_EQ(E_OK, resultSet->GetInt(5, id));
326 EXPECT_EQ(1, id);
327
328 std::string name;
329 EXPECT_EQ(E_OK, resultSet->GetString(6, name));
330 EXPECT_EQ("SanGuo", name);
331
332 int userId_1;
333 EXPECT_EQ(E_OK, resultSet->GetInt(7, userId_1));
334 EXPECT_EQ(1, userId_1);
335 }
336
337 /**
338 * @tc.name: Join_LeftOuterJoin_001
339 * @tc.desc: Verify left outer join with Using clause returns correct result
340 * @tc.type: FUNC
341 * @tc.require: None
342 * @tc.precon: None
343 * @tc.step:
344 1. Create left outer join predicate using "userId" column
345 2. Add filter for name = "SanGuo"
346 3. Execute query on user table with join predicate
347 4. Verify row count is 1
348 5. Check row data matches expected values
349 * @tc.experct:
350 1. Query returns 1 row
351 2. Row contains correct user and book data for matching record
352 */
353 HWTEST_F(JoinTest, Join_LeftOuterJoin_001, TestSize.Level0)
354 {
355 auto helper = g_slientAccessHelper;
356 DataShare::DataSharePredicates predicates;
357 std::vector<std::string> fields;
358 fields.push_back("userId");
359 predicates.LeftOuterJoin("book")->Using(fields)->EqualTo("name", "SanGuo");
360
361 std::vector<std::string> columns;
362 Uri userUri (USER_URI);
363 auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns);
364
365 int rowCount;
366 resultSet->GetRowCount(rowCount);
367 EXPECT_EQ(1, rowCount);
368 EXPECT_EQ(E_OK, resultSet->GoToFirstRow());
369
370 int userId;
371 EXPECT_EQ(E_OK, resultSet->GetInt(0, userId));
372 EXPECT_EQ(1, userId);
373
374 std::string firstName;
375 EXPECT_EQ(E_OK, resultSet->GetString(1, firstName));
376 EXPECT_EQ("Zhang", firstName);
377
378 std::string lastName;
379 EXPECT_EQ(E_OK, resultSet->GetString(2, lastName));
380 EXPECT_EQ("San", lastName);
381
382 int age;
383 EXPECT_EQ(E_OK, resultSet->GetInt(3, age));
384 EXPECT_EQ(29, age);
385
386 double balance;
387 EXPECT_EQ(E_OK, resultSet->GetDouble(4, balance));
388 EXPECT_EQ(100.51, balance);
389
390 int id;
391 EXPECT_EQ(E_OK, resultSet->GetInt(5, id));
392 EXPECT_EQ(1, id);
393
394 std::string name;
395 EXPECT_EQ(E_OK, resultSet->GetString(6, name));
396 EXPECT_EQ("SanGuo", name);
397 }
398
399 /**
400 * @tc.name: Join_LeftOuterJoin_002
401 * @tc.desc: Verify left outer join returns all user records with matching books
402 * @tc.type: FUNC
403 * @tc.require: None
404 * @tc.precon: None
405 * @tc.step:
406 1. Create left outer join predicate with "user.userId = book.userId" condition
407 2. Execute query on user table with join predicate
408 3. Verify row count is 5 (all users including those without books)
409 * @tc.experct:
410 1. Query returns 5 rows
411 2. All user records are included in results
412 */
413 HWTEST_F(JoinTest, Join_LeftOuterJoin_002, TestSize.Level0)
414 {
415 auto helper = g_slientAccessHelper;
416 DataShare::DataSharePredicates predicates;
417 std::vector<std::string> clauses;
418 clauses.push_back("user.userId = book.userId");
419 predicates.LeftOuterJoin("book")->On(clauses);
420
421 std::vector<std::string> columns;
422 Uri userUri (USER_URI);
423 auto resultSet = g_slientAccessHelper->Query(userUri, predicates, columns);
424 int rowCount;
425 resultSet->GetRowCount(rowCount);
426 EXPECT_EQ(5, rowCount);
427 }
428 } // namespace DataShare
429 } // namespace OHOS