1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2023 The Chromium Authors 3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker 6*8975f5c5SAndroid Build Coastguard Workerimport os 7*8975f5c5SAndroid Build Coastguard Workerimport pathlib 8*8975f5c5SAndroid Build Coastguard Workerimport shutil 9*8975f5c5SAndroid Build Coastguard Workerimport sys 10*8975f5c5SAndroid Build Coastguard Workerimport tempfile 11*8975f5c5SAndroid Build Coastguard Workerimport time 12*8975f5c5SAndroid Build Coastguard Workerimport unittest 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Workerimport action_helpers 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker 17*8975f5c5SAndroid Build Coastguard Workerclass ActionHelpersTest(unittest.TestCase): 18*8975f5c5SAndroid Build Coastguard Worker def test_atomic_output(self): 19*8975f5c5SAndroid Build Coastguard Worker tmp_file = pathlib.Path(tempfile.mktemp()) 20*8975f5c5SAndroid Build Coastguard Worker tmp_file.write_text('test') 21*8975f5c5SAndroid Build Coastguard Worker try: 22*8975f5c5SAndroid Build Coastguard Worker # Test that same contents does not change mtime. 23*8975f5c5SAndroid Build Coastguard Worker orig_mtime = os.path.getmtime(tmp_file) 24*8975f5c5SAndroid Build Coastguard Worker with action_helpers.atomic_output(str(tmp_file), 'wt') as af: 25*8975f5c5SAndroid Build Coastguard Worker time.sleep(.01) 26*8975f5c5SAndroid Build Coastguard Worker af.write('test') 27*8975f5c5SAndroid Build Coastguard Worker 28*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(os.path.getmtime(tmp_file), orig_mtime) 29*8975f5c5SAndroid Build Coastguard Worker 30*8975f5c5SAndroid Build Coastguard Worker # Test that contents is written. 31*8975f5c5SAndroid Build Coastguard Worker with action_helpers.atomic_output(str(tmp_file), 'wt') as af: 32*8975f5c5SAndroid Build Coastguard Worker af.write('test2') 33*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(tmp_file.read_text(), 'test2') 34*8975f5c5SAndroid Build Coastguard Worker self.assertNotEqual(os.path.getmtime(tmp_file), orig_mtime) 35*8975f5c5SAndroid Build Coastguard Worker finally: 36*8975f5c5SAndroid Build Coastguard Worker tmp_file.unlink() 37*8975f5c5SAndroid Build Coastguard Worker 38*8975f5c5SAndroid Build Coastguard Worker def test_parse_gn_list(self): 39*8975f5c5SAndroid Build Coastguard Worker def test(value, expected): 40*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(action_helpers.parse_gn_list(value), expected) 41*8975f5c5SAndroid Build Coastguard Worker 42*8975f5c5SAndroid Build Coastguard Worker test(None, []) 43*8975f5c5SAndroid Build Coastguard Worker test('', []) 44*8975f5c5SAndroid Build Coastguard Worker test('asdf', ['asdf']) 45*8975f5c5SAndroid Build Coastguard Worker test('["one"]', ['one']) 46*8975f5c5SAndroid Build Coastguard Worker test(['["one"]', '["two"]'], ['one', 'two']) 47*8975f5c5SAndroid Build Coastguard Worker test(['["one", "two"]', '["three"]'], ['one', 'two', 'three']) 48*8975f5c5SAndroid Build Coastguard Worker 49*8975f5c5SAndroid Build Coastguard Worker def test_write_depfile(self): 50*8975f5c5SAndroid Build Coastguard Worker tmp_file = pathlib.Path(tempfile.mktemp()) 51*8975f5c5SAndroid Build Coastguard Worker try: 52*8975f5c5SAndroid Build Coastguard Worker 53*8975f5c5SAndroid Build Coastguard Worker def capture_output(inputs): 54*8975f5c5SAndroid Build Coastguard Worker action_helpers.write_depfile(str(tmp_file), 'output', inputs) 55*8975f5c5SAndroid Build Coastguard Worker return tmp_file.read_text() 56*8975f5c5SAndroid Build Coastguard Worker 57*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(capture_output(None), 'output: \n') 58*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(capture_output([]), 'output: \n') 59*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(capture_output(['a']), 'output: \\\n a\n') 60*8975f5c5SAndroid Build Coastguard Worker # Check sorted. 61*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(capture_output(['b', 'a']), 'output: \\\n a \\\n b\n') 62*8975f5c5SAndroid Build Coastguard Worker # Check converts to forward slashes. 63*8975f5c5SAndroid Build Coastguard Worker self.assertEqual(capture_output(['a', os.path.join('b', 'c')]), 64*8975f5c5SAndroid Build Coastguard Worker 'output: \\\n a \\\n b/c\n') 65*8975f5c5SAndroid Build Coastguard Worker 66*8975f5c5SAndroid Build Coastguard Worker # Arg should be a list. 67*8975f5c5SAndroid Build Coastguard Worker with self.assertRaises(AssertionError): 68*8975f5c5SAndroid Build Coastguard Worker capture_output('a') 69*8975f5c5SAndroid Build Coastguard Worker 70*8975f5c5SAndroid Build Coastguard Worker # Do not use depfile itself as an output. 71*8975f5c5SAndroid Build Coastguard Worker with self.assertRaises(AssertionError): 72*8975f5c5SAndroid Build Coastguard Worker capture_output([str(tmp_file)]) 73*8975f5c5SAndroid Build Coastguard Worker 74*8975f5c5SAndroid Build Coastguard Worker # Do not use absolute paths. 75*8975f5c5SAndroid Build Coastguard Worker with self.assertRaises(AssertionError): 76*8975f5c5SAndroid Build Coastguard Worker capture_output([os.path.sep + 'foo']) 77*8975f5c5SAndroid Build Coastguard Worker 78*8975f5c5SAndroid Build Coastguard Worker # Do not use absolute paths (output path). 79*8975f5c5SAndroid Build Coastguard Worker with self.assertRaises(AssertionError): 80*8975f5c5SAndroid Build Coastguard Worker action_helpers.write_depfile(str(tmp_file), '/output', []) 81*8975f5c5SAndroid Build Coastguard Worker 82*8975f5c5SAndroid Build Coastguard Worker finally: 83*8975f5c5SAndroid Build Coastguard Worker tmp_file.unlink() 84*8975f5c5SAndroid Build Coastguard Worker 85*8975f5c5SAndroid Build Coastguard Worker 86*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 87*8975f5c5SAndroid Build Coastguard Worker unittest.main() 88