• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 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 
16 #include "auto_sync_timer.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include "block_data.h"
21 #include "kvdb_service_client.h"
22 #include "store_manager.h"
23 
24 using namespace OHOS;
25 using namespace testing::ext;
26 using namespace OHOS::DistributedKv;
27 using namespace std::chrono;
28 namespace OHOS::Test {
29 class AutoSyncTimerTest : public testing::Test {
30 public:
31     class KVDBServiceMock : public KVDBServiceClient {
32     private:
33         static KVDBServiceMock *instance_;
34 
35     public:
GetInstance()36         static KVDBServiceMock *GetInstance()
37         {
38             KVDBServiceClient::GetInstance();
39             return instance_;
40         }
KVDBServiceMock(const sptr<IRemoteObject> & object)41         explicit KVDBServiceMock(const sptr<IRemoteObject> &object) : KVDBServiceClient(object)
42         {
43             instance_ = this;
44         }
~KVDBServiceMock()45         virtual ~KVDBServiceMock()
46         {
47             instance_ = nullptr;
48         }
49 
Sync(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)50         Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override
51         {
52             endTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
53             values_[appId.appId].insert(storeId.storeId);
54             {
55                 std::lock_guard<decltype(mutex_)> guard(mutex_);
56                 ++callCount;
57                 value_.SetValue(callCount);
58             }
59             return KVDBServiceClient::Sync(appId, storeId, syncInfo);
60         }
61 
GetCallCount(uint32_t value)62         uint32_t GetCallCount(uint32_t value)
63         {
64             uint32_t retry = 0;
65             uint32_t callTimes = 0;
66             while (retry < value) {
67                 callTimes = value_.GetValue();
68                 if (callTimes >= value) {
69                     break;
70                 }
71                 std::lock_guard<decltype(mutex_)> guard(mutex_);
72                 callTimes = value_.GetValue();
73                 if (callTimes >= value) {
74                     break;
75                 }
76                 value_.Clear(callTimes);
77                 retry++;
78             }
79             return callTimes;
80         }
81 
ResetToZero()82         void ResetToZero()
83         {
84             std::lock_guard<decltype(mutex_)> guard(mutex_);
85             callCount = 0;
86             value_.Clear(0);
87         }
88 
89         uint64_t startTime = 0;
90         uint64_t endTime = 0;
91         uint32_t callCount = 0;
92         std::map<std::string, std::set<std::string>> values_;
93         BlockData<uint32_t> value_{ 1, 0 };
94         std::mutex mutex_;
95     };
96     class TestSyncCallback : public KvStoreSyncCallback {
97     public:
SyncCompleted(const std::map<std::string,Status> & results)98         void SyncCompleted(const std::map<std::string, Status> &results) override
99         {
100             ASSERT_TRUE(true);
101         }
102     };
103     static void SetUpTestCase(void);
104     static void TearDownTestCase(void);
105     void SetUp();
106     void TearDown();
107 
108 protected:
109     static BrokerDelegator<KVDBServiceMock> delegator_;
110     static constexpr int SLEEP_TIME = 10;
111 };
112 BrokerDelegator<AutoSyncTimerTest::KVDBServiceMock> AutoSyncTimerTest::delegator_;
113 AutoSyncTimerTest::KVDBServiceMock *AutoSyncTimerTest::KVDBServiceMock::instance_ = nullptr;
SetUpTestCase(void)114 void AutoSyncTimerTest::SetUpTestCase(void)
115 {
116 }
117 
TearDownTestCase(void)118 void AutoSyncTimerTest::TearDownTestCase(void)
119 {
120 }
121 
SetUp(void)122 void AutoSyncTimerTest::SetUp(void)
123 {
124 }
125 
TearDown(void)126 void AutoSyncTimerTest::TearDown(void)
127 {
128     sleep(SLEEP_TIME); // make sure the case has executed completely
129 }
130 
131 /**
132 * @tc.name: SingleWrite
133 * @tc.desc:  single write
134 * @tc.type: FUNC
135 * @tc.require: I4XVQQ
136 * @tc.author: Yang Qing
137 */
138 HWTEST_F(AutoSyncTimerTest, SingleWrite, TestSize.Level0)
139 {
140     auto *instance = KVDBServiceMock::GetInstance();
141     ASSERT_NE(instance, nullptr);
142     instance->ResetToZero();
143     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
144     instance->endTime = 0;
145     instance->values_.clear();
146     AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } });
147     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
148     auto it = instance->values_.find("ut_test");
149     ASSERT_NE(it, instance->values_.end());
150     ASSERT_EQ(it->second.count("ut_test_store"), 1);
151     ASSERT_LT(instance->endTime - instance->startTime, 100);
152 }
153 
154 /**
155 * @tc.name: MultiWriteBelowDelayTime
156 * @tc.desc: write every 40 milliseconds
157 * @tc.type: FUNC
158 * @tc.require: I4XVQQ
159 * @tc.author: Yang Qing
160 */
161 HWTEST_F(AutoSyncTimerTest, MultiWriteBelowDelayTime, TestSize.Level1)
162 {
163     auto *instance = KVDBServiceMock::GetInstance();
164     ASSERT_NE(instance, nullptr);
165     instance->ResetToZero();
166     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
167     instance->endTime = 0;
168     instance->values_.clear();
169     std::atomic_bool finished = false;
__anon09de766e0102null170     std::thread thread([&finished] {
171         while (!finished.load()) {
172             AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } });
173             std::this_thread::sleep_for(std::chrono::milliseconds(40));
174         }
175     });
176     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
177     ASSERT_GE(instance->endTime - instance->startTime, 200);
178     ASSERT_LT(instance->endTime - instance->startTime, 250);
179     finished.store(true);
180     thread.join();
181     auto it = instance->values_.find("ut_test");
182     ASSERT_NE(it, instance->values_.end());
183     ASSERT_EQ(it->second.count("ut_test_store"), 1);
184 }
185 
186 /**
187 * @tc.name: MultiWriteOverDelayTime
188 * @tc.desc: write every 150 milliseconds
189 * @tc.type: FUNC
190 * @tc.require: I4XVQQ
191 * @tc.author: Yang Qing
192  */
193 HWTEST_F(AutoSyncTimerTest, MultiWriteOverDelayTime, TestSize.Level1)
194 {
195     auto *instance = KVDBServiceMock::GetInstance();
196     ASSERT_NE(instance, nullptr);
197     instance->ResetToZero();
198     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
199     instance->endTime = 0;
200     instance->values_.clear();
201     std::atomic_bool finished = false;
__anon09de766e0202null202     std::thread thread([&finished] {
203         while (!finished.load()) {
204             AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } });
205             std::this_thread::sleep_for(std::chrono::milliseconds(150));
206         }
207     });
208     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
209     ASSERT_LT(instance->endTime - instance->startTime, 100);
210     finished.store(true);
211     thread.join();
212     auto it = instance->values_.find("ut_test");
213     ASSERT_NE(it, instance->values_.end());
214     ASSERT_EQ(it->second.count("ut_test_store"), 1);
215 }
216 
217 /**
218 * @tc.name: MultiWriteOverForceTime
219 * @tc.desc: write every 400 milliseconds
220 * @tc.type: FUNC
221 * @tc.require: I4XVQQ
222 * @tc.author: Yang Qing
223  */
224 HWTEST_F(AutoSyncTimerTest, MultiWriteOverForceTime, TestSize.Level1)
225 {
226     auto *instance = KVDBServiceMock::GetInstance();
227     ASSERT_NE(instance, nullptr);
228     instance->ResetToZero();
229     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
230     instance->endTime = 0;
231     instance->values_.clear();
232     std::atomic_bool finished = false;
__anon09de766e0302null233     std::thread thread([&finished] {
234         while (!finished.load()) {
235             AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } });
236             std::this_thread::sleep_for(std::chrono::milliseconds(400));
237         }
238     });
239     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
240     ASSERT_LT(instance->endTime - instance->startTime, 100);
241     finished.store(true);
242     thread.join();
243     auto it = instance->values_.find("ut_test");
244     ASSERT_NE(it, instance->values_.end());
245     ASSERT_EQ(it->second.count("ut_test_store"), 1);
246 }
247 
248 /**
249 * @tc.name: SingleWriteOvertenKVStores
250 * @tc.desc: single write over ten kv stores
251 * @tc.type: FUNC
252 * @tc.require: I4XVQQ
253 * @tc.author: Yang Qing
254 */
255 HWTEST_F(AutoSyncTimerTest, SingleWriteOvertenKVStores, TestSize.Level1)
256 {
257     auto *instance = KVDBServiceMock::GetInstance();
258     ASSERT_NE(instance, nullptr);
259     instance->ResetToZero();
260     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
261     instance->endTime = 0;
262     instance->values_.clear();
263     AutoSyncTimer::GetInstance().DoAutoSync("ut_test", {
264                                                            { "ut_test_store0" },
265                                                            { "ut_test_store1" },
266                                                            { "ut_test_store2" },
267                                                            { "ut_test_store3" },
268                                                            { "ut_test_store4" },
269                                                            { "ut_test_store5" },
270                                                            { "ut_test_store6" },
271                                                            { "ut_test_store7" },
272                                                            { "ut_test_store8" },
273                                                            { "ut_test_store9" },
274                                                            { "ut_test_store10" },
275                                                        });
276     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
277     ASSERT_LT(instance->endTime - instance->startTime, 100);
278     EXPECT_EQ(static_cast<int>(instance->GetCallCount(11)), 11);
279     auto it = instance->values_.find("ut_test");
280     ASSERT_NE(it, instance->values_.end());
281     ASSERT_EQ(it->second.count("ut_test_store0"), 1);
282     ASSERT_EQ(it->second.count("ut_test_store1"), 1);
283     ASSERT_EQ(it->second.count("ut_test_store2"), 1);
284     ASSERT_EQ(it->second.count("ut_test_store3"), 1);
285     ASSERT_EQ(it->second.count("ut_test_store4"), 1);
286     ASSERT_EQ(it->second.count("ut_test_store5"), 1);
287     ASSERT_EQ(it->second.count("ut_test_store6"), 1);
288     ASSERT_EQ(it->second.count("ut_test_store7"), 1);
289     ASSERT_EQ(it->second.count("ut_test_store8"), 1);
290     ASSERT_EQ(it->second.count("ut_test_store9"), 1);
291     ASSERT_EQ(it->second.count("ut_test_store10"), 1);
292 }
293 
294 /**
295 * @tc.name: MultiWriteOvertenKVStores
296 * @tc.desc: mulity wirte
297 * @tc.type: FUNC
298 * @tc.require: I4XVQQ
299 * @tc.author: YangQing
300 */
301 HWTEST_F(AutoSyncTimerTest, MultiWriteOvertenKVStores, TestSize.Level1)
302 {
303     auto *instance = KVDBServiceMock::GetInstance();
304     ASSERT_NE(instance, nullptr);
305     instance->ResetToZero();
306     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
307     instance->endTime = 0;
308     instance->values_.clear();
309     std::atomic_bool finished = false;
__anon09de766e0402null310     std::thread thread([&finished] {
311         while (!finished.load()) {
312             AutoSyncTimer::GetInstance().DoAutoSync("ut_test", {
313                                                                    { "ut_test_store0" },
314                                                                    { "ut_test_store1" },
315                                                                    { "ut_test_store2" },
316                                                                    { "ut_test_store3" },
317                                                                    { "ut_test_store4" },
318                                                                    { "ut_test_store5" },
319                                                                    { "ut_test_store6" },
320                                                                    { "ut_test_store7" },
321                                                                    { "ut_test_store8" },
322                                                                    { "ut_test_store9" },
323                                                                    { "ut_test_store10" },
324                                                                });
325             usleep(40);
326         }
327     });
328     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
329     ASSERT_GE(instance->endTime - instance->startTime, 200);
330     ASSERT_LT(instance->endTime - instance->startTime, 250);
331     EXPECT_EQ(static_cast<int>(instance->GetCallCount(11)), 11);
332     auto it = instance->values_.find("ut_test");
333     ASSERT_EQ(it->second.count("ut_test_store0"), 1);
334     ASSERT_EQ(it->second.count("ut_test_store1"), 1);
335     ASSERT_EQ(it->second.count("ut_test_store2"), 1);
336     ASSERT_EQ(it->second.count("ut_test_store3"), 1);
337     ASSERT_EQ(it->second.count("ut_test_store4"), 1);
338     ASSERT_EQ(it->second.count("ut_test_store5"), 1);
339     ASSERT_EQ(it->second.count("ut_test_store6"), 1);
340     ASSERT_EQ(it->second.count("ut_test_store7"), 1);
341     ASSERT_EQ(it->second.count("ut_test_store8"), 1);
342     ASSERT_EQ(it->second.count("ut_test_store9"), 1);
343     ASSERT_EQ(it->second.count("ut_test_store10"), 1);
344     finished.store(true);
345     thread.join();
346 }
347 
348 /**
349 * @tc.name: DoubleWrite
350 * @tc.desc: double wirte
351 * @tc.type: FUNC
352 * @tc.require: I4XVQQ
353 * @tc.author: YangQing
354  */
355 HWTEST_F(AutoSyncTimerTest, DoubleWrite, TestSize.Level1)
356 {
357     auto *instance = KVDBServiceMock::GetInstance();
358     ASSERT_NE(instance, nullptr);
359     instance->ResetToZero();
360     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
361     instance->endTime = 0;
362     instance->values_.clear();
363     AutoSyncTimer::GetInstance().DoAutoSync("ut_test", {
364                                                            { "ut_test_store0" },
365                                                            { "ut_test_store1" },
366                                                            { "ut_test_store2" },
367                                                            { "ut_test_store3" },
368                                                            { "ut_test_store4" },
369                                                            { "ut_test_store5" },
370                                                            { "ut_test_store6" },
371                                                            { "ut_test_store7" },
372                                                            { "ut_test_store8" },
373                                                            { "ut_test_store9" },
374                                                            { "ut_test_store10" },
375                                                        });
376     AutoSyncTimer::GetInstance().DoAutoSync("ut_test", {
377                                                            { "ut_test_store-0" },
378                                                            { "ut_test_store-1" },
379                                                            { "ut_test_store-2" },
380                                                            { "ut_test_store-3" },
381                                                            { "ut_test_store-4" },
382                                                            { "ut_test_store-5" },
383                                                            { "ut_test_store-6" },
384                                                            { "ut_test_store-7" },
385                                                            { "ut_test_store-8" },
386                                                        });
387     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
388     ASSERT_LT(instance->endTime - instance->startTime, 100);
389     EXPECT_EQ(static_cast<int>(instance->GetCallCount(20)), 20);
390     auto it = instance->values_.find("ut_test");
391     ASSERT_EQ(it->second.count("ut_test_store0"), 1);
392     ASSERT_EQ(it->second.count("ut_test_store1"), 1);
393     ASSERT_EQ(it->second.count("ut_test_store2"), 1);
394     ASSERT_EQ(it->second.count("ut_test_store3"), 1);
395     ASSERT_EQ(it->second.count("ut_test_store4"), 1);
396     ASSERT_EQ(it->second.count("ut_test_store5"), 1);
397     ASSERT_EQ(it->second.count("ut_test_store6"), 1);
398     ASSERT_EQ(it->second.count("ut_test_store7"), 1);
399     ASSERT_EQ(it->second.count("ut_test_store8"), 1);
400     ASSERT_EQ(it->second.count("ut_test_store9"), 1);
401     ASSERT_EQ(it->second.count("ut_test_store10"), 1);
402     ASSERT_EQ(it->second.count("ut_test_store-0"), 1);
403     ASSERT_EQ(it->second.count("ut_test_store-1"), 1);
404     ASSERT_EQ(it->second.count("ut_test_store-2"), 1);
405     ASSERT_EQ(it->second.count("ut_test_store-3"), 1);
406     ASSERT_EQ(it->second.count("ut_test_store-4"), 1);
407     ASSERT_EQ(it->second.count("ut_test_store-5"), 1);
408     ASSERT_EQ(it->second.count("ut_test_store-6"), 1);
409     ASSERT_EQ(it->second.count("ut_test_store-7"), 1);
410     ASSERT_EQ(it->second.count("ut_test_store-8"), 1);
411 }
412 } // namespace OHOS::Test