1 // Copyright (c) 2012 The Chromium 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 "chromeos/dbus/shill/shill_manager_client.h"
6 
7 #include <memory>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/bind.h"
12 #include "base/run_loop.h"
13 #include "base/test/mock_callback.h"
14 #include "base/values.h"
15 #include "chromeos/dbus/shill/shill_client_unittest_base.h"
16 #include "dbus/message.h"
17 #include "dbus/object_path.h"
18 #include "dbus/values_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/cros_system_api/dbus/service_constants.h"
21 
22 using testing::_;
23 using testing::ByRef;
24 
25 namespace chromeos {
26 
27 namespace {
28 
ExpectThrottlingArguments(bool throttling_enabled_expected,uint32_t upload_rate_kbits_expected,uint32_t download_rate_kbits_expected,dbus::MessageReader * reader)29 void ExpectThrottlingArguments(bool throttling_enabled_expected,
30                                uint32_t upload_rate_kbits_expected,
31                                uint32_t download_rate_kbits_expected,
32                                dbus::MessageReader* reader) {
33   bool throttling_enabled_actual;
34   uint32_t upload_rate_kbits_actual;
35   uint32_t download_rate_kbits_actual;
36   ASSERT_TRUE(reader->PopBool(&throttling_enabled_actual));
37   EXPECT_EQ(throttling_enabled_actual, throttling_enabled_expected);
38   ASSERT_TRUE(reader->PopUint32(&upload_rate_kbits_actual));
39   EXPECT_EQ(upload_rate_kbits_expected, upload_rate_kbits_actual);
40   ASSERT_TRUE(reader->PopUint32(&download_rate_kbits_actual));
41   EXPECT_EQ(download_rate_kbits_expected, download_rate_kbits_actual);
42   EXPECT_FALSE(reader->HasMoreData());
43 }
44 
45 }  // namespace
46 
47 class ShillManagerClientTest : public ShillClientUnittestBase {
48  public:
ShillManagerClientTest()49   ShillManagerClientTest()
50       : ShillClientUnittestBase(shill::kFlimflamManagerInterface,
51                                 dbus::ObjectPath(shill::kFlimflamServicePath)) {
52   }
53 
SetUp()54   void SetUp() override {
55     ShillClientUnittestBase::SetUp();
56     // Create a client with the mock bus.
57     ShillManagerClient::Initialize(mock_bus_.get());
58     client_ = ShillManagerClient::Get();
59     // Run the message loop to run the signal connection result callback.
60     base::RunLoop().RunUntilIdle();
61   }
62 
TearDown()63   void TearDown() override {
64     ShillManagerClient::Shutdown();
65     ShillClientUnittestBase::TearDown();
66   }
67 
68  protected:
69   ShillManagerClient* client_ = nullptr;  // Unowned convenience pointer.
70 };
71 
TEST_F(ShillManagerClientTest,PropertyChanged)72 TEST_F(ShillManagerClientTest, PropertyChanged) {
73   // Create a signal.
74   base::Value kArpGateway(true);
75   dbus::Signal signal(shill::kFlimflamManagerInterface,
76                       shill::kMonitorPropertyChanged);
77   dbus::MessageWriter writer(&signal);
78   writer.AppendString(shill::kArpGatewayProperty);
79   dbus::AppendBasicTypeValueData(&writer, kArpGateway);
80 
81   // Set expectations.
82   MockPropertyChangeObserver observer;
83   EXPECT_CALL(observer, OnPropertyChanged(shill::kArpGatewayProperty,
84                                           ValueEq(ByRef(kArpGateway))))
85       .Times(1);
86 
87   // Add the observer
88   client_->AddPropertyChangedObserver(&observer);
89 
90   // Run the signal callback.
91   SendPropertyChangedSignal(&signal);
92 
93   // Remove the observer.
94   client_->RemovePropertyChangedObserver(&observer);
95 
96   // Make sure it's not called anymore.
97   EXPECT_CALL(observer, OnPropertyChanged(_, _)).Times(0);
98 
99   // Run the signal callback again and make sure the observer isn't called.
100   SendPropertyChangedSignal(&signal);
101 }
102 
TEST_F(ShillManagerClientTest,GetProperties)103 TEST_F(ShillManagerClientTest, GetProperties) {
104   // Create response.
105   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
106   dbus::MessageWriter writer(response.get());
107   dbus::MessageWriter array_writer(NULL);
108   writer.OpenArray("{sv}", &array_writer);
109   dbus::MessageWriter entry_writer(NULL);
110   array_writer.OpenDictEntry(&entry_writer);
111   entry_writer.AppendString(shill::kArpGatewayProperty);
112   entry_writer.AppendVariantOfBool(true);
113   array_writer.CloseContainer(&entry_writer);
114   writer.CloseContainer(&array_writer);
115 
116   // Create the expected value.
117   base::Value value(base::Value::Type::DICTIONARY);
118   value.SetKey(shill::kArpGatewayProperty, base::Value(true));
119   // Set expectations.
120   PrepareForMethodCall(shill::kGetPropertiesFunction,
121                        base::BindRepeating(&ExpectNoArgument), response.get());
122   // Call method.
123   client_->GetProperties(base::BindOnce(&ExpectValueResult, &value));
124   // Run the message loop.
125   base::RunLoop().RunUntilIdle();
126 }
127 
TEST_F(ShillManagerClientTest,GetNetworksForGeolocation)128 TEST_F(ShillManagerClientTest, GetNetworksForGeolocation) {
129   // Create response.
130   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
131 
132   dbus::MessageWriter writer(response.get());
133   dbus::MessageWriter type_dict_writer(NULL);
134   writer.OpenArray("{sv}", &type_dict_writer);
135   dbus::MessageWriter type_entry_writer(NULL);
136   type_dict_writer.OpenDictEntry(&type_entry_writer);
137   type_entry_writer.AppendString(shill::kTypeWifi);
138   dbus::MessageWriter variant_writer(NULL);
139   type_entry_writer.OpenVariant("aa{ss}", &variant_writer);
140   dbus::MessageWriter wap_list_writer(NULL);
141   variant_writer.OpenArray("a{ss}", &wap_list_writer);
142   dbus::MessageWriter property_dict_writer(NULL);
143   wap_list_writer.OpenArray("{ss}", &property_dict_writer);
144   dbus::MessageWriter property_entry_writer(NULL);
145   property_dict_writer.OpenDictEntry(&property_entry_writer);
146   property_entry_writer.AppendString(shill::kGeoMacAddressProperty);
147   property_entry_writer.AppendString("01:23:45:67:89:AB");
148   property_dict_writer.CloseContainer(&property_entry_writer);
149   wap_list_writer.CloseContainer(&property_dict_writer);
150   variant_writer.CloseContainer(&wap_list_writer);
151   type_entry_writer.CloseContainer(&variant_writer);
152   type_dict_writer.CloseContainer(&type_entry_writer);
153   writer.CloseContainer(&type_dict_writer);
154 
155   // Create the expected value.
156   base::Value property_dict_value(base::Value::Type::DICTIONARY);
157   property_dict_value.SetKey(shill::kGeoMacAddressProperty,
158                              base::Value("01:23:45:67:89:AB"));
159   base::Value type_entry_value(base::Value::Type::LIST);
160   type_entry_value.Append(std::move(property_dict_value));
161   base::Value type_dict_value(base::Value::Type::DICTIONARY);
162   type_dict_value.SetKey("wifi", std::move(type_entry_value));
163 
164   // Set expectations.
165   PrepareForMethodCall(shill::kGetNetworksForGeolocation,
166                        base::BindRepeating(&ExpectNoArgument), response.get());
167   // Call method.
168   client_->GetNetworksForGeolocation(
169       base::BindOnce(&ExpectValueResult, &type_dict_value));
170 
171   // Run the message loop.
172   base::RunLoop().RunUntilIdle();
173 }
174 
TEST_F(ShillManagerClientTest,SetProperty)175 TEST_F(ShillManagerClientTest, SetProperty) {
176   // Create response.
177   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
178   // Set expectations.
179   base::Value value("portal list");
180   PrepareForMethodCall(
181       shill::kSetPropertyFunction,
182       base::BindRepeating(ExpectStringAndValueArguments,
183                           shill::kCheckPortalListProperty, &value),
184       response.get());
185   // Call method.
186   base::MockCallback<base::OnceClosure> mock_closure;
187   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
188   client_->SetProperty(shill::kCheckPortalListProperty, value,
189                        mock_closure.Get(), mock_error_callback.Get());
190   EXPECT_CALL(mock_closure, Run()).Times(1);
191   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
192 
193   // Run the message loop.
194   base::RunLoop().RunUntilIdle();
195 }
196 
TEST_F(ShillManagerClientTest,RequestScan)197 TEST_F(ShillManagerClientTest, RequestScan) {
198   // Create response.
199   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
200   // Set expectations.
201   PrepareForMethodCall(
202       shill::kRequestScanFunction,
203       base::BindRepeating(&ExpectStringArgument, shill::kTypeWifi),
204       response.get());
205   // Call method.
206   base::MockCallback<base::OnceClosure> mock_closure;
207   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
208   client_->RequestScan(shill::kTypeWifi, mock_closure.Get(),
209                        mock_error_callback.Get());
210   EXPECT_CALL(mock_closure, Run()).Times(1);
211   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
212 
213   // Run the message loop.
214   base::RunLoop().RunUntilIdle();
215 }
216 
TEST_F(ShillManagerClientTest,EnableTechnology)217 TEST_F(ShillManagerClientTest, EnableTechnology) {
218   // Create response.
219   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
220   // Set expectations.
221   PrepareForMethodCall(
222       shill::kEnableTechnologyFunction,
223       base::BindRepeating(&ExpectStringArgument, shill::kTypeWifi),
224       response.get());
225   // Call method.
226   base::MockCallback<base::OnceClosure> mock_closure;
227   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
228   client_->EnableTechnology(shill::kTypeWifi, mock_closure.Get(),
229                             mock_error_callback.Get());
230   EXPECT_CALL(mock_closure, Run()).Times(1);
231   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
232 
233   // Run the message loop.
234   base::RunLoop().RunUntilIdle();
235 }
236 
TEST_F(ShillManagerClientTest,NetworkThrottling)237 TEST_F(ShillManagerClientTest, NetworkThrottling) {
238   // Create response.
239   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
240   // Set expectations.
241   const bool enabled = true;
242   const uint32_t upload_rate = 1200;
243   const uint32_t download_rate = 2000;
244   PrepareForMethodCall(shill::kSetNetworkThrottlingFunction,
245                        base::BindRepeating(&ExpectThrottlingArguments, enabled,
246                                            upload_rate, download_rate),
247                        response.get());
248   // Call method.
249   base::MockCallback<base::OnceClosure> mock_closure;
250   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
251   EXPECT_CALL(mock_closure, Run()).Times(1);
252   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
253 
254   client_->SetNetworkThrottlingStatus(
255       ShillManagerClient::NetworkThrottlingStatus{enabled, upload_rate,
256                                                   download_rate},
257       mock_closure.Get(), mock_error_callback.Get());
258   base::RunLoop().RunUntilIdle();
259 }
260 
TEST_F(ShillManagerClientTest,DisableTechnology)261 TEST_F(ShillManagerClientTest, DisableTechnology) {
262   // Create response.
263   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
264   // Set expectations.
265   PrepareForMethodCall(
266       shill::kDisableTechnologyFunction,
267       base::BindRepeating(&ExpectStringArgument, shill::kTypeWifi),
268       response.get());
269   // Call method.
270   base::MockCallback<base::OnceClosure> mock_closure;
271   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
272   client_->DisableTechnology(shill::kTypeWifi, mock_closure.Get(),
273                              mock_error_callback.Get());
274   EXPECT_CALL(mock_closure, Run()).Times(1);
275   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
276 
277   // Run the message loop.
278   base::RunLoop().RunUntilIdle();
279 }
280 
TEST_F(ShillManagerClientTest,ConfigureService)281 TEST_F(ShillManagerClientTest, ConfigureService) {
282   // Create response.
283   const dbus::ObjectPath object_path("/");
284   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
285   dbus::MessageWriter writer(response.get());
286   writer.AppendObjectPath(object_path);
287   // Create the argument dictionary.
288   base::Value arg = CreateExampleServiceProperties();
289   // Use a variant valued dictionary rather than a string valued one.
290   const bool string_valued = false;
291   // Set expectations.
292   PrepareForMethodCall(
293       shill::kConfigureServiceFunction,
294       base::BindRepeating(&ExpectValueDictionaryArgument, &arg, string_valued),
295       response.get());
296   // Call method.
297   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
298   client_->ConfigureService(
299       arg, base::BindOnce(&ExpectObjectPathResultWithoutStatus, object_path),
300       mock_error_callback.Get());
301   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
302 
303   // Run the message loop.
304   base::RunLoop().RunUntilIdle();
305 }
306 
TEST_F(ShillManagerClientTest,GetService)307 TEST_F(ShillManagerClientTest, GetService) {
308   // Create response.
309   const dbus::ObjectPath object_path("/");
310   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
311   dbus::MessageWriter writer(response.get());
312   writer.AppendObjectPath(object_path);
313   // Create the argument dictionary.
314   base::Value arg = CreateExampleServiceProperties();
315   // Use a variant valued dictionary rather than a string valued one.
316   const bool string_valued = false;
317   // Set expectations.
318   PrepareForMethodCall(
319       shill::kGetServiceFunction,
320       base::BindRepeating(&ExpectValueDictionaryArgument, &arg, string_valued),
321       response.get());
322   // Call method.
323   base::MockCallback<ShillManagerClient::ErrorCallback> mock_error_callback;
324   client_->GetService(
325       arg, base::BindOnce(&ExpectObjectPathResultWithoutStatus, object_path),
326       mock_error_callback.Get());
327   EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
328 
329   // Run the message loop.
330   base::RunLoop().RunUntilIdle();
331 }
332 
333 }  // namespace chromeos
334