// // Copyright (C) 2012 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "shill/wimax/wimax.h" #include <memory> #include <string> #include "shill/dhcp/mock_dhcp_config.h" #include "shill/dhcp/mock_dhcp_provider.h" #include "shill/mock_manager.h" #include "shill/mock_metrics.h" #include "shill/nice_mock_control.h" #include "shill/test_event_dispatcher.h" #include "shill/testing.h" #include "shill/wimax/mock_wimax_device_proxy.h" #include "shill/wimax/mock_wimax_provider.h" #include "shill/wimax/mock_wimax_service.h" using base::Bind; using base::Unretained; using std::string; using testing::_; using testing::NiceMock; using testing::Return; namespace shill { namespace { const char kTestLinkName[] = "wm0"; const char kTestAddress[] = "01:23:45:67:89:ab"; const int kTestInterfaceIndex = 5; const char kTestPath[] = "/org/chromium/WiMaxManager/Device/6"; } // namespace class WiMaxTest : public testing::Test { public: WiMaxTest() : proxy_(new MockWiMaxDeviceProxy()), metrics_(&dispatcher_), manager_(&control_, &dispatcher_, &metrics_), dhcp_config_(new MockDHCPConfig(&control_, kTestLinkName)), device_(new WiMax(&control_, &dispatcher_, &metrics_, &manager_, kTestLinkName, kTestAddress, kTestInterfaceIndex, kTestPath)) {} virtual ~WiMaxTest() {} protected: class Target { public: virtual ~Target() {} MOCK_METHOD1(EnabledStateChanged, void(const Error& error)); }; virtual void SetUp() { device_->set_dhcp_provider(&dhcp_provider_); } virtual void TearDown() { device_->SelectService(nullptr); device_->pending_service_ = nullptr; } std::unique_ptr<MockWiMaxDeviceProxy> proxy_; NiceMockControl control_; EventDispatcherForTest dispatcher_; NiceMock<MockMetrics> metrics_; MockManager manager_; MockDHCPProvider dhcp_provider_; scoped_refptr<MockDHCPConfig> dhcp_config_; WiMaxRefPtr device_; }; TEST_F(WiMaxTest, Constructor) { EXPECT_EQ(kTestPath, device_->path()); EXPECT_FALSE(device_->scanning()); } TEST_F(WiMaxTest, StartStop) { EXPECT_FALSE(device_->proxy_.get()); EXPECT_CALL(control_, CreateWiMaxDeviceProxy(_)) .WillOnce(ReturnAndReleasePointee(&proxy_)); EXPECT_CALL(*proxy_, Enable(_, _, _)); EXPECT_CALL(*proxy_, set_networks_changed_callback(_)); EXPECT_CALL(*proxy_, set_status_changed_callback(_)); EXPECT_CALL(*proxy_, Disable(_, _, _)); device_->Start(nullptr, EnabledStateChangedCallback()); ASSERT_TRUE(device_->proxy_.get()); scoped_refptr<MockWiMaxService> service( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); device_->pending_service_ = service; EXPECT_CALL(*service, SetState(Service::kStateIdle)); device_->networks_.insert("path"); MockWiMaxProvider provider; EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); EXPECT_CALL(provider, OnNetworksChanged()); device_->StartConnectTimeout(); device_->Stop(nullptr, EnabledStateChangedCallback()); EXPECT_TRUE(device_->networks_.empty()); EXPECT_FALSE(device_->IsConnectTimeoutStarted()); EXPECT_FALSE(device_->pending_service_); } TEST_F(WiMaxTest, OnServiceStopped) { scoped_refptr<NiceMock<MockWiMaxService>> service0( new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_)); scoped_refptr<MockWiMaxService> service1( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); device_->SelectService(service0); device_->pending_service_ = service1; device_->OnServiceStopped(nullptr); EXPECT_TRUE(device_->selected_service()); EXPECT_TRUE(device_->pending_service_); device_->OnServiceStopped(service0); EXPECT_FALSE(device_->selected_service()); EXPECT_TRUE(device_->pending_service_); device_->OnServiceStopped(service1); EXPECT_FALSE(device_->selected_service()); EXPECT_FALSE(device_->pending_service_); } TEST_F(WiMaxTest, OnNetworksChanged) { MockWiMaxProvider provider; EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); EXPECT_CALL(provider, OnNetworksChanged()); device_->networks_.insert("foo"); RpcIdentifiers networks; networks.push_back("bar"); networks.push_back("zoo"); networks.push_back("bar"); device_->OnNetworksChanged(networks); EXPECT_EQ(2, device_->networks_.size()); EXPECT_TRUE(ContainsKey(device_->networks_, "bar")); EXPECT_TRUE(ContainsKey(device_->networks_, "zoo")); } TEST_F(WiMaxTest, OnConnectComplete) { scoped_refptr<MockWiMaxService> service( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); device_->pending_service_ = service; EXPECT_CALL(*service, SetState(_)).Times(0); EXPECT_TRUE(device_->pending_service_); EXPECT_CALL(*service, SetState(Service::kStateFailure)); device_->OnConnectComplete(Error(Error::kOperationFailed)); EXPECT_FALSE(device_->pending_service_); } TEST_F(WiMaxTest, OnStatusChanged) { scoped_refptr<MockWiMaxService> service( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); EXPECT_EQ(wimax_manager::kDeviceStatusUninitialized, device_->status_); device_->pending_service_ = service; EXPECT_CALL(*service, SetState(_)).Times(0); EXPECT_CALL(*service, ClearPassphrase()).Times(0); device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning); EXPECT_TRUE(device_->pending_service_); EXPECT_EQ(wimax_manager::kDeviceStatusScanning, device_->status_); device_->status_ = wimax_manager::kDeviceStatusConnecting; EXPECT_CALL(*service, SetState(Service::kStateFailure)); EXPECT_CALL(*service, ClearPassphrase()).Times(0); device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning); EXPECT_FALSE(device_->pending_service_); device_->status_ = wimax_manager::kDeviceStatusConnecting; device_->SelectService(service); EXPECT_CALL(*service, SetState(Service::kStateFailure)); EXPECT_CALL(*service, SetState(Service::kStateIdle)); EXPECT_CALL(*service, ClearPassphrase()).Times(0); device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning); EXPECT_FALSE(device_->selected_service()); device_->pending_service_ = service; device_->SelectService(service); EXPECT_CALL(*service, SetState(_)).Times(0); EXPECT_CALL(*service, ClearPassphrase()).Times(0); device_->OnStatusChanged(wimax_manager::kDeviceStatusConnecting); EXPECT_TRUE(device_->pending_service_); EXPECT_TRUE(device_->selected_service()); EXPECT_EQ(wimax_manager::kDeviceStatusConnecting, device_->status_); EXPECT_CALL(*service, SetState(Service::kStateIdle)); device_->SelectService(nullptr); } TEST_F(WiMaxTest, UseNoArpGateway) { EXPECT_CALL(dhcp_provider_, CreateIPv4Config(kTestLinkName, _, false, _)) .WillOnce(Return(dhcp_config_)); device_->AcquireIPConfig(); } TEST_F(WiMaxTest, DropService) { scoped_refptr<NiceMock<MockWiMaxService>> service0( new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_)); scoped_refptr<MockWiMaxService> service1( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); device_->SelectService(service0); device_->pending_service_ = service1; device_->StartConnectTimeout(); EXPECT_CALL(*service0, SetState(Service::kStateIdle)).Times(2); EXPECT_CALL(*service1, SetState(Service::kStateIdle)); device_->DropService(Service::kStateIdle); EXPECT_FALSE(device_->selected_service()); EXPECT_FALSE(device_->pending_service_); EXPECT_FALSE(device_->IsConnectTimeoutStarted()); // Expect no crash. device_->DropService(Service::kStateFailure); } TEST_F(WiMaxTest, OnDeviceVanished) { device_->proxy_.reset(proxy_.release()); scoped_refptr<MockWiMaxService> service( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); device_->pending_service_ = service; EXPECT_CALL(*service, SetState(Service::kStateIdle)); device_->OnDeviceVanished(); EXPECT_FALSE(device_->proxy_.get()); EXPECT_FALSE(device_->pending_service_); } TEST_F(WiMaxTest, OnEnableComplete) { MockWiMaxProvider provider; EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); RpcIdentifiers networks(1, "path"); EXPECT_CALL(*proxy_, Networks(_)).WillOnce(Return(networks)); device_->proxy_.reset(proxy_.release()); EXPECT_CALL(provider, OnNetworksChanged()); Target target; EXPECT_CALL(target, EnabledStateChanged(_)); EnabledStateChangedCallback callback( Bind(&Target::EnabledStateChanged, Unretained(&target))); Error error; device_->OnEnableComplete(callback, error); EXPECT_EQ(1, device_->networks_.size()); EXPECT_TRUE(ContainsKey(device_->networks_, "path")); EXPECT_TRUE(device_->proxy_.get()); error.Populate(Error::kOperationFailed); EXPECT_CALL(target, EnabledStateChanged(_)); device_->OnEnableComplete(callback, error); EXPECT_FALSE(device_->proxy_.get()); } TEST_F(WiMaxTest, ConnectTimeout) { EXPECT_EQ(&dispatcher_, device_->dispatcher()); EXPECT_TRUE(device_->connect_timeout_callback_.IsCancelled()); EXPECT_FALSE(device_->IsConnectTimeoutStarted()); EXPECT_EQ(WiMax::kDefaultConnectTimeoutSeconds, device_->connect_timeout_seconds_); device_->connect_timeout_seconds_ = 0; device_->StartConnectTimeout(); EXPECT_FALSE(device_->connect_timeout_callback_.IsCancelled()); EXPECT_TRUE(device_->IsConnectTimeoutStarted()); device_->dispatcher_ = nullptr; device_->StartConnectTimeout(); // Expect no crash. scoped_refptr<MockWiMaxService> service( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); device_->pending_service_ = service; EXPECT_CALL(*service, SetState(Service::kStateFailure)); dispatcher_.DispatchPendingEvents(); EXPECT_TRUE(device_->connect_timeout_callback_.IsCancelled()); EXPECT_FALSE(device_->IsConnectTimeoutStarted()); EXPECT_FALSE(device_->pending_service_); } TEST_F(WiMaxTest, ConnectTo) { static const char kPath[] = "/network/path"; scoped_refptr<MockWiMaxService> service( new MockWiMaxService(&control_, nullptr, &metrics_, &manager_)); EXPECT_CALL(*service, SetState(Service::kStateAssociating)); device_->status_ = wimax_manager::kDeviceStatusScanning; EXPECT_CALL(*service, GetNetworkObjectPath()).WillOnce(Return(kPath)); EXPECT_CALL(*proxy_, Connect(kPath, _, _, _, _)) .WillOnce(SetErrorTypeInArgument<2>(Error::kSuccess)); device_->proxy_.reset(proxy_.release()); Error error; device_->ConnectTo(service, &error); EXPECT_TRUE(error.IsSuccess()); EXPECT_EQ(service.get(), device_->pending_service_.get()); EXPECT_EQ(wimax_manager::kDeviceStatusUninitialized, device_->status_); EXPECT_TRUE(device_->IsConnectTimeoutStarted()); device_->ConnectTo(service, &error); EXPECT_EQ(Error::kInProgress, error.type()); device_->pending_service_ = nullptr; } TEST_F(WiMaxTest, IsIdle) { EXPECT_TRUE(device_->IsIdle()); scoped_refptr<NiceMock<MockWiMaxService>> service( new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_)); device_->pending_service_ = service; EXPECT_FALSE(device_->IsIdle()); device_->pending_service_ = nullptr; device_->SelectService(service); EXPECT_FALSE(device_->IsIdle()); } } // namespace shill