Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 #include <fcntl.h> | 50 #include <fcntl.h> |
| 51 | 51 |
| 52 #include "base/files/file_descriptor_watcher_posix.h" | 52 #include "base/files/file_descriptor_watcher_posix.h" |
| 53 #endif | 53 #endif |
| 54 | 54 |
| 55 #if defined(OS_MACOSX) | 55 #if defined(OS_MACOSX) |
| 56 #include "base/mac/scoped_nsautorelease_pool.h" | 56 #include "base/mac/scoped_nsautorelease_pool.h" |
| 57 #endif | 57 #endif |
| 58 | 58 |
| 59 #if defined(OS_WIN) | 59 #if defined(OS_WIN) |
| 60 #include <limits> | |
|
Paweł Hajdan Jr.
2017/02/01 11:10:48
nit: Include system headers before chromium header
| |
| 60 #include "base/win/windows_version.h" | 61 #include "base/win/windows_version.h" |
| 61 #endif | 62 #endif |
| 62 | 63 |
| 63 namespace base { | 64 namespace base { |
| 64 | 65 |
| 65 // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/u T3FaE_sgkAJ . | 66 // See https://groups.google.com/a/chromium.org/d/msg/chromium-dev/nkdTP7sstSc/u T3FaE_sgkAJ . |
| 66 using ::operator<<; | 67 using ::operator<<; |
| 67 | 68 |
| 68 // The environment variable name for the total number of test shards. | 69 // The environment variable name for the total number of test shards. |
| 69 const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; | 70 const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n"); | 164 fprintf(stdout, "\nCaught signal. Killing spawned test processes...\n"); |
| 164 fflush(stdout); | 165 fflush(stdout); |
| 165 | 166 |
| 166 KillSpawnedTestProcesses(); | 167 KillSpawnedTestProcesses(); |
| 167 | 168 |
| 168 // The signal would normally kill the process, so exit now. | 169 // The signal would normally kill the process, so exit now. |
| 169 _exit(1); | 170 _exit(1); |
| 170 } | 171 } |
| 171 #endif // defined(OS_POSIX) | 172 #endif // defined(OS_POSIX) |
| 172 | 173 |
| 174 #if defined(OS_WIN) | |
| 175 // Does the same as base::ReadFileToString() but uses FILE_SHARE_DELETE flag | |
|
Paweł Hajdan Jr.
2017/02/01 11:10:48
I'm worried about duplication here.
Actually from
Tomasz Moniuszko
2017/02/02 16:16:43
I tried to add the handle to temp file to |handles
grt (UTC plus 2)
2017/02/03 09:53:23
I wrote that in the bug before realizing that spec
| |
| 176 // when opening file. | |
| 177 bool ReadFileToStringShareDelete(const FilePath& path, std::string* contents) { | |
| 178 if (contents) | |
| 179 contents->clear(); | |
| 180 if (path.ReferencesParent()) | |
| 181 return false; | |
| 182 | |
| 183 win::ScopedHandle handle( | |
| 184 CreateFile(path.value().c_str(), GENERIC_READ, | |
| 185 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, | |
| 186 OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL)); | |
| 187 if (!handle.IsValid()) | |
| 188 return false; | |
| 189 | |
| 190 const size_t max_size = std::numeric_limits<size_t>::max(); | |
| 191 const size_t kBufferSize = 1 << 16; | |
| 192 std::unique_ptr<char[]> buf(new char[kBufferSize]); | |
| 193 DWORD len; | |
| 194 size_t size = 0; | |
| 195 bool read_status = true; | |
| 196 | |
| 197 // Many files supplied in |path| have incorrect size (proc files etc). | |
| 198 // Hence, the file is read sequentially as opposed to a one-shot read. | |
| 199 do { | |
| 200 read_status = | |
| 201 !!::ReadFile(handle.Get(), buf.get(), kBufferSize, &len, NULL); | |
| 202 if (!read_status || len <= 0) | |
| 203 break; | |
| 204 if (contents) { | |
| 205 contents->append(buf.get(), | |
| 206 std::min(static_cast<size_t>(len), max_size - size)); | |
| 207 } | |
| 208 | |
| 209 if ((max_size - size) < len) { | |
| 210 read_status = false; | |
| 211 break; | |
| 212 } | |
| 213 | |
| 214 size += len; | |
| 215 } while (true); | |
| 216 | |
| 217 return read_status; | |
| 218 } | |
| 219 #endif // OS_WIN | |
| 220 | |
| 173 // Parses the environment variable var as an Int32. If it is unset, returns | 221 // Parses the environment variable var as an Int32. If it is unset, returns |
| 174 // true. If it is set, unsets it then converts it to Int32 before | 222 // true. If it is set, unsets it then converts it to Int32 before |
| 175 // returning it in |result|. Returns true on success. | 223 // returning it in |result|. Returns true on success. |
| 176 bool TakeInt32FromEnvironment(const char* const var, int32_t* result) { | 224 bool TakeInt32FromEnvironment(const char* const var, int32_t* result) { |
| 177 std::unique_ptr<Environment> env(Environment::Create()); | 225 std::unique_ptr<Environment> env(Environment::Create()); |
| 178 std::string str_val; | 226 std::string str_val; |
| 179 | 227 |
| 180 if (!env->GetVar(var, &str_val)) | 228 if (!env->GetVar(var, &str_val)) |
| 181 return true; | 229 return true; |
| 182 | 230 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 | 353 |
| 306 { | 354 { |
| 307 // Note how we grab the lock before the process possibly gets created. | 355 // Note how we grab the lock before the process possibly gets created. |
| 308 // This ensures that when the lock is held, ALL the processes are registered | 356 // This ensures that when the lock is held, ALL the processes are registered |
| 309 // in the set. | 357 // in the set. |
| 310 AutoLock lock(g_live_processes_lock.Get()); | 358 AutoLock lock(g_live_processes_lock.Get()); |
| 311 | 359 |
| 312 process = LaunchProcess(command_line, new_options); | 360 process = LaunchProcess(command_line, new_options); |
| 313 if (!process.IsValid()) | 361 if (!process.IsValid()) |
| 314 return -1; | 362 return -1; |
| 315 | 363 |
|
grt (UTC plus 2)
2017/02/01 13:04:44
since the problem is that new_options.stdout_handl
Tomasz Moniuszko
2017/02/02 16:16:43
It doesn't seem to work. I added the above code to
grt (UTC plus 2)
2017/02/03 09:53:23
Did you try it without your other changes? I just
Tomasz Moniuszko
2017/02/03 10:08:48
Yes, I did it on clean master. I used gpu_unittest
grt (UTC plus 2)
2017/02/03 12:45:18
This almost fixes it: https://codereview.chromium.
| |
| 316 // TODO(rvargas) crbug.com/417532: Don't store process handles. | 364 // TODO(rvargas) crbug.com/417532: Don't store process handles. |
| 317 g_live_processes.Get().insert(std::make_pair(process.Handle(), | 365 g_live_processes.Get().insert(std::make_pair(process.Handle(), |
| 318 command_line)); | 366 command_line)); |
| 319 } | 367 } |
| 320 | 368 |
| 321 if (!launched_callback.is_null()) | 369 if (!launched_callback.is_null()) |
| 322 launched_callback.Run(process.Handle(), process.Pid()); | 370 launched_callback.Run(process.Handle(), process.Pid()); |
| 323 | 371 |
| 324 int exit_code = 0; | 372 int exit_code = 0; |
| 325 if (!process.WaitForExitWithTimeout(timeout, &exit_code)) { | 373 if (!process.WaitForExitWithTimeout(timeout, &exit_code)) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 if (redirect_stdio) { | 494 if (redirect_stdio) { |
| 447 #if defined(OS_WIN) | 495 #if defined(OS_WIN) |
| 448 FlushFileBuffers(handle.Get()); | 496 FlushFileBuffers(handle.Get()); |
| 449 handle.Close(); | 497 handle.Close(); |
| 450 #elif defined(OS_POSIX) | 498 #elif defined(OS_POSIX) |
| 451 output_file_fd.reset(); | 499 output_file_fd.reset(); |
| 452 #endif | 500 #endif |
| 453 } | 501 } |
| 454 | 502 |
| 455 std::string output_file_contents; | 503 std::string output_file_contents; |
| 504 #if defined(OS_WIN) | |
| 505 CHECK(ReadFileToStringShareDelete(output_file, &output_file_contents)); | |
| 506 #else | |
| 456 CHECK(ReadFileToString(output_file, &output_file_contents)); | 507 CHECK(ReadFileToString(output_file, &output_file_contents)); |
| 508 #endif | |
| 457 | 509 |
| 458 if (!DeleteFile(output_file, false)) { | 510 CHECK(DeleteFile(output_file, false)); |
| 459 // This needs to be non-fatal at least for Windows. | |
| 460 LOG(WARNING) << "Failed to delete " << output_file.AsUTF8Unsafe(); | |
| 461 } | |
| 462 | 511 |
| 463 // Run target callback on the thread it was originating from, not on | 512 // Run target callback on the thread it was originating from, not on |
| 464 // a worker pool thread. | 513 // a worker pool thread. |
| 465 task_runner->PostTask( | 514 task_runner->PostTask( |
| 466 FROM_HERE, | 515 FROM_HERE, |
| 467 Bind(&RunCallback, completed_callback, exit_code, | 516 Bind(&RunCallback, completed_callback, exit_code, |
| 468 TimeTicks::Now() - start_time, was_timeout, output_file_contents)); | 517 TimeTicks::Now() - start_time, was_timeout, output_file_contents)); |
| 469 } | 518 } |
| 470 | 519 |
| 471 } // namespace | 520 } // namespace |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1205 } | 1254 } |
| 1206 | 1255 |
| 1207 std::string snippet(full_output.substr(run_pos)); | 1256 std::string snippet(full_output.substr(run_pos)); |
| 1208 if (end_pos != std::string::npos) | 1257 if (end_pos != std::string::npos) |
| 1209 snippet = full_output.substr(run_pos, end_pos - run_pos); | 1258 snippet = full_output.substr(run_pos, end_pos - run_pos); |
| 1210 | 1259 |
| 1211 return snippet; | 1260 return snippet; |
| 1212 } | 1261 } |
| 1213 | 1262 |
| 1214 } // namespace base | 1263 } // namespace base |
| OLD | NEW |