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
17namespace rtc {
18
19#define SIG_NAME "NameAcquired"
20
21static const uint32_t kTimeoutMs = 5000U;
22
23class 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
29  DBusSigFilterTest()
30      : DBusSigFilter(GetFilter()),
31        message_received_(false) {
32  }
33
34  bool MessageReceived() {
35    return message_received_;
36  }
37
38 private:
39  static std::string GetFilter() {
40    return rtc::DBusSigFilter::BuildFilterString("", "", SIG_NAME);
41  }
42
43  // Implement virtual method of DBusSigFilter. On caller thread.
44  virtual void ProcessSignal(DBusMessage *message) {
45    EXPECT_TRUE(message != NULL);
46    message_received_ = true;
47  }
48
49  bool message_received_;
50};
51
52TEST(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.
84TEST(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
101TEST(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
129TEST(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
151TEST(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
170TEST(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
195TEST(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
217TEST(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