1# 2# This file and its contents are supplied under the terms of the 3# Common Development and Distribution License ("CDDL"), version 1.0. 4# You may only use this file in accordance with the terms of version 5# 1.0 of the CDDL. 6# 7# A full copy of the text of the CDDL should have accompanied this 8# source. A copy of the CDDL is also available via the Internet at 9# http://www.illumos.org/license/CDDL. 10# 11 12# 13# Copyright 2024 Bill Sommerfeld <sommerfeld@hamachi.org> 14# 15 16# 17# Unit test for onbld comment checker 18# 19# To run this as a simple unit test: 20# python3 Comments_test.py 21# 22# To use this to measure coverage: 23# coverage3 erase 24# coverage3 run --branch Comments_test.py 25# coverage3 report -m --include Comments.py 26 27 28import io 29import os 30import sys 31import unittest 32from unittest.mock import patch 33 34sys.path.insert(2, os.path.join(os.path.dirname(__file__), "../..")) 35 36import onbld.Checks.Comments as Comments 37 38class fake_bug_db: 39 40 db = { 41 '10': { 'cr_number': '10', 42 'synopsis': 'this is a bug', 43 'status': 'New' 44 } 45 } 46 47 def lookup(self, buglist): 48 return { bug: self.db[bug] for bug in buglist if bug in self.db } 49 50class comchk_helper_test(unittest.TestCase): 51 52 def test_isBug(self): 53 self.assertTrue(Comments.isBug('10 this is a bug')) 54 self.assertTrue(Comments.isBug('12345 this is a bug')) 55 self.assertFalse(Comments.isBug('this is not a bug (no id)')) 56 self.assertFalse(Comments.isBug('10000000 this is too big to be a bug')) 57 58 def test_changeid_present(self): 59 self.assertTrue(Comments.changeid_present( 60 ['10 this is a bug', 61 '', 62 'Change-Id: Ideadbeef'])) 63 self.assertTrue(Comments.changeid_present( 64 ['10 this is a bug', 65 '20 this is another bug', 66 '', 67 'Change-Id: Ideadbeef'])) 68 69 self.assertFalse(Comments.changeid_present([])) 70 self.assertFalse(Comments.changeid_present(['10 this is a bug'])) 71 self.assertFalse(Comments.changeid_present( 72 ['10 this is a bug', 73 ''])) 74 75 # Not a valid Change-Id 76 self.assertFalse(Comments.changeid_present( 77 ['10 this is a bug', 78 '', 79 'this is not a changeid'])) 80 self.assertFalse(Comments.changeid_present( 81 ['10 this is a bug', 82 '', 83 'Change-Id: this is not a changeid'])) 84 85 # more than one Change-Id 86 self.assertFalse(Comments.changeid_present( 87 ['10 this is a bug', 88 '', 89 'Change-Id: Ideadbeef', 90 'Change-Id: Ifeedface'])) 91 92class comchk_test(unittest.TestCase): 93 94 def setUp(self): 95 self.bugs = {} 96 self.bugdb = fake_bug_db() 97 98 def split_input(self, str): 99 return [ line.strip() for line in str.splitlines() ] 100 101 def expect_pass(self, input, *, check_db=False): 102 103 with patch('onbld.Checks.Comments.BugDB') as mockdb: 104 mockdb.configure_mock(return_value=self.bugdb) 105 106 out = io.StringIO() 107 self.assertEqual(0, Comments.comchk(self.split_input(input), 108 check_db, out, bugs=self.bugs)) 109 self.assertEqual(out.getvalue(), '') 110 111 def expect_fail(self, input, output, *, check_db=False): 112 with patch('onbld.Checks.Comments.BugDB') as mockdb: 113 mockdb.configure_mock(return_value=self.bugdb) 114 115 out = io.StringIO() 116 self.assertEqual(1, Comments.comchk(self.split_input(input), 117 check_db, out, bugs=self.bugs)) 118 self.assertEqual(out.getvalue(), output) 119 120 def test_comchk_newline(self): 121 out = io.StringIO() 122 with self.assertRaises(ValueError): 123 Comments.comchk(['\n'], False, out) 124 125 def test_comchk_basic(self): 126 self.expect_pass('10 this is a bug\n') 127 128 def test_comchk_reviewer(self): 129 self.expect_pass('10 this is a bug\nReviewed by: alice\n') 130 131 def test_comchk_approver(self): 132 self.expect_pass('10 this is a bug\nReviewed by: alice\n' 133 'Approved by: bob\n') 134 135 def test_comchk_changeid(self): 136 self.expect_fail('10 this is a bug\n\nChange-Id: Ideadbeef', 137 'NOTE: Change-Id present in comment\n') 138 139 def test_comchk_fail_spelling(self): 140 141 self.expect_fail('10 this is the the bug\n', 142 'Spellcheck:\ncomment line 1 - ' 143 'contains "the the", a common misspelling of "the"\n') 144 145 def test_comchk_fail_not_bug(self): 146 self.expect_fail('XX this is a bug\n', 147 'These comments are not valid bugs:\n' 148 ' XX this is a bug\n') 149 150 def test_comchk_fail_blank_lines(self): 151 self.expect_fail('10 this is a bug\n\n', 152 'WARNING: Blank line(s) in comments\n') 153 154 def test_comchk_fail_bug_no_space(self): 155 self.expect_fail('10this is a bug\n', 156 'These bugs are missing a single space ' 157 'following the ID:\n' 158 ' 10this is a bug\n') 159 160 def test_comchk_fail_bug_dup(self): 161 self.expect_fail('10 this is a bug\n10 this is another bug\n', 162 'These IDs appear more than once in your comments:\n' 163 ' 10\n') 164 165 def test_comchk_fail_bug_dup_no_space(self): 166 self.expect_fail('10 this is a bug\n10this is another bug\n', 167 'These IDs appear more than once in your comments:\n' 168 ' 10\n' 169 'These bugs are missing a single space ' 170 'following the ID:\n' 171 ' 10this is another bug\n') 172 173 def test_comchk_multi_commit_dup(self): 174 self.expect_pass('10 this is a bug\nReviewed-by: bob') 175 self.expect_fail('10 this is a bug\nReviewed-by: bob', 176 'These IDs appear more than once in your comments:\n' 177 ' 10\n') 178 self.expect_pass('20 this is another bug\nReviewed-by: alice') 179 180 def test_comchk_multi_changeid(self): 181 self.expect_fail('10 this is a bug\n\nChange-Id: Ideadbeef', 182 'NOTE: Change-Id present in comment\n') 183 self.expect_fail('20 this is a another bug\n\nChange-Id: Ifeedface', 184 'NOTE: Change-Id present in comment\n') 185 186 def test_comchk_bugdb_pass(self): 187 self.expect_pass('10 this is a bug\n', check_db=True) 188 189 def test_comchk_bugdb_fail_synopsis(self): 190 self.expect_fail('10 this is the wrong synopsis\n', 191 "These bug synopses don't match " 192 "the database entries:\n" 193 "Synopsis of 10 is wrong:\n" 194 " should be: 'this is a bug'\n" 195 " is: 'this is the wrong synopsis'\n", 196 check_db=True) 197 198 def test_comchk_bugdb_wrong_bugid(self): 199 self.expect_fail('20 this is the wrong bugid\n', 200 'These bugs were not found in the databases:\n' 201 ' 20\n', 202 check_db=True) 203 204 205 206if __name__ == '__main__': 207 unittest.main() 208