#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2020 The Chromium OS 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 rust_watch.py.""" import logging import pathlib import subprocess import time import unittest import unittest.mock from cros_utils import tiny_render import rust_watch class Test(unittest.TestCase): """Tests.""" def _silence_logs(self): """Silences all log output until the end of the current test.""" def should_log(_record): return 0 logger = logging.root logger.addFilter(should_log) self.addCleanup(logger.removeFilter, should_log) def test_release_version_parsing(self): self.assertEqual( rust_watch.RustReleaseVersion.from_string('1.2.3'), rust_watch.RustReleaseVersion(1, 2, 3), ) def test_release_version_json_round_trips(self): ver = rust_watch.RustReleaseVersion(1, 2, 3) self.assertEqual(rust_watch.RustReleaseVersion.from_json(ver.to_json()), ver) def test_state_json_round_trips(self): state = rust_watch.State( last_seen_release=rust_watch.RustReleaseVersion(1, 2, 3), last_gentoo_sha='abc123', ) self.assertEqual(rust_watch.State.from_json(state.to_json()), state) @unittest.mock.patch.object(subprocess, 'run') @unittest.mock.patch.object(time, 'sleep') def test_update_git_repo_tries_again_on_failure(self, sleep_mock, run_mock): self._silence_logs() oh_no_error = ValueError('oh no') def check_returncode(): raise oh_no_error run_call_count = 0 def run_sideeffect(*_args, **_kwargs): nonlocal run_call_count run_call_count += 1 result = unittest.mock.Mock() result.returncode = 1 result.check_returncode = check_returncode return result run_mock.side_effect = run_sideeffect with self.assertRaises(ValueError) as raised: rust_watch.update_git_repo(pathlib.Path('/does/not/exist/at/all')) self.assertIs(raised.exception, oh_no_error) self.assertEqual(run_call_count, 5) sleep_timings = [unittest.mock.call(60 * i) for i in range(1, 5)] self.assertEqual(sleep_mock.mock_calls, sleep_timings) @unittest.mock.patch.object(subprocess, 'run') def test_get_new_gentoo_commits_functions(self, run_mock): returned = unittest.mock.Mock() returned.returncode = 0 returned.stdout = '\n'.join(( 'abc123 newer commit', 'abcdef and an older commit', )) run_mock.return_value = returned results = rust_watch.get_new_gentoo_commits( pathlib.Path('/does/not/exist/at/all'), 'defabc') self.assertEqual(results, [ rust_watch.GitCommit('abcdef', 'and an older commit'), rust_watch.GitCommit('abc123', 'newer commit'), ]) def test_compose_email_on_a_new_gentoo_commit(self): sha_a = 'a' * 40 new_commit = rust_watch.maybe_compose_email(new_gentoo_commits=[ rust_watch.GitCommit( sha=sha_a, subject='summary_a', ), ], ) self.assertEqual(new_commit, ('[rust-watch] new rust ebuild commit detected', [ 'commit:', tiny_render.UnorderedList([ [ tiny_render.Link( rust_watch.gentoo_sha_to_link(sha_a), sha_a[:12], ), ': summary_a', ], ]) ])) def test_compose_email_composes_nothing_when_no_new_updates_exist(self): self.assertIsNone(rust_watch.maybe_compose_email(new_gentoo_commits=())) def test_compose_bug_creates_bugs_on_new_versions(self): title, body = rust_watch.maybe_compose_bug( old_state=rust_watch.State( last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0), last_gentoo_sha='', ), newest_release=rust_watch.RustReleaseVersion(1, 0, 1), ) self.assertEqual(title, '[Rust] Update to 1.0.1') self.assertTrue(body.startswith('A new release has been detected;')) title, body = rust_watch.maybe_compose_bug( old_state=rust_watch.State( last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0), last_gentoo_sha='', ), newest_release=rust_watch.RustReleaseVersion(1, 1, 0), ) self.assertEqual(title, '[Rust] Update to 1.1.0') self.assertTrue(body.startswith('A new release has been detected;')) title, body = rust_watch.maybe_compose_bug( old_state=rust_watch.State( last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0), last_gentoo_sha='', ), newest_release=rust_watch.RustReleaseVersion(2, 0, 0), ) self.assertEqual(title, '[Rust] Update to 2.0.0') self.assertTrue(body.startswith('A new release has been detected;')) def test_compose_bug_does_nothing_when_no_new_updates_exist(self): self.assertIsNone( rust_watch.maybe_compose_bug( old_state=rust_watch.State( last_seen_release=rust_watch.RustReleaseVersion(1, 0, 0), last_gentoo_sha='', ), newest_release=rust_watch.RustReleaseVersion(1, 0, 0), )) if __name__ == '__main__': unittest.main()