Adjust addends rather than targets for RELA configurations.
[chromium-blink-merge.git] / chromeos / process_proxy / process_proxy_unittest.cc
blob35d9cf2e3779806a4b118e91e2b9da2239508de7
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <gtest/gtest.h>
7 #include <string>
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/process/kill.h"
13 #include "base/threading/thread.h"
14 #include "chromeos/process_proxy/process_proxy_registry.h"
16 namespace chromeos {
18 namespace {
20 // The test line must have all distinct characters.
21 const char kTestLineToSend[] = "abcdefgh\n";
22 const char kTestLineExpected[] = "abcdefgh\r\n";
24 const char kCatCommand[] = "cat";
25 const char kStdoutType[] = "stdout";
26 const int kTestLineNum = 100;
28 class TestRunner {
29 public:
30 virtual ~TestRunner() {}
31 virtual void SetupExpectations(pid_t pid) = 0;
32 virtual void OnSomeRead(pid_t pid, const std::string& type,
33 const std::string& output) = 0;
34 virtual void StartRegistryTest(ProcessProxyRegistry* registry) = 0;
36 protected:
37 pid_t pid_;
40 class RegistryTestRunner : public TestRunner {
41 public:
42 virtual ~RegistryTestRunner() {}
44 virtual void SetupExpectations(pid_t pid) OVERRIDE {
45 pid_ = pid;
46 left_to_check_index_[0] = 0;
47 left_to_check_index_[1] = 0;
48 // We consider that a line processing has started if a value in
49 // left_to_check__[index] is set to 0, thus -2.
50 lines_left_ = 2 * kTestLineNum - 2;
51 expected_line_ = kTestLineExpected;
54 // Method to test validity of received input. We will receive two streams of
55 // the same data. (input will be echoed twice by the testing process). Each
56 // stream will contain the same string repeated |kTestLineNum| times. So we
57 // have to match 2 * |kTestLineNum| lines. The problem is the received lines
58 // from different streams may be interleaved (e.g. we may receive
59 // abc|abcdef|defgh|gh). To deal with that, we allow to test received text
60 // against two lines. The lines MUST NOT have two same characters for this
61 // algorithm to work.
62 virtual void OnSomeRead(pid_t pid, const std::string& type,
63 const std::string& output) OVERRIDE {
64 EXPECT_EQ(type, kStdoutType);
65 EXPECT_EQ(pid_, pid);
67 bool valid = true;
68 for (size_t i = 0; i < output.length(); i++) {
69 // The character output[i] should be next in at least one of the lines we
70 // are testing.
71 valid = (ProcessReceivedCharacter(output[i], 0) ||
72 ProcessReceivedCharacter(output[i], 1));
73 EXPECT_TRUE(valid) << "Received: " << output;
76 if (!valid || TestSucceeded()) {
77 base::MessageLoop::current()->PostTask(FROM_HERE,
78 base::MessageLoop::QuitClosure());
82 virtual void StartRegistryTest(ProcessProxyRegistry* registry) OVERRIDE {
83 for (int i = 0; i < kTestLineNum; i++) {
84 EXPECT_TRUE(registry->SendInput(pid_, kTestLineToSend));
88 private:
89 bool ProcessReceivedCharacter(char received, size_t stream) {
90 if (stream >= arraysize(left_to_check_index_))
91 return false;
92 bool success = left_to_check_index_[stream] < expected_line_.length() &&
93 expected_line_[left_to_check_index_[stream]] == received;
94 if (success)
95 left_to_check_index_[stream]++;
96 if (left_to_check_index_[stream] == expected_line_.length() &&
97 lines_left_ > 0) {
98 // Take another line to test for this stream, if there are any lines left.
99 // If not, this stream is done.
100 left_to_check_index_[stream] = 0;
101 lines_left_--;
103 return success;
106 bool TestSucceeded() {
107 return left_to_check_index_[0] == expected_line_.length() &&
108 left_to_check_index_[1] == expected_line_.length() &&
109 lines_left_ == 0;
112 size_t left_to_check_index_[2];
113 size_t lines_left_;
114 std::string expected_line_;
117 class RegistryNotifiedOnProcessExitTestRunner : public TestRunner {
118 public:
119 virtual ~RegistryNotifiedOnProcessExitTestRunner() {}
121 virtual void SetupExpectations(pid_t pid) OVERRIDE {
122 output_received_ = false;
123 pid_ = pid;
126 virtual void OnSomeRead(pid_t pid, const std::string& type,
127 const std::string& output) OVERRIDE {
128 EXPECT_EQ(pid_, pid);
129 if (!output_received_) {
130 output_received_ = true;
131 EXPECT_EQ(type, "stdout");
132 EXPECT_EQ(output, "p");
133 base::KillProcess(pid_, 0 , true);
134 return;
136 EXPECT_EQ("exit", type);
137 base::MessageLoop::current()->PostTask(FROM_HERE,
138 base::MessageLoop::QuitClosure());
141 virtual void StartRegistryTest(ProcessProxyRegistry* registry) OVERRIDE {
142 EXPECT_TRUE(registry->SendInput(pid_, "p"));
145 private:
146 bool output_received_;
149 class SigIntTestRunner : public TestRunner {
150 public:
151 virtual ~SigIntTestRunner() {}
153 virtual void SetupExpectations(pid_t pid) OVERRIDE {
154 pid_ = pid;
157 virtual void OnSomeRead(pid_t pid, const std::string& type,
158 const std::string& output) OVERRIDE {
159 EXPECT_EQ(pid_, pid);
160 // We may receive ^C on stdout, but we don't care about that, as long as we
161 // eventually received exit event.
162 if (type == "exit") {
163 base::MessageLoop::current()->PostTask(FROM_HERE,
164 base::MessageLoop::QuitClosure());
168 virtual void StartRegistryTest(ProcessProxyRegistry* registry) OVERRIDE {
169 // Send SingInt and verify the process exited.
170 EXPECT_TRUE(registry->SendInput(pid_, "\003"));
174 } // namespace
176 class ProcessProxyTest : public testing::Test {
177 public:
178 ProcessProxyTest() {}
179 virtual ~ProcessProxyTest() {}
181 protected:
182 void InitRegistryTest() {
183 registry_ = ProcessProxyRegistry::Get();
185 EXPECT_TRUE(registry_->OpenProcess(
186 kCatCommand, &pid_,
187 base::Bind(&TestRunner::OnSomeRead,
188 base::Unretained(test_runner_.get()))));
190 test_runner_->SetupExpectations(pid_);
191 test_runner_->StartRegistryTest(registry_);
194 void EndRegistryTest() {
195 registry_->CloseProcess(pid_);
197 base::TerminationStatus status = base::GetTerminationStatus(pid_, NULL);
198 EXPECT_NE(base::TERMINATION_STATUS_STILL_RUNNING, status);
199 if (status == base::TERMINATION_STATUS_STILL_RUNNING)
200 base::KillProcess(pid_, 0, true);
202 base::MessageLoop::current()->PostTask(FROM_HERE,
203 base::MessageLoop::QuitClosure());
206 void RunTest() {
207 base::MessageLoop::current()->PostTask(
208 FROM_HERE,
209 base::Bind(&ProcessProxyTest::InitRegistryTest,
210 base::Unretained(this)));
212 // Wait until all data from output watcher is received (QuitTask will be
213 // fired on watcher thread).
214 base::MessageLoop::current()->Run();
216 base::MessageLoop::current()->PostTask(
217 FROM_HERE,
218 base::Bind(&ProcessProxyTest::EndRegistryTest,
219 base::Unretained(this)));
221 // Wait until we clean up the process proxy.
222 base::MessageLoop::current()->Run();
225 scoped_ptr<TestRunner> test_runner_;
227 private:
228 ProcessProxyRegistry* registry_;
229 pid_t pid_;
231 base::MessageLoop message_loop_;
234 // Test will open new process that will run cat command, and verify data we
235 // write to process gets echoed back.
236 TEST_F(ProcessProxyTest, RegistryTest) {
237 test_runner_.reset(new RegistryTestRunner());
238 RunTest();
241 // Open new process, then kill it. Verifiy that we detect when the process dies.
242 TEST_F(ProcessProxyTest, RegistryNotifiedOnProcessExit) {
243 test_runner_.reset(new RegistryNotifiedOnProcessExitTestRunner());
244 RunTest();
247 // Test verifies that \003 message send to process is processed as SigInt.
248 // Timing out on the waterfall: http://crbug.com/115064
249 TEST_F(ProcessProxyTest, DISABLED_SigInt) {
250 test_runner_.reset(new SigIntTestRunner());
251 RunTest();
254 } // namespace chromeos