1326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu//
2326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// Copyright (C) 2014 The Android Open Source Project
3326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu//
4326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// you may not use this file except in compliance with the License.
6326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// You may obtain a copy of the License at
7326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu//
8326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu//
10326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// Unless required by applicable law or agreed to in writing, software
11326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// See the License for the specific language governing permissions and
14326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// limitations under the License.
15326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu//
16376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
17376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include "apmanager/service.h"
18376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
19376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include <string>
20376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
21376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include <base/strings/string_util.h>
22376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include <base/strings/stringprintf.h>
238d0c31bb481b712a3b2e6612390679e29053c620Alex Vakulenko#include <brillo/process_mock.h>
24376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include <gmock/gmock.h>
25376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include <gtest/gtest.h>
26376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
277a420d3e06aa7fb5eba305dc587624eb58bde7b7Peter Qiu#if !defined(__ANDROID__)
287a420d3e06aa7fb5eba305dc587624eb58bde7b7Peter Qiu#include <chromeos/dbus/service_constants.h>
297a420d3e06aa7fb5eba305dc587624eb58bde7b7Peter Qiu#else
302ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu#include <dbus/apmanager/dbus-constants.h>
317a420d3e06aa7fb5eba305dc587624eb58bde7b7Peter Qiu#endif  // __ANDROID__
327a420d3e06aa7fb5eba305dc587624eb58bde7b7Peter Qiu
33d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu#include "apmanager/error.h"
34d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu#include "apmanager/fake_config_adaptor.h"
35376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu#include "apmanager/mock_config.h"
36d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu#include "apmanager/mock_control.h"
37bf8e36cde93c8714b5e1482d205d2e3e424d1290Peter Qiu#include "apmanager/mock_dhcp_server.h"
38bf8e36cde93c8714b5e1482d205d2e3e424d1290Peter Qiu#include "apmanager/mock_dhcp_server_factory.h"
39775173013ee886be244417eba0a3b302c4da11e0Peter Qiu#include "apmanager/mock_file_writer.h"
40fda548ca8f0b29834a37b83e836f4ccc3268fa1dPeter Qiu#include "apmanager/mock_hostapd_monitor.h"
41fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "apmanager/mock_manager.h"
421dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu#include "apmanager/mock_process_factory.h"
432ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu#include "apmanager/mock_service_adaptor.h"
44376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
458d0c31bb481b712a3b2e6612390679e29053c620Alex Vakulenkousing brillo::ProcessMock;
46376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiuusing ::testing::_;
47376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiuusing ::testing::Mock;
48376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiuusing ::testing::Return;
49d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiuusing ::testing::ReturnNew;
50376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiuusing ::testing::SetArgPointee;
51376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
52376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiunamespace {
53376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  const int kServiceIdentifier = 1;
54376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  const char kHostapdConfig[] = "ssid=test\n";
556789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu#if !defined(__ANDROID__)
568b9b2540ada6098ac6eb4edc3265016be7170fc3David Pursell  const char kBinSleep[] = "/bin/sleep";
57775173013ee886be244417eba0a3b302c4da11e0Peter Qiu  const char kHostapdConfigFilePath[] =
58775173013ee886be244417eba0a3b302c4da11e0Peter Qiu      "/var/run/apmanager/hostapd/hostapd-1.conf";
59015a499835529e3e632e0bb86d76ca03c6121770Peter Qiu#else
606789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  const char kBinSleep[] = "/system/bin/sleep";
616789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  const char kHostapdConfigFilePath[] =
62015a499835529e3e632e0bb86d76ca03c6121770Peter Qiu      "/data/misc/apmanager/hostapd/hostapd-1.conf";
63015a499835529e3e632e0bb86d76ca03c6121770Peter Qiu#endif  // __ANDROID__
64376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}  // namespace
65376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
66376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiunamespace apmanager {
67376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
68376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiuclass ServiceTest : public testing::Test {
69376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu public:
701dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu  ServiceTest()
71d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu      : manager_(&control_interface_),
72d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu        hostapd_monitor_(new MockHostapdMonitor()) {
732ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu    ON_CALL(control_interface_, CreateServiceAdaptorRaw())
742ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu        .WillByDefault(ReturnNew<MockServiceAdaptor>());
75d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    ON_CALL(control_interface_, CreateConfigAdaptorRaw())
76d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu        .WillByDefault(ReturnNew<FakeConfigAdaptor>());
77d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    // Defer creation of Service object to allow ControlInterface to
78d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    // setup expectations for generating fake adaptors.
797758d8db3ddb2582fb57bda4a26c9f6f6bd20316Peter Qiu    service_ = new Service(&manager_, kServiceIdentifier);
80d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  }
811dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu  virtual void SetUp() {
82d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->dhcp_server_factory_ = &dhcp_server_factory_;
83d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->file_writer_ = &file_writer_;
84d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->process_factory_ = &process_factory_;
85d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->hostapd_monitor_.reset(hostapd_monitor_);
861dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu  }
87376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
882ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  bool StartService(Error* error) {
89d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    return service_->StartInternal(error);
90682a9324b86ce27fd1c461704fa2e80e40ed043dPeter Qiu  }
91682a9324b86ce27fd1c461704fa2e80e40ed043dPeter Qiu
92376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  void StartDummyProcess() {
93d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->hostapd_process_.reset(new brillo::ProcessImpl);
94d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->hostapd_process_->AddArg(kBinSleep);
95d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->hostapd_process_->AddArg("12345");
96d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    CHECK(service_->hostapd_process_->Start());
97d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    LOG(INFO) << "DummyProcess: " << service_->hostapd_process_->pid();
98376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  }
99376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
100376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  void SetConfig(Config* config) {
101d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu    service_->config_.reset(config);
102376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  }
103376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
1042ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  void VerifyError(const Error& error,
1052ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu                   Error::Type expected_type,
1062ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu                   const std::string& expected_message_start) {
1072ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu    EXPECT_EQ(expected_type, error.type());
108fca478e3db86521918313d3d92290b1928de3702Alex Vakulenko    EXPECT_TRUE(base::StartsWith(error.message(), expected_message_start,
109fca478e3db86521918313d3d92290b1928de3702Alex Vakulenko                                 base::CompareCase::INSENSITIVE_ASCII));
1102ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  }
1112ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu
112376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu protected:
113d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  MockControl control_interface_;
114fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu  MockManager manager_;
1156789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  MockDHCPServerFactory dhcp_server_factory_;
1166789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  MockFileWriter file_writer_;
1176789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  MockProcessFactory process_factory_;
118fda548ca8f0b29834a37b83e836f4ccc3268fa1dPeter Qiu  MockHostapdMonitor* hostapd_monitor_;
1197758d8db3ddb2582fb57bda4a26c9f6f6bd20316Peter Qiu  scoped_refptr<Service> service_;
120376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu};
121376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
122376e40426ad6055adfb384240b6e9a5d732f06e5Peter QiuTEST_F(ServiceTest, StartWhenServiceAlreadyRunning) {
123376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  StartDummyProcess();
124376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
1252ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  Error error;
126682a9324b86ce27fd1c461704fa2e80e40ed043dPeter Qiu  EXPECT_FALSE(StartService(&error));
1272ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  VerifyError(error, Error::kInternalError, "Service already running");
128376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}
129376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
130376e40426ad6055adfb384240b6e9a5d732f06e5Peter QiuTEST_F(ServiceTest, StartWhenConfigFileFailed) {
131d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  MockConfig* config = new MockConfig(&manager_);
132376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  SetConfig(config);
133376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
1342ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  Error error;
135376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  EXPECT_CALL(*config, GenerateConfigFile(_, _)).WillOnce(Return(false));
136682a9324b86ce27fd1c461704fa2e80e40ed043dPeter Qiu  EXPECT_FALSE(StartService(&error));
137376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}
138376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
139376e40426ad6055adfb384240b6e9a5d732f06e5Peter QiuTEST_F(ServiceTest, StartSuccess) {
140d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  MockConfig* config = new MockConfig(&manager_);
141376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  SetConfig(config);
142376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
143bf8e36cde93c8714b5e1482d205d2e3e424d1290Peter Qiu  // Setup mock DHCP server.
144bf8e36cde93c8714b5e1482d205d2e3e424d1290Peter Qiu  MockDHCPServer* dhcp_server = new MockDHCPServer();
1451dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu  // Setup mock process.
1461dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu  ProcessMock* process = new ProcessMock();
147775173013ee886be244417eba0a3b302c4da11e0Peter Qiu
148376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  std::string config_str(kHostapdConfig);
1492ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  Error error;
150376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  EXPECT_CALL(*config, GenerateConfigFile(_, _)).WillOnce(
151376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu      DoAll(SetArgPointee<1>(config_str), Return(true)));
1526789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  EXPECT_CALL(file_writer_, Write(kHostapdConfigFilePath, kHostapdConfig))
153775173013ee886be244417eba0a3b302c4da11e0Peter Qiu      .WillOnce(Return(true));
154fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu  EXPECT_CALL(*config, ClaimDevice()).WillOnce(Return(true));
1556789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  EXPECT_CALL(process_factory_, CreateProcess()).WillOnce(Return(process));
1561dbf9fdfef00d80e151d13e5a4ff016f9d916ad7Peter Qiu  EXPECT_CALL(*process, Start()).WillOnce(Return(true));
1576789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  EXPECT_CALL(dhcp_server_factory_, CreateDHCPServer(_, _))
158bf8e36cde93c8714b5e1482d205d2e3e424d1290Peter Qiu      .WillOnce(Return(dhcp_server));
159bf8e36cde93c8714b5e1482d205d2e3e424d1290Peter Qiu  EXPECT_CALL(*dhcp_server, Start()).WillOnce(Return(true));
160943cf3a0afdad2cc6bea02b181f09e6ff23df628Peter Qiu  EXPECT_CALL(manager_, RequestDHCPPortAccess(_));
161fda548ca8f0b29834a37b83e836f4ccc3268fa1dPeter Qiu  EXPECT_CALL(*hostapd_monitor_, Start());
162682a9324b86ce27fd1c461704fa2e80e40ed043dPeter Qiu  EXPECT_TRUE(StartService(&error));
1632ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  EXPECT_TRUE(error.IsSuccess());
164376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}
165376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
166376e40426ad6055adfb384240b6e9a5d732f06e5Peter QiuTEST_F(ServiceTest, StopWhenServiceNotRunning) {
1672ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  Error error;
168d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  EXPECT_FALSE(service_->Stop(&error));
1692ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  VerifyError(
1702ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu      error, Error::kInternalError, "Service is not currently running");
171376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}
172376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
173376e40426ad6055adfb384240b6e9a5d732f06e5Peter QiuTEST_F(ServiceTest, StopSuccess) {
174376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu  StartDummyProcess();
175376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
176d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  MockConfig* config = new MockConfig(&manager_);
177fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu  SetConfig(config);
1782ea547f45d2a143e1b25b275c46d1f317186b07aPeter Qiu  Error error;
179fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu  EXPECT_CALL(*config, ReleaseDevice()).Times(1);
180d9c79aa078a5df1882848d26a52d48a02b4057a5Peter Qiu  EXPECT_TRUE(service_->Stop(&error));
1816789bcbfbc2cbc7eec7713513b4b2038f7f8c52cPeter Qiu  Mock::VerifyAndClearExpectations(config);
182376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}
183376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu
184376e40426ad6055adfb384240b6e9a5d732f06e5Peter Qiu}  // namespace apmanager
185