// // Copyright (C) 2014 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 "apmanager/service.h" #include #include #include #include #include #include #if !defined(__ANDROID__) #include #else #include #endif // __ANDROID__ #include "apmanager/error.h" #include "apmanager/fake_config_adaptor.h" #include "apmanager/mock_config.h" #include "apmanager/mock_control.h" #include "apmanager/mock_dhcp_server.h" #include "apmanager/mock_dhcp_server_factory.h" #include "apmanager/mock_file_writer.h" #include "apmanager/mock_hostapd_monitor.h" #include "apmanager/mock_manager.h" #include "apmanager/mock_process_factory.h" #include "apmanager/mock_service_adaptor.h" using brillo::ProcessMock; using ::testing::_; using ::testing::Mock; using ::testing::Return; using ::testing::ReturnNew; using ::testing::SetArgPointee; namespace { const int kServiceIdentifier = 1; const char kHostapdConfig[] = "ssid=test\n"; #if !defined(__ANDROID__) const char kBinSleep[] = "/bin/sleep"; const char kHostapdConfigFilePath[] = "/var/run/apmanager/hostapd/hostapd-1.conf"; #else const char kBinSleep[] = "/system/bin/sleep"; const char kHostapdConfigFilePath[] = "/data/misc/apmanager/hostapd/hostapd-1.conf"; #endif // __ANDROID__ } // namespace namespace apmanager { class ServiceTest : public testing::Test { public: ServiceTest() : manager_(&control_interface_), hostapd_monitor_(new MockHostapdMonitor()) { ON_CALL(control_interface_, CreateServiceAdaptorRaw()) .WillByDefault(ReturnNew()); ON_CALL(control_interface_, CreateConfigAdaptorRaw()) .WillByDefault(ReturnNew()); // Defer creation of Service object to allow ControlInterface to // setup expectations for generating fake adaptors. service_ = new Service(&manager_, kServiceIdentifier); } virtual void SetUp() { service_->dhcp_server_factory_ = &dhcp_server_factory_; service_->file_writer_ = &file_writer_; service_->process_factory_ = &process_factory_; service_->hostapd_monitor_.reset(hostapd_monitor_); } bool StartService(Error* error) { return service_->StartInternal(error); } void StartDummyProcess() { service_->hostapd_process_.reset(new brillo::ProcessImpl); service_->hostapd_process_->AddArg(kBinSleep); service_->hostapd_process_->AddArg("12345"); CHECK(service_->hostapd_process_->Start()); LOG(INFO) << "DummyProcess: " << service_->hostapd_process_->pid(); } void SetConfig(Config* config) { service_->config_.reset(config); } void VerifyError(const Error& error, Error::Type expected_type, const std::string& expected_message_start) { EXPECT_EQ(expected_type, error.type()); EXPECT_TRUE(base::StartsWith(error.message(), expected_message_start, base::CompareCase::INSENSITIVE_ASCII)); } protected: MockControl control_interface_; MockManager manager_; MockDHCPServerFactory dhcp_server_factory_; MockFileWriter file_writer_; MockProcessFactory process_factory_; MockHostapdMonitor* hostapd_monitor_; scoped_refptr service_; }; TEST_F(ServiceTest, StartWhenServiceAlreadyRunning) { StartDummyProcess(); Error error; EXPECT_FALSE(StartService(&error)); VerifyError(error, Error::kInternalError, "Service already running"); } TEST_F(ServiceTest, StartWhenConfigFileFailed) { MockConfig* config = new MockConfig(&manager_); SetConfig(config); Error error; EXPECT_CALL(*config, GenerateConfigFile(_, _)).WillOnce(Return(false)); EXPECT_FALSE(StartService(&error)); } TEST_F(ServiceTest, StartSuccess) { MockConfig* config = new MockConfig(&manager_); SetConfig(config); // Setup mock DHCP server. MockDHCPServer* dhcp_server = new MockDHCPServer(); // Setup mock process. ProcessMock* process = new ProcessMock(); std::string config_str(kHostapdConfig); Error error; EXPECT_CALL(*config, GenerateConfigFile(_, _)).WillOnce( DoAll(SetArgPointee<1>(config_str), Return(true))); EXPECT_CALL(file_writer_, Write(kHostapdConfigFilePath, kHostapdConfig)) .WillOnce(Return(true)); EXPECT_CALL(*config, ClaimDevice()).WillOnce(Return(true)); EXPECT_CALL(process_factory_, CreateProcess()).WillOnce(Return(process)); EXPECT_CALL(*process, Start()).WillOnce(Return(true)); EXPECT_CALL(dhcp_server_factory_, CreateDHCPServer(_, _)) .WillOnce(Return(dhcp_server)); EXPECT_CALL(*dhcp_server, Start()).WillOnce(Return(true)); EXPECT_CALL(manager_, RequestDHCPPortAccess(_)); EXPECT_CALL(*hostapd_monitor_, Start()); EXPECT_TRUE(StartService(&error)); EXPECT_TRUE(error.IsSuccess()); } TEST_F(ServiceTest, StopWhenServiceNotRunning) { Error error; EXPECT_FALSE(service_->Stop(&error)); VerifyError( error, Error::kInternalError, "Service is not currently running"); } TEST_F(ServiceTest, StopSuccess) { StartDummyProcess(); MockConfig* config = new MockConfig(&manager_); SetConfig(config); Error error; EXPECT_CALL(*config, ReleaseDevice()).Times(1); EXPECT_TRUE(service_->Stop(&error)); Mock::VerifyAndClearExpectations(config); } } // namespace apmanager