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