Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: chromeos/process_proxy/process_output_watcher_unittest.cc

Issue 1258193002: User MessageLoopForIO::WatchFileDescriptor in proces_output_watcher (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <gtest/gtest.h> 5 #include <gtest/gtest.h>
6 6
7 #include <queue> 7 #include <queue>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/threading/thread.h" 19 #include "base/threading/thread.h"
20 #include "chromeos/process_proxy/process_output_watcher.h" 20 #include "chromeos/process_proxy/process_output_watcher.h"
21 21
22 namespace chromeos { 22 namespace chromeos {
23 23
24 namespace {
25
24 struct TestCase { 26 struct TestCase {
25 TestCase(const std::string& input, bool send_terminating_null) 27 TestCase(const std::string& input, bool send_terminating_null)
26 : input(input), 28 : input(input),
27 should_send_terminating_null(send_terminating_null), 29 should_send_terminating_null(send_terminating_null),
28 expected_output(input) {} 30 expected_output(input) {}
29 31
30 // Conctructor for cases where the output is not expected to be the same as 32 // Conctructor for cases where the output is not expected to be the same as
31 // input. 33 // input.
32 TestCase(const std::string& input, 34 TestCase(const std::string& input,
33 bool send_terminating_null, 35 bool send_terminating_null,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 78
77 bool IsDone() { 79 bool IsDone() {
78 return received_from_out_ >= out_expectations_.length(); 80 return received_from_out_ >= out_expectations_.length();
79 } 81 }
80 82
81 private: 83 private:
82 std::string out_expectations_; 84 std::string out_expectations_;
83 size_t received_from_out_; 85 size_t received_from_out_;
84 }; 86 };
85 87
88 void StopProcessOutputWatcher(scoped_ptr<ProcessOutputWatcher> watcher) {
89 // Just deleting |watcher| if sufficient.
90 }
91
92 } // namespace
93
86 class ProcessOutputWatcherTest : public testing::Test { 94 class ProcessOutputWatcherTest : public testing::Test {
87 public: 95 public:
88 ProcessOutputWatcherTest() : output_watch_thread_started_(false), 96 ProcessOutputWatcherTest() : output_watch_thread_started_(false),
89 failed_(false) { 97 failed_(false) {
90 } 98 }
91 99
92 ~ProcessOutputWatcherTest() override {} 100 ~ProcessOutputWatcherTest() override {}
93 101
94 void TearDown() override { 102 void TearDown() override {
95 if (output_watch_thread_started_) 103 if (output_watch_thread_started_)
96 output_watch_thread_->Stop(); 104 output_watch_thread_->Stop();
97 } 105 }
98 106
99 void StartWatch(int pt, int stop) {
100 // This will delete itself.
101 ProcessOutputWatcher* crosh_watcher = new ProcessOutputWatcher(pt, stop,
102 base::Bind(&ProcessOutputWatcherTest::OnRead, base::Unretained(this)));
103 crosh_watcher->Start();
104 }
105
106 void OnRead(ProcessOutputType type, const std::string& output) { 107 void OnRead(ProcessOutputType type, const std::string& output) {
107 ASSERT_FALSE(failed_); 108 ASSERT_FALSE(failed_);
108 // There may be an EXIT signal sent during test tear down (which is sent 109 // There may be an EXIT signal sent during test tear down (which is sent
109 // by process output watcher when master end of test pseudo-terminal is 110 // by process output watcher when master end of test pseudo-terminal is
110 // closed). If this happens, ignore it. If EXIT is seen before test 111 // closed). If this happens, ignore it. If EXIT is seen before test
111 // expectations are met, fall through in order to fail the test. 112 // expectations are met, fall through in order to fail the test.
112 if (type == PROCESS_OUTPUT_TYPE_EXIT && expectations_.IsDone()) { 113 if (type == PROCESS_OUTPUT_TYPE_EXIT && expectations_.IsDone()) {
113 ASSERT_TRUE(test_case_done_callback_.is_null()); 114 ASSERT_TRUE(test_case_done_callback_.is_null());
114 return; 115 return;
115 } 116 }
(...skipping 11 matching lines...) Expand all
127 std::string VeryLongString() { 128 std::string VeryLongString() {
128 std::string result = "0123456789"; 129 std::string result = "0123456789";
129 for (int i = 0; i < 8; i++) 130 for (int i = 0; i < 8; i++)
130 result = result.append(result); 131 result = result.append(result);
131 return result; 132 return result;
132 } 133 }
133 134
134 void RunTest(const std::vector<TestCase>& test_cases) { 135 void RunTest(const std::vector<TestCase>& test_cases) {
135 ASSERT_FALSE(output_watch_thread_started_); 136 ASSERT_FALSE(output_watch_thread_started_);
136 output_watch_thread_.reset(new base::Thread("ProcessOutpuWatchThread")); 137 output_watch_thread_.reset(new base::Thread("ProcessOutpuWatchThread"));
137 output_watch_thread_started_ = output_watch_thread_->Start(); 138 output_watch_thread_started_ = output_watch_thread_->StartWithOptions(
139 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
138 ASSERT_TRUE(output_watch_thread_started_); 140 ASSERT_TRUE(output_watch_thread_started_);
139 141
140 int pt_pipe[2], stop_pipe[2]; 142 int pt_pipe[2];
141 ASSERT_FALSE(HANDLE_EINTR(pipe(pt_pipe))); 143 ASSERT_FALSE(HANDLE_EINTR(pipe(pt_pipe)));
142 ASSERT_FALSE(HANDLE_EINTR(pipe(stop_pipe))); 144
145 scoped_ptr<ProcessOutputWatcher> crosh_watcher(new ProcessOutputWatcher(
146 pt_pipe[0],
147 base::Bind(&ProcessOutputWatcherTest::OnRead, base::Unretained(this))));
143 148
144 output_watch_thread_->task_runner()->PostTask( 149 output_watch_thread_->task_runner()->PostTask(
145 FROM_HERE, 150 FROM_HERE, base::Bind(&ProcessOutputWatcher::Start,
146 base::Bind(&ProcessOutputWatcherTest::StartWatch, 151 base::Unretained(crosh_watcher.get())));
147 base::Unretained(this), pt_pipe[0], stop_pipe[0]));
148 152
149 for (size_t i = 0; i < test_cases.size(); i++) { 153 for (size_t i = 0; i < test_cases.size(); i++) {
150 expectations_.SetTestCase(test_cases[i]); 154 expectations_.SetTestCase(test_cases[i]);
151 155
152 base::RunLoop run_loop; 156 base::RunLoop run_loop;
153 ASSERT_TRUE(test_case_done_callback_.is_null()); 157 ASSERT_TRUE(test_case_done_callback_.is_null());
154 test_case_done_callback_ = run_loop.QuitClosure(); 158 test_case_done_callback_ = run_loop.QuitClosure();
155 159
156 const std::string& test_str = test_cases[i].input; 160 const std::string& test_str = test_cases[i].input;
157 // Let's make inputs not NULL terminated, unless other is specified in 161 // Let's make inputs not NULL terminated, unless other is specified in
158 // the test case. 162 // the test case.
159 ssize_t test_size = test_str.length() * sizeof(*test_str.c_str()); 163 ssize_t test_size = test_str.length() * sizeof(*test_str.c_str());
160 if (test_cases[i].should_send_terminating_null) 164 if (test_cases[i].should_send_terminating_null)
161 test_size += sizeof(*test_str.c_str()); 165 test_size += sizeof(*test_str.c_str());
162 EXPECT_TRUE(base::WriteFileDescriptor(pt_pipe[1], test_str.c_str(), 166 EXPECT_TRUE(base::WriteFileDescriptor(pt_pipe[1], test_str.c_str(),
163 test_size)); 167 test_size));
164 168
165 run_loop.Run(); 169 run_loop.Run();
166 EXPECT_TRUE(expectations_.IsDone()); 170 EXPECT_TRUE(expectations_.IsDone());
167 if (failed_) 171 if (failed_)
168 break; 172 break;
169 } 173 }
170 174
171 // Send stop signal. It is not important which string we send. 175 output_watch_thread_->task_runner()->PostTask(
172 EXPECT_TRUE(base::WriteFileDescriptor(stop_pipe[1], "q", 1)); 176 FROM_HERE,
177 base::Bind(&StopProcessOutputWatcher, base::Passed(&crosh_watcher)));
173 178
174 EXPECT_NE(-1, IGNORE_EINTR(close(stop_pipe[1])));
175 EXPECT_NE(-1, IGNORE_EINTR(close(pt_pipe[1]))); 179 EXPECT_NE(-1, IGNORE_EINTR(close(pt_pipe[1])));
176 } 180 }
177 181
178 private: 182 private:
179 base::Closure test_case_done_callback_; 183 base::Closure test_case_done_callback_;
180 base::MessageLoop message_loop_; 184 base::MessageLoop message_loop_;
181 scoped_ptr<base::Thread> output_watch_thread_; 185 scoped_ptr<base::Thread> output_watch_thread_;
182 bool output_watch_thread_started_; 186 bool output_watch_thread_started_;
183 bool failed_; 187 bool failed_;
184 ProcessWatcherExpectations expectations_; 188 ProcessWatcherExpectations expectations_;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 // This will send '\0' to output watcher. 312 // This will send '\0' to output watcher.
309 test_cases.push_back(TestCase("", true)); 313 test_cases.push_back(TestCase("", true));
310 // Let's verify that next input also gets detected (i.e. output watcher does 314 // Let's verify that next input also gets detected (i.e. output watcher does
311 // not exit after seeing '\0' from previous test case). 315 // not exit after seeing '\0' from previous test case).
312 test_cases.push_back(TestCase("a", true)); 316 test_cases.push_back(TestCase("a", true));
313 317
314 RunTest(test_cases); 318 RunTest(test_cases);
315 } 319 }
316 320
317 } // namespace chromeos 321 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/process_proxy/process_output_watcher.cc ('k') | chromeos/process_proxy/process_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698