Skip to content

Commit 192ee35

Browse files
committed
Add unit tests for commitmessage module
1 parent 6e00db5 commit 192ee35

File tree

3 files changed

+193
-1
lines changed

3 files changed

+193
-1
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ test_specfile:
1313
test_abireport:
1414
PYTHONPATH=`pwd`/autospec python3 tests/test_abireport.py
1515

16+
test_commitmessage:
17+
PYTHONPATH=`pwd`/autospec python3 tests/test_commitmessage.py
18+
1619
test_autospec:
1720
python3 tests/test_autospec.py -c ${CASES}
1821

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[egg_info]
22
tag_build =
3-
[pep8]
3+
[pycodestyle]
44
ignore = E501

tests/test_commitmessage.py

+189
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import unittest
2+
import unittest.mock as mock
3+
import os
4+
import tempfile
5+
import commitmessage
6+
7+
8+
class TestCommitmessage(unittest.TestCase):
9+
10+
def setUp(self):
11+
commitmessage.tarball.name = 'testball'
12+
commitmessage.tarball.version = '0.0.1'
13+
commitmessage.config.old_version = '0.0.0'
14+
15+
def test_is_header(self):
16+
"""
17+
Test is_header function with list of lines. First and last line, line
18+
followed by a line containing '---', and lines after a blank '' line
19+
should be recognized as headers. Last line recognized as header because
20+
it is a relevant ending point.
21+
"""
22+
lines = ['line1', # True
23+
'line2', # False
24+
'', # False
25+
'line4', # True
26+
'line5', # True
27+
'---', # False
28+
'line7', # False
29+
'line8'] # True
30+
for idx, line in enumerate(lines):
31+
print(line, idx)
32+
if idx in [0, 3, 4, 7]:
33+
self.assertTrue(commitmessage.is_header(lines, idx))
34+
else:
35+
self.assertFalse(commitmessage.is_header(lines, idx))
36+
37+
def test_find_in_line(self):
38+
"""
39+
Trivially tests commitmessage.find_in_line(). Just makes sure results
40+
evaluate to the correct bool.
41+
"""
42+
self.assertTrue(commitmessage.find_in_line(r'Version', 'AVersionInThisLine'))
43+
self.assertFalse(commitmessage.find_in_line(r'z', 'the quick brown fox jumps over the lady dog'))
44+
45+
def test_process_NEWS(self):
46+
"""
47+
Test process_NEWS() function with valid newsfile provided
48+
"""
49+
with tempfile.TemporaryDirectory() as tmpd:
50+
commitmessage.build.download_path = tmpd
51+
with open(os.path.join(tmpd, 'NEWS'), 'w') as newsfile:
52+
newsfile.write(GOOD_NEWS)
53+
# commitmessage returned will have an empty string as first and
54+
# last items
55+
expected_msg = [""] + GOOD_NEWS.split('\n')[3:13]
56+
expected_cvs = set()
57+
self.assertEqual(commitmessage.process_NEWS('NEWS'),
58+
(expected_msg, expected_cvs))
59+
60+
def test_process_NEWS_bad_news(self):
61+
"""
62+
Test process_NEWS() function with irrelevant newsfile provided
63+
"""
64+
with tempfile.TemporaryDirectory() as tmpd:
65+
commitmessage.build.download_path = tmpd
66+
with open(os.path.join(tmpd, 'NEWS'), 'w') as newsfile:
67+
# make GOOD_NEWS irrelevant by replacing current version
68+
newsfile.write(GOOD_NEWS.replace('0.0.1', '0.0.0'))
69+
self.assertEqual(commitmessage.process_NEWS('NEWS'), ([], set()))
70+
71+
def test_process_NEWS_good_cves(self):
72+
"""
73+
Test process_NEWS() function with valid newsfile and CVEs
74+
"""
75+
with tempfile.TemporaryDirectory() as tmpd:
76+
commitmessage.build.download_path = tmpd
77+
with open(os.path.join(tmpd, 'NEWS'), 'w') as newsfile:
78+
# give GOOD_NEWS some CVEs
79+
newsfile.write(GOOD_NEWS.replace('change2.1', 'CVE-2-1')
80+
.replace('change2.2', 'CVE-2-2'))
81+
# commitmessage returned will have an empty string as first and
82+
# last items.
83+
# replace change2.* strings with CVE strings
84+
expected_msg = [""] + GOOD_NEWS.replace('change2.1', 'CVE-2-1')\
85+
.replace('change2.2', 'CVE-2-2')\
86+
.split('\n')[3:13]
87+
expected_cvs = set(['CVE-2-1', 'CVE-2-2'])
88+
self.assertEqual(commitmessage.process_NEWS('NEWS'),
89+
(expected_msg, expected_cvs))
90+
91+
def test_process_NEWS_long(self):
92+
"""
93+
Test process_NEWS() function with valid newsfile provided, but relevant
94+
block is longer than 15 lines, causing it to be truncated.
95+
"""
96+
with tempfile.TemporaryDirectory() as tmpd:
97+
commitmessage.build.download_path = tmpd
98+
long_news = GOOD_NEWS.replace('text explaining change2.2',
99+
'1\n2\n3\n4\n5\n6\n7\n8\n9\n')
100+
with open(os.path.join(tmpd, 'NEWS'), 'w') as newsfile:
101+
newsfile.write(long_news)
102+
# commitmessage returned will have an empty string as first and
103+
# last items, extend the expected message with extra lines and
104+
# truncate message.
105+
expected_msg = [""] + GOOD_NEWS.split('\n')[3:11]
106+
expected_msg.extend(['1', '2', '3', '4', '5', '6', '7', '',
107+
'(NEWS truncated at 15 lines)', ''])
108+
expected_cvs = set()
109+
self.assertEqual(commitmessage.process_NEWS('NEWS'),
110+
(expected_msg, expected_cvs))
111+
112+
def test_guess_commit_message(self):
113+
"""
114+
Test guess_commit_message() with mocked internal functions and both
115+
commitmessage information and cves available from newsfile.
116+
"""
117+
process_NEWS_backup = commitmessage.process_NEWS
118+
119+
def mock_process_NEWS(newsfile):
120+
return (['', 'commit', 'message', 'with', 'cves', ''],
121+
set(['cve1', 'cve2']))
122+
123+
commitmessage.process_NEWS = mock_process_NEWS
124+
open_name = 'commitmessage.open'
125+
with mock.patch(open_name, create=True) as mock_open:
126+
mock_open.return_value = mock.MagicMock()
127+
commitmessage.guess_commit_message()
128+
# reset mocks before asserting so a failure doesn't cascade to
129+
# other tests
130+
commitmessage.process_NEWS = process_NEWS_backup
131+
fh = mock_open.return_value.__enter__.return_value
132+
fh.write.assert_called_with(
133+
'testball: Autospec creation for update from version 0.0.0 to '
134+
'version 0.0.1\n\n\ncommit\nmessage\nwith\ncves\n\n\ncommit\n'
135+
'message\nwith\ncves\n\nCVEs fixed in this build:\ncve1\ncve2'
136+
'\n\n')
137+
138+
def test_guess_commit_message_cve_config(self):
139+
"""
140+
Test guess_commit_message() with mocked internal functions and both
141+
commitmessage information and cves available from newsfile. A cve is
142+
also available from config, which changes the first line of the commmit
143+
message.
144+
"""
145+
process_NEWS_backup = commitmessage.process_NEWS
146+
147+
def mock_process_NEWS(newsfile):
148+
return (['', 'commit', 'message', 'with', 'cves', ''],
149+
set(['cve1', 'cve2']))
150+
151+
commitmessage.process_NEWS = mock_process_NEWS
152+
commitmessage.config.cves = set(['CVE-1234-5678'])
153+
commitmessage.config.old_version = None # Allow cve title to be set
154+
open_name = 'commitmessage.open'
155+
with mock.patch(open_name, create=True) as mock_open:
156+
mock_open.return_value = mock.MagicMock()
157+
commitmessage.guess_commit_message()
158+
# reset mocks before asserting so a failure doesn't cascade to
159+
# other tests
160+
commitmessage.process_NEWS = process_NEWS_backup
161+
commitmessage.config.cves = set()
162+
fh = mock_open.return_value.__enter__.return_value
163+
fh.write.assert_called_with(
164+
'testball: Fix for CVE-1234-5678\n\n\ncommit\nmessage\nwith\n'
165+
'cves\n\n\ncommit\nmessage\nwith\ncves\n\nCVEs fixed in this '
166+
'build:\nCVE-1234-5678\ncve1\ncve2\n\n')
167+
168+
169+
GOOD_NEWS = """
170+
GOOD NEWS -- History of user-visible changes.
171+
172+
* Version 0.0.1
173+
174+
change1.1
175+
change1.2
176+
177+
change2.1
178+
text explaining change2.1
179+
change2.2
180+
text explaining change2.2
181+
182+
* Version 0.0.0
183+
184+
This better not show up
185+
"""
186+
187+
188+
if __name__ == '__main__':
189+
unittest.main(buffer=True)

0 commit comments

Comments
 (0)