OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # valgrind_test.py | 6 # valgrind_test.py |
7 | 7 |
8 """Runs an exe through Valgrind and puts the intermediate files in a | 8 """Runs an exe through Valgrind and puts the intermediate files in a |
9 directory. | 9 directory. |
10 """ | 10 """ |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 appropriately. | 390 appropriately. |
391 """ | 391 """ |
392 command = " ".join(proc) | 392 command = " ".join(proc) |
393 command = command.replace("%p", "$$.%p") | 393 command = command.replace("%p", "$$.%p") |
394 | 394 |
395 (fd, indirect_fname) = tempfile.mkstemp(dir=self.log_dir, | 395 (fd, indirect_fname) = tempfile.mkstemp(dir=self.log_dir, |
396 prefix="browser_wrapper.", | 396 prefix="browser_wrapper.", |
397 text=True) | 397 text=True) |
398 f = os.fdopen(fd, "w") | 398 f = os.fdopen(fd, "w") |
399 f.write("#!/bin/sh\n") | 399 f.write("#!/bin/sh\n") |
400 f.write('echo "Started Valgrind wrapper for this test, PID=$$"\n') | 400 f.write('echo "Started Valgrind wrapper for this test, PID=$$"\n\n') |
| 401 f.write('for arg in $@\ndo\n') |
| 402 f.write(' if [[ "$arg" =~ --test-name=(.*) ]]\n then\n') |
| 403 f.write(' TESTCASE=${BASH_REMATCH[1]}\n') |
| 404 f.write(' echo $TESTCASE >`dirname $0`/testcase.$$.name\n') |
| 405 f.write(' fi\ndone\n') |
401 # Add the PID of the browser wrapper to the logfile names so we can | 406 # Add the PID of the browser wrapper to the logfile names so we can |
402 # separate log files for different UI tests at the analyze stage. | 407 # separate log files for different UI tests at the analyze stage. |
403 f.write(command) | 408 f.write(command) |
404 f.write(' "$@"\n') | 409 f.write(' "$@"\n') |
405 f.close() | 410 f.close() |
406 os.chmod(indirect_fname, stat.S_IRUSR|stat.S_IXUSR) | 411 os.chmod(indirect_fname, stat.S_IRUSR|stat.S_IXUSR) |
407 return indirect_fname | 412 return indirect_fname |
408 | 413 |
409 def CreateAnalyzer(self): | 414 def CreateAnalyzer(self): |
410 raise NotImplementedError, "This method should be implemented " \ | 415 raise NotImplementedError, "This method should be implemented " \ |
411 "in the tool-specific subclass" | 416 "in the tool-specific subclass" |
412 | 417 |
413 def GetAnalyzeResults(self, check_sanity=False): | 418 def GetAnalyzeResults(self, check_sanity=False): |
414 # Glob all the files in the "testing.tmp" directory | 419 # Glob all the files in the "testing.tmp" directory |
415 filenames = glob.glob(self.log_dir + "/" + self.ToolName() + ".*") | 420 filenames = glob.glob(self.log_dir + "/" + self.ToolName() + ".*") |
416 | 421 |
417 # If we have browser wrapper, the logfiles are named as | 422 # If we have browser wrapper, the logfiles are named as |
418 # "toolname.wrapper_PID.valgrind_PID". | 423 # "toolname.wrapper_PID.valgrind_PID". |
419 # Let's extract the list of wrapper_PIDs and name it ppids | 424 # Let's extract the list of wrapper_PIDs and name it ppids |
420 ppids = set([int(f.split(".")[-2]) \ | 425 ppids = set([int(f.split(".")[-2]) \ |
421 for f in filenames if re.search("\.[0-9]+\.[0-9]+$", f)]) | 426 for f in filenames if re.search("\.[0-9]+\.[0-9]+$", f)]) |
422 | 427 |
423 analyzer = self.CreateAnalyzer() | 428 analyzer = self.CreateAnalyzer() |
424 if len(ppids) == 0: | 429 if len(ppids) == 0: |
425 # Fast path - no browser wrapper was set. | 430 # Fast path - no browser wrapper was set. |
426 return analyzer.Report(filenames, check_sanity) | 431 return analyzer.Report(filenames, None, check_sanity) |
427 | 432 |
428 ret = 0 | 433 ret = 0 |
429 for ppid in ppids: | 434 for ppid in ppids: |
| 435 testcase_name = None |
| 436 try: |
| 437 f = open(self.log_dir + ("/testcase.%d.name" % ppid)) |
| 438 testcase_name = f.read().strip() |
| 439 f.close() |
| 440 except IOError: |
| 441 pass |
430 print "=====================================================" | 442 print "=====================================================" |
431 print " Below is the report for valgrind wrapper PID=%d." % ppid | 443 print " Below is the report for valgrind wrapper PID=%d." % ppid |
432 print " You can find the corresponding test" | 444 if testcase_name: |
433 print " by searching the above log for 'PID=%d'" % ppid | 445 print " It was used while running the `%s` test." % testcase_name |
| 446 else: |
| 447 print " You can find the corresponding test" |
| 448 print " by searching the above log for 'PID=%d'" % ppid |
434 sys.stdout.flush() | 449 sys.stdout.flush() |
435 | 450 |
436 ppid_filenames = [f for f in filenames \ | 451 ppid_filenames = [f for f in filenames \ |
437 if re.search("\.%d\.[0-9]+$" % ppid, f)] | 452 if re.search("\.%d\.[0-9]+$" % ppid, f)] |
438 # check_sanity won't work with browser wrappers | 453 # check_sanity won't work with browser wrappers |
439 assert check_sanity == False | 454 assert check_sanity == False |
440 ret |= analyzer.Report(ppid_filenames) | 455 ret |= analyzer.Report(ppid_filenames, testcase_name) |
441 print "=====================================================" | 456 print "=====================================================" |
442 sys.stdout.flush() | 457 sys.stdout.flush() |
443 | 458 |
444 if ret != 0: | 459 if ret != 0: |
445 print "" | 460 print "" |
446 print "The Valgrind reports are grouped by test names." | 461 print "The Valgrind reports are grouped by test names." |
447 print "Each test has its PID printed in the log when the test was run" | 462 print "Each test has its PID printed in the log when the test was run" |
448 print "and at the beginning of its Valgrind report." | 463 print "and at the beginning of its Valgrind report." |
| 464 print "Hint: you can search for the reports by Ctrl+F -> `=#`" |
449 sys.stdout.flush() | 465 sys.stdout.flush() |
450 | 466 |
451 return ret | 467 return ret |
452 | 468 |
453 | 469 |
454 # TODO(timurrrr): Split into a separate file. | 470 # TODO(timurrrr): Split into a separate file. |
455 class Memcheck(ValgrindTool): | 471 class Memcheck(ValgrindTool): |
456 """Memcheck | 472 """Memcheck |
457 Dynamic memory error detector for Linux & Mac | 473 Dynamic memory error detector for Linux & Mac |
458 | 474 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 proc += ["--log-file=" + logfilename] | 709 proc += ["--log-file=" + logfilename] |
694 | 710 |
695 # TODO(timurrrr): Add flags for Valgrind trace children analog when we | 711 # TODO(timurrrr): Add flags for Valgrind trace children analog when we |
696 # start running complex tests (e.g. UI) under TSan/Win. | 712 # start running complex tests (e.g. UI) under TSan/Win. |
697 | 713 |
698 return proc | 714 return proc |
699 | 715 |
700 def Analyze(self, check_sanity=False): | 716 def Analyze(self, check_sanity=False): |
701 filenames = glob.glob(self.log_dir + "/tsan.*") | 717 filenames = glob.glob(self.log_dir + "/tsan.*") |
702 analyzer = tsan_analyze.TsanAnalyzer(self._source_dir) | 718 analyzer = tsan_analyze.TsanAnalyzer(self._source_dir) |
703 ret = analyzer.Report(filenames, check_sanity) | 719 ret = analyzer.Report(filenames, None, check_sanity) |
704 if ret != 0: | 720 if ret != 0: |
705 logging.info(self.INFO_MESSAGE) | 721 logging.info(self.INFO_MESSAGE) |
706 return ret | 722 return ret |
707 | 723 |
708 | 724 |
709 class DrMemory(BaseTool): | 725 class DrMemory(BaseTool): |
710 """Dr.Memory | 726 """Dr.Memory |
711 Dynamic memory error detector for Windows. | 727 Dynamic memory error detector for Windows. |
712 | 728 |
713 http://dev.chromium.org/developers/how-tos/using-drmemory | 729 http://dev.chromium.org/developers/how-tos/using-drmemory |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 platform_name = sys.platform + "(Unknown)" | 1116 platform_name = sys.platform + "(Unknown)" |
1101 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, | 1117 raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, |
1102 platform_name) | 1118 platform_name) |
1103 | 1119 |
1104 def CreateTool(tool): | 1120 def CreateTool(tool): |
1105 return ToolFactory().Create(tool) | 1121 return ToolFactory().Create(tool) |
1106 | 1122 |
1107 if __name__ == '__main__': | 1123 if __name__ == '__main__': |
1108 logging.error(sys.argv[0] + " can not be run from command line") | 1124 logging.error(sys.argv[0] + " can not be run from command line") |
1109 sys.exit(1) | 1125 sys.exit(1) |
OLD | NEW |