1 /*
2  * Copyright (c) 2023 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 <gtest/gtest.h>
17 
18 #include "db_constant.h"
19 #include "distributeddb_data_generate_unit_test.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "log_print.h"
22 #include "relational_store_manager.h"
23 #include "runtime_config.h"
24 #include "virtual_relational_ver_sync_db_interface.h"
25 
26 using namespace testing::ext;
27 using namespace DistributedDB;
28 using namespace DistributedDBUnitTest;
29 using namespace std;
30 
31 namespace {
32     constexpr const char *DB_SUFFIX = ".db";
33     constexpr const char *STORE_ID = "Relational_Store_ID";
34     std::string g_testDir;
35     std::string g_dbDir;
36     std::string g_storePath;
37     DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
38     RelationalStoreDelegate *g_delegate = nullptr;
39 
40     class DistributedDBInterfacesRelationalObserverTest : public testing::Test {
41     public:
42         static void SetUpTestCase(void);
43         static void TearDownTestCase(void);
44         void SetUp();
45         void TearDown();
46     };
47 
SetUpTestCase(void)48     void DistributedDBInterfacesRelationalObserverTest::SetUpTestCase(void)
49     {
50         DistributedDBToolsUnitTest::TestDirInit(g_testDir);
51         LOGD("Test dir is %s", g_testDir.c_str());
52         g_dbDir = g_testDir + "/";
53         g_storePath = g_dbDir + STORE_ID + DB_SUFFIX;
54         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
55     }
56 
TearDownTestCase(void)57     void DistributedDBInterfacesRelationalObserverTest::TearDownTestCase(void)
58     {
59     }
60 
SetUp(void)61     void DistributedDBInterfacesRelationalObserverTest::SetUp(void)
62     {
63         sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath);
64         ASSERT_NE(db, nullptr);
65         EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
66         EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
67 
68         DBStatus status = g_mgr.OpenStore(g_storePath, STORE_ID, {}, g_delegate);
69         EXPECT_EQ(status, OK);
70         ASSERT_NE(g_delegate, nullptr);
71     }
72 
TearDown(void)73     void DistributedDBInterfacesRelationalObserverTest::TearDown(void)
74     {
75         EXPECT_EQ(g_mgr.CloseStore(g_delegate), OK);
76         g_delegate = nullptr;
77         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
78     }
79 
80     /**
81      * @tc.name: RelationalObserverTest001
82      * @tc.desc: Test invalid args for register unregister observer
83      * @tc.type: FUNC
84      * @tc.require:
85      * @tc.author: zhangshjie
86      */
87     HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest001, TestSize.Level0)
88     {
89         EXPECT_EQ(g_delegate->RegisterObserver(nullptr), INVALID_ARGS);
90         EXPECT_EQ(g_delegate->UnRegisterObserver(nullptr), INVALID_ARGS);
91     }
92 
93     /**
94      * @tc.name: RelationalObserverTest002
95      * @tc.desc: Test register same observer twice
96      * @tc.type: FUNC
97      * @tc.require:
98      * @tc.author: zhangshjie
99      */
100     HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest002, TestSize.Level0)
101     {
102         /**
103          * @tc.steps:step1. register observer1 twice
104          * @tc.expected: step1. Return OK for first, return ALREADY_SET for second.
105          */
106         RelationalStoreObserverUnitTest *observer1 = new (std::nothrow) RelationalStoreObserverUnitTest();
107         EXPECT_NE(observer1, nullptr);
108         EXPECT_EQ(g_delegate->RegisterObserver(observer1), OK);
109         EXPECT_EQ(g_delegate->RegisterObserver(observer1), ALREADY_SET);
110 
111         /**
112          * @tc.steps:step2. unregister observer1 twice
113          * @tc.expected: step2. Return OK for first, return NOT_FOUND for second.
114          */
115         EXPECT_EQ(g_delegate->UnRegisterObserver(observer1), OK);
116         EXPECT_EQ(g_delegate->UnRegisterObserver(observer1), NOT_FOUND);
117 
118         /**
119          * @tc.steps:step3. register observer1 again
120          * @tc.expected: step3. Return OK.
121          */
122         EXPECT_EQ(g_delegate->RegisterObserver(observer1), OK);
123 
124         delete observer1;
125         observer1 = nullptr;
126     }
127 
128     /**
129      * @tc.name: RelationalObserverTest003
130      * @tc.desc: Test register observer over limit
131      * @tc.type: FUNC
132      * @tc.require:
133      * @tc.author: zhangshjie
134      */
135     HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest003, TestSize.Level0)
136     {
137         /**
138          * @tc.steps:step1. register DBConstant::MAX_OBSERVER_COUNT + 1 observer
139          * @tc.expected: step1. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for
140          * DBConstant::MAX_OBSERVER_COUNT + 1.
141          */
142         RelationalStoreObserverUnitTest *observerArr[DBConstant::MAX_OBSERVER_COUNT + 1] = { nullptr };
143         for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) {
144             observerArr[i] = new (std::nothrow) RelationalStoreObserverUnitTest();
145             EXPECT_NE(observerArr[i], nullptr);
146             if (i < DBConstant::MAX_OBSERVER_COUNT) {
147                 EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OK);
148             } else {
149                 EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS);
150             }
151         }
152 
153         /**
154          * @tc.steps:step2. unregister observer1, than register again
155          * @tc.expected: step2. Return OK
156          */
157         EXPECT_EQ(g_delegate->UnRegisterObserver(observerArr[0]), OK);
158         EXPECT_EQ(g_delegate->RegisterObserver(observerArr[0]), OK);
159 
160         /**
161          * @tc.steps:step3. call UnRegisterObserver() unregister all observer
162          * @tc.expected: step3. Return OK
163          */
164         EXPECT_EQ(g_delegate->UnRegisterObserver(), OK);
165 
166         /**
167          * @tc.steps:step4. register DBConstant::MAX_OBSERVER_COUNT + 1 observer
168          * @tc.expected: step4. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for
169          * DBConstant::MAX_OBSERVER_COUNT + 1.
170          */
171         for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) {
172             if (i < DBConstant::MAX_OBSERVER_COUNT) {
173                 EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OK);
174             } else {
175                 EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS);
176             }
177         }
178 
179         for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) {
180             delete observerArr[i];
181             observerArr[i] = nullptr;
182         }
183     }
184 
185     /**
186      * @tc.name: RelationalObserverTest004
187      * @tc.desc: Test register observer over limit when OpenStore will register one observer
188      * @tc.type: FUNC
189      * @tc.require:
190      * @tc.author: zhangshjie
191      */
192     HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest004, TestSize.Level0)
193     {
194         /**
195          * @tc.steps:step1. open store with observer
196          * @tc.expected: step1. Return OK
197          */
198         RelationalStoreDelegate *delegate = nullptr;
199         RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest();
200         EXPECT_NE(observer, nullptr);
201         RelationalStoreDelegate::Option option;
202         option.observer = observer;
203         EXPECT_EQ(g_mgr.OpenStore(g_storePath, STORE_ID, option, delegate), OK);
204         ASSERT_NE(delegate, nullptr);
205 
206         /**
207          * @tc.steps:step2. register DBConstant::MAX_OBSERVER_COUNT observer
208          * @tc.expected: step2. Return OK for first DBConstant::MAX_OBSERVER_COUNT - 1, return OVER_MAX_LIMITS for
209          * DBConstant::MAX_OBSERVER_COUNT because already register one observer when open store.
210          */
211         RelationalStoreObserverUnitTest *observerArr[DBConstant::MAX_OBSERVER_COUNT] = { nullptr };
212         for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) {
213             observerArr[i] = new (std::nothrow) RelationalStoreObserverUnitTest();
214             EXPECT_NE(observerArr[i], nullptr);
215             if (i < DBConstant::MAX_OBSERVER_COUNT - 1) {
216                 EXPECT_EQ(delegate->RegisterObserver(observerArr[i]), OK);
217             } else {
218                 EXPECT_EQ(delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS);
219             }
220         }
221 
222         /**
223          * @tc.steps:step3. close store
224          * @tc.expected: step3. Return OK
225          */
226         EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
227         delegate = nullptr;
228         delete observer;
229         observer = nullptr;
230         for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) {
231             delete observerArr[i];
232             observerArr[i] = nullptr;
233         }
234     }
235 
236     /**
237      * @tc.name: RelationalObserverTest005
238      * @tc.desc: Test register observer with two delegate
239      * @tc.type: FUNC
240      * @tc.require:
241      * @tc.author: zhangshjie
242      */
243     HWTEST_F(DistributedDBInterfacesRelationalObserverTest, RegisterObserverTest005, TestSize.Level0)
244     {
245         /**
246          * @tc.steps:step1. register DBConstant::MAX_OBSERVER_COUNT + 1 observer
247          * @tc.expected: step1. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for
248          * DBConstant::MAX_OBSERVER_COUNT + 1.
249          */
250         RelationalStoreObserverUnitTest *observerArr[DBConstant::MAX_OBSERVER_COUNT + 1] = {nullptr};
251         for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) {
252             observerArr[i] = new(std::nothrow) RelationalStoreObserverUnitTest();
253             EXPECT_NE(observerArr[i], nullptr);
254             if (i < DBConstant::MAX_OBSERVER_COUNT) {
255                 EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OK);
256             } else {
257                 EXPECT_EQ(g_delegate->RegisterObserver(observerArr[i]), OVER_MAX_LIMITS);
258             }
259         }
260 
261         /**
262          * @tc.steps:step2. register DBConstant::MAX_OBSERVER_COUNT + 1 observer with another delegate
263          * @tc.expected: step2. Return OK for first DBConstant::MAX_OBSERVER_COUNT, return OVER_MAX_LIMITS for
264          * DBConstant::MAX_OBSERVER_COUNT + 1.
265          */
266         RelationalStoreDelegate *delegate = nullptr;
267         EXPECT_EQ(g_mgr.OpenStore(g_storePath, STORE_ID, {}, delegate), OK);
268         ASSERT_NE(delegate, nullptr);
269         RelationalStoreObserverUnitTest *observerArr1[DBConstant::MAX_OBSERVER_COUNT + 1] = {nullptr};
270         for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) {
271             observerArr1[i] = new(std::nothrow) RelationalStoreObserverUnitTest();
272             EXPECT_NE(observerArr1[i], nullptr);
273             if (i < DBConstant::MAX_OBSERVER_COUNT) {
274                 EXPECT_EQ(delegate->RegisterObserver(observerArr1[i]), OK);
275             } else {
276                 EXPECT_EQ(delegate->RegisterObserver(observerArr1[i]), OVER_MAX_LIMITS);
277             }
278         }
279 
280         /**
281          * @tc.steps:step3. close store and delete observer
282          * @tc.expected: step3. Return OK
283          */
284         EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
285         delegate = nullptr;
286         for (int i = 0; i <= DBConstant::MAX_OBSERVER_COUNT; i++) {
287             delete observerArr[i];
288             observerArr[i] = nullptr;
289             delete observerArr1[i];
290             observerArr1[i] = nullptr;
291         }
292     }
293 }
294