1// 2// Copyright (C) 2012 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "shill/wimax/wimax.h" 18 19#include <memory> 20#include <string> 21 22#include "shill/dhcp/mock_dhcp_config.h" 23#include "shill/dhcp/mock_dhcp_provider.h" 24#include "shill/mock_manager.h" 25#include "shill/mock_metrics.h" 26#include "shill/nice_mock_control.h" 27#include "shill/test_event_dispatcher.h" 28#include "shill/testing.h" 29#include "shill/wimax/mock_wimax_device_proxy.h" 30#include "shill/wimax/mock_wimax_provider.h" 31#include "shill/wimax/mock_wimax_service.h" 32 33using base::Bind; 34using base::Unretained; 35using std::string; 36using testing::_; 37using testing::NiceMock; 38using testing::Return; 39 40namespace shill { 41 42namespace { 43 44const char kTestLinkName[] = "wm0"; 45const char kTestAddress[] = "01:23:45:67:89:ab"; 46const int kTestInterfaceIndex = 5; 47const char kTestPath[] = "/org/chromium/WiMaxManager/Device/6"; 48 49} // namespace 50 51class WiMaxTest : public testing::Test { 52 public: 53 WiMaxTest() 54 : proxy_(new MockWiMaxDeviceProxy()), 55 metrics_(&dispatcher_), 56 manager_(&control_, &dispatcher_, &metrics_), 57 dhcp_config_(new MockDHCPConfig(&control_, 58 kTestLinkName)), 59 device_(new WiMax(&control_, &dispatcher_, &metrics_, &manager_, 60 kTestLinkName, kTestAddress, kTestInterfaceIndex, 61 kTestPath)) {} 62 63 virtual ~WiMaxTest() {} 64 65 protected: 66 class Target { 67 public: 68 virtual ~Target() {} 69 70 MOCK_METHOD1(EnabledStateChanged, void(const Error& error)); 71 }; 72 73 virtual void SetUp() { 74 device_->set_dhcp_provider(&dhcp_provider_); 75 } 76 77 virtual void TearDown() { 78 device_->SelectService(nullptr); 79 device_->pending_service_ = nullptr; 80 } 81 82 std::unique_ptr<MockWiMaxDeviceProxy> proxy_; 83 NiceMockControl control_; 84 EventDispatcherForTest dispatcher_; 85 NiceMock<MockMetrics> metrics_; 86 MockManager manager_; 87 MockDHCPProvider dhcp_provider_; 88 scoped_refptr<MockDHCPConfig> dhcp_config_; 89 WiMaxRefPtr device_; 90}; 91 92TEST_F(WiMaxTest, Constructor) { 93 EXPECT_EQ(kTestPath, device_->path()); 94 EXPECT_FALSE(device_->scanning()); 95} 96 97TEST_F(WiMaxTest, StartStop) { 98 EXPECT_FALSE(device_->proxy_.get()); 99 EXPECT_CALL(control_, CreateWiMaxDeviceProxy(_)) 100 .WillOnce(ReturnAndReleasePointee(&proxy_)); 101 EXPECT_CALL(*proxy_, Enable(_, _, _)); 102 EXPECT_CALL(*proxy_, set_networks_changed_callback(_)); 103 EXPECT_CALL(*proxy_, set_status_changed_callback(_)); 104 EXPECT_CALL(*proxy_, Disable(_, _, _)); 105 device_->Start(nullptr, EnabledStateChangedCallback()); 106 ASSERT_TRUE(device_->proxy_.get()); 107 108 scoped_refptr<MockWiMaxService> service( 109 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 110 device_->pending_service_ = service; 111 EXPECT_CALL(*service, SetState(Service::kStateIdle)); 112 device_->networks_.insert("path"); 113 MockWiMaxProvider provider; 114 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); 115 EXPECT_CALL(provider, OnNetworksChanged()); 116 device_->StartConnectTimeout(); 117 device_->Stop(nullptr, EnabledStateChangedCallback()); 118 EXPECT_TRUE(device_->networks_.empty()); 119 EXPECT_FALSE(device_->IsConnectTimeoutStarted()); 120 EXPECT_FALSE(device_->pending_service_); 121} 122 123TEST_F(WiMaxTest, OnServiceStopped) { 124 scoped_refptr<NiceMock<MockWiMaxService>> service0( 125 new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_)); 126 scoped_refptr<MockWiMaxService> service1( 127 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 128 device_->SelectService(service0); 129 device_->pending_service_ = service1; 130 131 device_->OnServiceStopped(nullptr); 132 EXPECT_TRUE(device_->selected_service()); 133 EXPECT_TRUE(device_->pending_service_); 134 135 device_->OnServiceStopped(service0); 136 EXPECT_FALSE(device_->selected_service()); 137 EXPECT_TRUE(device_->pending_service_); 138 139 device_->OnServiceStopped(service1); 140 EXPECT_FALSE(device_->selected_service()); 141 EXPECT_FALSE(device_->pending_service_); 142} 143 144TEST_F(WiMaxTest, OnNetworksChanged) { 145 MockWiMaxProvider provider; 146 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); 147 EXPECT_CALL(provider, OnNetworksChanged()); 148 device_->networks_.insert("foo"); 149 RpcIdentifiers networks; 150 networks.push_back("bar"); 151 networks.push_back("zoo"); 152 networks.push_back("bar"); 153 device_->OnNetworksChanged(networks); 154 EXPECT_EQ(2, device_->networks_.size()); 155 EXPECT_TRUE(ContainsKey(device_->networks_, "bar")); 156 EXPECT_TRUE(ContainsKey(device_->networks_, "zoo")); 157} 158 159TEST_F(WiMaxTest, OnConnectComplete) { 160 scoped_refptr<MockWiMaxService> service( 161 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 162 device_->pending_service_ = service; 163 EXPECT_CALL(*service, SetState(_)).Times(0); 164 EXPECT_TRUE(device_->pending_service_); 165 EXPECT_CALL(*service, SetState(Service::kStateFailure)); 166 device_->OnConnectComplete(Error(Error::kOperationFailed)); 167 EXPECT_FALSE(device_->pending_service_); 168} 169 170TEST_F(WiMaxTest, OnStatusChanged) { 171 scoped_refptr<MockWiMaxService> service( 172 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 173 174 EXPECT_EQ(wimax_manager::kDeviceStatusUninitialized, device_->status_); 175 device_->pending_service_ = service; 176 EXPECT_CALL(*service, SetState(_)).Times(0); 177 EXPECT_CALL(*service, ClearPassphrase()).Times(0); 178 device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning); 179 EXPECT_TRUE(device_->pending_service_); 180 EXPECT_EQ(wimax_manager::kDeviceStatusScanning, device_->status_); 181 182 device_->status_ = wimax_manager::kDeviceStatusConnecting; 183 EXPECT_CALL(*service, SetState(Service::kStateFailure)); 184 EXPECT_CALL(*service, ClearPassphrase()).Times(0); 185 device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning); 186 EXPECT_FALSE(device_->pending_service_); 187 188 device_->status_ = wimax_manager::kDeviceStatusConnecting; 189 device_->SelectService(service); 190 EXPECT_CALL(*service, SetState(Service::kStateFailure)); 191 EXPECT_CALL(*service, SetState(Service::kStateIdle)); 192 EXPECT_CALL(*service, ClearPassphrase()).Times(0); 193 device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning); 194 EXPECT_FALSE(device_->selected_service()); 195 196 device_->pending_service_ = service; 197 device_->SelectService(service); 198 EXPECT_CALL(*service, SetState(_)).Times(0); 199 EXPECT_CALL(*service, ClearPassphrase()).Times(0); 200 device_->OnStatusChanged(wimax_manager::kDeviceStatusConnecting); 201 EXPECT_TRUE(device_->pending_service_); 202 EXPECT_TRUE(device_->selected_service()); 203 EXPECT_EQ(wimax_manager::kDeviceStatusConnecting, device_->status_); 204 205 EXPECT_CALL(*service, SetState(Service::kStateIdle)); 206 device_->SelectService(nullptr); 207} 208 209TEST_F(WiMaxTest, UseNoArpGateway) { 210 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(kTestLinkName, _, false, _)) 211 .WillOnce(Return(dhcp_config_)); 212 device_->AcquireIPConfig(); 213} 214 215TEST_F(WiMaxTest, DropService) { 216 scoped_refptr<NiceMock<MockWiMaxService>> service0( 217 new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_)); 218 scoped_refptr<MockWiMaxService> service1( 219 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 220 device_->SelectService(service0); 221 device_->pending_service_ = service1; 222 device_->StartConnectTimeout(); 223 224 EXPECT_CALL(*service0, SetState(Service::kStateIdle)).Times(2); 225 EXPECT_CALL(*service1, SetState(Service::kStateIdle)); 226 device_->DropService(Service::kStateIdle); 227 EXPECT_FALSE(device_->selected_service()); 228 EXPECT_FALSE(device_->pending_service_); 229 EXPECT_FALSE(device_->IsConnectTimeoutStarted()); 230 231 // Expect no crash. 232 device_->DropService(Service::kStateFailure); 233} 234 235TEST_F(WiMaxTest, OnDeviceVanished) { 236 device_->proxy_.reset(proxy_.release()); 237 scoped_refptr<MockWiMaxService> service( 238 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 239 device_->pending_service_ = service; 240 EXPECT_CALL(*service, SetState(Service::kStateIdle)); 241 device_->OnDeviceVanished(); 242 EXPECT_FALSE(device_->proxy_.get()); 243 EXPECT_FALSE(device_->pending_service_); 244} 245 246TEST_F(WiMaxTest, OnEnableComplete) { 247 MockWiMaxProvider provider; 248 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); 249 RpcIdentifiers networks(1, "path"); 250 EXPECT_CALL(*proxy_, Networks(_)).WillOnce(Return(networks)); 251 device_->proxy_.reset(proxy_.release()); 252 EXPECT_CALL(provider, OnNetworksChanged()); 253 Target target; 254 EXPECT_CALL(target, EnabledStateChanged(_)); 255 EnabledStateChangedCallback callback( 256 Bind(&Target::EnabledStateChanged, Unretained(&target))); 257 Error error; 258 device_->OnEnableComplete(callback, error); 259 EXPECT_EQ(1, device_->networks_.size()); 260 EXPECT_TRUE(ContainsKey(device_->networks_, "path")); 261 262 EXPECT_TRUE(device_->proxy_.get()); 263 error.Populate(Error::kOperationFailed); 264 EXPECT_CALL(target, EnabledStateChanged(_)); 265 device_->OnEnableComplete(callback, error); 266 EXPECT_FALSE(device_->proxy_.get()); 267} 268 269TEST_F(WiMaxTest, ConnectTimeout) { 270 EXPECT_EQ(&dispatcher_, device_->dispatcher()); 271 EXPECT_TRUE(device_->connect_timeout_callback_.IsCancelled()); 272 EXPECT_FALSE(device_->IsConnectTimeoutStarted()); 273 EXPECT_EQ(WiMax::kDefaultConnectTimeoutSeconds, 274 device_->connect_timeout_seconds_); 275 device_->connect_timeout_seconds_ = 0; 276 device_->StartConnectTimeout(); 277 EXPECT_FALSE(device_->connect_timeout_callback_.IsCancelled()); 278 EXPECT_TRUE(device_->IsConnectTimeoutStarted()); 279 device_->dispatcher_ = nullptr; 280 device_->StartConnectTimeout(); // Expect no crash. 281 scoped_refptr<MockWiMaxService> service( 282 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 283 device_->pending_service_ = service; 284 EXPECT_CALL(*service, SetState(Service::kStateFailure)); 285 dispatcher_.DispatchPendingEvents(); 286 EXPECT_TRUE(device_->connect_timeout_callback_.IsCancelled()); 287 EXPECT_FALSE(device_->IsConnectTimeoutStarted()); 288 EXPECT_FALSE(device_->pending_service_); 289} 290 291TEST_F(WiMaxTest, ConnectTo) { 292 static const char kPath[] = "/network/path"; 293 scoped_refptr<MockWiMaxService> service( 294 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); 295 EXPECT_CALL(*service, SetState(Service::kStateAssociating)); 296 device_->status_ = wimax_manager::kDeviceStatusScanning; 297 EXPECT_CALL(*service, GetNetworkObjectPath()).WillOnce(Return(kPath)); 298 EXPECT_CALL(*proxy_, Connect(kPath, _, _, _, _)) 299 .WillOnce(SetErrorTypeInArgument<2>(Error::kSuccess)); 300 device_->proxy_.reset(proxy_.release()); 301 Error error; 302 device_->ConnectTo(service, &error); 303 EXPECT_TRUE(error.IsSuccess()); 304 EXPECT_EQ(service.get(), device_->pending_service_.get()); 305 EXPECT_EQ(wimax_manager::kDeviceStatusUninitialized, device_->status_); 306 EXPECT_TRUE(device_->IsConnectTimeoutStarted()); 307 308 device_->ConnectTo(service, &error); 309 EXPECT_EQ(Error::kInProgress, error.type()); 310 311 device_->pending_service_ = nullptr; 312} 313 314TEST_F(WiMaxTest, IsIdle) { 315 EXPECT_TRUE(device_->IsIdle()); 316 scoped_refptr<NiceMock<MockWiMaxService>> service( 317 new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_)); 318 device_->pending_service_ = service; 319 EXPECT_FALSE(device_->IsIdle()); 320 device_->pending_service_ = nullptr; 321 device_->SelectService(service); 322 EXPECT_FALSE(device_->IsIdle()); 323} 324 325} // namespace shill 326