1 /*
2  * Copyright (c) 2021 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_errno.h"
19 #include "distributeddb_tools_unit_test.h"
20 #include "log_print.h"
21 #include "notification_chain.h"
22 
23 using namespace testing::ext;
24 using namespace DistributedDB;
25 using namespace std;
26 using namespace DistributedDBUnitTest;
27 
28 namespace {
29     const EventType COMMIT_EVENT = 1;
30     const int INVALID_EVENT = 0;
31     NotificationChain *g_notificationChain = nullptr;
32     NotificationChain::Listener *g_listener = nullptr;
33     int g_onEventTestNum = 0;
34     bool g_onFinalizeCalled = false;
35 
__anonf519c1050202(void *arg) 36     auto g_onEventFunction = [](void *arg) {
37         g_onEventTestNum = *(reinterpret_cast<int *>(arg));
38         LOGI("g_onEventFunction called.");
39     };
40 
__anonf519c1050302() 41     auto g_onFinalize = []() {
42         g_onFinalizeCalled = true;
43         LOGI("g_onFinalize called.");
44     };
45 }
46 
47 class DistributedDBNotificationChainTest : public testing::Test {
48 public:
49     static void SetUpTestCase(void);
50     static void TearDownTestCase(void);
51     void SetUp();
52     void TearDown();
53 };
54 
SetUpTestCase(void)55 void DistributedDBNotificationChainTest::SetUpTestCase(void)
56 {
57     /**
58      * @tc.setup: Create a NotificationChain.
59      */
60     g_notificationChain = new (std::nothrow) NotificationChain();
61     EXPECT_TRUE(g_notificationChain != nullptr);
62 }
63 
TearDownTestCase(void)64 void DistributedDBNotificationChainTest::TearDownTestCase(void)
65 {
66     /**
67      * @tc.setup: Release a NotificationChain.
68      */
69     g_notificationChain->OnLastRef([]() { LOGI("g_notificationChain finalize called."); });
70     g_notificationChain->KillAndDecObjRef(g_notificationChain);
71     g_notificationChain = nullptr;
72 }
73 
SetUp(void)74 void DistributedDBNotificationChainTest::SetUp(void)
75 {
76     DistributedDBToolsUnitTest::PrintTestCaseInfo();
77     /**
78      * @tc.setup: Register a listener to the NotificationChain
79      */
80     g_onEventTestNum = 0;
81     g_onFinalizeCalled = false;
82     int result = g_notificationChain->RegisterEventType(COMMIT_EVENT);
83     EXPECT_TRUE(result == E_OK);
84     int errCode = E_OK;
85     g_listener = g_notificationChain->RegisterListener(COMMIT_EVENT, g_onEventFunction, g_onFinalize, errCode);
86     EXPECT_TRUE(g_listener != nullptr);
87 }
88 
TearDown(void)89 void DistributedDBNotificationChainTest::TearDown(void)
90 {
91     /**
92      * @tc.setup: Unregister a listener to the NotificationChain
93      */
94     g_listener->Drop();
95     g_listener = nullptr;
96     EXPECT_TRUE(g_notificationChain->UnRegisterEventType(COMMIT_EVENT) == E_OK);
97 }
98 
99 /**
100  * @tc.name: RegisterEvent001
101  * @tc.desc: Register an exits event.
102  * @tc.type: FUNC
103  * @tc.require: AR000BVDFP AR000CQDVI
104  * @tc.author: xushaohua
105  */
106 HWTEST_F(DistributedDBNotificationChainTest, RegisterEvent001, TestSize.Level0)
107 {
108     /**
109      * @tc.steps: step1. call RegisterEventType to register a exist event
110      * @tc.expected: step1. function return -E_ALREADY_REGISTER
111      */
112     int result = g_notificationChain->RegisterEventType(COMMIT_EVENT);
113     EXPECT_TRUE(result == -E_ALREADY_REGISTER);
114 }
115 
116 /**
117  * @tc.name: RegisterListener001
118  * @tc.desc: Register and unregister a listener.
119  * @tc.type: FUNC
120  * @tc.require: AR000BVDFP AR000CQDVI
121  * @tc.author: xushaohua
122  */
123 HWTEST_F(DistributedDBNotificationChainTest, RegisterListener001, TestSize.Level0)
124 {
125     /**
126      * @tc.steps: step1. call RegisterListener to register a listener
127      * @tc.expected: step1. function return a not null listener
128      */
129     int errCode = E_OK;
130     NotificationChain::Listener *listener =
131         g_notificationChain->RegisterListener(COMMIT_EVENT, g_onEventFunction, g_onFinalize, errCode);
132     EXPECT_TRUE(listener != nullptr);
133 
134     /**
135      * @tc.steps: step2. call Drop to unregister the listener
136      * @tc.expected: step2. function return E_OK
137      */
138     int result = listener->Drop();
139     EXPECT_TRUE(g_onFinalizeCalled);
140     EXPECT_TRUE(result == E_OK);
141 }
142 
143 /**
144  * @tc.name: NotifyEvent001
145  * @tc.desc: notify an event to listener.
146  * @tc.type: FUNC
147  * @tc.require: AR000BVDFQ AR000CQDVJ
148  * @tc.author: xushaohua
149  */
150 HWTEST_F(DistributedDBNotificationChainTest, NotifyEvent001, TestSize.Level0)
151 {
152     int errCode = E_OK;
153     /**
154      * @tc.steps: step1. call RegisterListener to register a listener
155      * @tc.expected: step1. function return a not null listener
156      */
157     NotificationChain::Listener *listener =
158         g_notificationChain->RegisterListener(COMMIT_EVENT, g_onEventFunction, g_onFinalize, errCode);
159     EXPECT_TRUE(listener != nullptr);
160 
161     /**
162      * @tc.steps: step2. call NotifyEvent to notify an event
163      * @tc.expected: step2. the listener's callback should be called
164      */
165     int testNum = 2048;
166     g_notificationChain->NotifyEvent(COMMIT_EVENT, &testNum);
167     EXPECT_TRUE(g_onEventTestNum == testNum);
168     listener->Drop();
169 }
170 
171 /**
172  * @tc.name: UnRegisterEvent001
173  * @tc.desc: unregister a invalid event.
174  * @tc.type: FUNC
175  * @tc.require: AR000BVDFP AR000CQDVI
176  * @tc.author: xushaohua
177  */
178 HWTEST_F(DistributedDBNotificationChainTest, UnRegisterEvent001, TestSize.Level0)
179 {
180     /**
181      * @tc.steps: step1. UnRegisterEventType a invalid event
182      * @tc.expected: step1. function should return -E_NOT_FOUND
183      */
184     int result = g_notificationChain->UnRegisterEventType(INVALID_EVENT);
185     EXPECT_EQ(result, -E_NOT_FOUND);
186 }
187