1 | #!/usr/bin/env python3
|
---|
2 | # SPDX-License-Identifier: MIT
|
---|
3 |
|
---|
4 | # Copyright © 2021 Intel Corporation
|
---|
5 |
|
---|
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
7 | # of this software and associated documentation files (the "Software"), to deal
|
---|
8 | # in the Software without restriction, including without limitation the rights
|
---|
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
10 | # copies of the Software, and to permit persons to whom the Software is
|
---|
11 | # furnished to do so, subject to the following conditions:
|
---|
12 |
|
---|
13 | # The above copyright notice and this permission notice shall be included in
|
---|
14 | # all copies or substantial portions of the Software.
|
---|
15 |
|
---|
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
---|
22 | # SOFTWARE.
|
---|
23 |
|
---|
24 | from __future__ import annotations
|
---|
25 | from unittest import mock
|
---|
26 | import argparse
|
---|
27 | import csv
|
---|
28 | import contextlib
|
---|
29 | import datetime
|
---|
30 | import tempfile
|
---|
31 | import os
|
---|
32 | import pathlib
|
---|
33 | import typing
|
---|
34 |
|
---|
35 | import pytest
|
---|
36 |
|
---|
37 | from . import gen_calendar_entries
|
---|
38 |
|
---|
39 |
|
---|
40 | @contextlib.contextmanager
|
---|
41 | def mock_csv(data: typing.List[gen_calendar_entries.CalendarRowType]) -> typing.Iterator[None]:
|
---|
42 | """Replace the actual CSV data with our test data."""
|
---|
43 | with tempfile.TemporaryDirectory() as d:
|
---|
44 | c = os.path.join(d, 'calendar.csv')
|
---|
45 | with open(c, 'w') as f:
|
---|
46 | writer = csv.writer(f)
|
---|
47 | writer.writerows(data)
|
---|
48 |
|
---|
49 | with mock.patch('bin.gen_calendar_entries.CALENDAR_CSV', pathlib.Path(c)):
|
---|
50 | yield
|
---|
51 |
|
---|
52 |
|
---|
53 | @pytest.fixture(autouse=True, scope='module')
|
---|
54 | def disable_git_commits() -> None:
|
---|
55 | """Mock out the commit function so no git commits are made during testing."""
|
---|
56 | with mock.patch('bin.gen_calendar_entries.commit', mock.Mock()):
|
---|
57 | yield
|
---|
58 |
|
---|
59 |
|
---|
60 | class TestReleaseStart:
|
---|
61 |
|
---|
62 | def test_first_is_wednesday(self) -> None:
|
---|
63 | d = gen_calendar_entries._calculate_release_start('20', '0')
|
---|
64 | assert d.day == 15
|
---|
65 | assert d.month == 1
|
---|
66 | assert d.year == 2020
|
---|
67 |
|
---|
68 | def test_first_is_before_wednesday(self) -> None:
|
---|
69 | d = gen_calendar_entries._calculate_release_start('19', '0')
|
---|
70 | assert d.day == 16
|
---|
71 | assert d.month == 1
|
---|
72 | assert d.year == 2019
|
---|
73 |
|
---|
74 | def test_first_is_after_wednesday(self) -> None:
|
---|
75 | d = gen_calendar_entries._calculate_release_start('21', '0')
|
---|
76 | assert d.day == 13
|
---|
77 | assert d.month == 1
|
---|
78 | assert d.year == 2021
|
---|
79 |
|
---|
80 |
|
---|
81 | class TestNextReleaseDate:
|
---|
82 |
|
---|
83 | @contextlib.contextmanager
|
---|
84 | def _patch_date(date: datetime.date) -> typing.Iterator[None]:
|
---|
85 | mdate = mock.Mock()
|
---|
86 | mdate.today = mock.Mock(return_value=date)
|
---|
87 | with mock.patch('bin.gen_calendar_entries.datetime.date', mdate):
|
---|
88 | yield
|
---|
89 |
|
---|
90 | class TestIsWeds:
|
---|
91 |
|
---|
92 | @pytest.fixture(scope='class', autouse=True)
|
---|
93 | def data(self) -> None:
|
---|
94 | date = datetime.date(2021, 1, 6)
|
---|
95 | with TestNextReleaseDate._patch_date(date):
|
---|
96 | yield
|
---|
97 |
|
---|
98 | @pytest.mark.parametrize(
|
---|
99 | 'is_zero, expected',
|
---|
100 | [
|
---|
101 | (True, 13),
|
---|
102 | (False, 20),
|
---|
103 | ],
|
---|
104 | )
|
---|
105 | def test(self, is_zero: bool, expected: int) -> None:
|
---|
106 | date = gen_calendar_entries._calculate_next_release_date(is_zero)
|
---|
107 | assert date.day == expected
|
---|
108 |
|
---|
109 | class TestBeforeWeds:
|
---|
110 |
|
---|
111 | @pytest.fixture(scope='class', autouse=True)
|
---|
112 | def data(self) -> None:
|
---|
113 | date = datetime.date(2021, 1, 5)
|
---|
114 | with TestNextReleaseDate._patch_date(date):
|
---|
115 | yield
|
---|
116 |
|
---|
117 | @pytest.mark.parametrize(
|
---|
118 | 'is_zero, expected',
|
---|
119 | [
|
---|
120 | (True, 13),
|
---|
121 | (False, 20),
|
---|
122 | ],
|
---|
123 | )
|
---|
124 | def test(self, is_zero: bool, expected: int) -> None:
|
---|
125 | date = gen_calendar_entries._calculate_next_release_date(is_zero)
|
---|
126 | assert date.day == expected
|
---|
127 |
|
---|
128 | class TestAfterWeds:
|
---|
129 |
|
---|
130 | @pytest.fixture(scope='class', autouse=True)
|
---|
131 | def data(self) -> None:
|
---|
132 | date = datetime.date(2021, 1, 8)
|
---|
133 | with TestNextReleaseDate._patch_date(date):
|
---|
134 | yield
|
---|
135 |
|
---|
136 | @pytest.mark.parametrize(
|
---|
137 | 'is_zero, expected',
|
---|
138 | [
|
---|
139 | (True, 13),
|
---|
140 | (False, 20),
|
---|
141 | ],
|
---|
142 | )
|
---|
143 | def test(self, is_zero: bool, expected: int) -> None:
|
---|
144 | date = gen_calendar_entries._calculate_next_release_date(is_zero)
|
---|
145 | assert date.day == expected
|
---|
146 |
|
---|
147 |
|
---|
148 | class TestRC:
|
---|
149 |
|
---|
150 | ORIGINAL_DATA = [
|
---|
151 | ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''),
|
---|
152 | ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'Last planned release of the 20.3.x series'),
|
---|
153 | ]
|
---|
154 |
|
---|
155 | @pytest.fixture(autouse=True, scope='class')
|
---|
156 | def mock_version(self) -> None:
|
---|
157 | """Keep the version set at a specific value."""
|
---|
158 | with tempfile.TemporaryDirectory() as d:
|
---|
159 | v = os.path.join(d, 'version')
|
---|
160 | with open(v, 'w') as f:
|
---|
161 | f.write('21.0.0-devel\n')
|
---|
162 |
|
---|
163 | with mock.patch('bin.gen_calendar_entries.VERSION', pathlib.Path(v)):
|
---|
164 | yield
|
---|
165 |
|
---|
166 | @pytest.fixture(autouse=True)
|
---|
167 | def csv(self) -> None:
|
---|
168 | """inject our test data.."""
|
---|
169 | with mock_csv(self.ORIGINAL_DATA):
|
---|
170 | yield
|
---|
171 |
|
---|
172 | def test_basic(self) -> None:
|
---|
173 | args: gen_calendar_entries.RCArguments = argparse.Namespace()
|
---|
174 | args.manager = "Dylan Baker"
|
---|
175 | gen_calendar_entries.release_candidate(args)
|
---|
176 |
|
---|
177 | expected = self.ORIGINAL_DATA.copy()
|
---|
178 | expected.append(('21.0', '2021-01-13', f'21.0.0-rc1', 'Dylan Baker'))
|
---|
179 | expected.append(( '', '2021-01-20', f'21.0.0-rc2', 'Dylan Baker'))
|
---|
180 | expected.append(( '', '2021-01-27', f'21.0.0-rc3', 'Dylan Baker'))
|
---|
181 | expected.append(( '', '2021-02-03', f'21.0.0-rc4', 'Dylan Baker', 'Or 21.0.0 final.'))
|
---|
182 |
|
---|
183 | actual = gen_calendar_entries.read_calendar()
|
---|
184 |
|
---|
185 | assert actual == expected
|
---|
186 |
|
---|
187 |
|
---|
188 | class TestExtend:
|
---|
189 |
|
---|
190 | def test_one_release(self) -> None:
|
---|
191 | data = [
|
---|
192 | ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''),
|
---|
193 | ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'),
|
---|
194 | ]
|
---|
195 |
|
---|
196 | args: gen_calendar_entries.ExtendArguments = argparse.Namespace()
|
---|
197 | args.series = '20.3'
|
---|
198 | args.count = 2
|
---|
199 |
|
---|
200 | with mock_csv(data):
|
---|
201 | gen_calendar_entries.extend(args)
|
---|
202 | actual = gen_calendar_entries.read_calendar()
|
---|
203 |
|
---|
204 | expected = [
|
---|
205 | data[0],
|
---|
206 | ('', '2021-01-27', '20.3.4', 'Dylan Baker', ''),
|
---|
207 | ('', '2021-02-10', '20.3.5', 'Dylan Baker', ''),
|
---|
208 | ('', '2021-02-24', '20.3.6', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'),
|
---|
209 | ]
|
---|
210 |
|
---|
211 | assert actual == expected
|
---|
212 | def test_one_release(self) -> None:
|
---|
213 | data = [
|
---|
214 | ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''),
|
---|
215 | ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'),
|
---|
216 | ('21.0', '2021-01-13', '21.0.1', 'Dylan Baker', ''),
|
---|
217 | ('', '2021-01-27', '21.0.2', 'Dylan Baker', ''),
|
---|
218 | ('', '2021-02-10', '21.0.3', 'Dylan Baker', ''),
|
---|
219 | ('', '2021-02-24', '21.0.4', 'Dylan Baker', 'This is the last planned release of the 21.0.x series.'),
|
---|
220 | ]
|
---|
221 |
|
---|
222 | args: gen_calendar_entries.ExtendArguments = argparse.Namespace()
|
---|
223 | args.series = '21.0'
|
---|
224 | args.count = 1
|
---|
225 |
|
---|
226 | with mock_csv(data):
|
---|
227 | gen_calendar_entries.extend(args)
|
---|
228 | actual = gen_calendar_entries.read_calendar()
|
---|
229 |
|
---|
230 | expected = data.copy()
|
---|
231 | d = list(data[-1])
|
---|
232 | d[-1] = ''
|
---|
233 | expected[-1] = tuple(d)
|
---|
234 | expected.extend([
|
---|
235 | ('', '2021-03-10', '21.0.5', 'Dylan Baker', 'This is the last planned release of the 21.0.x series.'),
|
---|
236 | ])
|
---|
237 |
|
---|
238 | assert actual == expected
|
---|
239 |
|
---|
240 | def test_rc(self) -> None:
|
---|
241 | data = [
|
---|
242 | ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''),
|
---|
243 | ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'This is the last planned release of the 20.3.x series.'),
|
---|
244 | ('21.0', '2021-01-13', '21.0.0-rc1', 'Dylan Baker', ''),
|
---|
245 | ('', '2021-01-20', '21.0.0-rc2', 'Dylan Baker', gen_calendar_entries.OR_FINAL.format('21.0')),
|
---|
246 | ]
|
---|
247 |
|
---|
248 | args: gen_calendar_entries.ExtendArguments = argparse.Namespace()
|
---|
249 | args.series = '21.0'
|
---|
250 | args.count = 2
|
---|
251 |
|
---|
252 | with mock_csv(data):
|
---|
253 | gen_calendar_entries.extend(args)
|
---|
254 | actual = gen_calendar_entries.read_calendar()
|
---|
255 |
|
---|
256 | expected = data.copy()
|
---|
257 | d = list(expected[-1])
|
---|
258 | d[-1] = ''
|
---|
259 | expected[-1] = tuple(d)
|
---|
260 | expected.extend([
|
---|
261 | ('', '2021-01-27', '21.0.0-rc3', 'Dylan Baker', ''),
|
---|
262 | ('', '2021-02-03', '21.0.0-rc4', 'Dylan Baker', gen_calendar_entries.OR_FINAL.format('21.0')),
|
---|
263 | ])
|
---|
264 |
|
---|
265 | assert actual == expected
|
---|
266 |
|
---|
267 |
|
---|
268 | class TestFinal:
|
---|
269 |
|
---|
270 | @pytest.fixture(autouse=True, scope='class')
|
---|
271 | def _patch_date(self) -> typing.Iterator[None]:
|
---|
272 | mdate = mock.Mock()
|
---|
273 | mdate.today = mock.Mock(return_value=datetime.date(2021, 1, 6))
|
---|
274 | with mock.patch('bin.gen_calendar_entries.datetime.date', mdate):
|
---|
275 | yield
|
---|
276 |
|
---|
277 | ORIGINAL_DATA = [
|
---|
278 | ('20.3', '2021-01-13', '20.3.3', 'Dylan Baker', ''),
|
---|
279 | ('', '2021-01-27', '20.3.4', 'Dylan Baker', 'Last planned release of the 20.3.x series'),
|
---|
280 | ]
|
---|
281 |
|
---|
282 | @pytest.fixture(autouse=True)
|
---|
283 | def csv(self) -> None:
|
---|
284 | """inject our test data.."""
|
---|
285 | with mock_csv(self.ORIGINAL_DATA):
|
---|
286 | yield
|
---|
287 |
|
---|
288 | def test_zero_released(self) -> None:
|
---|
289 | args: gen_calendar_entries.FinalArguments = argparse.Namespace()
|
---|
290 | args.manager = "Dylan Baker"
|
---|
291 | args.zero_released = True
|
---|
292 | args.series = '21.0'
|
---|
293 | gen_calendar_entries.final_release(args)
|
---|
294 |
|
---|
295 | expected = self.ORIGINAL_DATA.copy()
|
---|
296 | expected.append(('21.0', '2021-01-20', f'21.0.1', 'Dylan Baker'))
|
---|
297 | expected.append(( '', '2021-02-03', f'21.0.2', 'Dylan Baker'))
|
---|
298 | expected.append(( '', '2021-02-17', f'21.0.3', 'Dylan Baker', gen_calendar_entries.LAST_RELEASE.format(args.series)))
|
---|
299 |
|
---|
300 | actual = gen_calendar_entries.read_calendar()
|
---|
301 |
|
---|
302 | assert actual == expected
|
---|
303 |
|
---|
304 | def test_zero_not_released(self) -> None:
|
---|
305 | args: gen_calendar_entries.FinalArguments = argparse.Namespace()
|
---|
306 | args.manager = "Dylan Baker"
|
---|
307 | args.zero_released = False
|
---|
308 | args.series = '21.0'
|
---|
309 | gen_calendar_entries.final_release(args)
|
---|
310 |
|
---|
311 | expected = self.ORIGINAL_DATA.copy()
|
---|
312 | expected.append(('21.0', '2021-01-13', f'21.0.0', 'Dylan Baker'))
|
---|
313 | expected.append(( '', '2021-01-27', f'21.0.1', 'Dylan Baker'))
|
---|
314 | expected.append(( '', '2021-02-10', f'21.0.2', 'Dylan Baker'))
|
---|
315 | expected.append(( '', '2021-02-24', f'21.0.3', 'Dylan Baker', gen_calendar_entries.LAST_RELEASE.format(args.series)))
|
---|
316 |
|
---|
317 | actual = gen_calendar_entries.read_calendar()
|
---|
318 |
|
---|
319 | assert actual == expected
|
---|