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

Side by Side Diff: base/test/launcher/test_launcher.cc

Issue 314173005: Revert of Convert installer_util_unittests, sbox_integration_tests, sbox_validation_tests, sbox_unittests to … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « base/test/launcher/test_launcher.h ('k') | base/test/launcher/unit_test_launcher.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "base/test/launcher/test_launcher.h" 5 #include "base/test/launcher/test_launcher.h"
6 6
7 #if defined(OS_POSIX) 7 #if defined(OS_POSIX)
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #endif 9 #endif
10 10
(...skipping 25 matching lines...) Expand all
36 #include "base/threading/thread_checker.h" 36 #include "base/threading/thread_checker.h"
37 #include "base/time/time.h" 37 #include "base/time/time.h"
38 #include "testing/gtest/include/gtest/gtest.h" 38 #include "testing/gtest/include/gtest/gtest.h"
39 39
40 #if defined(OS_MACOSX) 40 #if defined(OS_MACOSX)
41 #include "base/mac/scoped_nsautorelease_pool.h" 41 #include "base/mac/scoped_nsautorelease_pool.h"
42 #endif 42 #endif
43 43
44 namespace base { 44 namespace base {
45 45
46 // Launches a child process using |command_line|. If the child process is still
47 // running after |timeout|, it is terminated and |*was_timeout| is set to true.
48 // Returns exit code of the process.
49 int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
50 const LaunchOptions& options,
51 bool use_job_objects,
52 base::TimeDelta timeout,
53 bool* was_timeout);
54
55 // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/u T3FaE_sgkAJ . 46 // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/u T3FaE_sgkAJ .
56 using ::operator<<; 47 using ::operator<<;
57 48
58 // The environment variable name for the total number of test shards. 49 // The environment variable name for the total number of test shards.
59 const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; 50 const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
60 // The environment variable name for the test shard index. 51 // The environment variable name for the test shard index.
61 const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; 52 const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
62 53
63 namespace { 54 namespace {
64 55
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 int exit_code, 202 int exit_code,
212 const TimeDelta& elapsed_time, 203 const TimeDelta& elapsed_time,
213 bool was_timeout, 204 bool was_timeout,
214 const std::string& output) { 205 const std::string& output) {
215 callback.Run(exit_code, elapsed_time, was_timeout, output); 206 callback.Run(exit_code, elapsed_time, was_timeout, output);
216 } 207 }
217 208
218 void DoLaunchChildTestProcess( 209 void DoLaunchChildTestProcess(
219 const CommandLine& command_line, 210 const CommandLine& command_line,
220 base::TimeDelta timeout, 211 base::TimeDelta timeout,
221 bool use_job_objects,
222 bool redirect_stdio, 212 bool redirect_stdio,
223 scoped_refptr<MessageLoopProxy> message_loop_proxy, 213 scoped_refptr<MessageLoopProxy> message_loop_proxy,
224 const TestLauncher::LaunchChildGTestProcessCallback& callback) { 214 const TestLauncher::LaunchChildGTestProcessCallback& callback) {
225 TimeTicks start_time = TimeTicks::Now(); 215 TimeTicks start_time = TimeTicks::Now();
226 216
227 // Redirect child process output to a file. 217 // Redirect child process output to a file.
228 base::FilePath output_file; 218 base::FilePath output_file;
229 CHECK(base::CreateTemporaryFile(&output_file)); 219 CHECK(base::CreateTemporaryFile(&output_file));
230 220
231 LaunchOptions options; 221 LaunchOptions options;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 CHECK(output_file_fd.is_valid()); 253 CHECK(output_file_fd.is_valid());
264 254
265 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDOUT_FILENO)); 255 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDOUT_FILENO));
266 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDERR_FILENO)); 256 fds_mapping.push_back(std::make_pair(output_file_fd.get(), STDERR_FILENO));
267 options.fds_to_remap = &fds_mapping; 257 options.fds_to_remap = &fds_mapping;
268 } 258 }
269 #endif 259 #endif
270 260
271 bool was_timeout = false; 261 bool was_timeout = false;
272 int exit_code = LaunchChildTestProcessWithOptions( 262 int exit_code = LaunchChildTestProcessWithOptions(
273 command_line, options, use_job_objects, timeout, &was_timeout); 263 command_line, options, timeout, &was_timeout);
274 264
275 if (redirect_stdio) { 265 if (redirect_stdio) {
276 #if defined(OS_WIN) 266 #if defined(OS_WIN)
277 FlushFileBuffers(handle.Get()); 267 FlushFileBuffers(handle.Get());
278 handle.Close(); 268 handle.Close();
279 #elif defined(OS_POSIX) 269 #elif defined(OS_POSIX)
280 output_file_fd.reset(); 270 output_file_fd.reset();
281 #endif 271 #endif
282 } 272 }
283 273
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 // --test-launcher-jobs flag. 335 // --test-launcher-jobs flag.
346 parallel_jobs_ = 1; 336 parallel_jobs_ = 1;
347 } 337 }
348 } 338 }
349 339
350 TestLauncher::~TestLauncher() { 340 TestLauncher::~TestLauncher() {
351 if (worker_pool_owner_) 341 if (worker_pool_owner_)
352 worker_pool_owner_->pool()->Shutdown(); 342 worker_pool_owner_->pool()->Shutdown();
353 } 343 }
354 344
355 bool TestLauncher::Run() { 345 bool TestLauncher::Run(int argc, char** argv) {
356 if (!Init()) 346 if (!Init())
357 return false; 347 return false;
358 348
359 // Value of |cycles_| changes after each iteration. Keep track of the 349 // Value of |cycles_| changes after each iteration. Keep track of the
360 // original value. 350 // original value.
361 int requested_cycles = cycles_; 351 int requested_cycles = cycles_;
362 352
363 #if defined(OS_POSIX) 353 #if defined(OS_POSIX)
364 CHECK_EQ(0, pipe(g_shutdown_pipe)); 354 CHECK_EQ(0, pipe(g_shutdown_pipe));
365 355
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 387
398 MaybeSaveSummaryAsJSON(); 388 MaybeSaveSummaryAsJSON();
399 389
400 return run_result_; 390 return run_result_;
401 } 391 }
402 392
403 void TestLauncher::LaunchChildGTestProcess( 393 void TestLauncher::LaunchChildGTestProcess(
404 const CommandLine& command_line, 394 const CommandLine& command_line,
405 const std::string& wrapper, 395 const std::string& wrapper,
406 base::TimeDelta timeout, 396 base::TimeDelta timeout,
407 bool use_job_objects,
408 const LaunchChildGTestProcessCallback& callback) { 397 const LaunchChildGTestProcessCallback& callback) {
409 DCHECK(thread_checker_.CalledOnValidThread()); 398 DCHECK(thread_checker_.CalledOnValidThread());
410 399
411 // Record the exact command line used to launch the child. 400 // Record the exact command line used to launch the child.
412 CommandLine new_command_line( 401 CommandLine new_command_line(
413 PrepareCommandLineForGTest(command_line, wrapper)); 402 PrepareCommandLineForGTest(command_line, wrapper));
414 403
415 // When running in parallel mode we need to redirect stdio to avoid mixed-up 404 // When running in parallel mode we need to redirect stdio to avoid mixed-up
416 // output. We also always redirect on the bots to get the test output into 405 // output. We also always redirect on the bots to get the test output into
417 // JSON summary. 406 // JSON summary.
418 bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled(); 407 bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
419 408
420 worker_pool_owner_->pool()->PostWorkerTask( 409 worker_pool_owner_->pool()->PostWorkerTask(
421 FROM_HERE, 410 FROM_HERE,
422 Bind(&DoLaunchChildTestProcess, 411 Bind(&DoLaunchChildTestProcess,
423 new_command_line, 412 new_command_line,
424 timeout, 413 timeout,
425 use_job_objects,
426 redirect_stdio, 414 redirect_stdio,
427 MessageLoopProxy::current(), 415 MessageLoopProxy::current(),
428 Bind(&TestLauncher::OnLaunchTestProcessFinished, 416 Bind(&TestLauncher::OnLaunchTestProcessFinished,
429 Unretained(this), 417 Unretained(this),
430 callback))); 418 callback)));
431 } 419 }
432 420
433 void TestLauncher::OnTestFinished(const TestResult& result) { 421 void TestLauncher::OnTestFinished(const TestResult& result) {
434 ++test_finished_count_; 422 ++test_finished_count_;
435 423
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 end_pos = newline_pos + 1; 937 end_pos = newline_pos + 1;
950 } 938 }
951 939
952 std::string snippet(full_output.substr(run_pos)); 940 std::string snippet(full_output.substr(run_pos));
953 if (end_pos != std::string::npos) 941 if (end_pos != std::string::npos)
954 snippet = full_output.substr(run_pos, end_pos - run_pos); 942 snippet = full_output.substr(run_pos, end_pos - run_pos);
955 943
956 return snippet; 944 return snippet;
957 } 945 }
958 946
947 int LaunchChildGTestProcess(const CommandLine& command_line,
948 const std::string& wrapper,
949 base::TimeDelta timeout,
950 bool* was_timeout) {
951 LaunchOptions options;
952
953 #if defined(OS_POSIX)
954 // On POSIX, we launch the test in a new process group with pgid equal to
955 // its pid. Any child processes that the test may create will inherit the
956 // same pgid. This way, if the test is abruptly terminated, we can clean up
957 // any orphaned child processes it may have left behind.
958 options.new_process_group = true;
959 #endif
960
961 return LaunchChildTestProcessWithOptions(
962 PrepareCommandLineForGTest(command_line, wrapper),
963 options,
964 timeout,
965 was_timeout);
966 }
967
959 CommandLine PrepareCommandLineForGTest(const CommandLine& command_line, 968 CommandLine PrepareCommandLineForGTest(const CommandLine& command_line,
960 const std::string& wrapper) { 969 const std::string& wrapper) {
961 CommandLine new_command_line(command_line.GetProgram()); 970 CommandLine new_command_line(command_line.GetProgram());
962 CommandLine::SwitchMap switches = command_line.GetSwitches(); 971 CommandLine::SwitchMap switches = command_line.GetSwitches();
963 972
964 // Strip out gtest_repeat flag - this is handled by the launcher process. 973 // Strip out gtest_repeat flag - this is handled by the launcher process.
965 switches.erase(kGTestRepeatFlag); 974 switches.erase(kGTestRepeatFlag);
966 975
967 // Don't try to write the final XML report in child processes. 976 // Don't try to write the final XML report in child processes.
968 switches.erase(kGTestOutputFlag); 977 switches.erase(kGTestOutputFlag);
969 978
970 for (CommandLine::SwitchMap::const_iterator iter = switches.begin(); 979 for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
971 iter != switches.end(); ++iter) { 980 iter != switches.end(); ++iter) {
972 new_command_line.AppendSwitchNative((*iter).first, (*iter).second); 981 new_command_line.AppendSwitchNative((*iter).first, (*iter).second);
973 } 982 }
974 983
975 // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine 984 // Prepend wrapper after last CommandLine quasi-copy operation. CommandLine
976 // does not really support removing switches well, and trying to do that 985 // does not really support removing switches well, and trying to do that
977 // on a CommandLine with a wrapper is known to break. 986 // on a CommandLine with a wrapper is known to break.
978 // TODO(phajdan.jr): Give it a try to support CommandLine removing switches. 987 // TODO(phajdan.jr): Give it a try to support CommandLine removing switches.
979 #if defined(OS_WIN) 988 #if defined(OS_WIN)
980 new_command_line.PrependWrapper(ASCIIToWide(wrapper)); 989 new_command_line.PrependWrapper(ASCIIToWide(wrapper));
981 #elif defined(OS_POSIX) 990 #elif defined(OS_POSIX)
982 new_command_line.PrependWrapper(wrapper); 991 new_command_line.PrependWrapper(wrapper);
983 #endif 992 #endif
984 993
985 return new_command_line; 994 return new_command_line;
986 } 995 }
987 996
988 // TODO(phajdan.jr): Move to anonymous namespace.
989 int LaunchChildTestProcessWithOptions(const CommandLine& command_line, 997 int LaunchChildTestProcessWithOptions(const CommandLine& command_line,
990 const LaunchOptions& options, 998 const LaunchOptions& options,
991 bool use_job_objects,
992 base::TimeDelta timeout, 999 base::TimeDelta timeout,
993 bool* was_timeout) { 1000 bool* was_timeout) {
994 #if defined(OS_POSIX) 1001 #if defined(OS_POSIX)
995 // Make sure an option we rely on is present - see LaunchChildGTestProcess. 1002 // Make sure an option we rely on is present - see LaunchChildGTestProcess.
996 DCHECK(options.new_process_group); 1003 DCHECK(options.new_process_group);
997 #endif 1004 #endif
998 1005
999 LaunchOptions new_options(options); 1006 LaunchOptions new_options(options);
1000 1007
1001 #if defined(OS_WIN) 1008 #if defined(OS_WIN)
1002 DCHECK(!new_options.job_handle); 1009 DCHECK(!new_options.job_handle);
1003 1010
1004 win::ScopedHandle job_handle; 1011 win::ScopedHandle job_handle(CreateJobObject(NULL, NULL));
1005 if (use_job_objects) { 1012 if (!job_handle.IsValid()) {
1006 job_handle.Set(CreateJobObject(NULL, NULL)); 1013 LOG(ERROR) << "Could not create JobObject.";
1007 if (!job_handle.IsValid()) { 1014 return -1;
1008 LOG(ERROR) << "Could not create JobObject."; 1015 }
1009 return -1;
1010 }
1011 1016
1012 // Allow break-away from job since sandbox and few other places rely on it 1017 // Allow break-away from job since sandbox and few other places rely on it
1013 // on Windows versions prior to Windows 8 (which supports nested jobs). 1018 // on Windows versions prior to Windows 8 (which supports nested jobs).
1014 // TODO(phajdan.jr): Do not allow break-away on Windows 8. 1019 // TODO(phajdan.jr): Do not allow break-away on Windows 8.
1015 if (!SetJobObjectLimitFlags(job_handle.Get(), 1020 if (!SetJobObjectLimitFlags(job_handle.Get(),
1016 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | 1021 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE |
1017 JOB_OBJECT_LIMIT_BREAKAWAY_OK)) { 1022 JOB_OBJECT_LIMIT_BREAKAWAY_OK)) {
1018 LOG(ERROR) << "Could not SetJobObjectLimitFlags."; 1023 LOG(ERROR) << "Could not SetJobObjectLimitFlags.";
1019 return -1; 1024 return -1;
1020 } 1025 }
1021 1026
1022 new_options.job_handle = job_handle.Get(); 1027 new_options.job_handle = job_handle.Get();
1023 }
1024 #endif // defined(OS_WIN) 1028 #endif // defined(OS_WIN)
1025 1029
1026 #if defined(OS_LINUX) 1030 #if defined(OS_LINUX)
1027 // To prevent accidental privilege sharing to an untrusted child, processes 1031 // To prevent accidental privilege sharing to an untrusted child, processes
1028 // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this 1032 // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
1029 // new child will be privileged and trusted. 1033 // new child will be privileged and trusted.
1030 new_options.allow_new_privs = true; 1034 new_options.allow_new_privs = true;
1031 #endif 1035 #endif
1032 1036
1033 base::ProcessHandle process_handle; 1037 base::ProcessHandle process_handle;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 1077
1074 g_live_processes.Get().erase(process_handle); 1078 g_live_processes.Get().erase(process_handle);
1075 } 1079 }
1076 1080
1077 base::CloseProcessHandle(process_handle); 1081 base::CloseProcessHandle(process_handle);
1078 1082
1079 return exit_code; 1083 return exit_code;
1080 } 1084 }
1081 1085
1082 } // namespace base 1086 } // namespace base
OLDNEW
« no previous file with comments | « base/test/launcher/test_launcher.h ('k') | base/test/launcher/unit_test_launcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698