| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # Copyright 2020 The ChromiumOS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Tests for nightly_revert_checker.""" |
| |
| from __future__ import print_function |
| |
| import io |
| import unittest |
| from unittest.mock import patch |
| |
| import cros_utils.tiny_render as tiny_render |
| import get_upstream_patch |
| import nightly_revert_checker |
| import revert_checker |
| |
| # pylint: disable=protected-access |
| |
| |
| class Test(unittest.TestCase): |
| """Tests for nightly_revert_checker.""" |
| |
| def test_email_rendering_works_for_singular_revert(self): |
| def prettify_sha(sha: str) -> tiny_render.Piece: |
| return 'pretty_' + sha |
| |
| def get_sha_description(sha: str) -> tiny_render.Piece: |
| return 'subject_' + sha |
| |
| email = nightly_revert_checker._generate_revert_email( |
| repository_name='${repo}', |
| friendly_name='${name}', |
| sha='${sha}', |
| prettify_sha=prettify_sha, |
| get_sha_description=get_sha_description, |
| new_reverts=[ |
| revert_checker.Revert(sha='${revert_sha}', |
| reverted_sha='${reverted_sha}') |
| ]) |
| |
| expected_email = nightly_revert_checker._Email( |
| subject='[revert-checker/${repo}] new revert discovered across ${name}', |
| body=[ |
| 'It looks like there may be a new revert across ${name} (', |
| 'pretty_${sha}', |
| ').', |
| tiny_render.line_break, |
| tiny_render.line_break, |
| 'That is:', |
| tiny_render.UnorderedList([[ |
| 'pretty_${revert_sha}', |
| ' (appears to revert ', |
| 'pretty_${reverted_sha}', |
| '): ', |
| 'subject_${revert_sha}', |
| ]]), |
| tiny_render.line_break, |
| 'PTAL and consider reverting them locally.', |
| ]) |
| |
| self.assertEqual(email, expected_email) |
| |
| def test_email_rendering_works_for_multiple_reverts(self): |
| def prettify_sha(sha: str) -> tiny_render.Piece: |
| return 'pretty_' + sha |
| |
| def get_sha_description(sha: str) -> tiny_render.Piece: |
| return 'subject_' + sha |
| |
| email = nightly_revert_checker._generate_revert_email( |
| repository_name='${repo}', |
| friendly_name='${name}', |
| sha='${sha}', |
| prettify_sha=prettify_sha, |
| get_sha_description=get_sha_description, |
| new_reverts=[ |
| revert_checker.Revert(sha='${revert_sha1}', |
| reverted_sha='${reverted_sha1}'), |
| revert_checker.Revert(sha='${revert_sha2}', |
| reverted_sha='${reverted_sha2}'), |
| # Keep this out-of-order to check that we sort based on SHAs |
| revert_checker.Revert(sha='${revert_sha0}', |
| reverted_sha='${reverted_sha0}'), |
| ]) |
| |
| expected_email = nightly_revert_checker._Email( |
| subject='[revert-checker/${repo}] new reverts discovered across ' |
| '${name}', |
| body=[ |
| 'It looks like there may be new reverts across ${name} (', |
| 'pretty_${sha}', |
| ').', |
| tiny_render.line_break, |
| tiny_render.line_break, |
| 'These are:', |
| tiny_render.UnorderedList([ |
| [ |
| 'pretty_${revert_sha0}', |
| ' (appears to revert ', |
| 'pretty_${reverted_sha0}', |
| '): ', |
| 'subject_${revert_sha0}', |
| ], |
| [ |
| 'pretty_${revert_sha1}', |
| ' (appears to revert ', |
| 'pretty_${reverted_sha1}', |
| '): ', |
| 'subject_${revert_sha1}', |
| ], |
| [ |
| 'pretty_${revert_sha2}', |
| ' (appears to revert ', |
| 'pretty_${reverted_sha2}', |
| '): ', |
| 'subject_${revert_sha2}', |
| ], |
| ]), |
| tiny_render.line_break, |
| 'PTAL and consider reverting them locally.', |
| ]) |
| |
| self.assertEqual(email, expected_email) |
| |
| def test_llvm_ebuild_parsing_appears_to_function(self): |
| llvm_ebuild = io.StringIO('\n'.join(( |
| 'foo', |
| '#LLVM_HASH="123"', |
| 'LLVM_HASH="123" # comment', |
| 'LLVM_NEXT_HASH="456"', |
| ))) |
| |
| shas = nightly_revert_checker._parse_llvm_ebuild_for_shas(llvm_ebuild) |
| self.assertEqual(shas, [ |
| ('llvm', '123'), |
| ('llvm-next', '456'), |
| ]) |
| |
| def test_llvm_ebuild_parsing_fails_if_both_hashes_arent_present(self): |
| bad_bodies = [ |
| '', |
| 'LLVM_HASH="123" # comment', |
| 'LLVM_NEXT_HASH="123" # comment', |
| 'LLVM_NEXT_HASH="123" # comment\n#LLVM_HASH="123"', |
| ] |
| |
| for bad in bad_bodies: |
| with self.assertRaises(ValueError) as e: |
| nightly_revert_checker._parse_llvm_ebuild_for_shas(io.StringIO(bad)) |
| |
| self.assertIn('Failed to detect SHAs', str(e.exception)) |
| |
| @patch('revert_checker.find_reverts') |
| @patch('get_upstream_patch.get_from_upstream') |
| def test_do_cherrypick_is_called(self, do_cherrypick, find_reverts): |
| find_reverts.return_value = [ |
| revert_checker.Revert('12345abcdef', 'fedcba54321') |
| ] |
| nightly_revert_checker.do_cherrypick(chroot_path='/path/to/chroot', |
| llvm_dir='/path/to/llvm', |
| interesting_shas=[('12345abcdef', |
| 'fedcba54321')], |
| state={}, |
| reviewers=['meow@chromium.org'], |
| cc=['purr@chromium.org']) |
| |
| do_cherrypick.assert_called_once() |
| find_reverts.assert_called_once() |
| |
| @patch('revert_checker.find_reverts') |
| @patch('get_upstream_patch.get_from_upstream') |
| def test_do_cherrypick_handles_cherrypick_error(self, do_cherrypick, |
| find_reverts): |
| find_reverts.return_value = [ |
| revert_checker.Revert('12345abcdef', 'fedcba54321') |
| ] |
| do_cherrypick.side_effect = get_upstream_patch.CherrypickError( |
| 'Patch at 12345abcdef already exists in PATCHES.json') |
| nightly_revert_checker.do_cherrypick(chroot_path='/path/to/chroot', |
| llvm_dir='/path/to/llvm', |
| interesting_shas=[('12345abcdef', |
| 'fedcba54321')], |
| state={}, |
| reviewers=['meow@chromium.org'], |
| cc=['purr@chromium.org']) |
| |
| do_cherrypick.assert_called_once() |
| find_reverts.assert_called_once() |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |