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

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

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