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/types.h>
7 #include <sys/socket.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() {
39 cb1_data.data = 0;
40 }
41
TearDown()42 virtual void TearDown() {
43 }
44 };
45
TEST_F(Alert,OneCallback)46 TEST_F(Alert, OneCallback) {
47 struct cras_alert *alert = cras_alert_create(NULL, 0);
48 cras_alert_add_callback(alert, &callback1, NULL);
49 ResetStub();
50 cras_alert_pending(alert);
51 EXPECT_EQ(0, cb1_called);
52 cras_alert_process_all_pending_alerts();
53 EXPECT_EQ(1, cb1_called);
54 cras_alert_destroy(alert);
55 }
56
TEST_F(Alert,OneCallbackPost2Call1)57 TEST_F(Alert, OneCallbackPost2Call1) {
58 struct cras_alert *alert = cras_alert_create(NULL, 0);
59 cras_alert_add_callback(alert, &callback1, NULL);
60 ResetStub();
61 // Alert twice, callback should only be called once.
62 cras_alert_pending(alert);
63 cras_alert_pending(alert);
64 EXPECT_EQ(0, cb1_called);
65 cras_alert_process_all_pending_alerts();
66 EXPECT_EQ(1, cb1_called);
67 cras_alert_destroy(alert);
68 }
69
TEST_F(Alert,OneCallbackWithData)70 TEST_F(Alert, OneCallbackWithData) {
71 struct cras_alert *alert = cras_alert_create(NULL, 0);
72 struct cb_data_struct data = {1};
73 cras_alert_add_callback(alert, &callback1, NULL);
74 ResetStub();
75 cras_alert_pending_data(alert, (void *)&data, sizeof(struct cb_data_struct));
76 EXPECT_EQ(0, cb1_called);
77 cras_alert_process_all_pending_alerts();
78 EXPECT_EQ(1, cb1_called);
79 EXPECT_EQ(1, cb1_data.data);
80 cras_alert_destroy(alert);
81 }
82
TEST_F(Alert,OneCallbackTwoDataCalledOnce)83 TEST_F(Alert, OneCallbackTwoDataCalledOnce) {
84 struct cras_alert *alert = cras_alert_create(NULL, 0);
85 struct cb_data_struct data = {1};
86 struct cb_data_struct data2 = {2};
87 cras_alert_add_callback(alert, &callback1, NULL);
88 ResetStub();
89 // Callback called with last data only.
90 cras_alert_pending_data(
91 alert, (void *)&data, sizeof(struct cb_data_struct));
92 cras_alert_pending_data(
93 alert, (void *)&data2, sizeof(struct cb_data_struct));
94 EXPECT_EQ(0, cb1_called);
95 cras_alert_process_all_pending_alerts();
96 EXPECT_EQ(1, cb1_called);
97 EXPECT_EQ(2, cb1_data.data);
98 cras_alert_destroy(alert);
99 }
100
TEST_F(Alert,OneCallbackTwoDataKeepAll)101 TEST_F(Alert, OneCallbackTwoDataKeepAll) {
102 struct cras_alert *alert = cras_alert_create(
103 NULL, CRAS_ALERT_FLAG_KEEP_ALL_DATA);
104 struct cb_data_struct data = {1};
105 struct cb_data_struct data2 = {2};
106 cras_alert_add_callback(alert, &callback1, NULL);
107 ResetStub();
108 // Callbacks with data should each be called.
109 cras_alert_pending_data(alert, (void *)&data, sizeof(cb_data_struct));
110 cras_alert_pending_data(alert, (void *)&data2, sizeof(cb_data_struct));
111 EXPECT_EQ(0, cb1_called);
112 cras_alert_process_all_pending_alerts();
113 EXPECT_EQ(2, cb1_called);
114 EXPECT_EQ(2, cb1_data.data);
115 cras_alert_destroy(alert);
116 }
117
TEST_F(Alert,TwoCallbacks)118 TEST_F(Alert, TwoCallbacks) {
119 struct cras_alert *alert = cras_alert_create(NULL, 0);
120 cras_alert_add_callback(alert, &callback1, NULL);
121 cras_alert_add_callback(alert, &callback2, NULL);
122 ResetStub();
123 cras_alert_pending(alert);
124 EXPECT_EQ(0, cb1_called);
125 EXPECT_EQ(0, cb2_called);
126 cras_alert_process_all_pending_alerts();
127 EXPECT_EQ(1, cb1_called);
128 EXPECT_EQ(1, cb2_called);
129 cras_alert_destroy(alert);
130 }
131
TEST_F(Alert,NoPending)132 TEST_F(Alert, NoPending) {
133 struct cras_alert *alert = cras_alert_create(NULL, 0);
134 cras_alert_add_callback(alert, &callback1, NULL);
135 ResetStub();
136 EXPECT_EQ(0, cb1_called);
137 cras_alert_process_all_pending_alerts();
138 EXPECT_EQ(0, cb1_called);
139 cras_alert_destroy(alert);
140 }
141
TEST_F(Alert,PendingInCallback)142 TEST_F(Alert, PendingInCallback) {
143 struct cras_alert *alert1 = cras_alert_create(NULL, 0);
144 struct cras_alert *alert2 = cras_alert_create(NULL, 0);
145 cras_alert_add_callback(alert1, &callback1, NULL);
146 cras_alert_add_callback(alert2, &callback2, alert1);
147 ResetStub();
148 cras_alert_pending(alert2);
149 EXPECT_EQ(0, cb1_called);
150 EXPECT_EQ(0, cb2_called);
151 cb2_set_pending = 1;
152 cras_alert_process_all_pending_alerts();
153 EXPECT_EQ(1, cb1_called);
154 EXPECT_EQ(1, cb2_called);
155 cras_alert_destroy(alert1);
156 cras_alert_destroy(alert2);
157 }
158
TEST_F(Alert,Prepare)159 TEST_F(Alert, Prepare) {
160 struct cras_alert *alert = cras_alert_create(prepare, 0);
161 cras_alert_add_callback(alert, &callback1, NULL);
162 ResetStub();
163 cras_alert_pending(alert);
164 EXPECT_EQ(0, cb1_called);
165 cras_alert_process_all_pending_alerts();
166 EXPECT_EQ(1, prepare_called);
167 EXPECT_EQ(1, cb1_called);
168 cras_alert_destroy(alert);
169 }
170
TEST_F(Alert,TwoAlerts)171 TEST_F(Alert, TwoAlerts) {
172 struct cras_alert *alert1 = cras_alert_create(prepare, 0);
173 struct cras_alert *alert2 = cras_alert_create(prepare, 0);
174 cras_alert_add_callback(alert1, &callback1, NULL);
175 cras_alert_add_callback(alert2, &callback2, NULL);
176
177 ResetStub();
178 cras_alert_pending(alert1);
179 EXPECT_EQ(0, cb1_called);
180 EXPECT_EQ(0, cb2_called);
181 cras_alert_process_all_pending_alerts();
182 EXPECT_EQ(1, prepare_called);
183 EXPECT_EQ(1, cb1_called);
184 EXPECT_EQ(0, cb2_called);
185
186 ResetStub();
187 cras_alert_pending(alert2);
188 EXPECT_EQ(0, cb1_called);
189 EXPECT_EQ(0, cb2_called);
190 cras_alert_process_all_pending_alerts();
191 EXPECT_EQ(1, prepare_called);
192 EXPECT_EQ(0, cb1_called);
193 EXPECT_EQ(1, cb2_called);
194
195 ResetStub();
196 cras_alert_pending(alert1);
197 cras_alert_pending(alert2);
198 EXPECT_EQ(0, cb1_called);
199 EXPECT_EQ(0, cb2_called);
200 cras_alert_process_all_pending_alerts();
201 EXPECT_EQ(2, prepare_called);
202 EXPECT_EQ(1, cb1_called);
203 EXPECT_EQ(1, cb2_called);
204
205 cras_alert_destroy_all();
206 }
207
callback1(void * arg,void * data)208 void callback1(void *arg, void *data)
209 {
210 cb1_called++;
211 if(data)
212 cb1_data.data = ((struct cb_data_struct *)data)->data;
213 }
214
callback2(void * arg,void * data)215 void callback2(void *arg, void *data)
216 {
217 cb2_called++;
218 if (cb2_set_pending) {
219 cb2_set_pending = 0;
220 cras_alert_pending((struct cras_alert *)arg);
221 }
222 }
223
prepare(struct cras_alert * alert)224 void prepare(struct cras_alert *alert)
225 {
226 prepare_called++;
227 return;
228 }
229
230 }
231
main(int argc,char ** argv)232 int main(int argc, char **argv) {
233 ::testing::InitGoogleTest(&argc, argv);
234 return RUN_ALL_TESTS();
235 }
236