1 /*
2  * Copyright (c) 2024 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 <cctype>
16 #include <condition_variable>
17 #include <cstdint>
18 #include <fcntl.h>
19 #include <filesystem>
20 #include <functional>
21 #include <gtest/gtest.h>
22 #include <iostream>
23 #include <list>
24 #include <map>
25 #include <memory>
26 #include <mutex>
27 #include <string>
28 #include <sys/mman.h>
29 #include <thread>
30 #include <vector>
31 
32 #include "log_print.h"
33 #include "preferences_test_utils.h"
34 #include "oh_preferences_impl.h"
35 #include "oh_preferences.h"
36 #include "oh_preferences_err_code.h"
37 #include "oh_preferences_value.h"
38 #include "oh_preferences_option.h"
39 #include "preferences_helper.h"
40 
41 using namespace testing::ext;
42 using namespace testing;
43 using namespace OHOS::PreferencesNdk;
44 using namespace OHOS::NativePreferences;
45 namespace {
46 class PreferencesNdkTest : public testing::Test {
47 public:
48     static void SetUpTestCase(void);
49     static void TearDownTestCase(void);
50     void SetUp();
51     void TearDown();
52 };
53 
SetUpTestCase(void)54 void PreferencesNdkTest::SetUpTestCase(void)
55 {
56     NdkTestUtils::CreateDirectoryRecursively("/data/test/");
57 }
TearDownTestCase(void)58 void PreferencesNdkTest::TearDownTestCase(void) {}
59 
SetUp(void)60 void PreferencesNdkTest::SetUp(void)
61 {
62     NdkTestUtils::CreateDirectoryRecursively("/data/test/");
63 }
64 
TearDown(void)65 void PreferencesNdkTest::TearDown(void) {}
66 
67 enum class PrefDataType { UNASSIGNED, INT, STRING, BOOL };
68 
69 const uint32_t INVALID_INDEX = 100;
70 
GetCommonOption()71 static OH_PreferencesOption *GetCommonOption()
72 {
73     OH_PreferencesOption *option = OH_PreferencesOption_Create();
74     EXPECT_EQ(OH_PreferencesOption_SetFileName(option, "testdb"), PREFERENCES_OK);
75     EXPECT_EQ(OH_PreferencesOption_SetBundleName(option, "com.uttest"), PREFERENCES_OK);
76     EXPECT_EQ(OH_PreferencesOption_SetDataGroupId(option, "123"), PREFERENCES_OK);
77     return option;
78 }
79 
80 std::map<std::string, int> g_intDataMap = {
81     {"ndktest_int_key_1", -2147483648},
82     {"ndktest_int_key_2", -1},
83     {"ndktest_int_key_3", 0},
84     {"ndktest_int_key_4", 1},
85     {"ndktest_int_key_5", 2147483647}
86 };
87 
88 std::map<std::string, std::string> g_stringDataMap = {
89     {"ndktest_string_key_1", "2679b2c70120214984b3aec34fc849dc996f40e3cdb60f3b3eaf8abe2559439a"},
90     {"ndktest_string_key_2", "+88780079687688"},
91     {"ndktest_string_key_3", "/data/storage/el2/base/files/Thumbnail_1717209543267.jpg"},
92     {"ndktest_string_key_4", "A NEW PHONE"},
93     {"ndktest_string_key_5", "https://upfile-drcn.platform.hicloud.com/"}
94 };
95 
96 std::map<std::string, bool> g_boolDataMap = {
97     {"ndktest_bool_key_1", true},
98     {"ndktest_bool_key_2", false},
99     {"ndktest_bool_key_3", false},
100     {"ndktest_bool_key_4", true},
101     {"ndktest_bool_key_5", true}
102 };
103 
104 int g_changeNum = 0;
DataChangeObserverCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count)105 void DataChangeObserverCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count)
106 {
107     for (uint32_t i = 0; i < count; i++) {
108         const OH_PreferencesValue *pValue = OH_PreferencesPair_GetPreferencesValue(pairs, i);
109         Preference_ValueType type = OH_PreferencesValue_GetValueType(pValue);
110         const char *pKey = OH_PreferencesPair_GetKey(pairs, i);
111         EXPECT_NE(pKey, nullptr);
112         if (type == Preference_ValueType::PREFERENCE_TYPE_INT) {
113             int intV = 0;
114             OH_PreferencesValue_GetInt(pValue, &intV);
115         } else if (type == Preference_ValueType::PREFERENCE_TYPE_BOOL) {
116             bool boolV = false;
117             OH_PreferencesValue_GetBool(pValue, &boolV);
118         } else if (type == Preference_ValueType::PREFERENCE_TYPE_STRING) {
119             char *stringV = nullptr;
120             uint32_t len = 0;
121             OH_PreferencesValue_GetString(pValue, &stringV, &len);
122             OH_Preferences_FreeString(stringV);
123         }
124         g_changeNum++;
125     }
126 }
127 
PreferencesFlush(OH_Preferences *preference)128 int PreferencesFlush(OH_Preferences *preference)
129 {
130     OH_PreferencesImpl *pref = static_cast<OH_PreferencesImpl *>(preference);
131     std::shared_ptr<OHOS::NativePreferences::Preferences> nativePreferences = pref->GetNativePreferences();
132     return nativePreferences->FlushSync();
133 }
134 
SetAllValuesWithCheck(OH_Preferences *pref)135 void SetAllValuesWithCheck(OH_Preferences *pref)
136 {
137     for (auto &[key, value] : g_intDataMap) {
138         EXPECT_EQ(OH_Preferences_SetInt(pref, key.c_str(), value), PREFERENCES_OK);
139         EXPECT_EQ(PreferencesFlush(pref), OHOS::NativePreferences::E_OK);
140         int res = 0;
141         EXPECT_EQ(OH_Preferences_GetInt(pref, key.c_str(), &res), PREFERENCES_OK);
142         EXPECT_EQ(res, value);
143     }
144     for (auto &[key, value] : g_stringDataMap) {
145         EXPECT_EQ(OH_Preferences_SetString(pref, key.c_str(), value.c_str()), PREFERENCES_OK);
146         EXPECT_EQ(PreferencesFlush(pref), OHOS::NativePreferences::E_OK);
147         char *res = nullptr;
148         uint32_t len = 0;
149         EXPECT_EQ(OH_Preferences_GetString(pref, key.c_str(), &res, &len), PREFERENCES_OK);
150         EXPECT_EQ(strcmp(res, value.c_str()), 0);
151         OH_Preferences_FreeString(res);
152     }
153     for (auto &[key, value] : g_boolDataMap) {
154         EXPECT_EQ(OH_Preferences_SetBool(pref, key.c_str(), value), PREFERENCES_OK);
155         EXPECT_EQ(PreferencesFlush(pref), OHOS::NativePreferences::E_OK);
156         bool res;
157         EXPECT_EQ(OH_Preferences_GetBool(pref, key.c_str(), &res), PREFERENCES_OK);
158         EXPECT_EQ(res, value);
159     }
160 }
161 
CheckTargetTypeValues(OH_Preferences *pref, bool exist, PrefDataType pdt)162 void CheckTargetTypeValues(OH_Preferences *pref, bool exist, PrefDataType pdt)
163 {
164     if (pdt == PrefDataType::INT) {
165         for (auto &[key, value] : g_intDataMap) {
166             int res;
167             if (exist) {
168                 EXPECT_EQ(OH_Preferences_GetInt(pref, key.c_str(), &res), PREFERENCES_OK);
169                 EXPECT_EQ(res, value);
170             } else {
171                 EXPECT_EQ(OH_Preferences_GetInt(pref, key.c_str(), &res), PREFERENCES_ERROR_KEY_NOT_FOUND);
172             }
173         }
174     } else if (pdt == PrefDataType::STRING) {
175         for (auto &[key, value] : g_stringDataMap) {
176             char *res = nullptr;
177             uint32_t len = 0;
178             if (exist) {
179                 EXPECT_EQ(OH_Preferences_GetString(pref, key.c_str(), &res, &len), PREFERENCES_OK);
180                 EXPECT_EQ(strcmp(res, value.c_str()), 0);
181             } else {
182                 EXPECT_EQ(OH_Preferences_GetString(pref, key.c_str(), &res, &len), PREFERENCES_ERROR_KEY_NOT_FOUND);
183             }
184             OH_Preferences_FreeString(res);
185         }
186     } else if (pdt == PrefDataType::BOOL) {
187         for (auto &[key, value] : g_boolDataMap) {
188             bool res;
189             if (exist) {
190                 EXPECT_EQ(OH_Preferences_GetBool(pref, key.c_str(), &res), PREFERENCES_OK);
191                 EXPECT_EQ(res, value);
192             } else {
193                 EXPECT_EQ(OH_Preferences_GetBool(pref, key.c_str(), &res), PREFERENCES_ERROR_KEY_NOT_FOUND);
194             }
195         }
196     }
197 }
198 
199 /**
200  * @tc.name: NDKPreferencesGetTest_001
201  * @tc.desc: 测试先put int类型的kv,再get相同的key,值相同
202  * @tc.type: FUNC
203  * @tc.require: NA
204  * @tc.author: Song Yixiu
205  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_001, TestSize.Level1)206 HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_001, TestSize.Level1)
207 {
208     int errCode = PREFERENCES_OK;
209     OH_PreferencesOption *option = GetCommonOption();
210     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
211     (void)OH_PreferencesOption_Destroy(option);
212     ASSERT_EQ(errCode, PREFERENCES_OK);
213 
214     SetAllValuesWithCheck(pref);
215 
216     const char *key = "test_key_int";
217     EXPECT_EQ(OH_Preferences_SetInt(pref, key, 12), PREFERENCES_OK);
218     int ret;
219     EXPECT_EQ(OH_Preferences_GetInt(pref, key, &ret), PREFERENCES_OK);
220     EXPECT_EQ(ret, 12);
221 
222     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
223     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
224         OHOS::NativePreferences::E_OK);
225 }
226 
227 /**
228  * @tc.name: NDKPreferencesGetTest_002
229  * @tc.desc: 测试先put string类型的kv,再get相同的key,值相同
230  * @tc.type: FUNC
231  * @tc.require: NA
232  * @tc.author: Song Yixiu
233  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_002, TestSize.Level1)234 HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_002, TestSize.Level1)
235 {
236     int errCode = PREFERENCES_OK;
237     OH_PreferencesOption *option = GetCommonOption();
238     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
239     (void)OH_PreferencesOption_Destroy(option);
240     ASSERT_EQ(errCode, PREFERENCES_OK);
241 
242     SetAllValuesWithCheck(pref);
243 
244     const char *key = "test_key_string";
245     const char *value = "test_value";
246     EXPECT_EQ(OH_Preferences_SetString(pref, key, value), PREFERENCES_OK);
247     char *ret = nullptr;
248     uint32_t len = 0;
249     EXPECT_EQ(OH_Preferences_GetString(pref, key, &ret, &len), PREFERENCES_OK);
250     EXPECT_EQ(strcmp(ret, value), 0);
251     OH_Preferences_FreeString(ret);
252 
253     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
254     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
255         OHOS::NativePreferences::E_OK);
256 }
257 
258 /**
259  * @tc.name: NDKPreferencesGetTest_003
260  * @tc.desc: 测试先put bool类型的kv,再get相同的key,值相同
261  * @tc.type: FUNC
262  * @tc.require: NA
263  * @tc.author: Song Yixiu
264  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_003, TestSize.Level1)265 HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_003, TestSize.Level1)
266 {
267     int errCode = PREFERENCES_OK;
268     OH_PreferencesOption *option = GetCommonOption();
269     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
270     (void)OH_PreferencesOption_Destroy(option);
271     ASSERT_EQ(errCode, PREFERENCES_OK);
272 
273     SetAllValuesWithCheck(pref);
274 
275     const char *key = "test_key_bool";
276     bool value = true;
277     EXPECT_EQ(OH_Preferences_SetBool(pref, key, value), PREFERENCES_OK);
278     bool ret;
279     EXPECT_EQ(OH_Preferences_GetBool(pref, key, &ret), PREFERENCES_OK);
280     EXPECT_EQ(ret, value);
281 
282     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
283     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
284         OHOS::NativePreferences::E_OK);
285 }
286 
287 /**
288  * @tc.name: NDKPreferencesGetTest_004
289  * @tc.desc: 测试get不存在的kv
290  * @tc.type: FUNC
291  * @tc.require: NA
292  * @tc.author: Song Yixiu
293  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_004, TestSize.Level1)294 HWTEST_F(PreferencesNdkTest, NDKPreferencesGetTest_004, TestSize.Level1)
295 {
296     int errCode = PREFERENCES_OK;
297     OH_PreferencesOption *option = GetCommonOption();
298     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
299     (void)OH_PreferencesOption_Destroy(option);
300     ASSERT_EQ(errCode, PREFERENCES_OK);
301 
302     CheckTargetTypeValues(pref, false, PrefDataType::INT);
303     CheckTargetTypeValues(pref, false, PrefDataType::STRING);
304     CheckTargetTypeValues(pref, false, PrefDataType::BOOL);
305 
306     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
307     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
308         OHOS::NativePreferences::E_OK);
309 }
310 
311 /**
312  * @tc.name: NDKPreferencesPutTest_001
313  * @tc.desc: 测试先get不存在的kv,再put进kv,然后get
314  * @tc.type: FUNC
315  * @tc.require: NA
316  * @tc.author: Song Yixiu
317  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesPutTest_001, TestSize.Level1)318 HWTEST_F(PreferencesNdkTest, NDKPreferencesPutTest_001, TestSize.Level1)
319 {
320     int errCode = PREFERENCES_OK;
321     OH_PreferencesOption *option = GetCommonOption();
322     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
323     (void)OH_PreferencesOption_Destroy(option);
324     ASSERT_EQ(errCode, PREFERENCES_OK);
325 
326     CheckTargetTypeValues(pref, false, PrefDataType::INT);
327     CheckTargetTypeValues(pref, false, PrefDataType::STRING);
328     CheckTargetTypeValues(pref, false, PrefDataType::BOOL);
329 
330     SetAllValuesWithCheck(pref);
331 
332     CheckTargetTypeValues(pref, true, PrefDataType::INT);
333     CheckTargetTypeValues(pref, true, PrefDataType::STRING);
334     CheckTargetTypeValues(pref, true, PrefDataType::BOOL);
335 
336     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
337     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
338         OHOS::NativePreferences::E_OK);
339 }
340 
341 /**
342  * @tc.name: NDKPreferencesUpdateTest_001
343  * @tc.desc: 测试先put int类型的kv,然后get,然后再put新的值进行更新,再get
344  * @tc.type: FUNC
345  * @tc.require: NA
346  * @tc.author: Song Yixiu
347  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesUpdateTest_001, TestSize.Level1)348 HWTEST_F(PreferencesNdkTest, NDKPreferencesUpdateTest_001, TestSize.Level1)
349 {
350     int errCode = PREFERENCES_OK;
351     OH_PreferencesOption *option = GetCommonOption();
352     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
353     (void)OH_PreferencesOption_Destroy(option);
354     ASSERT_EQ(errCode, PREFERENCES_OK);
355 
356     SetAllValuesWithCheck(pref);
357 
358     const char *key = "ndktest_int_key_1";
359     int newValue = 10;
360     EXPECT_EQ(OH_Preferences_SetInt(pref, key, newValue), PREFERENCES_OK);
361     int ret;
362     EXPECT_EQ(OH_Preferences_GetInt(pref, key, &ret), PREFERENCES_OK);
363     EXPECT_EQ(ret, newValue);
364 
365     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
366     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
367         OHOS::NativePreferences::E_OK);
368 }
369 
370 /**
371  * @tc.name: NDKPreferencesUpdateTest_002
372  * @tc.desc: 测试先put string类型的kv,然后get,然后再put新的值进行更新,再get
373  * @tc.type: FUNC
374  * @tc.require: NA
375  * @tc.author: Song Yixiu
376  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesUpdateTest_002, TestSize.Level1)377 HWTEST_F(PreferencesNdkTest, NDKPreferencesUpdateTest_002, TestSize.Level1)
378 {
379     int errCode = PREFERENCES_OK;
380     OH_PreferencesOption *option = GetCommonOption();
381     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
382     (void)OH_PreferencesOption_Destroy(option);
383     ASSERT_EQ(errCode, PREFERENCES_OK);
384 
385     SetAllValuesWithCheck(pref);
386 
387     const char *key = "ndktest_string_key_1";
388     const char *newValue = "adlkj1#$&sdioj9i0i841a61aa4gh44o98()!@@.,.{:/',}";
389     EXPECT_EQ(OH_Preferences_SetString(pref, key, newValue), PREFERENCES_OK);
390     char *ret = nullptr;
391     uint32_t len = 0;
392     EXPECT_EQ(OH_Preferences_GetString(pref, key, &ret, &len), PREFERENCES_OK);
393     EXPECT_EQ(strcmp(ret, newValue), 0);
394     OH_Preferences_FreeString(ret);
395 
396     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
397     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
398         OHOS::NativePreferences::E_OK);
399 }
400 
401 /**
402  * @tc.name: NDKPreferencesUpdateTest_003
403  * @tc.desc: 测试先put bool类型的kv,然后get,然后再put新的值进行更新,再get
404  * @tc.type: FUNC
405  * @tc.require: NA
406  * @tc.author: Song Yixiu
407  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesUpdateTest_003, TestSize.Level1)408 HWTEST_F(PreferencesNdkTest, NDKPreferencesUpdateTest_003, TestSize.Level1)
409 {
410     int errCode = PREFERENCES_OK;
411     OH_PreferencesOption *option = GetCommonOption();
412     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
413     (void)OH_PreferencesOption_Destroy(option);
414     ASSERT_EQ(errCode, PREFERENCES_OK);
415 
416     SetAllValuesWithCheck(pref);
417 
418     const char *key = "ndktest_bool_key_1";
419     bool newValue = false;
420     EXPECT_EQ(OH_Preferences_SetBool(pref, key, newValue), PREFERENCES_OK);
421     bool ret;
422     EXPECT_EQ(OH_Preferences_GetBool(pref, key, &ret), PREFERENCES_OK);
423     EXPECT_EQ(ret, newValue);
424 
425     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
426     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
427         OHOS::NativePreferences::E_OK);
428 }
429 
430 /**
431  * @tc.name: NDKPreferencesDeleteTest_001
432  * @tc.desc: test Delete exist key
433  * @tc.type: FUNC
434  * @tc.require: NA
435  * @tc.author: Liu Xiaolong
436  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesDeleteTest_001, TestSize.Level1)437 HWTEST_F(PreferencesNdkTest, NDKPreferencesDeleteTest_001, TestSize.Level1)
438 {
439     int errCode = PREFERENCES_OK;
440     OH_PreferencesOption *option = GetCommonOption();
441     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
442     (void)OH_PreferencesOption_Destroy(option);
443     ASSERT_EQ(errCode, PREFERENCES_OK);
444 
445     SetAllValuesWithCheck(pref);
446 
447     for (auto &[key, value] : g_stringDataMap) {
448         EXPECT_EQ(OH_Preferences_Delete(pref, key.c_str()), PREFERENCES_OK);
449     }
450 
451     CheckTargetTypeValues(pref, true, PrefDataType::INT);
452     CheckTargetTypeValues(pref, false, PrefDataType::STRING);
453     CheckTargetTypeValues(pref, true, PrefDataType::BOOL);
454 
455     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
456     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
457         OHOS::NativePreferences::E_OK);
458 }
459 
460 /**
461  * @tc.name: NDKPreferencesDeleteTest_002
462  * @tc.desc: test Delete non-exist key
463  * @tc.type: FUNC
464  * @tc.require: NA
465  * @tc.author: Liu Xiaolong
466  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesDeleteTest_002, TestSize.Level1)467 HWTEST_F(PreferencesNdkTest, NDKPreferencesDeleteTest_002, TestSize.Level1)
468 {
469     int errCode = PREFERENCES_OK;
470     OH_PreferencesOption *option = GetCommonOption();
471     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
472     (void)OH_PreferencesOption_Destroy(option);
473     ASSERT_EQ(errCode, PREFERENCES_OK);
474 
475     CheckTargetTypeValues(pref, false, PrefDataType::INT);
476 
477     for (auto &[key, value] : g_intDataMap) {
478         EXPECT_EQ(OH_Preferences_Delete(pref, key.c_str()), PREFERENCES_OK);
479     }
480 
481     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
482     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
483         OHOS::NativePreferences::E_OK);
484 }
485 
RegisterObsInFunc(OH_Preferences *pref)486 static void RegisterObsInFunc(OH_Preferences *pref)
487 {
488     const char *keys[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
489 
490     int ret = OH_Preferences_RegisterDataObserver(pref, nullptr, DataChangeObserverCallback, keys, 3);
491     ASSERT_EQ(ret, PREFERENCES_OK);
492 }
493 
UnRegisterObsInFunc(OH_Preferences *pref)494 static void UnRegisterObsInFunc(OH_Preferences *pref)
495 {
496     const char *keys[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
497 
498     int ret = OH_Preferences_UnregisterDataObserver(pref, nullptr, DataChangeObserverCallback, keys, 3);
499     ASSERT_EQ(ret, PREFERENCES_OK);
500 }
501 
502 /**
503  * @tc.name: NDKPreferencesObserverTest_001
504  * @tc.desc: test Observer
505  * @tc.type: FUNC
506  * @tc.require: NA
507  * @tc.author: Liu Xiaolong
508  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_001, TestSize.Level1)509 HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_001, TestSize.Level1)
510 {
511     int errCode = PREFERENCES_OK;
512     OH_PreferencesOption *option = GetCommonOption();
513     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
514     (void)OH_PreferencesOption_Destroy(option);
515     ASSERT_EQ(errCode, PREFERENCES_OK);
516 
517     RegisterObsInFunc(pref);
518 
519     SetAllValuesWithCheck(pref);
520 
521     for (auto &[key, value] : g_intDataMap) {
522         EXPECT_EQ(OH_Preferences_Delete(pref, key.c_str()), PREFERENCES_OK);
523         EXPECT_EQ(PreferencesFlush(pref), OHOS::NativePreferences::E_OK);
524     }
525 
526     for (auto &[key, value] : g_stringDataMap) {
527         const char *newValue = "update_string_value_109uokadnf894u5";
528         EXPECT_EQ(OH_Preferences_SetString(pref, key.c_str(), newValue), PREFERENCES_OK);
529         EXPECT_EQ(PreferencesFlush(pref), OHOS::NativePreferences::E_OK);
530     }
531 
532     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
533 
534     EXPECT_EQ(g_changeNum, 5);
535 
536     UnRegisterObsInFunc(pref);
537 
538     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
539     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
540         OHOS::NativePreferences::E_OK);
541 }
542 
543 /**
544  * @tc.name: NDKPreferencesObserverTest_002
545  * @tc.desc: test Observer
546  * @tc.type: FUNC
547  * @tc.require: NA
548  * @tc.author: bluhuang
549  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_002, TestSize.Level1)550 HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_002, TestSize.Level1)
551 {
552     // cannot get callback when unregister
553     int errCode = PREFERENCES_OK;
554     OH_PreferencesOption *option = GetCommonOption();
555     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
556     (void)OH_PreferencesOption_Destroy(option);
557     ASSERT_EQ(errCode, PREFERENCES_OK);
558 
559     const char *keys[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
560     g_changeNum = 0;
561     int ret = OH_Preferences_RegisterDataObserver(pref, nullptr, DataChangeObserverCallback, keys, 3);
562     ASSERT_EQ(ret, PREFERENCES_OK);
563     const char *empty[] = {};
564     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, DataChangeObserverCallback, empty, 0),
565         PREFERENCES_OK);
566 
567     SetAllValuesWithCheck(pref);
568     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
569     EXPECT_EQ(g_changeNum, 0);
570     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
571 
572     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
573         OHOS::NativePreferences::E_OK);
574 }
575 
576 /**
577  * @tc.name: NDKPreferencesObserverTest_003
578  * @tc.desc: test Observer
579  * @tc.type: FUNC
580  * @tc.require: NA
581  * @tc.author: bluhuang
582  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_003, TestSize.Level1)583 HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_003, TestSize.Level1)
584 {
585     int errCode = PREFERENCES_OK;
586     OH_PreferencesOption *option = GetCommonOption();
587     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
588     (void)OH_PreferencesOption_Destroy(option);
589     ASSERT_EQ(errCode, PREFERENCES_OK);
590 
591     const char *keys[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
592     g_changeNum = 0;
593     ASSERT_EQ(OH_Preferences_RegisterDataObserver(nullptr, nullptr, DataChangeObserverCallback, keys, 3),
594         PREFERENCES_ERROR_INVALID_PARAM);
595     ASSERT_EQ(OH_Preferences_RegisterDataObserver(pref, nullptr, nullptr, keys, 3), PREFERENCES_ERROR_INVALID_PARAM);
596     ASSERT_EQ(OH_Preferences_RegisterDataObserver(pref, nullptr, DataChangeObserverCallback, nullptr, 3),
597         PREFERENCES_ERROR_INVALID_PARAM);
598     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(nullptr, nullptr, DataChangeObserverCallback, keys, 0),
599         PREFERENCES_ERROR_INVALID_PARAM);
600     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, nullptr, keys, 0),
601         PREFERENCES_ERROR_INVALID_PARAM);
602     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, DataChangeObserverCallback, nullptr, 0),
603         PREFERENCES_ERROR_INVALID_PARAM);
604 }
605 
606 /**
607  * @tc.name: NDKPreferencesObserverTest_004
608  * @tc.desc: test Observer
609  * @tc.type: FUNC
610  * @tc.require: NA
611  * @tc.author: bluhuang
612  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_004, TestSize.Level1)613 HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_004, TestSize.Level1)
614 {
615     int errCode = PREFERENCES_OK;
616     OH_PreferencesOption *option = GetCommonOption();
617     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
618     (void)OH_PreferencesOption_Destroy(option);
619     ASSERT_EQ(errCode, PREFERENCES_OK);
620 
621     const char *keys1[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
622     g_changeNum = 0;
623     double obj = 1.1;
624     void *context1 = &obj;
625     ASSERT_EQ(OH_Preferences_RegisterDataObserver(pref, (void*) context1, DataChangeObserverCallback, keys1, 3),
626         PREFERENCES_OK);
627 
628     const char *keys2[] = {"ndktest_int_key_5"};
629     double obj2 = 2.2;
630     void *context2 = &obj2;
631     ASSERT_EQ(OH_Preferences_RegisterDataObserver(pref, (void*) context2, DataChangeObserverCallback, keys2, 1),
632         PREFERENCES_OK);
633     SetAllValuesWithCheck(pref);
634 
635     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
636 
637     EXPECT_EQ(g_changeNum, 4);
638 
639     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, DataChangeObserverCallback, keys1, 3),
640         PREFERENCES_OK);
641     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, DataChangeObserverCallback, keys2, 1),
642         PREFERENCES_OK);
643     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
644 
645     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
646         OHOS::NativePreferences::E_OK);
647 }
648 
649 /**
650  * @tc.name: NDKPreferencesObserverTest_005
651  * @tc.desc: test Observer
652  * @tc.type: FUNC
653  * @tc.require: NA
654  * @tc.author: bluhuang
655  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_005, TestSize.Level1)656 HWTEST_F(PreferencesNdkTest, NDKPreferencesObserverTest_005, TestSize.Level1)
657 {
658     // cancel part of all registerd key
659     int errCode = PREFERENCES_OK;
660     OH_PreferencesOption *option = GetCommonOption();
661     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
662     (void)OH_PreferencesOption_Destroy(option);
663     ASSERT_EQ(errCode, PREFERENCES_OK);
664 
665     const char *keys[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
666     g_changeNum = 0;
667     ASSERT_EQ(OH_Preferences_RegisterDataObserver(pref, nullptr, DataChangeObserverCallback, keys, 3),
668         PREFERENCES_OK);
669     const char *cancel[] = {"ndktest_bool_key_1"};
670     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, DataChangeObserverCallback, cancel, 1),
671         PREFERENCES_OK);
672 
673     SetAllValuesWithCheck(pref);
674 
675     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
676     EXPECT_EQ(g_changeNum, 2);
677 
678     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
679     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
680         OHOS::NativePreferences::E_OK);
681 }
682 
NullTestCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count)683 void NullTestCallback(void *context, const OH_PreferencesPair *pairs, uint32_t count)
684 {
685     for (uint32_t i = 0; i < count; i++) {
686         EXPECT_EQ(OH_PreferencesPair_GetPreferencesValue(nullptr, INVALID_INDEX), nullptr);
687         EXPECT_EQ(OH_PreferencesPair_GetPreferencesValue(pairs, INVALID_INDEX), nullptr);
688 
689         EXPECT_EQ(OH_PreferencesValue_GetValueType(nullptr), Preference_ValueType::PREFERENCE_TYPE_NULL);
690 
691         EXPECT_EQ(OH_PreferencesPair_GetKey(nullptr, INVALID_INDEX), nullptr);
692         EXPECT_EQ(OH_PreferencesPair_GetKey(pairs, INVALID_INDEX), nullptr);
693 
694         const OH_PreferencesValue *pValue = OH_PreferencesPair_GetPreferencesValue(pairs, i);
695         Preference_ValueType type = OH_PreferencesValue_GetValueType(pValue);
696         const char *pKey = OH_PreferencesPair_GetKey(pairs, i);
697         EXPECT_NE(pKey, nullptr);
698         if (type == Preference_ValueType::PREFERENCE_TYPE_INT) {
699             EXPECT_EQ(OH_PreferencesValue_GetInt(nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
700             EXPECT_EQ(OH_PreferencesValue_GetInt(pValue, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
701 
702             bool boolV = false;
703             EXPECT_EQ(OH_PreferencesValue_GetBool(pValue, &boolV), PREFERENCES_ERROR_KEY_NOT_FOUND);
704         } else if (type == Preference_ValueType::PREFERENCE_TYPE_BOOL) {
705             EXPECT_EQ(OH_PreferencesValue_GetBool(nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
706             EXPECT_EQ(OH_PreferencesValue_GetBool(pValue, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
707 
708             char *stringV = nullptr;
709             uint32_t len = 0;
710             EXPECT_EQ(OH_PreferencesValue_GetString(pValue, &stringV, &len), PREFERENCES_ERROR_KEY_NOT_FOUND);
711         } else if (type == Preference_ValueType::PREFERENCE_TYPE_STRING) {
712             char *stringV = nullptr;
713             EXPECT_EQ(OH_PreferencesValue_GetString(nullptr, nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
714             EXPECT_EQ(OH_PreferencesValue_GetString(pValue, nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
715             EXPECT_EQ(OH_PreferencesValue_GetString(pValue, &stringV, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
716 
717             int intV = 0;
718             EXPECT_EQ(OH_PreferencesValue_GetInt(pValue, &intV), PREFERENCES_ERROR_KEY_NOT_FOUND);
719         }
720     }
721 }
722 
723 /**
724  * @tc.name: NDKPreferencesNullInputTest_001
725  * @tc.desc: test NULL Input
726  * @tc.type: FUNC
727  * @tc.require: NA
728  * @tc.author: Liu Xiaolong
729  */
HWTEST_F(PreferencesNdkTest, NDKPreferencesNullInputTest_001, TestSize.Level1)730 HWTEST_F(PreferencesNdkTest, NDKPreferencesNullInputTest_001, TestSize.Level1)
731 {
732     int errCode = PREFERENCES_OK;
733     OH_PreferencesOption *option = OH_PreferencesOption_Create();
734 
735     EXPECT_EQ(OH_PreferencesOption_SetFileName(nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
736     EXPECT_EQ(OH_PreferencesOption_SetFileName(option, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
737     EXPECT_EQ(OH_PreferencesOption_SetFileName(option, ""), PREFERENCES_ERROR_INVALID_PARAM);
738 
739     EXPECT_EQ(OH_PreferencesOption_SetBundleName(nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
740     EXPECT_EQ(OH_PreferencesOption_SetBundleName(option, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
741 
742     EXPECT_EQ(OH_PreferencesOption_SetDataGroupId(nullptr, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
743     EXPECT_EQ(OH_PreferencesOption_SetDataGroupId(option, nullptr), PREFERENCES_ERROR_INVALID_PARAM);
744 
745     EXPECT_EQ(OH_PreferencesOption_Destroy(nullptr), PREFERENCES_ERROR_INVALID_PARAM);
746 
747     EXPECT_EQ(OH_PreferencesOption_SetFileName(option, "testdb"), PREFERENCES_OK);
748     EXPECT_EQ(OH_PreferencesOption_SetBundleName(option, "com.uttest"), PREFERENCES_OK);
749     EXPECT_EQ(OH_PreferencesOption_SetDataGroupId(option, "123"), PREFERENCES_OK);
750     OH_Preferences *pref = OH_Preferences_Open(option, &errCode);
751     (void)OH_PreferencesOption_Destroy(option);
752     ASSERT_EQ(errCode, PREFERENCES_OK);
753 
754     const char *keys[] = {"ndktest_int_key_1", "ndktest_string_key_1", "ndktest_bool_key_1"};
755     ASSERT_EQ(OH_Preferences_RegisterDataObserver(pref, nullptr, NullTestCallback, keys, 3), PREFERENCES_OK);
756 
757     SetAllValuesWithCheck(pref);
758 
759     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
760 
761     EXPECT_EQ(OH_Preferences_UnregisterDataObserver(pref, nullptr, NullTestCallback, keys, 3), PREFERENCES_OK);
762     EXPECT_EQ(OH_Preferences_Close(pref), PREFERENCES_OK);
763 
764     EXPECT_EQ(OH_Preferences_Close(nullptr), PREFERENCES_ERROR_INVALID_PARAM);
765 
766     EXPECT_EQ(OHOS::NativePreferences::PreferencesHelper::DeletePreferences("/data/test/testdb"),
767         OHOS::NativePreferences::E_OK);
768 }
769 }
770