1 /*
2  *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifdef HAVE_DBUS_GLIB
12 
13 #include "webrtc/base/dbus.h"
14 #include "webrtc/base/gunit.h"
15 #include "webrtc/base/thread.h"
16 
17 namespace rtc {
18 
19 #define SIG_NAME "NameAcquired"
20 
21 static const uint32_t kTimeoutMs = 5000U;
22 
23 class DBusSigFilterTest : public DBusSigFilter {
24  public:
25   // DBusSigFilterTest listens on DBus service itself for "NameAcquired" signal.
26   // This signal should be received when the application connects to DBus
27   // service and gains ownership of a name.
28   // http://dbus.freedesktop.org/doc/dbus-specification.html
DBusSigFilterTest()29   DBusSigFilterTest()
30       : DBusSigFilter(GetFilter()),
31         message_received_(false) {
32   }
33 
MessageReceived()34   bool MessageReceived() {
35     return message_received_;
36   }
37 
38  private:
GetFilter()39   static std::string GetFilter() {
40     return rtc::DBusSigFilter::BuildFilterString("", "", SIG_NAME);
41   }
42 
43   // Implement virtual method of DBusSigFilter. On caller thread.
ProcessSignal(DBusMessage * message)44   virtual void ProcessSignal(DBusMessage *message) {
45     EXPECT_TRUE(message != NULL);
46     message_received_ = true;
47   }
48 
49   bool message_received_;
50 };
51 
TEST(DBusMonitorTest,StartStopStartStop)52 TEST(DBusMonitorTest, StartStopStartStop) {
53   DBusSigFilterTest filter;
54   rtc::scoped_ptr<rtc::DBusMonitor> monitor;
55   monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
56   if (monitor) {
57     EXPECT_TRUE(monitor->AddFilter(&filter));
58 
59     EXPECT_TRUE(monitor->StopMonitoring());
60     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_NOT_INITIALIZED);
61 
62     EXPECT_TRUE(monitor->StartMonitoring());
63     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
64     EXPECT_TRUE(monitor->StopMonitoring());
65     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
66     EXPECT_TRUE(monitor->StopMonitoring());
67     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
68 
69     EXPECT_TRUE(monitor->StartMonitoring());
70     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
71     EXPECT_TRUE(monitor->StartMonitoring());
72     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_RUNNING);
73     EXPECT_TRUE(monitor->StopMonitoring());
74     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
75   } else {
76     LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
77   }
78 }
79 
80 // DBusMonitorTest listens on DBus service itself for "NameAcquired" signal.
81 // This signal should be received when the application connects to DBus
82 // service and gains ownership of a name.
83 // This test is to make sure that we capture the "NameAcquired" signal.
TEST(DBusMonitorTest,ReceivedNameAcquiredSignal)84 TEST(DBusMonitorTest, ReceivedNameAcquiredSignal) {
85   DBusSigFilterTest filter;
86   rtc::scoped_ptr<rtc::DBusMonitor> monitor;
87   monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
88   if (monitor) {
89     EXPECT_TRUE(monitor->AddFilter(&filter));
90 
91     EXPECT_TRUE(monitor->StartMonitoring());
92     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
93     EXPECT_TRUE_WAIT(filter.MessageReceived(), kTimeoutMs);
94     EXPECT_TRUE(monitor->StopMonitoring());
95     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
96   } else {
97     LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
98   }
99 }
100 
TEST(DBusMonitorTest,ConcurrentMonitors)101 TEST(DBusMonitorTest, ConcurrentMonitors) {
102   DBusSigFilterTest filter1;
103   rtc::scoped_ptr<rtc::DBusMonitor> monitor1;
104   monitor1.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
105   if (monitor1) {
106     EXPECT_TRUE(monitor1->AddFilter(&filter1));
107     DBusSigFilterTest filter2;
108     rtc::scoped_ptr<rtc::DBusMonitor> monitor2;
109     monitor2.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
110     EXPECT_TRUE(monitor2->AddFilter(&filter2));
111 
112     EXPECT_TRUE(monitor1->StartMonitoring());
113     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor1->GetStatus(), kTimeoutMs);
114     EXPECT_TRUE(monitor2->StartMonitoring());
115     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor2->GetStatus(), kTimeoutMs);
116 
117     EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs);
118     EXPECT_TRUE(monitor2->StopMonitoring());
119     EXPECT_EQ(monitor2->GetStatus(), DBusMonitor::DMS_STOPPED);
120 
121     EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
122     EXPECT_TRUE(monitor1->StopMonitoring());
123     EXPECT_EQ(monitor1->GetStatus(), DBusMonitor::DMS_STOPPED);
124   } else {
125     LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
126   }
127 }
128 
TEST(DBusMonitorTest,ConcurrentFilters)129 TEST(DBusMonitorTest, ConcurrentFilters) {
130   DBusSigFilterTest filter1;
131   DBusSigFilterTest filter2;
132   rtc::scoped_ptr<rtc::DBusMonitor> monitor;
133   monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
134   if (monitor) {
135     EXPECT_TRUE(monitor->AddFilter(&filter1));
136     EXPECT_TRUE(monitor->AddFilter(&filter2));
137 
138     EXPECT_TRUE(monitor->StartMonitoring());
139     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
140 
141     EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
142     EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs);
143 
144     EXPECT_TRUE(monitor->StopMonitoring());
145     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
146   } else {
147     LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
148   }
149 }
150 
TEST(DBusMonitorTest,NoAddFilterIfRunning)151 TEST(DBusMonitorTest, NoAddFilterIfRunning) {
152   DBusSigFilterTest filter1;
153   DBusSigFilterTest filter2;
154   rtc::scoped_ptr<rtc::DBusMonitor> monitor;
155   monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
156   if (monitor) {
157     EXPECT_TRUE(monitor->AddFilter(&filter1));
158 
159     EXPECT_TRUE(monitor->StartMonitoring());
160     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
161     EXPECT_FALSE(monitor->AddFilter(&filter2));
162 
163     EXPECT_TRUE(monitor->StopMonitoring());
164     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
165   } else {
166     LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
167   }
168 }
169 
TEST(DBusMonitorTest,AddFilterAfterStop)170 TEST(DBusMonitorTest, AddFilterAfterStop) {
171   DBusSigFilterTest filter1;
172   DBusSigFilterTest filter2;
173   rtc::scoped_ptr<rtc::DBusMonitor> monitor;
174   monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
175   if (monitor) {
176     EXPECT_TRUE(monitor->AddFilter(&filter1));
177     EXPECT_TRUE(monitor->StartMonitoring());
178     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
179     EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
180     EXPECT_TRUE(monitor->StopMonitoring());
181     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
182 
183     EXPECT_TRUE(monitor->AddFilter(&filter2));
184     EXPECT_TRUE(monitor->StartMonitoring());
185     EXPECT_EQ_WAIT(DBusMonitor::DMS_RUNNING, monitor->GetStatus(), kTimeoutMs);
186     EXPECT_TRUE_WAIT(filter1.MessageReceived(), kTimeoutMs);
187     EXPECT_TRUE_WAIT(filter2.MessageReceived(), kTimeoutMs);
188     EXPECT_TRUE(monitor->StopMonitoring());
189     EXPECT_EQ(monitor->GetStatus(), DBusMonitor::DMS_STOPPED);
190   } else {
191     LOG(LS_WARNING) << "DBus Monitor not started. Skipping test.";
192   }
193 }
194 
TEST(DBusMonitorTest,StopRightAfterStart)195 TEST(DBusMonitorTest, StopRightAfterStart) {
196   DBusSigFilterTest filter;
197   rtc::scoped_ptr<rtc::DBusMonitor> monitor;
198   monitor.reset(rtc::DBusMonitor::Create(DBUS_BUS_SYSTEM));
199   if (monitor) {
200     EXPECT_TRUE(monitor->AddFilter(&filter));
201 
202     EXPECT_TRUE(monitor->StartMonitoring());
203     EXPECT_TRUE(monitor->StopMonitoring());
204 
205     // Stop the monitoring thread right after it had been started.
206     // If the monitoring thread got a chance to receive a DBus signal, it would
207     // post a message to the main thread and signal the main thread wakeup.
208     // This message will be cleaned out automatically when the filter get
209     // destructed. Here we also consume the wakeup signal (if there is one) so
210     // that the testing (main) thread is reset to a clean state.
211     rtc::Thread::Current()->ProcessMessages(1);
212   } else {
213     LOG(LS_WARNING) << "DBus Monitor not started.";
214   }
215 }
216 
TEST(DBusSigFilter,BuildFilterString)217 TEST(DBusSigFilter, BuildFilterString) {
218   EXPECT_EQ(DBusSigFilter::BuildFilterString("", "", ""),
219       (DBUS_TYPE "='" DBUS_SIGNAL "'"));
220   EXPECT_EQ(DBusSigFilter::BuildFilterString("p", "", ""),
221       (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p'"));
222   EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i", ""),
223       (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p',"
224           DBUS_INTERFACE "='i'"));
225   EXPECT_EQ(DBusSigFilter::BuildFilterString("p","i","m"),
226       (DBUS_TYPE "='" DBUS_SIGNAL "'," DBUS_PATH "='p',"
227           DBUS_INTERFACE "='i'," DBUS_MEMBER "='m'"));
228 }
229 
230 }  // namespace rtc
231 
232 #endif  // HAVE_DBUS_GLIB
233