| #!/usr/bin/env python3 |
| # SPDX-License-Identifier: MIT |
| |
| # Copyright © 2021 Intel Corporation |
| |
| # Permission is hereby granted, free of charge, to any person obtaining a copy |
| # of this software and associated documentation files (the "Software"), to deal |
| # in the Software without restriction, including without limitation the rights |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| # copies of the Software, and to permit persons to whom the Software is |
| # furnished to do so, subject to the following conditions: |
| |
| # The above copyright notice and this permission notice shall be included in |
| # all copies or substantial portions of the Software. |
| |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| # SOFTWARE. |
| |
| from __future__ import annotations |
| from unittest import mock |
| import argparse |
| import csv |
| import contextlib |
| import datetime |
| import tempfile |
| import os |
| import pathlib |
| import typing |
| |
| import pytest |
| |
| from . import gen_calendar_entries |
| |
| |
| @contextlib.contextmanager |
| def mock_csv(data: typing.List[gen_calendar_entries.CalendarRowType]) -> typing.Iterator[None]: |
| """Replace the actual CSV data with our test data.""" |
| with tempfile.TemporaryDirectory() as d: |
| c = os.path.join(d, 'calendar.csv') |
| with open(c, 'w') as f: |
| writer = csv.writer(f) |
| writer.writerows(data) |
| |
| with mock.patch('bin.gen_calendar_entries.CALENDAR_CSV', pathlib.Path(c)): |
| yield |
| |
| |
| @pytest.fixture(autouse=True, scope='module') |
| def disable_git_commits() -> None: |
| """Mock out the commit function so no git commits are made durring testing.""" |
| with mock.patch('bin.gen_calendar_entries.commit', mock.Mock()): |
| yield |
| |
| |
| class TestReleaseStart: |
| |
| def test_first_is_wednesday(self) -> None: |
| d = gen_calendar_entries._calculate_release_start('20', '0') |
| assert d.day == 15 |
| assert d.month == 1 |
| assert d.year == 2020 |
| |
| def test_first_is_before_wednesday(self) -> None: |
| d = gen_calendar_entries._calculate_release_start('19', '0') |
| assert d.day == 16 |
| assert d.month == 1 |
| assert d.year == 2019 |
| |
| def test_first_is_after_wednesday(self) -> None: |
| d = gen_calendar_entries._calculate_release_start('21', '0') |
| assert d.day == 13 |
| assert d.month == 1 |
| assert d.year == 2021 |
| |
| |
| class TestNextReleaseDate: |
| |
| @contextlib.contextmanager |
| def _patch_date(date: datetime.date) -> typing.Iterator[None]: |
| mdate = mock.Mock() |
| mdate.today = mock.Mock(return_value=date) |
| with mock.patch('bin.gen_calendar_entries.datetime.date', mdate): |
| yield |
| |
| class TestIsWeds: |
| |
| @pytest.fixture(scope='class', autouse=True) |
| def data(self) -> None: |
| date = datetime.date(2021, 1, 6) |
| with TestNextReleaseDate._patch_date(date): |
| yield |
| |
| @pytest.mark.parametrize( |
| 'is_zero, expected', |
| [ |
| (True, 13), |
| (False, 20), |
| ], |
| ) |
| def test(self, is_zero: bool, expected: int) -> None: |
| date = gen_calendar_entries._calculate_next_release_date(is_zero) |
| assert date.day == expected |
| |
| class TestBeforeWeds: |
| |
| @pytest.fixture(scope='class', autouse=True) |
| def data(self) -> None: |
| date = datetime.date(2021, 1, 5) |
| with TestNextReleaseDate._patch_date(date): |
| yield |
| |
| @pytest.mark.parametrize( |
| 'is_zero, expected', |
| [ |
| (True, 13), |
| (False, 20), |
| ], |
| ) |
| def test(self, is_zero: bool, expected: int) -> None: |
| date = gen_calendar_entries._calculate_next_release_date(is_zero) |
| assert date.day == expected |
| |
| class TestAfterWeds: |
| |
| @pytest.fixture(scope='class', autouse=True) |
| def data(self) -> None: |
| date = datetime.date(2021, 1, 8) |
| with TestNextReleaseDate._patch_date(date): |
| yield |
| |
| @pytest.mark.parametrize( |
| 'is_zero, expected', |
| [ |
| (True, 13), |
| (False, 20), |
| ], |
| ) |
| def test(self, is_zero: bool, expected: int) -> None: |
| date = gen_calendar_entries._calculate_next_release_date(is_zero) |
| assert date.day == expected |
| |
| |
| class TestRC: |
| |
| ORIGINAL_DATA = [ |
| ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), |
| ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'Last planned release of the 20.3.x series'), |
| ] |
| |
| @pytest.fixture(autouse=True, scope='class') |
| def mock_version(self) -> None: |
| """Keep the version set at a specific value.""" |
| with tempfile.TemporaryDirectory() as d: |
| v = os.path.join(d, 'version') |
| with open(v, 'w') as f: |
| f.write('21.0.0-devel\n') |
| |
| with mock.patch('bin.gen_calendar_entries.VERSION', pathlib.Path(v)): |
| yield |
| |
| @pytest.fixture(autouse=True) |
| def csv(self) -> None: |
| """inject our test data..""" |
| with mock_csv(self.ORIGINAL_DATA): |
| yield |
| |
| def test_basic(self) -> None: |
| args: gen_calendar_entries.RCArguments = argparse.Namespace() |
| args.manager = "Dylan Baker" |
| gen_calendar_entries.release_candidate(args) |
| |
| expected = self.ORIGINAL_DATA.copy() |
| expected.append(('21.0', '2021-01-13', f'21.0.0-rc1', 'Dylan Baker')) |
| expected.append(( '', '2021-01-20', f'21.0.0-rc2', 'Dylan Baker')) |
| expected.append(( '', '2021-01-27', f'21.0.0-rc3', 'Dylan Baker')) |
| expected.append(( '', '2021-02-03', f'21.0.0-rc4', 'Dylan Baker', 'Or 21.0.0 final.')) |
| |
| actual = gen_calendar_entries.read_calendar() |
| |
| assert actual == expected |
| |
| |
| class TestExtend: |
| |
| def test_one_release(self) -> None: |
| data = [ |
| ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), |
| ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), |
| ] |
| |
| args: gen_calendar_entries.ExtendArguments = argparse.Namespace() |
| args.series = '20.3' |
| args.count = 2 |
| |
| with mock_csv(data): |
| gen_calendar_entries.extend(args) |
| actual = gen_calendar_entries.read_calendar() |
| |
| expected = [ |
| data[0], |
| ('', '2021-01-27', '20.3.4', 'Dylan Baker', ''), |
| ('', '2021-02-10', '20.3.5', 'Dylan Baker', ''), |
| ('', '2021-02-24', '20.3.6', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), |
| ] |
| |
| assert actual == expected |
| def test_one_release(self) -> None: |
| data = [ |
| ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), |
| ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), |
| ('21.0', '2021-01-13', '21.0.1', 'Dylan Baker', ''), |
| ('', '2021-01-27', '21.0.2', 'Dylan Baker', ''), |
| ('', '2021-02-10', '21.0.3', 'Dylan Baker', ''), |
| ('', '2021-02-24', '21.0.4', 'Dylan Baker', 'This is the last planned release of the 21.0.x series.'), |
| ] |
| |
| args: gen_calendar_entries.ExtendArguments = argparse.Namespace() |
| args.series = '21.0' |
| args.count = 1 |
| |
| with mock_csv(data): |
| gen_calendar_entries.extend(args) |
| actual = gen_calendar_entries.read_calendar() |
| |
| expected = data.copy() |
| d = list(data[-1]) |
| d[-1] = '' |
| expected[-1] = tuple(d) |
| expected.extend([ |
| ('', '2021-03-10', '21.0.5', 'Dylan Baker', 'This is the last planned release of the 21.0.x series.'), |
| ]) |
| |
| assert actual == expected |
| |
| def test_rc(self) -> None: |
| data = [ |
| ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), |
| ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'), |
| ('21.0', '2021-01-13', '21.0.0-rc1', 'Dylan Baker', ''), |
| ('', '2021-01-20', '21.0.0-rc2', 'Dylan Baker', gen_calendar_entries.OR_FINAL.format('21.0')), |
| ] |
| |
| args: gen_calendar_entries.ExtendArguments = argparse.Namespace() |
| args.series = '21.0' |
| args.count = 2 |
| |
| with mock_csv(data): |
| gen_calendar_entries.extend(args) |
| actual = gen_calendar_entries.read_calendar() |
| |
| expected = data.copy() |
| d = list(expected[-1]) |
| d[-1] = '' |
| expected[-1] = tuple(d) |
| expected.extend([ |
| ('', '2021-01-27', '21.0.0-rc3', 'Dylan Baker', ''), |
| ('', '2021-02-03', '21.0.0-rc4', 'Dylan Baker', gen_calendar_entries.OR_FINAL.format('21.0')), |
| ]) |
| |
| assert actual == expected |
| |
| |
| class TestFinal: |
| |
| @pytest.fixture(autouse=True, scope='class') |
| def _patch_date(self) -> typing.Iterator[None]: |
| mdate = mock.Mock() |
| mdate.today = mock.Mock(return_value=datetime.date(2021, 1, 6)) |
| with mock.patch('bin.gen_calendar_entries.datetime.date', mdate): |
| yield |
| |
| ORIGINAL_DATA = [ |
| ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''), |
| ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'Last planned release of the 20.3.x series'), |
| ] |
| |
| @pytest.fixture(autouse=True) |
| def csv(self) -> None: |
| """inject our test data..""" |
| with mock_csv(self.ORIGINAL_DATA): |
| yield |
| |
| def test_zero_released(self) -> None: |
| args: gen_calendar_entries.FinalArguments = argparse.Namespace() |
| args.manager = "Dylan Baker" |
| args.zero_released = True |
| args.series = '21.0' |
| gen_calendar_entries.final_release(args) |
| |
| expected = self.ORIGINAL_DATA.copy() |
| expected.append(('21.0', '2021-01-20', f'21.0.1', 'Dylan Baker')) |
| expected.append(( '', '2021-02-03', f'21.0.2', 'Dylan Baker')) |
| expected.append(( '', '2021-02-17', f'21.0.3', 'Dylan Baker', gen_calendar_entries.LAST_RELEASE.format(args.series))) |
| |
| actual = gen_calendar_entries.read_calendar() |
| |
| assert actual == expected |
| |
| def test_zero_not_released(self) -> None: |
| args: gen_calendar_entries.FinalArguments = argparse.Namespace() |
| args.manager = "Dylan Baker" |
| args.zero_released = False |
| args.series = '21.0' |
| gen_calendar_entries.final_release(args) |
| |
| expected = self.ORIGINAL_DATA.copy() |
| expected.append(('21.0', '2021-01-13', f'21.0.0', 'Dylan Baker')) |
| expected.append(( '', '2021-01-27', f'21.0.1', 'Dylan Baker')) |
| expected.append(( '', '2021-02-10', f'21.0.2', 'Dylan Baker')) |
| expected.append(( '', '2021-02-24', f'21.0.3', 'Dylan Baker', gen_calendar_entries.LAST_RELEASE.format(args.series))) |
| |
| actual = gen_calendar_entries.read_calendar() |
| |
| assert actual == expected |