1*d68f33bcSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*d68f33bcSAndroid Build Coastguard Worker# Copyright 2016 The Android Open Source Project 3*d68f33bcSAndroid Build Coastguard Worker# 4*d68f33bcSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*d68f33bcSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*d68f33bcSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*d68f33bcSAndroid Build Coastguard Worker# 8*d68f33bcSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*d68f33bcSAndroid Build Coastguard Worker# 10*d68f33bcSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*d68f33bcSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*d68f33bcSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d68f33bcSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*d68f33bcSAndroid Build Coastguard Worker# limitations under the License. 15*d68f33bcSAndroid Build Coastguard Worker 16*d68f33bcSAndroid Build Coastguard Worker"""Unittests for the hooks module.""" 17*d68f33bcSAndroid Build Coastguard Worker 18*d68f33bcSAndroid Build Coastguard Workerimport os 19*d68f33bcSAndroid Build Coastguard Workerimport sys 20*d68f33bcSAndroid Build Coastguard Workerimport unittest 21*d68f33bcSAndroid Build Coastguard Workerfrom unittest import mock 22*d68f33bcSAndroid Build Coastguard Worker 23*d68f33bcSAndroid Build Coastguard Worker_path = os.path.realpath(__file__ + '/../..') 24*d68f33bcSAndroid Build Coastguard Workerif sys.path[0] != _path: 25*d68f33bcSAndroid Build Coastguard Worker sys.path.insert(0, _path) 26*d68f33bcSAndroid Build Coastguard Workerdel _path 27*d68f33bcSAndroid Build Coastguard Worker 28*d68f33bcSAndroid Build Coastguard Worker# We have to import our local modules after the sys.path tweak. We can't use 29*d68f33bcSAndroid Build Coastguard Worker# relative imports because this is an executable program, not a module. 30*d68f33bcSAndroid Build Coastguard Worker# pylint: disable=wrong-import-position 31*d68f33bcSAndroid Build Coastguard Workerimport rh 32*d68f33bcSAndroid Build Coastguard Workerimport rh.config 33*d68f33bcSAndroid Build Coastguard Workerimport rh.hooks 34*d68f33bcSAndroid Build Coastguard Worker 35*d68f33bcSAndroid Build Coastguard Worker 36*d68f33bcSAndroid Build Coastguard Worker# pylint: disable=unused-argument 37*d68f33bcSAndroid Build Coastguard Workerdef mock_find_repo_root(path=None, outer=False): 38*d68f33bcSAndroid Build Coastguard Worker return '/ ${BUILD_OS}' if outer else '/ ${BUILD_OS}/sub' 39*d68f33bcSAndroid Build Coastguard Worker 40*d68f33bcSAndroid Build Coastguard Worker 41*d68f33bcSAndroid Build Coastguard Workerclass HooksDocsTests(unittest.TestCase): 42*d68f33bcSAndroid Build Coastguard Worker """Make sure all hook features are documented. 43*d68f33bcSAndroid Build Coastguard Worker 44*d68f33bcSAndroid Build Coastguard Worker Note: These tests are a bit hokey in that they parse README.md. But they 45*d68f33bcSAndroid Build Coastguard Worker get the job done, so that's all that matters right? 46*d68f33bcSAndroid Build Coastguard Worker """ 47*d68f33bcSAndroid Build Coastguard Worker 48*d68f33bcSAndroid Build Coastguard Worker def setUp(self): 49*d68f33bcSAndroid Build Coastguard Worker self.readme = os.path.join(os.path.dirname(os.path.dirname( 50*d68f33bcSAndroid Build Coastguard Worker os.path.realpath(__file__))), 'README.md') 51*d68f33bcSAndroid Build Coastguard Worker 52*d68f33bcSAndroid Build Coastguard Worker def _grab_section(self, section): 53*d68f33bcSAndroid Build Coastguard Worker """Extract the |section| text out of the readme.""" 54*d68f33bcSAndroid Build Coastguard Worker ret = [] 55*d68f33bcSAndroid Build Coastguard Worker in_section = False 56*d68f33bcSAndroid Build Coastguard Worker with open(self.readme, encoding='utf-8') as fp: 57*d68f33bcSAndroid Build Coastguard Worker for line in fp: 58*d68f33bcSAndroid Build Coastguard Worker if not in_section: 59*d68f33bcSAndroid Build Coastguard Worker # Look for the section like "## [Tool Paths]". 60*d68f33bcSAndroid Build Coastguard Worker if (line.startswith('#') and 61*d68f33bcSAndroid Build Coastguard Worker line.lstrip('#').strip() == section): 62*d68f33bcSAndroid Build Coastguard Worker in_section = True 63*d68f33bcSAndroid Build Coastguard Worker else: 64*d68f33bcSAndroid Build Coastguard Worker # Once we hit the next section (higher or lower), break. 65*d68f33bcSAndroid Build Coastguard Worker if line[0] == '#': 66*d68f33bcSAndroid Build Coastguard Worker break 67*d68f33bcSAndroid Build Coastguard Worker ret.append(line) 68*d68f33bcSAndroid Build Coastguard Worker return ''.join(ret) 69*d68f33bcSAndroid Build Coastguard Worker 70*d68f33bcSAndroid Build Coastguard Worker def testBuiltinHooks(self): 71*d68f33bcSAndroid Build Coastguard Worker """Verify builtin hooks are documented.""" 72*d68f33bcSAndroid Build Coastguard Worker data = self._grab_section('[Builtin Hooks]') 73*d68f33bcSAndroid Build Coastguard Worker for hook in rh.hooks.BUILTIN_HOOKS: 74*d68f33bcSAndroid Build Coastguard Worker self.assertIn(f'* `{hook}`:', data, 75*d68f33bcSAndroid Build Coastguard Worker msg=f'README.md missing docs for hook "{hook}"') 76*d68f33bcSAndroid Build Coastguard Worker 77*d68f33bcSAndroid Build Coastguard Worker def testToolPaths(self): 78*d68f33bcSAndroid Build Coastguard Worker """Verify tools are documented.""" 79*d68f33bcSAndroid Build Coastguard Worker data = self._grab_section('[Tool Paths]') 80*d68f33bcSAndroid Build Coastguard Worker for tool in rh.hooks.TOOL_PATHS: 81*d68f33bcSAndroid Build Coastguard Worker self.assertIn(f'* `{tool}`:', data, 82*d68f33bcSAndroid Build Coastguard Worker msg=f'README.md missing docs for tool "{tool}"') 83*d68f33bcSAndroid Build Coastguard Worker 84*d68f33bcSAndroid Build Coastguard Worker def testPlaceholders(self): 85*d68f33bcSAndroid Build Coastguard Worker """Verify placeholder replacement vars are documented.""" 86*d68f33bcSAndroid Build Coastguard Worker data = self._grab_section('Placeholders') 87*d68f33bcSAndroid Build Coastguard Worker for var in rh.hooks.Placeholders.vars(): 88*d68f33bcSAndroid Build Coastguard Worker self.assertIn('* `${' + var + '}`:', data, 89*d68f33bcSAndroid Build Coastguard Worker msg=f'README.md missing docs for var "{var}"') 90*d68f33bcSAndroid Build Coastguard Worker 91*d68f33bcSAndroid Build Coastguard Worker 92*d68f33bcSAndroid Build Coastguard Workerclass PlaceholderTests(unittest.TestCase): 93*d68f33bcSAndroid Build Coastguard Worker """Verify behavior of replacement variables.""" 94*d68f33bcSAndroid Build Coastguard Worker 95*d68f33bcSAndroid Build Coastguard Worker def setUp(self): 96*d68f33bcSAndroid Build Coastguard Worker self._saved_environ = os.environ.copy() 97*d68f33bcSAndroid Build Coastguard Worker os.environ.update({ 98*d68f33bcSAndroid Build Coastguard Worker 'PREUPLOAD_COMMIT_MESSAGE': 'commit message', 99*d68f33bcSAndroid Build Coastguard Worker 'PREUPLOAD_COMMIT': '5c4c293174bb61f0f39035a71acd9084abfa743d', 100*d68f33bcSAndroid Build Coastguard Worker }) 101*d68f33bcSAndroid Build Coastguard Worker self.replacer = rh.hooks.Placeholders( 102*d68f33bcSAndroid Build Coastguard Worker [rh.git.RawDiffEntry(file=x) 103*d68f33bcSAndroid Build Coastguard Worker for x in ['path1/file1', 'path2/file2']]) 104*d68f33bcSAndroid Build Coastguard Worker 105*d68f33bcSAndroid Build Coastguard Worker def tearDown(self): 106*d68f33bcSAndroid Build Coastguard Worker os.environ.clear() 107*d68f33bcSAndroid Build Coastguard Worker os.environ.update(self._saved_environ) 108*d68f33bcSAndroid Build Coastguard Worker 109*d68f33bcSAndroid Build Coastguard Worker def testVars(self): 110*d68f33bcSAndroid Build Coastguard Worker """Light test for the vars inspection generator.""" 111*d68f33bcSAndroid Build Coastguard Worker ret = list(self.replacer.vars()) 112*d68f33bcSAndroid Build Coastguard Worker self.assertGreater(len(ret), 4) 113*d68f33bcSAndroid Build Coastguard Worker self.assertIn('PREUPLOAD_COMMIT', ret) 114*d68f33bcSAndroid Build Coastguard Worker 115*d68f33bcSAndroid Build Coastguard Worker @mock.patch.object(rh.git, 'find_repo_root', 116*d68f33bcSAndroid Build Coastguard Worker side_effect=mock_find_repo_root) 117*d68f33bcSAndroid Build Coastguard Worker def testExpandVars(self, _m): 118*d68f33bcSAndroid Build Coastguard Worker """Verify the replacement actually works.""" 119*d68f33bcSAndroid Build Coastguard Worker input_args = [ 120*d68f33bcSAndroid Build Coastguard Worker # Verify ${REPO_ROOT} is updated, but not REPO_ROOT. 121*d68f33bcSAndroid Build Coastguard Worker # We also make sure that things in ${REPO_ROOT} are not double 122*d68f33bcSAndroid Build Coastguard Worker # expanded (which is why the return includes ${BUILD_OS}). 123*d68f33bcSAndroid Build Coastguard Worker '${REPO_ROOT}/some/prog/REPO_ROOT/ok', 124*d68f33bcSAndroid Build Coastguard Worker # Verify that ${REPO_OUTER_ROOT} is expanded. 125*d68f33bcSAndroid Build Coastguard Worker '${REPO_OUTER_ROOT}/some/prog/REPO_OUTER_ROOT/ok', 126*d68f33bcSAndroid Build Coastguard Worker # Verify lists are merged rather than inserted. 127*d68f33bcSAndroid Build Coastguard Worker '${PREUPLOAD_FILES}', 128*d68f33bcSAndroid Build Coastguard Worker # Verify each file is preceded with '--file=' prefix. 129*d68f33bcSAndroid Build Coastguard Worker '--file=${PREUPLOAD_FILES_PREFIXED}', 130*d68f33bcSAndroid Build Coastguard Worker # Verify each file is preceded with '--file' argument. 131*d68f33bcSAndroid Build Coastguard Worker '--file', 132*d68f33bcSAndroid Build Coastguard Worker '${PREUPLOAD_FILES_PREFIXED}', 133*d68f33bcSAndroid Build Coastguard Worker # Verify values with whitespace don't expand into multiple args. 134*d68f33bcSAndroid Build Coastguard Worker '${PREUPLOAD_COMMIT_MESSAGE}', 135*d68f33bcSAndroid Build Coastguard Worker # Verify multiple values get replaced. 136*d68f33bcSAndroid Build Coastguard Worker '${PREUPLOAD_COMMIT}^${PREUPLOAD_COMMIT_MESSAGE}', 137*d68f33bcSAndroid Build Coastguard Worker # Unknown vars should be left alone. 138*d68f33bcSAndroid Build Coastguard Worker '${THIS_VAR_IS_GOOD}', 139*d68f33bcSAndroid Build Coastguard Worker ] 140*d68f33bcSAndroid Build Coastguard Worker output_args = self.replacer.expand_vars(input_args) 141*d68f33bcSAndroid Build Coastguard Worker exp_args = [ 142*d68f33bcSAndroid Build Coastguard Worker '/ ${BUILD_OS}/sub/some/prog/REPO_ROOT/ok', 143*d68f33bcSAndroid Build Coastguard Worker '/ ${BUILD_OS}/some/prog/REPO_OUTER_ROOT/ok', 144*d68f33bcSAndroid Build Coastguard Worker 'path1/file1', 145*d68f33bcSAndroid Build Coastguard Worker 'path2/file2', 146*d68f33bcSAndroid Build Coastguard Worker '--file=path1/file1', 147*d68f33bcSAndroid Build Coastguard Worker '--file=path2/file2', 148*d68f33bcSAndroid Build Coastguard Worker '--file', 149*d68f33bcSAndroid Build Coastguard Worker 'path1/file1', 150*d68f33bcSAndroid Build Coastguard Worker '--file', 151*d68f33bcSAndroid Build Coastguard Worker 'path2/file2', 152*d68f33bcSAndroid Build Coastguard Worker 'commit message', 153*d68f33bcSAndroid Build Coastguard Worker '5c4c293174bb61f0f39035a71acd9084abfa743d^commit message', 154*d68f33bcSAndroid Build Coastguard Worker '${THIS_VAR_IS_GOOD}', 155*d68f33bcSAndroid Build Coastguard Worker ] 156*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(output_args, exp_args) 157*d68f33bcSAndroid Build Coastguard Worker 158*d68f33bcSAndroid Build Coastguard Worker def testTheTester(self): 159*d68f33bcSAndroid Build Coastguard Worker """Make sure we have a test for every variable.""" 160*d68f33bcSAndroid Build Coastguard Worker for var in self.replacer.vars(): 161*d68f33bcSAndroid Build Coastguard Worker self.assertIn(f'test{var}', dir(self), 162*d68f33bcSAndroid Build Coastguard Worker msg=f'Missing unittest for variable {var}') 163*d68f33bcSAndroid Build Coastguard Worker 164*d68f33bcSAndroid Build Coastguard Worker def testPREUPLOAD_COMMIT_MESSAGE(self): 165*d68f33bcSAndroid Build Coastguard Worker """Verify handling of PREUPLOAD_COMMIT_MESSAGE.""" 166*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('PREUPLOAD_COMMIT_MESSAGE'), 167*d68f33bcSAndroid Build Coastguard Worker 'commit message') 168*d68f33bcSAndroid Build Coastguard Worker 169*d68f33bcSAndroid Build Coastguard Worker def testPREUPLOAD_COMMIT(self): 170*d68f33bcSAndroid Build Coastguard Worker """Verify handling of PREUPLOAD_COMMIT.""" 171*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('PREUPLOAD_COMMIT'), 172*d68f33bcSAndroid Build Coastguard Worker '5c4c293174bb61f0f39035a71acd9084abfa743d') 173*d68f33bcSAndroid Build Coastguard Worker 174*d68f33bcSAndroid Build Coastguard Worker def testPREUPLOAD_FILES(self): 175*d68f33bcSAndroid Build Coastguard Worker """Verify handling of PREUPLOAD_FILES.""" 176*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('PREUPLOAD_FILES'), 177*d68f33bcSAndroid Build Coastguard Worker ['path1/file1', 'path2/file2']) 178*d68f33bcSAndroid Build Coastguard Worker 179*d68f33bcSAndroid Build Coastguard Worker @mock.patch.object(rh.git, 'find_repo_root') 180*d68f33bcSAndroid Build Coastguard Worker def testREPO_OUTER_ROOT(self, m): 181*d68f33bcSAndroid Build Coastguard Worker """Verify handling of REPO_OUTER_ROOT.""" 182*d68f33bcSAndroid Build Coastguard Worker m.side_effect = mock_find_repo_root 183*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('REPO_OUTER_ROOT'), 184*d68f33bcSAndroid Build Coastguard Worker mock_find_repo_root(path=None, outer=True)) 185*d68f33bcSAndroid Build Coastguard Worker 186*d68f33bcSAndroid Build Coastguard Worker @mock.patch.object(rh.git, 'find_repo_root') 187*d68f33bcSAndroid Build Coastguard Worker def testREPO_ROOT(self, m): 188*d68f33bcSAndroid Build Coastguard Worker """Verify handling of REPO_ROOT.""" 189*d68f33bcSAndroid Build Coastguard Worker m.side_effect = mock_find_repo_root 190*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('REPO_ROOT'), 191*d68f33bcSAndroid Build Coastguard Worker mock_find_repo_root(path=None, outer=False)) 192*d68f33bcSAndroid Build Coastguard Worker 193*d68f33bcSAndroid Build Coastguard Worker def testREPO_PATH(self): 194*d68f33bcSAndroid Build Coastguard Worker """Verify handling of REPO_PATH.""" 195*d68f33bcSAndroid Build Coastguard Worker os.environ['REPO_PATH'] = '' 196*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('REPO_PATH'), '') 197*d68f33bcSAndroid Build Coastguard Worker os.environ['REPO_PATH'] = 'foo/bar' 198*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('REPO_PATH'), 'foo/bar') 199*d68f33bcSAndroid Build Coastguard Worker 200*d68f33bcSAndroid Build Coastguard Worker def testREPO_PROJECT(self): 201*d68f33bcSAndroid Build Coastguard Worker """Verify handling of REPO_PROJECT.""" 202*d68f33bcSAndroid Build Coastguard Worker os.environ['REPO_PROJECT'] = '' 203*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('REPO_PROJECT'), '') 204*d68f33bcSAndroid Build Coastguard Worker os.environ['REPO_PROJECT'] = 'platform/foo/bar' 205*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('REPO_PROJECT'), 'platform/foo/bar') 206*d68f33bcSAndroid Build Coastguard Worker 207*d68f33bcSAndroid Build Coastguard Worker @mock.patch.object(rh.hooks, '_get_build_os_name', return_value='vapier os') 208*d68f33bcSAndroid Build Coastguard Worker def testBUILD_OS(self, m): 209*d68f33bcSAndroid Build Coastguard Worker """Verify handling of BUILD_OS.""" 210*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(self.replacer.get('BUILD_OS'), m.return_value) 211*d68f33bcSAndroid Build Coastguard Worker 212*d68f33bcSAndroid Build Coastguard Worker 213*d68f33bcSAndroid Build Coastguard Workerclass ExclusionScopeTests(unittest.TestCase): 214*d68f33bcSAndroid Build Coastguard Worker """Verify behavior of ExclusionScope class.""" 215*d68f33bcSAndroid Build Coastguard Worker 216*d68f33bcSAndroid Build Coastguard Worker def testEmpty(self): 217*d68f33bcSAndroid Build Coastguard Worker """Verify the in operator for an empty scope.""" 218*d68f33bcSAndroid Build Coastguard Worker scope = rh.hooks.ExclusionScope([]) 219*d68f33bcSAndroid Build Coastguard Worker self.assertNotIn('external/*', scope) 220*d68f33bcSAndroid Build Coastguard Worker 221*d68f33bcSAndroid Build Coastguard Worker def testGlob(self): 222*d68f33bcSAndroid Build Coastguard Worker """Verify the in operator for a scope using wildcards.""" 223*d68f33bcSAndroid Build Coastguard Worker scope = rh.hooks.ExclusionScope(['vendor/*', 'external/*']) 224*d68f33bcSAndroid Build Coastguard Worker self.assertIn('external/tools', scope) 225*d68f33bcSAndroid Build Coastguard Worker 226*d68f33bcSAndroid Build Coastguard Worker def testRegex(self): 227*d68f33bcSAndroid Build Coastguard Worker """Verify the in operator for a scope using regular expressions.""" 228*d68f33bcSAndroid Build Coastguard Worker scope = rh.hooks.ExclusionScope(['^vendor/(?!google)', 229*d68f33bcSAndroid Build Coastguard Worker 'external/*']) 230*d68f33bcSAndroid Build Coastguard Worker self.assertIn('vendor/', scope) 231*d68f33bcSAndroid Build Coastguard Worker self.assertNotIn('vendor/google/', scope) 232*d68f33bcSAndroid Build Coastguard Worker self.assertIn('vendor/other/', scope) 233*d68f33bcSAndroid Build Coastguard Worker 234*d68f33bcSAndroid Build Coastguard Worker 235*d68f33bcSAndroid Build Coastguard Workerclass HookOptionsTests(unittest.TestCase): 236*d68f33bcSAndroid Build Coastguard Worker """Verify behavior of HookOptions object.""" 237*d68f33bcSAndroid Build Coastguard Worker 238*d68f33bcSAndroid Build Coastguard Worker @mock.patch.object(rh.hooks, '_get_build_os_name', return_value='vapier os') 239*d68f33bcSAndroid Build Coastguard Worker def testExpandVars(self, m): 240*d68f33bcSAndroid Build Coastguard Worker """Verify expand_vars behavior.""" 241*d68f33bcSAndroid Build Coastguard Worker # Simple pass through. 242*d68f33bcSAndroid Build Coastguard Worker args = ['who', 'goes', 'there ?'] 243*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(args, rh.hooks.HookOptions.expand_vars(args)) 244*d68f33bcSAndroid Build Coastguard Worker 245*d68f33bcSAndroid Build Coastguard Worker # At least one replacement. Most real testing is in PlaceholderTests. 246*d68f33bcSAndroid Build Coastguard Worker args = ['who', 'goes', 'there ?', '${BUILD_OS} is great'] 247*d68f33bcSAndroid Build Coastguard Worker exp_args = ['who', 'goes', 'there ?', f'{m.return_value} is great'] 248*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(exp_args, rh.hooks.HookOptions.expand_vars(args)) 249*d68f33bcSAndroid Build Coastguard Worker 250*d68f33bcSAndroid Build Coastguard Worker def testArgs(self): 251*d68f33bcSAndroid Build Coastguard Worker """Verify args behavior.""" 252*d68f33bcSAndroid Build Coastguard Worker # Verify initial args to __init__ has higher precedent. 253*d68f33bcSAndroid Build Coastguard Worker args = ['start', 'args'] 254*d68f33bcSAndroid Build Coastguard Worker options = rh.hooks.HookOptions('hook name', args, {}) 255*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(options.args(), args) 256*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(options.args(default_args=['moo']), args) 257*d68f33bcSAndroid Build Coastguard Worker 258*d68f33bcSAndroid Build Coastguard Worker # Verify we fall back to default_args. 259*d68f33bcSAndroid Build Coastguard Worker args = ['default', 'args'] 260*d68f33bcSAndroid Build Coastguard Worker options = rh.hooks.HookOptions('hook name', [], {}) 261*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(options.args(), []) 262*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(options.args(default_args=args), args) 263*d68f33bcSAndroid Build Coastguard Worker 264*d68f33bcSAndroid Build Coastguard Worker def testToolPath(self): 265*d68f33bcSAndroid Build Coastguard Worker """Verify tool_path behavior.""" 266*d68f33bcSAndroid Build Coastguard Worker options = rh.hooks.HookOptions('hook name', [], { 267*d68f33bcSAndroid Build Coastguard Worker 'cpplint': 'my cpplint', 268*d68f33bcSAndroid Build Coastguard Worker }) 269*d68f33bcSAndroid Build Coastguard Worker # Check a builtin (and not overridden) tool. 270*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(options.tool_path('pylint'), 'pylint') 271*d68f33bcSAndroid Build Coastguard Worker # Check an overridden tool. 272*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(options.tool_path('cpplint'), 'my cpplint') 273*d68f33bcSAndroid Build Coastguard Worker # Check an unknown tool fails. 274*d68f33bcSAndroid Build Coastguard Worker self.assertRaises(AssertionError, options.tool_path, 'extra_tool') 275*d68f33bcSAndroid Build Coastguard Worker 276*d68f33bcSAndroid Build Coastguard Worker 277*d68f33bcSAndroid Build Coastguard Workerclass UtilsTests(unittest.TestCase): 278*d68f33bcSAndroid Build Coastguard Worker """Verify misc utility functions.""" 279*d68f33bcSAndroid Build Coastguard Worker 280*d68f33bcSAndroid Build Coastguard Worker def testRunCommand(self): 281*d68f33bcSAndroid Build Coastguard Worker """Check _run behavior.""" 282*d68f33bcSAndroid Build Coastguard Worker # Most testing is done against the utils.RunCommand already. 283*d68f33bcSAndroid Build Coastguard Worker # pylint: disable=protected-access 284*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks._run(['true']) 285*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(ret.returncode, 0) 286*d68f33bcSAndroid Build Coastguard Worker 287*d68f33bcSAndroid Build Coastguard Worker def testBuildOs(self): 288*d68f33bcSAndroid Build Coastguard Worker """Check _get_build_os_name behavior.""" 289*d68f33bcSAndroid Build Coastguard Worker # Just verify it returns something and doesn't crash. 290*d68f33bcSAndroid Build Coastguard Worker # pylint: disable=protected-access 291*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks._get_build_os_name() 292*d68f33bcSAndroid Build Coastguard Worker self.assertTrue(isinstance(ret, str)) 293*d68f33bcSAndroid Build Coastguard Worker self.assertNotEqual(ret, '') 294*d68f33bcSAndroid Build Coastguard Worker 295*d68f33bcSAndroid Build Coastguard Worker def testGetHelperPath(self): 296*d68f33bcSAndroid Build Coastguard Worker """Check get_helper_path behavior.""" 297*d68f33bcSAndroid Build Coastguard Worker # Just verify it doesn't crash. It's a dirt simple func. 298*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.get_helper_path('booga') 299*d68f33bcSAndroid Build Coastguard Worker self.assertTrue(isinstance(ret, str)) 300*d68f33bcSAndroid Build Coastguard Worker self.assertNotEqual(ret, '') 301*d68f33bcSAndroid Build Coastguard Worker 302*d68f33bcSAndroid Build Coastguard Worker def testSortedToolPaths(self): 303*d68f33bcSAndroid Build Coastguard Worker """Check TOOL_PATHS is sorted.""" 304*d68f33bcSAndroid Build Coastguard Worker # This assumes dictionary key ordering matches insertion/definition 305*d68f33bcSAndroid Build Coastguard Worker # order which Python 3.7+ has codified. 306*d68f33bcSAndroid Build Coastguard Worker # https://docs.python.org/3.7/library/stdtypes.html#dict 307*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(list(rh.hooks.TOOL_PATHS), sorted(rh.hooks.TOOL_PATHS)) 308*d68f33bcSAndroid Build Coastguard Worker 309*d68f33bcSAndroid Build Coastguard Worker def testSortedBuiltinHooks(self): 310*d68f33bcSAndroid Build Coastguard Worker """Check BUILTIN_HOOKS is sorted.""" 311*d68f33bcSAndroid Build Coastguard Worker # This assumes dictionary key ordering matches insertion/definition 312*d68f33bcSAndroid Build Coastguard Worker # order which Python 3.7+ has codified. 313*d68f33bcSAndroid Build Coastguard Worker # https://docs.python.org/3.7/library/stdtypes.html#dict 314*d68f33bcSAndroid Build Coastguard Worker self.assertEqual( 315*d68f33bcSAndroid Build Coastguard Worker list(rh.hooks.BUILTIN_HOOKS), sorted(rh.hooks.BUILTIN_HOOKS)) 316*d68f33bcSAndroid Build Coastguard Worker 317*d68f33bcSAndroid Build Coastguard Worker 318*d68f33bcSAndroid Build Coastguard Worker@mock.patch.object(rh.utils, 'run') 319*d68f33bcSAndroid Build Coastguard Worker@mock.patch.object(rh.hooks, '_check_cmd', return_value=['check_cmd']) 320*d68f33bcSAndroid Build Coastguard Workerclass BuiltinHooksTests(unittest.TestCase): 321*d68f33bcSAndroid Build Coastguard Worker """Verify the builtin hooks.""" 322*d68f33bcSAndroid Build Coastguard Worker 323*d68f33bcSAndroid Build Coastguard Worker def setUp(self): 324*d68f33bcSAndroid Build Coastguard Worker self.project = rh.Project(name='project-name', dir='/.../repo/dir') 325*d68f33bcSAndroid Build Coastguard Worker self.options = rh.hooks.HookOptions('hook name', [], {}) 326*d68f33bcSAndroid Build Coastguard Worker 327*d68f33bcSAndroid Build Coastguard Worker def _test_commit_messages(self, func, accept, msgs, files=None): 328*d68f33bcSAndroid Build Coastguard Worker """Helper for testing commit message hooks. 329*d68f33bcSAndroid Build Coastguard Worker 330*d68f33bcSAndroid Build Coastguard Worker Args: 331*d68f33bcSAndroid Build Coastguard Worker func: The hook function to test. 332*d68f33bcSAndroid Build Coastguard Worker accept: Whether all the |msgs| should be accepted. 333*d68f33bcSAndroid Build Coastguard Worker msgs: List of messages to test. 334*d68f33bcSAndroid Build Coastguard Worker files: List of files to pass to the hook. 335*d68f33bcSAndroid Build Coastguard Worker """ 336*d68f33bcSAndroid Build Coastguard Worker if files: 337*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file=x) for x in files] 338*d68f33bcSAndroid Build Coastguard Worker else: 339*d68f33bcSAndroid Build Coastguard Worker diff = [] 340*d68f33bcSAndroid Build Coastguard Worker for desc in msgs: 341*d68f33bcSAndroid Build Coastguard Worker ret = func(self.project, 'commit', desc, diff, options=self.options) 342*d68f33bcSAndroid Build Coastguard Worker if accept: 343*d68f33bcSAndroid Build Coastguard Worker self.assertFalse( 344*d68f33bcSAndroid Build Coastguard Worker bool(ret), msg='Should have accepted: {{{' + desc + '}}}') 345*d68f33bcSAndroid Build Coastguard Worker else: 346*d68f33bcSAndroid Build Coastguard Worker self.assertTrue( 347*d68f33bcSAndroid Build Coastguard Worker bool(ret), msg='Should have rejected: {{{' + desc + '}}}') 348*d68f33bcSAndroid Build Coastguard Worker 349*d68f33bcSAndroid Build Coastguard Worker def _test_file_filter(self, mock_check, func, files): 350*d68f33bcSAndroid Build Coastguard Worker """Helper for testing hooks that filter by files and run external tools. 351*d68f33bcSAndroid Build Coastguard Worker 352*d68f33bcSAndroid Build Coastguard Worker Args: 353*d68f33bcSAndroid Build Coastguard Worker mock_check: The mock of _check_cmd. 354*d68f33bcSAndroid Build Coastguard Worker func: The hook function to test. 355*d68f33bcSAndroid Build Coastguard Worker files: A list of files that we'd check. 356*d68f33bcSAndroid Build Coastguard Worker """ 357*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 358*d68f33bcSAndroid Build Coastguard Worker ret = func(self.project, 'commit', 'desc', (), options=self.options) 359*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 360*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 361*d68f33bcSAndroid Build Coastguard Worker 362*d68f33bcSAndroid Build Coastguard Worker # Second call should include some checks. 363*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file=x) for x in files] 364*d68f33bcSAndroid Build Coastguard Worker ret = func(self.project, 'commit', 'desc', diff, options=self.options) 365*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(ret, mock_check.return_value) 366*d68f33bcSAndroid Build Coastguard Worker 367*d68f33bcSAndroid Build Coastguard Worker def testTheTester(self, _mock_check, _mock_run): 368*d68f33bcSAndroid Build Coastguard Worker """Make sure we have a test for every hook.""" 369*d68f33bcSAndroid Build Coastguard Worker for hook in rh.hooks.BUILTIN_HOOKS: 370*d68f33bcSAndroid Build Coastguard Worker self.assertIn(f'test_{hook}', dir(self), 371*d68f33bcSAndroid Build Coastguard Worker msg=f'Missing unittest for builtin hook {hook}') 372*d68f33bcSAndroid Build Coastguard Worker 373*d68f33bcSAndroid Build Coastguard Worker def test_aosp_license(self, mock_check, _mock_run): 374*d68f33bcSAndroid Build Coastguard Worker """Verify the aosp_license builtin hook.""" 375*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 376*d68f33bcSAndroid Build Coastguard Worker diff = [ 377*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='d.bp', status='D'), 378*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='m.bp', status='M'), 379*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='non-interested', status='A'), 380*d68f33bcSAndroid Build Coastguard Worker ] 381*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_aosp_license( 382*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 383*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 384*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 385*d68f33bcSAndroid Build Coastguard Worker 386*d68f33bcSAndroid Build Coastguard Worker # Second call will have some results. 387*d68f33bcSAndroid Build Coastguard Worker diff = [ 388*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='a.bp', status='A'), 389*d68f33bcSAndroid Build Coastguard Worker ] 390*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_aosp_license( 391*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 392*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(ret) 393*d68f33bcSAndroid Build Coastguard Worker 394*d68f33bcSAndroid Build Coastguard Worker # No result since all paths are excluded. 395*d68f33bcSAndroid Build Coastguard Worker diff = [ 396*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='a/a.bp', status='A'), 397*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='b/a.bp', status='A'), 398*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='c/d/a.bp', status='A'), 399*d68f33bcSAndroid Build Coastguard Worker ] 400*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_aosp_license( 401*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, 402*d68f33bcSAndroid Build Coastguard Worker options=rh.hooks.HookOptions('hook name', 403*d68f33bcSAndroid Build Coastguard Worker ['--exclude-dirs=a,b', '--exclude-dirs=c/d'], {}) 404*d68f33bcSAndroid Build Coastguard Worker ) 405*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 406*d68f33bcSAndroid Build Coastguard Worker 407*d68f33bcSAndroid Build Coastguard Worker # Make sure that `--exclude-dir` doesn't match the path in the middle. 408*d68f33bcSAndroid Build Coastguard Worker diff = [ 409*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='a/b/c.bp', status='A'), 410*d68f33bcSAndroid Build Coastguard Worker ] 411*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_aosp_license( 412*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, 413*d68f33bcSAndroid Build Coastguard Worker options=rh.hooks.HookOptions('hook name', ['--exclude-dirs=b'], {}) 414*d68f33bcSAndroid Build Coastguard Worker ) 415*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(ret) 416*d68f33bcSAndroid Build Coastguard Worker 417*d68f33bcSAndroid Build Coastguard Worker 418*d68f33bcSAndroid Build Coastguard Worker def test_bpfmt(self, mock_check, _mock_run): 419*d68f33bcSAndroid Build Coastguard Worker """Verify the bpfmt builtin hook.""" 420*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 421*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_bpfmt( 422*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 423*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 424*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 425*d68f33bcSAndroid Build Coastguard Worker 426*d68f33bcSAndroid Build Coastguard Worker # Second call will have some results. 427*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='Android.bp')] 428*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_bpfmt( 429*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 430*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(ret) 431*d68f33bcSAndroid Build Coastguard Worker for result in ret: 432*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(result.fixup_cmd) 433*d68f33bcSAndroid Build Coastguard Worker 434*d68f33bcSAndroid Build Coastguard Worker def test_checkpatch(self, mock_check, _mock_run): 435*d68f33bcSAndroid Build Coastguard Worker """Verify the checkpatch builtin hook.""" 436*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_checkpatch( 437*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 438*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(ret, mock_check.return_value) 439*d68f33bcSAndroid Build Coastguard Worker 440*d68f33bcSAndroid Build Coastguard Worker def test_clang_format(self, mock_check, _mock_run): 441*d68f33bcSAndroid Build Coastguard Worker """Verify the clang_format builtin hook.""" 442*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_clang_format( 443*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 444*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(ret, mock_check.return_value) 445*d68f33bcSAndroid Build Coastguard Worker 446*d68f33bcSAndroid Build Coastguard Worker def test_google_java_format(self, mock_check, _mock_run): 447*d68f33bcSAndroid Build Coastguard Worker """Verify the google_java_format builtin hook.""" 448*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 449*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_google_java_format( 450*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 451*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 452*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 453*d68f33bcSAndroid Build Coastguard Worker # Check that .java files are included by default. 454*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='foo.java'), 455*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='bar.kt'), 456*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='baz/blah.java')] 457*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_google_java_format( 458*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 459*d68f33bcSAndroid Build Coastguard Worker self.assertListEqual(ret[0].files, ['foo.java', 'baz/blah.java']) 460*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='foo/f1.java'), 461*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='bar/f2.java'), 462*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='baz/f2.java')] 463*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_google_java_format( 464*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, 465*d68f33bcSAndroid Build Coastguard Worker options=rh.hooks.HookOptions('hook name', 466*d68f33bcSAndroid Build Coastguard Worker ['--include-dirs=foo,baz'], {})) 467*d68f33bcSAndroid Build Coastguard Worker self.assertListEqual(ret[0].files, ['foo/f1.java', 'baz/f2.java']) 468*d68f33bcSAndroid Build Coastguard Worker 469*d68f33bcSAndroid Build Coastguard Worker def test_commit_msg_bug_field(self, _mock_check, _mock_run): 470*d68f33bcSAndroid Build Coastguard Worker """Verify the commit_msg_bug_field builtin hook.""" 471*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 472*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 473*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_bug_field, True, ( 474*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nBug: 1234\n', 475*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nBug: 1234\nChange-Id: blah\n', 476*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nFix: 1234\n', 477*d68f33bcSAndroid Build Coastguard Worker )) 478*d68f33bcSAndroid Build Coastguard Worker 479*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 480*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 481*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_bug_field, False, ( 482*d68f33bcSAndroid Build Coastguard Worker 'subj', 483*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nBUG=1234\n', 484*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nBUG: 1234\n', 485*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nBug: N/A\n', 486*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nBug:\n', 487*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nFIX=1234\n', 488*d68f33bcSAndroid Build Coastguard Worker )) 489*d68f33bcSAndroid Build Coastguard Worker 490*d68f33bcSAndroid Build Coastguard Worker def test_commit_msg_changeid_field(self, _mock_check, _mock_run): 491*d68f33bcSAndroid Build Coastguard Worker """Verify the commit_msg_changeid_field builtin hook.""" 492*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 493*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 494*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_changeid_field, True, ( 495*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nChange-Id: I1234\n', 496*d68f33bcSAndroid Build Coastguard Worker )) 497*d68f33bcSAndroid Build Coastguard Worker 498*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 499*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 500*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_changeid_field, False, ( 501*d68f33bcSAndroid Build Coastguard Worker 'subj', 502*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nChange-Id: 1234\n', 503*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nChange-ID: I1234\n', 504*d68f33bcSAndroid Build Coastguard Worker )) 505*d68f33bcSAndroid Build Coastguard Worker 506*d68f33bcSAndroid Build Coastguard Worker def test_commit_msg_prebuilt_apk_fields(self, _mock_check, _mock_run): 507*d68f33bcSAndroid Build Coastguard Worker """Verify the check_commit_msg_prebuilt_apk_fields builtin hook.""" 508*d68f33bcSAndroid Build Coastguard Worker # Commits without APKs should pass. 509*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 510*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_prebuilt_apk_fields, 511*d68f33bcSAndroid Build Coastguard Worker True, 512*d68f33bcSAndroid Build Coastguard Worker ( 513*d68f33bcSAndroid Build Coastguard Worker 'subj\nTest: test case\nBug: bug id\n', 514*d68f33bcSAndroid Build Coastguard Worker ), 515*d68f33bcSAndroid Build Coastguard Worker ['foo.cpp', 'bar.py',] 516*d68f33bcSAndroid Build Coastguard Worker ) 517*d68f33bcSAndroid Build Coastguard Worker 518*d68f33bcSAndroid Build Coastguard Worker # Commits with APKs and all the required messages should pass. 519*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 520*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_prebuilt_apk_fields, 521*d68f33bcSAndroid Build Coastguard Worker True, 522*d68f33bcSAndroid Build Coastguard Worker ( 523*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 524*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 525*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 526*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 527*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBuilt here:\n' 528*d68f33bcSAndroid Build Coastguard Worker 'http://foo.bar.com/builder\n\n' 529*d68f33bcSAndroid Build Coastguard Worker 'This build IS suitable for public release.\n\n' 530*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 531*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nBuilt here:\nhttp://foo.bar.com/builder\n\n' 532*d68f33bcSAndroid Build Coastguard Worker 'This build IS NOT suitable for public release.\n\n' 533*d68f33bcSAndroid Build Coastguard Worker 'bar.apk\npackage: name=\'com.foo.bar\'\n' 534*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 535*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 536*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 537*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBug: 123\nTest: test\n' 538*d68f33bcSAndroid Build Coastguard Worker 'Change-Id: XXXXXXX\n'), 539*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 540*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 541*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 542*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 543*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBuilt here:\n' 544*d68f33bcSAndroid Build Coastguard Worker 'http://foo.bar.com/builder\n\n' 545*d68f33bcSAndroid Build Coastguard Worker 'This build IS suitable for preview release but IS NOT ' 546*d68f33bcSAndroid Build Coastguard Worker 'suitable for public release.\n\n' 547*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 548*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 549*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 550*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 551*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 552*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBuilt here:\n' 553*d68f33bcSAndroid Build Coastguard Worker 'http://foo.bar.com/builder\n\n' 554*d68f33bcSAndroid Build Coastguard Worker 'This build IS NOT suitable for preview or public release.\n\n' 555*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 556*d68f33bcSAndroid Build Coastguard Worker ), 557*d68f33bcSAndroid Build Coastguard Worker ['foo.apk', 'bar.py',] 558*d68f33bcSAndroid Build Coastguard Worker ) 559*d68f33bcSAndroid Build Coastguard Worker 560*d68f33bcSAndroid Build Coastguard Worker # Commits with APKs and without all the required messages should fail. 561*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 562*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_prebuilt_apk_fields, 563*d68f33bcSAndroid Build Coastguard Worker False, 564*d68f33bcSAndroid Build Coastguard Worker ( 565*d68f33bcSAndroid Build Coastguard Worker 'subj\nTest: test case\nBug: bug id\n', 566*d68f33bcSAndroid Build Coastguard Worker # Missing 'package'. 567*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\n' 568*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 569*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 570*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 571*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBuilt here:\n' 572*d68f33bcSAndroid Build Coastguard Worker 'http://foo.bar.com/builder\n\n' 573*d68f33bcSAndroid Build Coastguard Worker 'This build IS suitable for public release.\n\n' 574*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 575*d68f33bcSAndroid Build Coastguard Worker # Missing 'sdkVersion'. 576*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 577*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 578*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 579*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\n' 580*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBuilt here:\n' 581*d68f33bcSAndroid Build Coastguard Worker 'http://foo.bar.com/builder\n\n' 582*d68f33bcSAndroid Build Coastguard Worker 'This build IS suitable for public release.\n\n' 583*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 584*d68f33bcSAndroid Build Coastguard Worker # Missing 'targetSdkVersion'. 585*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 586*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 587*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 588*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 589*d68f33bcSAndroid Build Coastguard Worker 'Built here:\nhttp://foo.bar.com/builder\n\n' 590*d68f33bcSAndroid Build Coastguard Worker 'This build IS suitable for public release.\n\n' 591*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 592*d68f33bcSAndroid Build Coastguard Worker # Missing build location. 593*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 594*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 595*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 596*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 597*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\n' 598*d68f33bcSAndroid Build Coastguard Worker 'This build IS suitable for public release.\n\n' 599*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 600*d68f33bcSAndroid Build Coastguard Worker # Missing public release indication. 601*d68f33bcSAndroid Build Coastguard Worker ('Test App\n\nbar.apk\npackage: name=\'com.foo.bar\'\n' 602*d68f33bcSAndroid Build Coastguard Worker 'versionCode=\'1001\'\nversionName=\'1.0.1001-A\'\n' 603*d68f33bcSAndroid Build Coastguard Worker 'platformBuildVersionName=\'\'\ncompileSdkVersion=\'28\'\n' 604*d68f33bcSAndroid Build Coastguard Worker 'compileSdkVersionCodename=\'9\'\nsdkVersion:\'16\'\n' 605*d68f33bcSAndroid Build Coastguard Worker 'targetSdkVersion:\'28\'\n\nBuilt here:\n' 606*d68f33bcSAndroid Build Coastguard Worker 'http://foo.bar.com/builder\n\n' 607*d68f33bcSAndroid Build Coastguard Worker 'Bug: 123\nTest: test\nChange-Id: XXXXXXX\n'), 608*d68f33bcSAndroid Build Coastguard Worker ), 609*d68f33bcSAndroid Build Coastguard Worker ['foo.apk', 'bar.py',] 610*d68f33bcSAndroid Build Coastguard Worker ) 611*d68f33bcSAndroid Build Coastguard Worker 612*d68f33bcSAndroid Build Coastguard Worker def test_commit_msg_test_field(self, _mock_check, _mock_run): 613*d68f33bcSAndroid Build Coastguard Worker """Verify the commit_msg_test_field builtin hook.""" 614*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 615*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 616*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_test_field, True, ( 617*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nTest: i did done dood it\n', 618*d68f33bcSAndroid Build Coastguard Worker )) 619*d68f33bcSAndroid Build Coastguard Worker 620*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 621*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 622*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_test_field, False, ( 623*d68f33bcSAndroid Build Coastguard Worker 'subj', 624*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nTEST=1234\n', 625*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nTEST: I1234\n', 626*d68f33bcSAndroid Build Coastguard Worker )) 627*d68f33bcSAndroid Build Coastguard Worker 628*d68f33bcSAndroid Build Coastguard Worker def test_commit_msg_relnote_field_format(self, _mock_check, _mock_run): 629*d68f33bcSAndroid Build Coastguard Worker """Verify the commit_msg_relnote_field_format builtin hook.""" 630*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 631*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 632*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_field_format, 633*d68f33bcSAndroid Build Coastguard Worker True, 634*d68f33bcSAndroid Build Coastguard Worker ( 635*d68f33bcSAndroid Build Coastguard Worker 'subj', 636*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nTest: i did done dood it\nBug: 1234', 637*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nMore content\n\nTest: i did done dood it\nBug: 1234', 638*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note\nBug: 1234', 639*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote:This is a release note\nBug: 1234', 640*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\nBug: 1234', 641*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: "This is a release note."\nBug: 1234', 642*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: "This is a \\"release note\\"."\n\nBug: 1234', 643*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\nChange-Id: 1234', 644*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\n\nChange-Id: 1234', 645*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note."\n\n' 646*d68f33bcSAndroid Build Coastguard Worker 'Change-Id: 1234'), 647*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is a release note.\n\n' 648*d68f33bcSAndroid Build Coastguard Worker 'It has more info, but it is not part of the release note' 649*d68f33bcSAndroid Build Coastguard Worker '\nChange-Id: 1234'), 650*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 651*d68f33bcSAndroid Build Coastguard Worker 'It contains a correct second line."'), 652*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote:"This is a release note.\n' 653*d68f33bcSAndroid Build Coastguard Worker 'It contains a correct second line."'), 654*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 655*d68f33bcSAndroid Build Coastguard Worker 'It contains a correct second line.\n' 656*d68f33bcSAndroid Build Coastguard Worker 'And even a third line."\n' 657*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 658*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 659*d68f33bcSAndroid Build Coastguard Worker 'It contains a correct second line.\n' 660*d68f33bcSAndroid Build Coastguard Worker '\\"Quotes\\" are even used on the third line."\n' 661*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 662*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1.\n' 663*d68f33bcSAndroid Build Coastguard Worker 'Relnote: This is release note 2.\n' 664*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 665*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1.\n' 666*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 667*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted third line."\n' 668*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 669*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is release note 1 with\n' 670*d68f33bcSAndroid Build Coastguard Worker 'a correctly formatted second line."\n\n' 671*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 672*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted second line."\n' 673*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 674*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note with\n' 675*d68f33bcSAndroid Build Coastguard Worker 'a correctly formatted second line."\n\n' 676*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234' 677*d68f33bcSAndroid Build Coastguard Worker 'Here is some extra "quoted" content.'), 678*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note.\n\n' 679*d68f33bcSAndroid Build Coastguard Worker 'This relnote contains an empty line.\n' 680*d68f33bcSAndroid Build Coastguard Worker 'Then a non-empty line.\n\n' 681*d68f33bcSAndroid Build Coastguard Worker 'And another empty line."""\n\n' 682*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 683*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note.\n\n' 684*d68f33bcSAndroid Build Coastguard Worker 'This relnote contains an empty line.\n' 685*d68f33bcSAndroid Build Coastguard Worker 'Then an acceptable "quoted" line.\n\n' 686*d68f33bcSAndroid Build Coastguard Worker 'And another empty line."""\n\n' 687*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 688*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note."""\n\n' 689*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 690*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note.\n' 691*d68f33bcSAndroid Build Coastguard Worker 'It has a second line."""\n\n' 692*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 693*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note.\n' 694*d68f33bcSAndroid Build Coastguard Worker 'It has a second line, but does not end here.\n' 695*d68f33bcSAndroid Build Coastguard Worker '"""\n\n' 696*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 697*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note.\n' 698*d68f33bcSAndroid Build Coastguard Worker '"It" has a second line, but does not end here.\n' 699*d68f33bcSAndroid Build Coastguard Worker '"""\n\n' 700*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 701*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 702*d68f33bcSAndroid Build Coastguard Worker 'It has a second line, but does not end here.\n' 703*d68f33bcSAndroid Build Coastguard Worker '"\n\n' 704*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 705*d68f33bcSAndroid Build Coastguard Worker )) 706*d68f33bcSAndroid Build Coastguard Worker 707*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 708*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 709*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_field_format, 710*d68f33bcSAndroid Build Coastguard Worker False, 711*d68f33bcSAndroid Build Coastguard Worker ( 712*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nReleaseNote: This is a release note.\n', 713*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnotes: This is a release note.\n', 714*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRel-note: This is a release note.\n', 715*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nrelnoTes: This is a release note.\n', 716*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nrel-Note: This is a release note.\n', 717*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: "This is a "release note"."\nBug: 1234', 718*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a "release note".\nBug: 1234', 719*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is a release note.\n' 720*d68f33bcSAndroid Build Coastguard Worker 'It contains an incorrect second line.'), 721*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 722*d68f33bcSAndroid Build Coastguard Worker 'It contains multiple lines.\n' 723*d68f33bcSAndroid Build Coastguard Worker 'But it does not provide an ending quote.\n'), 724*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 725*d68f33bcSAndroid Build Coastguard Worker 'It contains multiple lines but no closing quote.\n' 726*d68f33bcSAndroid Build Coastguard Worker 'Test: my test "hello world"\n'), 727*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1.\n' 728*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 729*d68f33bcSAndroid Build Coastguard Worker 'contains an incorrectly formatted third line.\n' 730*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 731*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1 with\n' 732*d68f33bcSAndroid Build Coastguard Worker 'an incorrectly formatted second line.\n\n' 733*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 734*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted second line."\n' 735*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 736*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is release note 1 with\n' 737*d68f33bcSAndroid Build Coastguard Worker 'a correctly formatted second line."\n\n' 738*d68f33bcSAndroid Build Coastguard Worker 'Relnote: This is release note 2, and it\n' 739*d68f33bcSAndroid Build Coastguard Worker 'contains an incorrectly formatted second line.\n' 740*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 741*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 742*d68f33bcSAndroid Build Coastguard Worker 'It contains a correct second line.\n' 743*d68f33bcSAndroid Build Coastguard Worker 'But incorrect "quotes" on the third line."\n' 744*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 745*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: """This is a release note.\n' 746*d68f33bcSAndroid Build Coastguard Worker 'It has a second line, but no closing triple quote.\n\n' 747*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 748*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: "This is a release note.\n' 749*d68f33bcSAndroid Build Coastguard Worker '"It" has a second line, but does not end here.\n' 750*d68f33bcSAndroid Build Coastguard Worker '"\n\n' 751*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 752*d68f33bcSAndroid Build Coastguard Worker )) 753*d68f33bcSAndroid Build Coastguard Worker 754*d68f33bcSAndroid Build Coastguard Worker def test_commit_msg_relnote_for_current_txt(self, _mock_check, _mock_run): 755*d68f33bcSAndroid Build Coastguard Worker """Verify the commit_msg_relnote_for_current_txt builtin hook.""" 756*d68f33bcSAndroid Build Coastguard Worker diff_without_current_txt = ['bar/foo.txt', 757*d68f33bcSAndroid Build Coastguard Worker 'foo.cpp', 758*d68f33bcSAndroid Build Coastguard Worker 'foo.java', 759*d68f33bcSAndroid Build Coastguard Worker 'foo_current.java', 760*d68f33bcSAndroid Build Coastguard Worker 'foo_current.txt', 761*d68f33bcSAndroid Build Coastguard Worker 'baz/current.java', 762*d68f33bcSAndroid Build Coastguard Worker 'baz/foo_current.txt'] 763*d68f33bcSAndroid Build Coastguard Worker diff_with_current_txt = diff_without_current_txt + ['current.txt'] 764*d68f33bcSAndroid Build Coastguard Worker diff_with_subdir_current_txt = \ 765*d68f33bcSAndroid Build Coastguard Worker diff_without_current_txt + ['foo/current.txt'] 766*d68f33bcSAndroid Build Coastguard Worker diff_with_experimental_current_txt = \ 767*d68f33bcSAndroid Build Coastguard Worker diff_without_current_txt + ['public_plus_experimental_current.txt'] 768*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 769*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 770*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 771*d68f33bcSAndroid Build Coastguard Worker True, 772*d68f33bcSAndroid Build Coastguard Worker ( 773*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note\n', 774*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\n\nChange-Id: 1234', 775*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1 with\n' 776*d68f33bcSAndroid Build Coastguard Worker 'an incorrectly formatted second line.\n\n' 777*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 778*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted second line."\n' 779*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 780*d68f33bcSAndroid Build Coastguard Worker ), 781*d68f33bcSAndroid Build Coastguard Worker files=diff_with_current_txt, 782*d68f33bcSAndroid Build Coastguard Worker ) 783*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 784*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 785*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 786*d68f33bcSAndroid Build Coastguard Worker True, 787*d68f33bcSAndroid Build Coastguard Worker ( 788*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note\n', 789*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\n\nChange-Id: 1234', 790*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1 with\n' 791*d68f33bcSAndroid Build Coastguard Worker 'an incorrectly formatted second line.\n\n' 792*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 793*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted second line."\n' 794*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 795*d68f33bcSAndroid Build Coastguard Worker ), 796*d68f33bcSAndroid Build Coastguard Worker files=diff_with_experimental_current_txt, 797*d68f33bcSAndroid Build Coastguard Worker ) 798*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 799*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 800*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 801*d68f33bcSAndroid Build Coastguard Worker True, 802*d68f33bcSAndroid Build Coastguard Worker ( 803*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note\n', 804*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\n\nChange-Id: 1234', 805*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1 with\n' 806*d68f33bcSAndroid Build Coastguard Worker 'an incorrectly formatted second line.\n\n' 807*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 808*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted second line."\n' 809*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 810*d68f33bcSAndroid Build Coastguard Worker ), 811*d68f33bcSAndroid Build Coastguard Worker files=diff_with_subdir_current_txt, 812*d68f33bcSAndroid Build Coastguard Worker ) 813*d68f33bcSAndroid Build Coastguard Worker # Check some good messages. 814*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 815*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 816*d68f33bcSAndroid Build Coastguard Worker True, 817*d68f33bcSAndroid Build Coastguard Worker ( 818*d68f33bcSAndroid Build Coastguard Worker 'subj', 819*d68f33bcSAndroid Build Coastguard Worker 'subj\nBug: 12345\nChange-Id: 1234', 820*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note\n', 821*d68f33bcSAndroid Build Coastguard Worker 'subj\n\nRelnote: This is a release note.\n\nChange-Id: 1234', 822*d68f33bcSAndroid Build Coastguard Worker ('subj\n\nRelnote: This is release note 1 with\n' 823*d68f33bcSAndroid Build Coastguard Worker 'an incorrectly formatted second line.\n\n' 824*d68f33bcSAndroid Build Coastguard Worker 'Relnote: "This is release note 2, and it\n' 825*d68f33bcSAndroid Build Coastguard Worker 'contains a correctly formatted second line."\n' 826*d68f33bcSAndroid Build Coastguard Worker 'Bug: 1234'), 827*d68f33bcSAndroid Build Coastguard Worker ), 828*d68f33bcSAndroid Build Coastguard Worker files=diff_without_current_txt, 829*d68f33bcSAndroid Build Coastguard Worker ) 830*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 831*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 832*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 833*d68f33bcSAndroid Build Coastguard Worker False, 834*d68f33bcSAndroid Build Coastguard Worker ( 835*d68f33bcSAndroid Build Coastguard Worker 'subj' 836*d68f33bcSAndroid Build Coastguard Worker 'subj\nBug: 12345\nChange-Id: 1234', 837*d68f33bcSAndroid Build Coastguard Worker ), 838*d68f33bcSAndroid Build Coastguard Worker files=diff_with_current_txt, 839*d68f33bcSAndroid Build Coastguard Worker ) 840*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 841*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 842*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 843*d68f33bcSAndroid Build Coastguard Worker False, 844*d68f33bcSAndroid Build Coastguard Worker ( 845*d68f33bcSAndroid Build Coastguard Worker 'subj' 846*d68f33bcSAndroid Build Coastguard Worker 'subj\nBug: 12345\nChange-Id: 1234', 847*d68f33bcSAndroid Build Coastguard Worker ), 848*d68f33bcSAndroid Build Coastguard Worker files=diff_with_experimental_current_txt, 849*d68f33bcSAndroid Build Coastguard Worker ) 850*d68f33bcSAndroid Build Coastguard Worker # Check some bad messages. 851*d68f33bcSAndroid Build Coastguard Worker self._test_commit_messages( 852*d68f33bcSAndroid Build Coastguard Worker rh.hooks.check_commit_msg_relnote_for_current_txt, 853*d68f33bcSAndroid Build Coastguard Worker False, 854*d68f33bcSAndroid Build Coastguard Worker ( 855*d68f33bcSAndroid Build Coastguard Worker 'subj' 856*d68f33bcSAndroid Build Coastguard Worker 'subj\nBug: 12345\nChange-Id: 1234', 857*d68f33bcSAndroid Build Coastguard Worker ), 858*d68f33bcSAndroid Build Coastguard Worker files=diff_with_subdir_current_txt, 859*d68f33bcSAndroid Build Coastguard Worker ) 860*d68f33bcSAndroid Build Coastguard Worker 861*d68f33bcSAndroid Build Coastguard Worker def test_cpplint(self, mock_check, _mock_run): 862*d68f33bcSAndroid Build Coastguard Worker """Verify the cpplint builtin hook.""" 863*d68f33bcSAndroid Build Coastguard Worker self._test_file_filter(mock_check, rh.hooks.check_cpplint, 864*d68f33bcSAndroid Build Coastguard Worker ('foo.cpp', 'foo.cxx')) 865*d68f33bcSAndroid Build Coastguard Worker 866*d68f33bcSAndroid Build Coastguard Worker def test_gofmt(self, mock_check, _mock_run): 867*d68f33bcSAndroid Build Coastguard Worker """Verify the gofmt builtin hook.""" 868*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 869*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_gofmt( 870*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 871*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 872*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 873*d68f33bcSAndroid Build Coastguard Worker 874*d68f33bcSAndroid Build Coastguard Worker # Second call will have some results. 875*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='foo.go')] 876*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_gofmt( 877*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 878*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(ret) 879*d68f33bcSAndroid Build Coastguard Worker 880*d68f33bcSAndroid Build Coastguard Worker def test_jsonlint(self, mock_check, _mock_run): 881*d68f33bcSAndroid Build Coastguard Worker """Verify the jsonlint builtin hook.""" 882*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 883*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_json( 884*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 885*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 886*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 887*d68f33bcSAndroid Build Coastguard Worker 888*d68f33bcSAndroid Build Coastguard Worker # TODO: Actually pass some valid/invalid json data down. 889*d68f33bcSAndroid Build Coastguard Worker 890*d68f33bcSAndroid Build Coastguard Worker def test_ktfmt(self, mock_check, _mock_run): 891*d68f33bcSAndroid Build Coastguard Worker """Verify the ktfmt builtin hook.""" 892*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 893*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_ktfmt( 894*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 895*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 896*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 897*d68f33bcSAndroid Build Coastguard Worker # Check that .kt files are included by default. 898*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='foo.kt'), 899*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='bar.java'), 900*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='baz/blah.kt')] 901*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_ktfmt( 902*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 903*d68f33bcSAndroid Build Coastguard Worker self.assertListEqual(ret[0].files, ['foo.kt', 'baz/blah.kt']) 904*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='foo/f1.kt'), 905*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='bar/f2.kt'), 906*d68f33bcSAndroid Build Coastguard Worker rh.git.RawDiffEntry(file='baz/f2.kt')] 907*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_ktfmt(self.project, 'commit', 'desc', diff, 908*d68f33bcSAndroid Build Coastguard Worker options=rh.hooks.HookOptions('hook name', [ 909*d68f33bcSAndroid Build Coastguard Worker '--include-dirs=foo,baz'], {})) 910*d68f33bcSAndroid Build Coastguard Worker self.assertListEqual(ret[0].files, ['foo/f1.kt', 'baz/f2.kt']) 911*d68f33bcSAndroid Build Coastguard Worker 912*d68f33bcSAndroid Build Coastguard Worker def test_pylint(self, mock_check, _mock_run): 913*d68f33bcSAndroid Build Coastguard Worker """Verify the pylint builtin hook.""" 914*d68f33bcSAndroid Build Coastguard Worker self._test_file_filter(mock_check, rh.hooks.check_pylint2, 915*d68f33bcSAndroid Build Coastguard Worker ('foo.py',)) 916*d68f33bcSAndroid Build Coastguard Worker 917*d68f33bcSAndroid Build Coastguard Worker def test_pylint2(self, mock_check, _mock_run): 918*d68f33bcSAndroid Build Coastguard Worker """Verify the pylint2 builtin hook.""" 919*d68f33bcSAndroid Build Coastguard Worker self._test_file_filter(mock_check, rh.hooks.check_pylint2, 920*d68f33bcSAndroid Build Coastguard Worker ('foo.py',)) 921*d68f33bcSAndroid Build Coastguard Worker 922*d68f33bcSAndroid Build Coastguard Worker def test_pylint3(self, mock_check, _mock_run): 923*d68f33bcSAndroid Build Coastguard Worker """Verify the pylint3 builtin hook.""" 924*d68f33bcSAndroid Build Coastguard Worker self._test_file_filter(mock_check, rh.hooks.check_pylint3, 925*d68f33bcSAndroid Build Coastguard Worker ('foo.py',)) 926*d68f33bcSAndroid Build Coastguard Worker 927*d68f33bcSAndroid Build Coastguard Worker def test_rustfmt(self, mock_check, _mock_run): 928*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 929*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_rustfmt( 930*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 931*d68f33bcSAndroid Build Coastguard Worker self.assertEqual(ret, None) 932*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 933*d68f33bcSAndroid Build Coastguard Worker 934*d68f33bcSAndroid Build Coastguard Worker # Second call will have some results. 935*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='lib.rs')] 936*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_rustfmt( 937*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 938*d68f33bcSAndroid Build Coastguard Worker self.assertNotEqual(ret, None) 939*d68f33bcSAndroid Build Coastguard Worker 940*d68f33bcSAndroid Build Coastguard Worker def test_xmllint(self, mock_check, _mock_run): 941*d68f33bcSAndroid Build Coastguard Worker """Verify the xmllint builtin hook.""" 942*d68f33bcSAndroid Build Coastguard Worker self._test_file_filter(mock_check, rh.hooks.check_xmllint, 943*d68f33bcSAndroid Build Coastguard Worker ('foo.xml',)) 944*d68f33bcSAndroid Build Coastguard Worker 945*d68f33bcSAndroid Build Coastguard Worker def test_android_test_mapping_format(self, mock_check, _mock_run): 946*d68f33bcSAndroid Build Coastguard Worker """Verify the android_test_mapping_format builtin hook.""" 947*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 948*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_android_test_mapping( 949*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 950*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 951*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 952*d68f33bcSAndroid Build Coastguard Worker 953*d68f33bcSAndroid Build Coastguard Worker # Second call will have some results. 954*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='TEST_MAPPING')] 955*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_android_test_mapping( 956*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 957*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(ret) 958*d68f33bcSAndroid Build Coastguard Worker 959*d68f33bcSAndroid Build Coastguard Worker def test_aidl_format(self, mock_check, _mock_run): 960*d68f33bcSAndroid Build Coastguard Worker """Verify the aidl_format builtin hook.""" 961*d68f33bcSAndroid Build Coastguard Worker # First call should do nothing as there are no files to check. 962*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_aidl_format( 963*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', (), options=self.options) 964*d68f33bcSAndroid Build Coastguard Worker self.assertIsNone(ret) 965*d68f33bcSAndroid Build Coastguard Worker self.assertFalse(mock_check.called) 966*d68f33bcSAndroid Build Coastguard Worker 967*d68f33bcSAndroid Build Coastguard Worker # Second call will have some results. 968*d68f33bcSAndroid Build Coastguard Worker diff = [rh.git.RawDiffEntry(file='IFoo.go')] 969*d68f33bcSAndroid Build Coastguard Worker ret = rh.hooks.check_gofmt( 970*d68f33bcSAndroid Build Coastguard Worker self.project, 'commit', 'desc', diff, options=self.options) 971*d68f33bcSAndroid Build Coastguard Worker self.assertIsNotNone(ret) 972*d68f33bcSAndroid Build Coastguard Worker 973*d68f33bcSAndroid Build Coastguard Worker 974*d68f33bcSAndroid Build Coastguard Workerif __name__ == '__main__': 975*d68f33bcSAndroid Build Coastguard Worker unittest.main() 976