1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
16ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
17ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include "shill/external_task.h"
18ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
19ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <map>
20cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan#include <memory>
21ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <set>
22ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <string>
23ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <vector>
24ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
25ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <base/bind.h>
26a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/files/file_path.h>
27ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <base/memory/weak_ptr.h>
28a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_util.h>
29ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <gmock/gmock.h>
30ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include <gtest/gtest.h>
31ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
32ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include "shill/mock_adaptors.h"
33a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu#include "shill/mock_process_manager.h"
34a41ab517725d036b63420f8445550246f8f50b99Alex Vakulenko#include "shill/nice_mock_control.h"
35a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu#include "shill/test_event_dispatcher.h"
36ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
37ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing std::map;
38ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing std::set;
39ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing std::string;
40ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing std::vector;
41ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::_;
42ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::Matcher;
43ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::MatchesRegex;
44e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawalusing testing::Mock;
45ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::NiceMock;
46ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::Return;
47ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::SetArgumentPointee;
48ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalusing testing::StrEq;
49ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
50ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalnamespace shill {
51ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
52ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalclass ExternalTaskTest : public testing::Test,
53ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal                         public RPCTaskDelegate {
54ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal public:
55ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  ExternalTaskTest()
56ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      : weak_ptr_factory_(this),
57ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal        death_callback_(
58ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal          base::Bind(&ExternalTaskTest::TaskDiedCallback,
59ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal                     weak_ptr_factory_.GetWeakPtr())),
60ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal        external_task_(
61a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu            new ExternalTask(&control_, &process_manager_,
62a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu                             weak_ptr_factory_.GetWeakPtr(),
63ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal                             death_callback_)),
64a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu        test_rpc_task_destroyed_(false) {}
65ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
66ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  virtual ~ExternalTaskTest() {}
67ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
68ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  virtual void TearDown() {
69ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    if (!external_task_) {
70ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      return;
71ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    }
72ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
73ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    if (external_task_->pid_) {
74a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu      EXPECT_CALL(process_manager_, StopProcess(external_task_->pid_));
75ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    }
76ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  }
77ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
78ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  void set_test_rpc_task_destroyed(bool destroyed) {
79ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    test_rpc_task_destroyed_ = destroyed;
80ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  }
81ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
82e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  // Defined out-of-line, due to dependency on TestRPCTask.
83e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  void FakeUpRunningProcess(unsigned int tag, int pid);
84e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal
85e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  void ExpectStop(unsigned int tag, int pid) {
86a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu    EXPECT_CALL(process_manager_, StopProcess(pid));
87e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  }
88e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal
89e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  void VerifyStop() {
90e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal    if (external_task_) {
91e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal      EXPECT_EQ(0, external_task_->pid_);
92e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal      EXPECT_FALSE(external_task_->rpc_task_);
93e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal    }
94e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal    EXPECT_TRUE(test_rpc_task_destroyed_);
95e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal    // Make sure EXPECTations were met before the fixture's dtor.
96a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu    Mock::VerifyAndClearExpectations(&process_manager_);
97e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  }
98e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal
99ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal protected:
100ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  // Implements RPCTaskDelegate interface.
1013b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MOCK_METHOD2(GetLogin, void(string* user, string* password));
1023b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MOCK_METHOD2(Notify, void(const string& reason,
1033b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                            const map<string, string>& dict));
104ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
105a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  MOCK_METHOD2(TaskDiedCallback, void(pid_t pid, int exit_status));
106ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
107ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  NiceMockControl control_;
108a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  EventDispatcherForTest dispatcher_;
109a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  MockProcessManager process_manager_;
110ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  base::WeakPtrFactory<ExternalTaskTest> weak_ptr_factory_;
111ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  base::Callback<void(pid_t, int)> death_callback_;
112cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  std::unique_ptr<ExternalTask> external_task_;
113ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  bool test_rpc_task_destroyed_;
114ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal};
115ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
116ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalnamespace {
117ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
118ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalclass TestRPCTask : public RPCTask {
119ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal public:
1203b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  TestRPCTask(ControlInterface* control, ExternalTaskTest* test);
121ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  virtual ~TestRPCTask();
122ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
123ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal private:
1243b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  ExternalTaskTest* test_;
125ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal};
126ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
1273b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul StewartTestRPCTask::TestRPCTask(ControlInterface* control, ExternalTaskTest* test)
128ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    : RPCTask(control, test),
129ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      test_(test) {
130ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  test_->set_test_rpc_task_destroyed(false);
131ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
132ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
133ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTestRPCTask::~TestRPCTask() {
134ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  test_->set_test_rpc_task_destroyed(true);
135cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  test_ = nullptr;
136ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
137ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
138ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}  // namespace
139ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
140e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawalvoid ExternalTaskTest::FakeUpRunningProcess(unsigned int tag, int pid) {
141e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  external_task_->pid_ = pid;
142e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  external_task_->rpc_task_.reset(new TestRPCTask(&control_, this));
143e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal}
144e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal
145ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, Destructor) {
146ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const unsigned int kTag = 123;
147ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const int kPID = 123456;
148e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  FakeUpRunningProcess(kTag, kPID);
149e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  ExpectStop(kTag, kPID);
150ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  external_task_.reset();
151e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  VerifyStop();
152e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal}
153e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal
154e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawalTEST_F(ExternalTaskTest, DestroyLater) {
155e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  const unsigned int kTag = 123;
156e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  const int kPID = 123456;
157e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  FakeUpRunningProcess(kTag, kPID);
158e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  ExpectStop(kTag, kPID);
159e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  external_task_.release()->DestroyLater(&dispatcher_);
160e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  dispatcher_.DispatchPendingEvents();
161e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  VerifyStop();
162ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
163ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
164ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalnamespace {
165ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
166ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal// Returns true iff. there is at least one anchored match in |arg|,
167ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal// for each item in |expected_values|. Order of items does not matter.
168ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal//
169ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal// |arg| is a NULL-terminated array of C-strings.
170ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal// |expected_values| is a container of regular expressions (as strings).
171ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalMATCHER_P(HasElementsMatching, expected_values, "") {
1723b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  for (const auto& expected_value : expected_values) {
173ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    auto regex_matcher(MatchesRegex(expected_value).impl());
1743b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    char** arg_local = arg;
175ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    while (*arg_local) {
176ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      if (regex_matcher.MatchAndExplain(*arg_local, result_listener)) {
177ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal        break;
178ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      }
179ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      ++arg_local;
180ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    }
181cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan    if (*arg_local == nullptr) {
182ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      *result_listener << "missing value " << expected_value << "\n";
183ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      arg_local = arg;
184ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      while (*arg_local) {
185ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal        *result_listener << "received: " << *arg_local << "\n";
186ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal        ++arg_local;
187ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      }
188ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal      return false;
189ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    }
190ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  }
191ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  return true;
192ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
193ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
194ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}  // namespace
195ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
196ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, Start) {
197ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const string kCommand = "/run/me";
198ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const vector<string> kCommandOptions{"arg1", "arg2"};
199ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const map<string, string> kCommandEnv{{"env1", "val1"}, {"env2", "val2"}};
200a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  map<string, string> expected_env;
201a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  expected_env.emplace(kRPCTaskServiceVariable, RPCTaskMockAdaptor::kRpcConnId);
202a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  expected_env.emplace(kRPCTaskPathVariable, RPCTaskMockAdaptor::kRpcId);
203a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  expected_env.insert(kCommandEnv.begin(), kCommandEnv.end());
204ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const int kPID = 234678;
205a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  EXPECT_CALL(process_manager_,
206a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu              StartProcess(_, base::FilePath(kCommand), kCommandOptions,
207a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu                           expected_env, false, _))
208a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu      .WillOnce(Return(-1))
209a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu      .WillOnce(Return(kPID));
210ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  Error error;
211c4f9aa0e795b6f79c628a763831d4dc6c01fb72bmukesh agrawal  EXPECT_FALSE(external_task_->Start(
212c4f9aa0e795b6f79c628a763831d4dc6c01fb72bmukesh agrawal      base::FilePath(kCommand), kCommandOptions, kCommandEnv, false, &error));
213ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_EQ(Error::kInternalError, error.type());
214ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_FALSE(external_task_->rpc_task_);
215ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
216ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  error.Reset();
217c4f9aa0e795b6f79c628a763831d4dc6c01fb72bmukesh agrawal  EXPECT_TRUE(external_task_->Start(
218c4f9aa0e795b6f79c628a763831d4dc6c01fb72bmukesh agrawal      base::FilePath(kCommand), kCommandOptions, kCommandEnv, false, &error));
219ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_TRUE(error.IsSuccess());
220ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_EQ(kPID, external_task_->pid_);
221cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  EXPECT_NE(nullptr, external_task_->rpc_task_);
222ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
223ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
224ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, Stop) {
225ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const unsigned int kTag = 123;
226ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const int kPID = 123456;
227e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  FakeUpRunningProcess(kTag, kPID);
228e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  ExpectStop(kTag, kPID);
229ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  external_task_->Stop();
230cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  ASSERT_NE(nullptr, external_task_);
231e3d4b3cde7c8f4c3f27a88014b64de814dc9acb7mukesh agrawal  VerifyStop();
232ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
233ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
234ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, StopNotStarted) {
235a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  EXPECT_CALL(process_manager_, StopProcess(_)).Times(0);
236ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  external_task_->Stop();
237ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_FALSE(test_rpc_task_destroyed_);
238ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
239ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
240ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, GetLogin) {
241ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  string username;
242ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  string password;
243ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_CALL(*this, GetLogin(&username, &password));
244ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_CALL(*this, Notify(_, _)).Times(0);
245ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  external_task_->GetLogin(&username, &password);
246ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
247ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
248ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, Notify) {
249ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const string kReason("you may already have won!");
2503b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const map<string, string>& kArgs{
251ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    {"arg1", "val1"},
252ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal    {"arg2", "val2"}};
253ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_CALL(*this, GetLogin(_, _)).Times(0);
254ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_CALL(*this, Notify(kReason, kArgs));
255ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  external_task_->Notify(kReason, kArgs);
256ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
257ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
258ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalTEST_F(ExternalTaskTest, OnTaskDied) {
259ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const int kPID = 99999;
260ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  const int kExitStatus = 1;
261ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  external_task_->pid_ = kPID;
262a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  EXPECT_CALL(process_manager_, StopProcess(_)).Times(0);
263ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_CALL(*this, TaskDiedCallback(kPID, kExitStatus));
264a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu  external_task_->OnTaskDied(kExitStatus);
265ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal  EXPECT_EQ(0, external_task_->pid_);
266ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}
267ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal
268ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal}  // namespace shill
269