1# Copyright (c) 2010 Google Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions are 5# met: 6# 7# * Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above 10# copyright notice, this list of conditions and the following disclaimer 11# in the documentation and/or other materials provided with the 12# distribution. 13# * Neither the name of Google Inc. nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29import unittest 30 31from webkitpy.common.config.committers import Committer 32from webkitpy.common.system.filesystem_mock import MockFileSystem 33from webkitpy.common.system.outputcapture import OutputCapture 34from webkitpy.layout_tests.layout_package import test_results 35from webkitpy.layout_tests.layout_package import test_failures 36from webkitpy.thirdparty.mock import Mock 37from webkitpy.tool.bot.flakytestreporter import FlakyTestReporter 38from webkitpy.tool.mocktool import MockTool, MockStatusServer 39 40 41# Creating fake CommitInfos is a pain, so we use a mock one here. 42class MockCommitInfo(object): 43 def __init__(self, author_email): 44 self._author_email = author_email 45 46 def author(self): 47 # It's definitely possible to have commits with authors who 48 # are not in our committers.py list. 49 if not self._author_email: 50 return None 51 return Committer("Mock Committer", self._author_email) 52 53 54class FlakyTestReporterTest(unittest.TestCase): 55 def _mock_test_result(self, testname): 56 return test_results.TestResult(testname, [test_failures.FailureTextMismatch()]) 57 58 def _assert_emails_for_test(self, emails): 59 tool = MockTool() 60 reporter = FlakyTestReporter(tool, 'dummy-queue') 61 commit_infos = [MockCommitInfo(email) for email in emails] 62 tool.checkout().recent_commit_infos_for_files = lambda paths: set(commit_infos) 63 self.assertEqual(reporter._author_emails_for_test([]), set(emails)) 64 65 def test_author_emails_for_test(self): 66 self._assert_emails_for_test([]) 67 self._assert_emails_for_test(["test1@test.com", "test1@test.com"]) 68 self._assert_emails_for_test(["test1@test.com", "test2@test.com"]) 69 70 def test_create_bug_for_flaky_test(self): 71 reporter = FlakyTestReporter(MockTool(), 'dummy-queue') 72 expected_stderr = """MOCK create_bug 73bug_title: Flaky Test: foo/bar.html 74bug_description: This is an automatically generated bug from the dummy-queue. 75foo/bar.html has been flaky on the dummy-queue. 76 77foo/bar.html was authored by test@test.com. 78http://trac.webkit.org/browser/trunk/LayoutTests/foo/bar.html 79 80FLAKE_MESSAGE 81 82The bots will update this with information from each new failure. 83 84If you believe this bug to be fixed or invalid, feel free to close. The bots will re-open if the flake re-occurs. 85 86If you would like to track this test fix with another bug, please close this bug as a duplicate. The bots will follow the duplicate chain when making future comments. 87 88component: Tools / Tests 89cc: test@test.com 90blocked: 50856 91""" 92 OutputCapture().assert_outputs(self, reporter._create_bug_for_flaky_test, ['foo/bar.html', ['test@test.com'], 'FLAKE_MESSAGE'], expected_stderr=expected_stderr) 93 94 def test_follow_duplicate_chain(self): 95 tool = MockTool() 96 reporter = FlakyTestReporter(tool, 'dummy-queue') 97 bug = tool.bugs.fetch_bug(78) 98 self.assertEqual(reporter._follow_duplicate_chain(bug).id(), 76) 99 100 def test_report_flaky_tests_creating_bug(self): 101 tool = MockTool() 102 tool.filesystem = MockFileSystem({"/mock/foo/bar-diffs.txt": "mock"}) 103 tool.status_server = MockStatusServer(bot_id="mock-bot-id") 104 reporter = FlakyTestReporter(tool, 'dummy-queue') 105 reporter._lookup_bug_for_flaky_test = lambda bug_id: None 106 patch = tool.bugs.fetch_attachment(197) 107 expected_stderr = """MOCK create_bug 108bug_title: Flaky Test: foo/bar.html 109bug_description: This is an automatically generated bug from the dummy-queue. 110foo/bar.html has been flaky on the dummy-queue. 111 112foo/bar.html was authored by abarth@webkit.org. 113http://trac.webkit.org/browser/trunk/LayoutTests/foo/bar.html 114 115The dummy-queue just saw foo/bar.html flake (Text diff mismatch) while processing attachment 197 on bug 42. 116Bot: mock-bot-id Port: MockPort Platform: MockPlatform 1.0 117 118The bots will update this with information from each new failure. 119 120If you believe this bug to be fixed or invalid, feel free to close. The bots will re-open if the flake re-occurs. 121 122If you would like to track this test fix with another bug, please close this bug as a duplicate. The bots will follow the duplicate chain when making future comments. 123 124component: Tools / Tests 125cc: abarth@webkit.org 126blocked: 50856 127MOCK add_attachment_to_bug: bug_id=78, description=Failure diff from mock-bot-id filename=failure.diff 128MOCK bug comment: bug_id=42, cc=None 129--- Begin comment --- 130The dummy-queue encountered the following flaky tests while processing attachment 197: 131 132foo/bar.html bug 78 (author: abarth@webkit.org) 133The dummy-queue is continuing to process your patch. 134--- End comment --- 135 136""" 137 test_results = [self._mock_test_result('foo/bar.html')] 138 139 class MockZipFile(object): 140 def read(self, path): 141 return "" 142 143 def namelist(self): 144 return ['foo/bar-diffs.txt'] 145 146 OutputCapture().assert_outputs(self, reporter.report_flaky_tests, [patch, test_results, MockZipFile()], expected_stderr=expected_stderr) 147 148 def test_optional_author_string(self): 149 reporter = FlakyTestReporter(MockTool(), 'dummy-queue') 150 self.assertEqual(reporter._optional_author_string([]), "") 151 self.assertEqual(reporter._optional_author_string(["foo@bar.com"]), " (author: foo@bar.com)") 152 self.assertEqual(reporter._optional_author_string(["a@b.com", "b@b.com"]), " (authors: a@b.com and b@b.com)") 153 154 def test_results_diff_path_for_test(self): 155 reporter = FlakyTestReporter(MockTool(), 'dummy-queue') 156 self.assertEqual(reporter._results_diff_path_for_test("test.html"), "test-diffs.txt") 157 158 def test_find_in_archive(self): 159 reporter = FlakyTestReporter(MockTool(), 'dummy-queue') 160 161 class MockZipFile(object): 162 def namelist(self): 163 return ["tmp/layout-test-results/foo/bar-diffs.txt"] 164 165 reporter._find_in_archive("foo/bar-diffs.txt", MockZipFile()) 166 # This is not ideal, but its 167 reporter._find_in_archive("txt", MockZipFile()) 168