• 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/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