• 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 class AutoSyncTimerTest : public testing::Test {
29 public:
30     class KVDBServiceMock : public KVDBServiceClient {
31     private:
32         static KVDBServiceMock *instance_;
33 
34     public:
GetInstance()35         static KVDBServiceMock *GetInstance()
36         {
37             KVDBServiceClient::GetInstance();
38             return instance_;
39         }
KVDBServiceMock(const sptr<IRemoteObject> & object)40         explicit KVDBServiceMock(const sptr<IRemoteObject> &object) : KVDBServiceClient(object)
41         {
42             startTime = 0;
43             endTime = 0;
44             instance_ = this;
45         }
~KVDBServiceMock()46         virtual ~KVDBServiceMock()
47         {
48             instance_ = nullptr;
49         }
50 
Sync(const AppId & appId,const StoreId & storeId,const SyncInfo & syncInfo)51         Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override
52         {
53             endTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
54             values_[appId.appId].insert(storeId.storeId);
55             {
56                 std::lock_guard<decltype(mutex_)> guard(mutex_);
57                 ++callCount;
58                 value_.SetValue(callCount);
59             }
60             return KVDBServiceClient::Sync(appId, storeId, syncInfo);
61         }
62 
GetCallCount(uint32_t value)63         uint32_t GetCallCount(uint32_t value)
64         {
65             int retry = 0;
66             uint32_t callTimes = 0;
67             while (retry < value) {
68                 callTimes = value_.GetValue();
69                 if (callTimes >= value) {
70                     break;
71                 }
72                 std::lock_guard<decltype(mutex_)> guard(mutex_);
73                 callTimes = value_.GetValue();
74                 if (callTimes >= value) {
75                     break;
76                 }
77                 value_.Clear(callTimes);
78                 retry++;
79             }
80             return callTimes;
81         }
82 
ResetToZero()83         void ResetToZero()
84         {
85             std::lock_guard<decltype(mutex_)> guard(mutex_);
86             callCount = 0;
87             value_.Clear(0);
88         }
89 
90         uint64_t startTime = 0;
91         uint64_t endTime = 0;
92         uint32_t callCount = 0;
93         std::map<std::string, std::set<std::string>> values_;
94         BlockData<uint32_t> value_{ 1, 0 };
95         std::mutex mutex_;
96     };
97     class TestSyncCallback : public KvStoreSyncCallback {
98     public:
SyncCompleted(const std::map<std::string,Status> & results)99         void SyncCompleted(const std::map<std::string, Status> &results) override
100         {
101             ASSERT_TRUE(true);
102         }
103     };
104     static void SetUpTestCase(void);
105     static void TearDownTestCase(void);
106     void SetUp();
107     void TearDown();
108 
109 protected:
110     static std::shared_ptr<SingleKvStore> kvStore_;
111     static BrokerDelegator<KVDBServiceMock> delegator_;
112 };
113 BrokerDelegator<AutoSyncTimerTest::KVDBServiceMock> AutoSyncTimerTest::delegator_;
114 AutoSyncTimerTest::KVDBServiceMock *AutoSyncTimerTest::KVDBServiceMock::instance_ = nullptr;
SetUpTestCase(void)115 void AutoSyncTimerTest::SetUpTestCase(void)
116 {
117 }
118 
TearDownTestCase(void)119 void AutoSyncTimerTest::TearDownTestCase(void)
120 {
121 }
122 
SetUp(void)123 void AutoSyncTimerTest::SetUp(void)
124 {
125 }
126 
TearDown(void)127 void AutoSyncTimerTest::TearDown(void)
128 {
129     sleep(10);
130 }
131 
132 /**
133 * @tc.name: SingleWrite
134 * @tc.desc: get the store id of the kv store
135 * @tc.type: FUNC
136 * @tc.require: I4XVQQ
137 * @tc.author: Yang Qing
138 */
139 HWTEST_F(AutoSyncTimerTest, SingleWrite, TestSize.Level0)
140 {
141     auto *instance = KVDBServiceMock::GetInstance();
142     ASSERT_NE(instance, nullptr);
143     instance->ResetToZero();
144     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
145     instance->endTime = 0;
146     instance->values_.clear();
147     AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } });
148     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
149     auto it = instance->values_.find("ut_test");
150     ASSERT_NE(it, instance->values_.end());
151     ASSERT_EQ(it->second.count("ut_test_store"), 1);
152     ASSERT_LT(instance->endTime - instance->startTime, 100);
153 }
154 
155 /**
156 * @tc.name: MultiWrite
157 * @tc.desc: get the store id of the kv store
158 * @tc.type: FUNC
159 * @tc.require: I4XVQQ
160 * @tc.author: Yang Qing
161 */
162 HWTEST_F(AutoSyncTimerTest, MultiWrite, TestSize.Level1)
163 {
164     auto *instance = KVDBServiceMock::GetInstance();
165     ASSERT_NE(instance, nullptr);
166     instance->ResetToZero();
167     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
168     instance->endTime = 0;
169     instance->values_.clear();
170     std::atomic_bool finished = false;
__anonc3743fd00102null171     std::thread thread([&finished] {
172         while (!finished.load()) {
173             AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } });
174             usleep(40);
175         }
176     });
177     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
178     ASSERT_GE(instance->endTime - instance->startTime, 200);
179     ASSERT_LT(instance->endTime - instance->startTime, 250);
180     finished.store(true);
181     thread.join();
182     auto it = instance->values_.find("ut_test");
183     ASSERT_NE(it, instance->values_.end());
184     ASSERT_EQ(it->second.count("ut_test_store"), 1);
185 }
186 
187 /**
188 * @tc.name: SingleWriteOvertenKVStores
189 * @tc.desc: single write over ten kv stores
190 * @tc.type: FUNC
191 * @tc.require: I4XVQQ
192 * @tc.author: Yang Qing
193 */
194 HWTEST_F(AutoSyncTimerTest, SingleWriteOvertenKVStores, TestSize.Level1)
195 {
196     auto *instance = KVDBServiceMock::GetInstance();
197     ASSERT_NE(instance, nullptr);
198     instance->ResetToZero();
199     instance->startTime = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
200     instance->endTime = 0;
201     instance->values_.clear();
202     AutoSyncTimer::GetInstance().DoAutoSync("ut_test", {
203                                                            { "ut_test_store0" },
204                                                            { "ut_test_store1" },
205                                                            { "ut_test_store2" },
206                                                            { "ut_test_store3" },
207                                                            { "ut_test_store4" },
208                                                            { "ut_test_store5" },
209                                                            { "ut_test_store6" },
210                                                            { "ut_test_store7" },
211                                                            { "ut_test_store8" },
212                                                            { "ut_test_store9" },
213                                                            { "ut_test_store10" },
214                                                        });
215     EXPECT_EQ(static_cast<int>(instance->GetCallCount(1)), 1);
216     ASSERT_LT(instance->endTime - instance->startTime, 100);
217     EXPECT_EQ(static_cast<int>(instance->GetCallCount(11)), 11);
218     auto it = instance->values_.find("ut_test");
219     ASSERT_NE(it, instance->values_.end());
220     ASSERT_EQ(it->second.count("ut_test_store0"), 1);
221     ASSERT_EQ(it->second.count("ut_test_store1"), 1);
222     ASSERT_EQ(it->second.count("ut_test_store2"), 1);
223     ASSERT_EQ(it->second.count("ut_test_store3"), 1);
224     ASSERT_EQ(it->second.count("ut_test_store4"), 1);
225     ASSERT_EQ(it->second.count("ut_test_store5"), 1);
226     ASSERT_EQ(it->second.count("ut_test_store6"), 1);
227     ASSERT_EQ(it->second.count("ut_test_store7"), 1);
228     ASSERT_EQ(it->second.count("ut_test_store8"), 1);
229     ASSERT_EQ(it->second.count("ut_test_store9"), 1);
230     ASSERT_EQ(it->second.count("ut_test_store10"), 1);
231 }