• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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