wifi_data_provider_linux_unittest.cc 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. #include "services/device/geolocation/wifi_data_provider_linux.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include "base/logging.h"
  8. #include "base/memory/ref_counted.h"
  9. #include "base/strings/utf_string_conversions.h"
  10. #include "base/test/task_environment.h"
  11. #include "dbus/message.h"
  12. #include "dbus/mock_bus.h"
  13. #include "dbus/mock_object_proxy.h"
  14. #include "dbus/object_path.h"
  15. #include "dbus/object_proxy.h"
  16. #include "testing/gmock/include/gmock/gmock.h"
  17. #include "testing/gtest/include/gtest/gtest.h"
  18. using ::testing::_;
  19. using ::testing::Invoke;
  20. using ::testing::Return;
  21. using ::testing::Unused;
  22. namespace device {
  23. class GeolocationWifiDataProviderLinuxTest : public testing::Test {
  24. void SetUp() override {
  25. // Create a mock bus.
  26. dbus::Bus::Options options;
  27. options.bus_type = dbus::Bus::SYSTEM;
  28. mock_bus_ = base::MakeRefCounted<dbus::MockBus>(options);
  29. // Create a mock proxy that behaves as NetworkManager.
  30. mock_network_manager_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
  31. mock_bus_.get(), "org.freedesktop.NetworkManager",
  32. dbus::ObjectPath("/org/freedesktop/NetworkManager"));
  33. // Set an expectation so mock_network_manager_proxy_'s
  34. // CallMethodAndBlock() will use CreateNetworkManagerProxyResponse()
  35. // to return responses.
  36. EXPECT_CALL(*mock_network_manager_proxy_.get(), CallMethodAndBlock(_, _))
  37. .WillRepeatedly(Invoke(this, &GeolocationWifiDataProviderLinuxTest::
  38. CreateNetworkManagerProxyResponse));
  39. // Create a mock proxy that behaves as NetworkManager/Devices/0.
  40. mock_device_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
  41. mock_bus_.get(), "org.freedesktop.NetworkManager",
  42. dbus::ObjectPath("/org/freedesktop/NetworkManager/Devices/0"));
  43. EXPECT_CALL(*mock_device_proxy_.get(), CallMethodAndBlock(_, _))
  44. .WillRepeatedly(Invoke(
  45. this,
  46. &GeolocationWifiDataProviderLinuxTest::CreateDeviceProxyResponse));
  47. // Create a mock proxy that behaves as NetworkManager/AccessPoint/0.
  48. mock_access_point_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
  49. mock_bus_.get(), "org.freedesktop.NetworkManager",
  50. dbus::ObjectPath("/org/freedesktop/NetworkManager/AccessPoint/0"));
  51. EXPECT_CALL(*mock_access_point_proxy_.get(), CallMethodAndBlock(_, _))
  52. .WillRepeatedly(Invoke(this, &GeolocationWifiDataProviderLinuxTest::
  53. CreateAccessPointProxyResponse));
  54. // Set an expectation so mock_bus_'s GetObjectProxy() for the given
  55. // service name and the object path will return
  56. // mock_network_manager_proxy_.
  57. EXPECT_CALL(
  58. *mock_bus_.get(),
  59. GetObjectProxy("org.freedesktop.NetworkManager",
  60. dbus::ObjectPath("/org/freedesktop/NetworkManager")))
  61. .WillOnce(Return(mock_network_manager_proxy_.get()));
  62. // Likewise, set an expectation for mock_device_proxy_.
  63. EXPECT_CALL(
  64. *mock_bus_.get(),
  65. GetObjectProxy(
  66. "org.freedesktop.NetworkManager",
  67. dbus::ObjectPath("/org/freedesktop/NetworkManager/Devices/0")))
  68. .WillOnce(Return(mock_device_proxy_.get()))
  69. .WillOnce(Return(mock_device_proxy_.get()));
  70. // Likewise, set an expectation for mock_access_point_proxy_.
  71. EXPECT_CALL(
  72. *mock_bus_.get(),
  73. GetObjectProxy(
  74. "org.freedesktop.NetworkManager",
  75. dbus::ObjectPath("/org/freedesktop/NetworkManager/AccessPoint/0")))
  76. .WillOnce(Return(mock_access_point_proxy_.get()));
  77. // ShutdownAndBlock() should be called.
  78. EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
  79. // Create the wlan API with the mock bus object injected.
  80. wifi_provider_linux_ = base::MakeRefCounted<WifiDataProviderLinux>();
  81. wlan_api_ = wifi_provider_linux_->CreateWlanApiForTesting(mock_bus_);
  82. ASSERT_TRUE(wlan_api_);
  83. }
  84. protected:
  85. GeolocationWifiDataProviderLinuxTest()
  86. : task_environment_(
  87. base::test::SingleThreadTaskEnvironment::MainThreadType::UI) {}
  88. // WifiDataProvider requires a task runner to be present. The |message_loop_|
  89. // is defined here, as it should outlive |wifi_provider_linux_|.
  90. base::test::SingleThreadTaskEnvironment task_environment_;
  91. scoped_refptr<dbus::MockBus> mock_bus_;
  92. scoped_refptr<dbus::MockObjectProxy> mock_network_manager_proxy_;
  93. scoped_refptr<dbus::MockObjectProxy> mock_access_point_proxy_;
  94. scoped_refptr<dbus::MockObjectProxy> mock_device_proxy_;
  95. scoped_refptr<WifiDataProviderLinux> wifi_provider_linux_;
  96. std::unique_ptr<WifiDataProviderCommon::WlanApiInterface> wlan_api_;
  97. private:
  98. // Creates a response for |mock_network_manager_proxy_|.
  99. std::unique_ptr<dbus::Response> CreateNetworkManagerProxyResponse(
  100. dbus::MethodCall* method_call,
  101. Unused) {
  102. if (method_call->GetInterface() == "org.freedesktop.NetworkManager" &&
  103. method_call->GetMember() == "GetDevices") {
  104. // The list of devices is asked. Return the object path.
  105. std::vector<dbus::ObjectPath> object_paths;
  106. object_paths.push_back(
  107. dbus::ObjectPath("/org/freedesktop/NetworkManager/Devices/0"));
  108. std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty();
  109. dbus::MessageWriter writer(response.get());
  110. writer.AppendArrayOfObjectPaths(object_paths);
  111. return response;
  112. }
  113. LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
  114. return nullptr;
  115. }
  116. // Creates a response for |mock_device_proxy_|.
  117. std::unique_ptr<dbus::Response> CreateDeviceProxyResponse(
  118. dbus::MethodCall* method_call,
  119. Unused) {
  120. if (method_call->GetInterface() == DBUS_INTERFACE_PROPERTIES &&
  121. method_call->GetMember() == "Get") {
  122. dbus::MessageReader reader(method_call);
  123. std::string interface_name;
  124. std::string property_name;
  125. if (reader.PopString(&interface_name) &&
  126. reader.PopString(&property_name)) {
  127. // The device type is asked. Respond that the device type is wifi.
  128. std::unique_ptr<dbus::Response> response =
  129. dbus::Response::CreateEmpty();
  130. dbus::MessageWriter writer(response.get());
  131. // This matches NM_DEVICE_TYPE_WIFI in wifi_data_provider_linux.cc.
  132. const int kDeviceTypeWifi = 2;
  133. writer.AppendVariantOfUint32(kDeviceTypeWifi);
  134. return response;
  135. }
  136. } else if (method_call->GetInterface() ==
  137. "org.freedesktop.NetworkManager.Device.Wireless" &&
  138. method_call->GetMember() == "GetAccessPoints") {
  139. // The list of access points is asked. Return the object path.
  140. std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty();
  141. dbus::MessageWriter writer(response.get());
  142. std::vector<dbus::ObjectPath> object_paths;
  143. object_paths.push_back(
  144. dbus::ObjectPath("/org/freedesktop/NetworkManager/AccessPoint/0"));
  145. writer.AppendArrayOfObjectPaths(object_paths);
  146. return response;
  147. }
  148. LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
  149. return nullptr;
  150. }
  151. // Creates a response for |mock_access_point_proxy_|.
  152. std::unique_ptr<dbus::Response> CreateAccessPointProxyResponse(
  153. dbus::MethodCall* method_call,
  154. Unused) {
  155. if (method_call->GetInterface() == DBUS_INTERFACE_PROPERTIES &&
  156. method_call->GetMember() == "Get") {
  157. dbus::MessageReader reader(method_call);
  158. std::string interface_name;
  159. std::string property_name;
  160. if (reader.PopString(&interface_name) &&
  161. reader.PopString(&property_name)) {
  162. std::unique_ptr<dbus::Response> response =
  163. dbus::Response::CreateEmpty();
  164. dbus::MessageWriter writer(response.get());
  165. if (property_name == "Ssid") {
  166. const uint8_t kSsid[] = {0x74, 0x65, 0x73, 0x74}; // "test"
  167. dbus::MessageWriter variant_writer(response.get());
  168. writer.OpenVariant("ay", &variant_writer);
  169. variant_writer.AppendArrayOfBytes(kSsid, std::size(kSsid));
  170. writer.CloseContainer(&variant_writer);
  171. } else if (property_name == "HwAddress") {
  172. // This will be converted to "00-11-22-33-44-55".
  173. const std::string kMacAddress = "00:11:22:33:44:55";
  174. writer.AppendVariantOfString(kMacAddress);
  175. } else if (property_name == "Strength") {
  176. // This will be converted to -50.
  177. const uint8_t kStrength = 100;
  178. writer.AppendVariantOfByte(kStrength);
  179. } else if (property_name == "Frequency") {
  180. // This will be converted to channel 4.
  181. const uint32_t kFrequency = 2427;
  182. writer.AppendVariantOfUint32(kFrequency);
  183. }
  184. return response;
  185. }
  186. }
  187. LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
  188. return nullptr;
  189. }
  190. };
  191. TEST_F(GeolocationWifiDataProviderLinuxTest, GetAccessPointData) {
  192. WifiData::AccessPointDataSet access_point_data_set;
  193. ASSERT_TRUE(wlan_api_->GetAccessPointData(&access_point_data_set));
  194. ASSERT_EQ(1U, access_point_data_set.size());
  195. const AccessPointData& access_point_data = *access_point_data_set.begin();
  196. // Check the contents of the access point data.
  197. // The expected values come from CreateAccessPointProxyResponse() above.
  198. EXPECT_EQ("test", base::UTF16ToUTF8(access_point_data.ssid));
  199. EXPECT_EQ("00-11-22-33-44-55",
  200. base::UTF16ToUTF8(access_point_data.mac_address));
  201. EXPECT_EQ(-50, access_point_data.radio_signal_strength);
  202. EXPECT_EQ(4, access_point_data.channel);
  203. }
  204. } // namespace device