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