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