1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <gtest/gtest.h>
6 #include <sys/socket.h>
7 #include <sys/types.h>
8 #include <unistd.h>
9
10 #include "cras_alert.h"
11
12 namespace {
13
14 void callback1(void* arg, void* data);
15 void callback2(void* arg, void* data);
16 void prepare(struct cras_alert* alert);
17
18 struct cb_data_struct {
19 int data;
20 };
21
22 static int cb1_called = 0;
23 static cb_data_struct cb1_data;
24 static int cb2_called = 0;
25 static int cb2_set_pending = 0;
26 static int prepare_called = 0;
27
ResetStub()28 void ResetStub() {
29 cb1_called = 0;
30 cb2_called = 0;
31 cb2_set_pending = 0;
32 prepare_called = 0;
33 cb1_data.data = 0;
34 }
35
36 class Alert : public testing::Test {
37 protected:
SetUp()38 virtual void SetUp() { cb1_data.data = 0; }
39
TearDown()40 virtual void TearDown() {}
41 };
42
TEST_F(Alert,OneCallback)43 TEST_F(Alert, OneCallback) {
44 struct cras_alert* alert = cras_alert_create(NULL, 0);
45 cras_alert_add_callback(alert, &callback1, NULL);
46 ResetStub();
47 cras_alert_pending(alert);
48 EXPECT_EQ(0, cb1_called);
49 cras_alert_process_all_pending_alerts();
50 EXPECT_EQ(1, cb1_called);
51 cras_alert_destroy(alert);
52 }
53
TEST_F(Alert,OneCallbackPost2Call1)54 TEST_F(Alert, OneCallbackPost2Call1) {
55 struct cras_alert* alert = cras_alert_create(NULL, 0);
56 cras_alert_add_callback(alert, &callback1, NULL);
57 ResetStub();
58 // Alert twice, callback should only be called once.
59 cras_alert_pending(alert);
60 cras_alert_pending(alert);
61 EXPECT_EQ(0, cb1_called);
62 cras_alert_process_all_pending_alerts();
63 EXPECT_EQ(1, cb1_called);
64 cras_alert_destroy(alert);
65 }
66
TEST_F(Alert,OneCallbackWithData)67 TEST_F(Alert, OneCallbackWithData) {
68 struct cras_alert* alert = cras_alert_create(NULL, 0);
69 struct cb_data_struct data = {1};
70 cras_alert_add_callback(alert, &callback1, NULL);
71 ResetStub();
72 cras_alert_pending_data(alert, (void*)&data, sizeof(struct cb_data_struct));
73 EXPECT_EQ(0, cb1_called);
74 cras_alert_process_all_pending_alerts();
75 EXPECT_EQ(1, cb1_called);
76 EXPECT_EQ(1, cb1_data.data);
77 cras_alert_destroy(alert);
78 }
79
TEST_F(Alert,OneCallbackTwoDataCalledOnce)80 TEST_F(Alert, OneCallbackTwoDataCalledOnce) {
81 struct cras_alert* alert = cras_alert_create(NULL, 0);
82 struct cb_data_struct data = {1};
83 struct cb_data_struct data2 = {2};
84 cras_alert_add_callback(alert, &callback1, NULL);
85 ResetStub();
86 // Callback called with last data only.
87 cras_alert_pending_data(alert, (void*)&data, sizeof(struct cb_data_struct));
88 cras_alert_pending_data(alert, (void*)&data2, sizeof(struct cb_data_struct));
89 EXPECT_EQ(0, cb1_called);
90 cras_alert_process_all_pending_alerts();
91 EXPECT_EQ(1, cb1_called);
92 EXPECT_EQ(2, cb1_data.data);
93 cras_alert_destroy(alert);
94 }
95
TEST_F(Alert,OneCallbackTwoDataKeepAll)96 TEST_F(Alert, OneCallbackTwoDataKeepAll) {
97 struct cras_alert* alert =
98 cras_alert_create(NULL, CRAS_ALERT_FLAG_KEEP_ALL_DATA);
99 struct cb_data_struct data = {1};
100 struct cb_data_struct data2 = {2};
101 cras_alert_add_callback(alert, &callback1, NULL);
102 ResetStub();
103 // Callbacks with data should each be called.
104 cras_alert_pending_data(alert, (void*)&data, sizeof(cb_data_struct));
105 cras_alert_pending_data(alert, (void*)&data2, sizeof(cb_data_struct));
106 EXPECT_EQ(0, cb1_called);
107 cras_alert_process_all_pending_alerts();
108 EXPECT_EQ(2, cb1_called);
109 EXPECT_EQ(2, cb1_data.data);
110 cras_alert_destroy(alert);
111 }
112
TEST_F(Alert,TwoCallbacks)113 TEST_F(Alert, TwoCallbacks) {
114 struct cras_alert* alert = cras_alert_create(NULL, 0);
115 cras_alert_add_callback(alert, &callback1, NULL);
116 cras_alert_add_callback(alert, &callback2, NULL);
117 ResetStub();
118 cras_alert_pending(alert);
119 EXPECT_EQ(0, cb1_called);
120 EXPECT_EQ(0, cb2_called);
121 cras_alert_process_all_pending_alerts();
122 EXPECT_EQ(1, cb1_called);
123 EXPECT_EQ(1, cb2_called);
124 cras_alert_destroy(alert);
125 }
126
TEST_F(Alert,NoPending)127 TEST_F(Alert, NoPending) {
128 struct cras_alert* alert = cras_alert_create(NULL, 0);
129 cras_alert_add_callback(alert, &callback1, NULL);
130 ResetStub();
131 EXPECT_EQ(0, cb1_called);
132 cras_alert_process_all_pending_alerts();
133 EXPECT_EQ(0, cb1_called);
134 cras_alert_destroy(alert);
135 }
136
TEST_F(Alert,PendingInCallback)137 TEST_F(Alert, PendingInCallback) {
138 struct cras_alert* alert1 = cras_alert_create(NULL, 0);
139 struct cras_alert* alert2 = cras_alert_create(NULL, 0);
140 cras_alert_add_callback(alert1, &callback1, NULL);
141 cras_alert_add_callback(alert2, &callback2, alert1);
142 ResetStub();
143 cras_alert_pending(alert2);
144 EXPECT_EQ(0, cb1_called);
145 EXPECT_EQ(0, cb2_called);
146 cb2_set_pending = 1;
147 cras_alert_process_all_pending_alerts();
148 EXPECT_EQ(1, cb1_called);
149 EXPECT_EQ(1, cb2_called);
150 cras_alert_destroy(alert1);
151 cras_alert_destroy(alert2);
152 }
153
TEST_F(Alert,Prepare)154 TEST_F(Alert, Prepare) {
155 struct cras_alert* alert = cras_alert_create(prepare, 0);
156 cras_alert_add_callback(alert, &callback1, NULL);
157 ResetStub();
158 cras_alert_pending(alert);
159 EXPECT_EQ(0, cb1_called);
160 cras_alert_process_all_pending_alerts();
161 EXPECT_EQ(1, prepare_called);
162 EXPECT_EQ(1, cb1_called);
163 cras_alert_destroy(alert);
164 }
165
TEST_F(Alert,TwoAlerts)166 TEST_F(Alert, TwoAlerts) {
167 struct cras_alert* alert1 = cras_alert_create(prepare, 0);
168 struct cras_alert* alert2 = cras_alert_create(prepare, 0);
169 cras_alert_add_callback(alert1, &callback1, NULL);
170 cras_alert_add_callback(alert2, &callback2, NULL);
171
172 ResetStub();
173 cras_alert_pending(alert1);
174 EXPECT_EQ(0, cb1_called);
175 EXPECT_EQ(0, cb2_called);
176 cras_alert_process_all_pending_alerts();
177 EXPECT_EQ(1, prepare_called);
178 EXPECT_EQ(1, cb1_called);
179 EXPECT_EQ(0, cb2_called);
180
181 ResetStub();
182 cras_alert_pending(alert2);
183 EXPECT_EQ(0, cb1_called);
184 EXPECT_EQ(0, cb2_called);
185 cras_alert_process_all_pending_alerts();
186 EXPECT_EQ(1, prepare_called);
187 EXPECT_EQ(0, cb1_called);
188 EXPECT_EQ(1, cb2_called);
189
190 ResetStub();
191 cras_alert_pending(alert1);
192 cras_alert_pending(alert2);
193 EXPECT_EQ(0, cb1_called);
194 EXPECT_EQ(0, cb2_called);
195 cras_alert_process_all_pending_alerts();
196 EXPECT_EQ(2, prepare_called);
197 EXPECT_EQ(1, cb1_called);
198 EXPECT_EQ(1, cb2_called);
199
200 cras_alert_destroy_all();
201 }
202
callback1(void * arg,void * data)203 void callback1(void* arg, void* data) {
204 cb1_called++;
205 if (data)
206 cb1_data.data = ((struct cb_data_struct*)data)->data;
207 }
208
callback2(void * arg,void * data)209 void callback2(void* arg, void* data) {
210 cb2_called++;
211 if (cb2_set_pending) {
212 cb2_set_pending = 0;
213 cras_alert_pending((struct cras_alert*)arg);
214 }
215 }
216
prepare(struct cras_alert * alert)217 void prepare(struct cras_alert* alert) {
218 prepare_called++;
219 return;
220 }
221
222 } // namespace
223
main(int argc,char ** argv)224 int main(int argc, char** argv) {
225 ::testing::InitGoogleTest(&argc, argv);
226 return RUN_ALL_TESTS();
227 }
228