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_service.h" 18 19 #include <string> 20 21 #include <base/strings/string_util.h> 22 #if defined(__ANDROID__) 23 #include <dbus/service_constants.h> 24 #else 25 #include <chromeos/dbus/service_constants.h> 26 #endif // __ANDROID__ 27 #include <gtest/gtest.h> 28 29 #include "shill/error.h" 30 #include "shill/mock_adaptors.h" 31 #include "shill/mock_eap_credentials.h" 32 #include "shill/mock_manager.h" 33 #include "shill/mock_metrics.h" 34 #include "shill/mock_store.h" 35 #include "shill/nice_mock_control.h" 36 #include "shill/service_property_change_test.h" 37 #include "shill/wimax/mock_wimax.h" 38 #include "shill/wimax/mock_wimax_network_proxy.h" 39 #include "shill/wimax/mock_wimax_provider.h" 40 41 using std::string; 42 using testing::_; 43 using testing::AnyNumber; 44 using testing::Mock; 45 using testing::NiceMock; 46 using testing::Return; 47 using wimax_manager::kEAPAnonymousIdentity; 48 using wimax_manager::kEAPUserIdentity; 49 using wimax_manager::kEAPUserPassword; 50 51 namespace shill { 52 53 namespace { 54 55 const char kTestLinkName[] = "wm0"; 56 const char kTestAddress[] = "0123456789AB"; 57 const int kTestInterfaceIndex = 5; 58 const char kTestPath[] = "/org/chromium/WiMaxManager/Device/wm7"; 59 const char kTestName[] = "Test WiMAX Network"; 60 const char kTestNetworkId[] = "1234abcd"; 61 62 } // namespace 63 64 class WiMaxServiceTest : public testing::Test { 65 public: 66 WiMaxServiceTest() 67 : proxy_(new MockWiMaxNetworkProxy()), 68 manager_(&control_, nullptr, nullptr), 69 metrics_(nullptr), 70 device_(new MockWiMax(&control_, nullptr, &metrics_, &manager_, 71 kTestLinkName, kTestAddress, kTestInterfaceIndex, 72 kTestPath)), 73 service_(new WiMaxService(&control_, nullptr, &metrics_, &manager_)), 74 eap_(new MockEapCredentials()) { 75 service_->set_friendly_name(kTestName); 76 service_->set_network_id(kTestNetworkId); 77 service_->InitStorageIdentifier(); 78 service_->eap_.reset(eap_); // Passes ownership. 79 } 80 81 virtual ~WiMaxServiceTest() {} 82 83 protected: 84 virtual void TearDown() { 85 service_->device_ = nullptr; 86 } 87 88 void ExpectUpdateService() { 89 EXPECT_CALL(manager_, HasService(_)).WillOnce(Return(true)); 90 EXPECT_CALL(manager_, UpdateService(_)); 91 } 92 93 void SetConnectable(bool connectable) { 94 service_->connectable_ = connectable; 95 } 96 97 void SetDevice(WiMaxRefPtr device) { 98 service_->SetDevice(device); 99 } 100 101 ServiceMockAdaptor* GetAdaptor() { 102 return static_cast<ServiceMockAdaptor*>(service_->adaptor()); 103 } 104 105 std::unique_ptr<MockWiMaxNetworkProxy> proxy_; 106 NiceMockControl control_; 107 MockManager manager_; 108 NiceMock<MockMetrics> metrics_; 109 scoped_refptr<MockWiMax> device_; 110 WiMaxServiceRefPtr service_; 111 MockEapCredentials* eap_; // Owned by |service_|. 112 }; 113 114 TEST_F(WiMaxServiceTest, GetConnectParameters) { 115 KeyValueStore parameters; 116 EXPECT_CALL(*eap_, PopulateWiMaxProperties(¶meters)); 117 service_->GetConnectParameters(¶meters); 118 } 119 120 TEST_F(WiMaxServiceTest, GetDeviceRpcId) { 121 Error error; 122 EXPECT_EQ(control_.NullRPCIdentifier(), service_->GetDeviceRpcId(&error)); 123 EXPECT_EQ(Error::kNotFound, error.type()); 124 service_->device_ = device_; 125 error.Reset(); 126 EXPECT_EQ(DeviceMockAdaptor::kRpcId, service_->GetDeviceRpcId(&error)); 127 EXPECT_TRUE(error.IsSuccess()); 128 } 129 130 TEST_F(WiMaxServiceTest, OnSignalStrengthChanged) { 131 const int kStrength = 55; 132 service_->OnSignalStrengthChanged(kStrength); 133 EXPECT_EQ(kStrength, service_->strength()); 134 } 135 136 TEST_F(WiMaxServiceTest, StartStop) { 137 static const char kName[] = "My WiMAX Network"; 138 const uint32_t kIdentifier = 0x1234abcd; 139 const int kStrength = 66; 140 EXPECT_FALSE(service_->connectable()); 141 EXPECT_FALSE(service_->IsStarted()); 142 EXPECT_FALSE(service_->IsVisible()); 143 EXPECT_EQ(0, service_->strength()); 144 EXPECT_FALSE(service_->proxy_.get()); 145 EXPECT_CALL(*proxy_, Name(_)).WillOnce(Return(kName)); 146 EXPECT_CALL(*proxy_, Identifier(_)).WillOnce(Return(kIdentifier)); 147 EXPECT_CALL(*proxy_, SignalStrength(_)).WillOnce(Return(kStrength)); 148 EXPECT_CALL(*proxy_, set_signal_strength_changed_callback(_)); 149 ServiceMockAdaptor* adaptor = GetAdaptor(); 150 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, _)) 151 .Times(AnyNumber()); 152 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true)); 153 ExpectUpdateService(); 154 service_->need_passphrase_ = false; 155 EXPECT_TRUE(service_->Start(proxy_.release())); 156 EXPECT_TRUE(service_->IsStarted()); 157 EXPECT_TRUE(service_->IsVisible()); 158 EXPECT_EQ(kStrength, service_->strength()); 159 EXPECT_EQ(kName, service_->network_name()); 160 EXPECT_EQ(kTestName, service_->friendly_name()); 161 EXPECT_EQ(kTestNetworkId, service_->network_id()); 162 EXPECT_TRUE(service_->connectable()); 163 EXPECT_TRUE(service_->proxy_.get()); 164 165 service_->device_ = device_; 166 EXPECT_CALL(*device_, OnServiceStopped(_)); 167 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false)); 168 ExpectUpdateService(); 169 service_->Stop(); 170 EXPECT_FALSE(service_->IsStarted()); 171 EXPECT_FALSE(service_->IsVisible()); 172 EXPECT_EQ(0, service_->strength()); 173 EXPECT_FALSE(service_->proxy_.get()); 174 } 175 176 TEST_F(WiMaxServiceTest, Connectable) { 177 EXPECT_TRUE(service_->Is8021x()); 178 EXPECT_TRUE(service_->need_passphrase_); 179 EXPECT_FALSE(service_->connectable()); 180 181 EXPECT_CALL(*eap_, IsConnectableUsingPassphrase()) 182 .WillOnce(Return(false)) 183 .WillRepeatedly(Return(true)); 184 185 // No WiMaxCredentials. 186 service_->OnEapCredentialsChanged(Service::kReasonPropertyUpdate); 187 EXPECT_TRUE(service_->need_passphrase_); 188 EXPECT_FALSE(service_->connectable()); 189 190 // Not started (no proxy). 191 service_->OnEapCredentialsChanged(Service::kReasonPropertyUpdate); 192 EXPECT_FALSE(service_->need_passphrase_); 193 EXPECT_FALSE(service_->connectable()); 194 195 // Connectable. 196 service_->proxy_.reset(proxy_.release()); 197 ExpectUpdateService(); 198 service_->OnEapCredentialsChanged(Service::kReasonPropertyUpdate); 199 EXPECT_FALSE(service_->need_passphrase_); 200 EXPECT_TRUE(service_->connectable()); 201 202 // Reset WimaxConnectable state. 203 Mock::VerifyAndClearExpectations(eap_); 204 EXPECT_CALL(*eap_, set_password("")); 205 EXPECT_CALL(*eap_, IsConnectableUsingPassphrase()) 206 .WillRepeatedly(Return(false)); 207 ExpectUpdateService(); 208 service_->ClearPassphrase(); 209 EXPECT_TRUE(service_->need_passphrase_); 210 EXPECT_FALSE(service_->connectable()); 211 } 212 213 TEST_F(WiMaxServiceTest, ChangeCredResetHasEverConnected) { 214 service_->has_ever_connected_ = true; 215 EXPECT_TRUE(service_->has_ever_connected()); 216 service_->OnEapCredentialsChanged(Service::kReasonPropertyUpdate); 217 EXPECT_FALSE(service_->has_ever_connected()); 218 } 219 220 TEST_F(WiMaxServiceTest, ConvertIdentifierToNetworkId) { 221 EXPECT_EQ("00000000", WiMaxService::ConvertIdentifierToNetworkId(0)); 222 EXPECT_EQ("abcd1234", WiMaxService::ConvertIdentifierToNetworkId(0xabcd1234)); 223 EXPECT_EQ("ffffffff", WiMaxService::ConvertIdentifierToNetworkId(0xffffffff)); 224 } 225 226 TEST_F(WiMaxServiceTest, StorageIdentifier) { 227 static const char kStorageId[] = "wimax_test_wimax_network_1234abcd"; 228 EXPECT_EQ(kStorageId, service_->GetStorageIdentifier()); 229 EXPECT_EQ(kStorageId, 230 WiMaxService::CreateStorageIdentifier(kTestNetworkId, kTestName)); 231 } 232 233 TEST_F(WiMaxServiceTest, Save) { 234 NiceMock<MockStore> storage; 235 string storage_id = service_->GetStorageIdentifier(); 236 EXPECT_CALL(storage, SetString(storage_id, _, _)) 237 .WillRepeatedly(Return(true)); 238 EXPECT_CALL(storage, DeleteKey(storage_id, _)).WillRepeatedly(Return(true)); 239 EXPECT_CALL(storage, SetString(storage_id, 240 WiMaxService::kStorageNetworkId, 241 kTestNetworkId)); 242 EXPECT_TRUE(service_->Save(&storage)); 243 } 244 245 TEST_F(WiMaxServiceTest, Connect) { 246 // Connect but not connectable. 247 Error error; 248 EXPECT_FALSE(service_->connectable()); 249 service_->Connect(&error, "in test"); 250 EXPECT_EQ(Error::kOperationFailed, error.type()); 251 SetConnectable(true); 252 253 // No carrier device available. 254 MockWiMaxProvider provider; 255 scoped_refptr<MockWiMax> null_device; 256 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); 257 EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(null_device)); 258 error.Reset(); 259 service_->Connect(&error, "in test"); 260 EXPECT_EQ(Error::kNoCarrier, error.type()); 261 262 // Successful connect. 263 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider)); 264 EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_)); 265 EXPECT_CALL(*device_, ConnectTo(_, _)); 266 error.Reset(); 267 service_->Connect(&error, "in test"); 268 EXPECT_TRUE(error.IsSuccess()); 269 270 // Connect while already connected. 271 // TODO(benchan): Check for error if we populate error again after changing 272 // the way that Chrome handles Error::kAlreadyConnected situation. 273 service_->Connect(&error, "in test"); 274 275 // Successful disconnect. 276 EXPECT_CALL(*eap_, set_password(_)).Times(0); 277 EXPECT_CALL(*device_, DisconnectFrom(_, _)); 278 error.Reset(); 279 service_->Disconnect(&error, "in test"); 280 EXPECT_TRUE(error.IsSuccess()); 281 EXPECT_TRUE(service_->connectable()); 282 283 // Disconnect while not connected. 284 service_->Disconnect(&error, "in test"); 285 EXPECT_EQ(Error::kNotConnected, error.type()); 286 } 287 288 TEST_F(WiMaxServiceTest, Unload) { 289 MockWiMaxProvider provider; 290 EXPECT_CALL(manager_, wimax_provider()) 291 .Times(2) 292 .WillRepeatedly(Return(&provider)); 293 EXPECT_CALL(*eap_, Reset()); 294 EXPECT_CALL(*eap_, set_password("")); 295 EXPECT_CALL(*eap_, IsConnectableUsingPassphrase()) 296 .WillRepeatedly(Return(false)); 297 EXPECT_CALL(provider, OnServiceUnloaded(_)).WillOnce(Return(false)); 298 EXPECT_FALSE(service_->Unload()); 299 Mock::VerifyAndClearExpectations(eap_); 300 301 EXPECT_CALL(*eap_, Reset()); 302 EXPECT_CALL(*eap_, set_password("")); 303 EXPECT_CALL(*eap_, IsConnectableUsingPassphrase()) 304 .WillRepeatedly(Return(false)); 305 EXPECT_CALL(provider, OnServiceUnloaded(_)).WillOnce(Return(true)); 306 EXPECT_TRUE(service_->Unload()); 307 } 308 309 TEST_F(WiMaxServiceTest, SetState) { 310 service_->device_ = device_; 311 EXPECT_EQ(Service::kStateIdle, service_->state()); 312 313 EXPECT_CALL(manager_, UpdateService(_)); 314 service_->SetState(Service::kStateAssociating); 315 EXPECT_EQ(Service::kStateAssociating, service_->state()); 316 EXPECT_TRUE(service_->device_); 317 318 EXPECT_CALL(manager_, UpdateService(_)); 319 service_->SetState(Service::kStateFailure); 320 EXPECT_EQ(Service::kStateFailure, service_->state()); 321 EXPECT_FALSE(service_->device_); 322 } 323 324 TEST_F(WiMaxServiceTest, IsAutoConnectable) { 325 EXPECT_FALSE(service_->connectable()); 326 const char* reason = ""; 327 328 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 329 330 MockWiMaxProvider provider; 331 EXPECT_CALL(manager_, wimax_provider()) 332 .Times(2) 333 .WillRepeatedly(Return(&provider)); 334 335 SetConnectable(true); 336 EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_)); 337 EXPECT_CALL(*device_, IsIdle()).WillOnce(Return(false)); 338 reason = ""; 339 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 340 EXPECT_EQ(WiMaxService::kAutoConnBusy, reason); 341 342 EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_)); 343 EXPECT_CALL(*device_, IsIdle()).WillOnce(Return(true)); 344 reason = ""; 345 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 346 EXPECT_STREQ("", reason); 347 } 348 349 TEST_F(WiMaxServiceTest, PropertyChanges) { 350 ServiceMockAdaptor* adaptor = GetAdaptor(); 351 TestCommonPropertyChanges(service_, adaptor); 352 TestAutoConnectPropertyChange(service_, adaptor); 353 354 EXPECT_CALL(*adaptor, 355 EmitRpcIdentifierChanged(kDeviceProperty, _)); 356 SetDevice(device_); 357 Mock::VerifyAndClearExpectations(adaptor); 358 359 EXPECT_CALL(*adaptor, 360 EmitRpcIdentifierChanged(kDeviceProperty, _)); 361 SetDevice(nullptr); 362 Mock::VerifyAndClearExpectations(adaptor); 363 } 364 365 // Custom property setters should return false, and make no changes, if 366 // the new value is the same as the old value. 367 TEST_F(WiMaxServiceTest, CustomSetterNoopChange) { 368 TestCustomSetterNoopChange(service_, &manager_); 369 } 370 371 } // namespace shill 372