| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 import logging | 5 import logging |
| 6 import os | 6 import os |
| 7 import posixpath | 7 import posixpath |
| 8 import re | 8 import re |
| 9 import sys | 9 import sys |
| 10 import tempfile | 10 import tempfile |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 google_storage_helper.unique_name( | 506 google_storage_helper.unique_name( |
| 507 'screenshot', device=device), | 507 'screenshot', device=device), |
| 508 screenshot_host_file, | 508 screenshot_host_file, |
| 509 bucket=('%s/screenshots' % | 509 bucket=('%s/screenshots' % |
| 510 self._test_instance.gs_results_bucket)) | 510 self._test_instance.gs_results_bucket)) |
| 511 for result in results: | 511 for result in results: |
| 512 result.SetLink('post_test_screenshot', link) | 512 result.SetLink('post_test_screenshot', link) |
| 513 | 513 |
| 514 def _ProcessRenderTestResults( | 514 def _ProcessRenderTestResults( |
| 515 self, device, render_tests_device_output_dir, results): | 515 self, device, render_tests_device_output_dir, results): |
| 516 # Will archive test images if we are given a GS bucket to store the results | 516 # If GS results bucket is specified, will archive render result images. |
| 517 # in and are given a results file to output the links to. | 517 # If render image dir is specified, will pull the render result image from |
| 518 if not bool(self._test_instance.gs_results_bucket): | 518 # the device and leave in the directory. |
| 519 if not (bool(self._test_instance.gs_results_bucket) or |
| 520 bool(self._test_instance.render_results_dir)): |
| 519 return | 521 return |
| 520 | 522 |
| 521 failure_images_device_dir = posixpath.join( | 523 failure_images_device_dir = posixpath.join( |
| 522 render_tests_device_output_dir, 'failures') | 524 render_tests_device_output_dir, 'failures') |
| 523 | |
| 524 if not device.FileExists(failure_images_device_dir): | 525 if not device.FileExists(failure_images_device_dir): |
| 525 return | 526 return |
| 526 | 527 |
| 527 render_tests_bucket = ( | |
| 528 self._test_instance.gs_results_bucket + '/render_tests') | |
| 529 | |
| 530 diff_images_device_dir = posixpath.join( | 528 diff_images_device_dir = posixpath.join( |
| 531 render_tests_device_output_dir, 'diffs') | 529 render_tests_device_output_dir, 'diffs') |
| 532 | 530 |
| 533 golden_images_device_dir = posixpath.join( | 531 golden_images_device_dir = posixpath.join( |
| 534 render_tests_device_output_dir, 'goldens') | 532 render_tests_device_output_dir, 'goldens') |
| 535 | 533 |
| 536 with tempfile_ext.NamedTemporaryDirectory() as temp_dir: | 534 with contextlib_ext.Optional( |
| 537 device.PullFile(failure_images_device_dir, temp_dir) | 535 tempfile_ext.NamedTemporaryDirectory(), |
| 536 not bool(self._test_instance.render_results_dir)) as render_temp_dir: |
| 537 render_host_dir = ( |
| 538 self._test_instance.render_results_dir or render_temp_dir) |
| 539 |
| 540 if not os.path.exists(render_host_dir): |
| 541 os.makedirs(render_host_dir) |
| 542 |
| 543 # Pull all render test results from device. |
| 544 device.PullFile(failure_images_device_dir, render_host_dir) |
| 538 | 545 |
| 539 if device.FileExists(diff_images_device_dir): | 546 if device.FileExists(diff_images_device_dir): |
| 540 device.PullFile(diff_images_device_dir, temp_dir) | 547 device.PullFile(diff_images_device_dir, render_host_dir) |
| 541 else: | 548 else: |
| 542 logging.error('Diff images not found on device.') | 549 logging.error('Diff images not found on device.') |
| 543 | 550 |
| 544 if device.FileExists(golden_images_device_dir): | 551 if device.FileExists(golden_images_device_dir): |
| 545 device.PullFile(golden_images_device_dir, temp_dir) | 552 device.PullFile(golden_images_device_dir, render_host_dir) |
| 546 else: | 553 else: |
| 547 logging.error('Golden images not found on device.') | 554 logging.error('Golden images not found on device.') |
| 548 | 555 |
| 549 for failure_filename in os.listdir(os.path.join(temp_dir, 'failures')): | 556 # Upload results to Google Storage. |
| 550 m = RE_RENDER_IMAGE_NAME.match(failure_filename) | 557 if self._test_instance.gs_results_bucket: |
| 551 if not m: | 558 self._UploadRenderTestResults(render_host_dir, results) |
| 552 logging.warning('Unexpected file in render test failures: %s', | |
| 553 failure_filename) | |
| 554 continue | |
| 555 | 559 |
| 556 failure_filepath = os.path.join(temp_dir, 'failures', failure_filename) | 560 def _UploadRenderTestResults(self, render_host_dir, results): |
| 557 failure_link = google_storage_helper.upload_content_addressed( | 561 render_tests_bucket = ( |
| 558 failure_filepath, bucket=render_tests_bucket) | 562 self._test_instance.gs_results_bucket + '/render_tests') |
| 559 | 563 |
| 560 golden_filepath = os.path.join(temp_dir, 'goldens', failure_filename) | 564 for failure_filename in os.listdir( |
| 561 if os.path.exists(golden_filepath): | 565 os.path.join(render_host_dir, 'failures')): |
| 562 golden_link = google_storage_helper.upload_content_addressed( | 566 m = RE_RENDER_IMAGE_NAME.match(failure_filename) |
| 563 golden_filepath, bucket=render_tests_bucket) | 567 if not m: |
| 564 else: | 568 logging.warning('Unexpected file in render test failures: %s', |
| 565 golden_link = '' | 569 failure_filename) |
| 570 continue |
| 566 | 571 |
| 567 diff_filepath = os.path.join(temp_dir, 'diffs', failure_filename) | 572 failure_filepath = os.path.join( |
| 568 if os.path.exists(diff_filepath): | 573 render_host_dir, 'failures', failure_filename) |
| 569 diff_link = google_storage_helper.upload_content_addressed( | 574 failure_link = google_storage_helper.upload_content_addressed( |
| 570 diff_filepath, bucket=render_tests_bucket) | 575 failure_filepath, bucket=render_tests_bucket) |
| 571 else: | |
| 572 diff_link = '' | |
| 573 | 576 |
| 574 with tempfile.NamedTemporaryFile(suffix='.html') as temp_html: | 577 golden_filepath = os.path.join( |
| 575 jinja2_env = jinja2.Environment( | 578 render_host_dir, 'goldens', failure_filename) |
| 576 loader=jinja2.FileSystemLoader(_JINJA_TEMPLATE_DIR), | 579 if os.path.exists(golden_filepath): |
| 577 trim_blocks=True) | 580 golden_link = google_storage_helper.upload_content_addressed( |
| 578 template = jinja2_env.get_template(_JINJA_TEMPLATE_FILENAME) | 581 golden_filepath, bucket=render_tests_bucket) |
| 579 # pylint: disable=no-member | 582 else: |
| 580 processed_template_output = template.render( | 583 golden_link = '' |
| 581 test_name=failure_filename, | |
| 582 failure_link=failure_link, | |
| 583 golden_link=golden_link, | |
| 584 diff_link=diff_link) | |
| 585 | 584 |
| 586 temp_html.write(processed_template_output) | 585 diff_filepath = os.path.join( |
| 587 temp_html.flush() | 586 render_host_dir, 'diffs', failure_filename) |
| 588 html_results_link = google_storage_helper.upload_content_addressed( | 587 if os.path.exists(diff_filepath): |
| 589 temp_html.name, | 588 diff_link = google_storage_helper.upload_content_addressed( |
| 590 bucket=render_tests_bucket, | 589 diff_filepath, bucket=render_tests_bucket) |
| 591 content_type='text/html') | 590 else: |
| 592 for result in results: | 591 diff_link = '' |
| 593 result.SetLink(failure_filename, html_results_link) | 592 |
| 593 with tempfile.NamedTemporaryFile(suffix='.html') as temp_html: |
| 594 jinja2_env = jinja2.Environment( |
| 595 loader=jinja2.FileSystemLoader(_JINJA_TEMPLATE_DIR), |
| 596 trim_blocks=True) |
| 597 template = jinja2_env.get_template(_JINJA_TEMPLATE_FILENAME) |
| 598 # pylint: disable=no-member |
| 599 processed_template_output = template.render( |
| 600 test_name=failure_filename, |
| 601 failure_link=failure_link, |
| 602 golden_link=golden_link, |
| 603 diff_link=diff_link) |
| 604 |
| 605 temp_html.write(processed_template_output) |
| 606 temp_html.flush() |
| 607 html_results_link = google_storage_helper.upload_content_addressed( |
| 608 temp_html.name, |
| 609 bucket=render_tests_bucket, |
| 610 content_type='text/html') |
| 611 for result in results: |
| 612 result.SetLink(failure_filename, html_results_link) |
| 594 | 613 |
| 595 #override | 614 #override |
| 596 def _ShouldRetry(self, test): | 615 def _ShouldRetry(self, test): |
| 597 if 'RetryOnFailure' in test.get('annotations', {}): | 616 if 'RetryOnFailure' in test.get('annotations', {}): |
| 598 return True | 617 return True |
| 599 | 618 |
| 600 # TODO(jbudorick): Remove this log message once @RetryOnFailure has been | 619 # TODO(jbudorick): Remove this log message once @RetryOnFailure has been |
| 601 # enabled for a while. See crbug.com/619055 for more details. | 620 # enabled for a while. See crbug.com/619055 for more details. |
| 602 logging.error('Default retries are being phased out. crbug.com/619055') | 621 logging.error('Default retries are being phased out. crbug.com/619055') |
| 603 return False | 622 return False |
| (...skipping 23 matching lines...) Expand all Loading... |
| 627 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) | 646 timeout *= cls._GetTimeoutScaleFromAnnotations(annotations) |
| 628 | 647 |
| 629 return timeout | 648 return timeout |
| 630 | 649 |
| 631 def _IsRenderTest(test): | 650 def _IsRenderTest(test): |
| 632 """Determines if a test or list of tests has a RenderTest amongst them.""" | 651 """Determines if a test or list of tests has a RenderTest amongst them.""" |
| 633 if not isinstance(test, list): | 652 if not isinstance(test, list): |
| 634 test = [test] | 653 test = [test] |
| 635 return any([RENDER_TEST_FEATURE_ANNOTATION in t['annotations'].get( | 654 return any([RENDER_TEST_FEATURE_ANNOTATION in t['annotations'].get( |
| 636 FEATURE_ANNOTATION, {}).get('value', ()) for t in test]) | 655 FEATURE_ANNOTATION, {}).get('value', ()) for t in test]) |
| OLD | NEW |