1*9c5db199SXin Li#!/usr/bin/python3 2*9c5db199SXin Li 3*9c5db199SXin Liimport contextlib 4*9c5db199SXin Liimport sys 5*9c5db199SXin Liimport unittest 6*9c5db199SXin Li 7*9c5db199SXin Liimport common 8*9c5db199SXin Lifrom autotest_lib.site_utils.deployment import cmdparse 9*9c5db199SXin Li 10*9c5db199SXin Li 11*9c5db199SXin Li@contextlib.contextmanager 12*9c5db199SXin Lidef _suppress_error_output(): 13*9c5db199SXin Li stderr_save = sys.stderr 14*9c5db199SXin Li try: 15*9c5db199SXin Li with open('/dev/null', 'w') as sys.stderr: 16*9c5db199SXin Li yield 17*9c5db199SXin Li finally: 18*9c5db199SXin Li sys.stderr = stderr_save 19*9c5db199SXin Li 20*9c5db199SXin Li 21*9c5db199SXin Liclass BooleanArgumentTestCase(unittest.TestCase): 22*9c5db199SXin Li """Tests for parsing and adding boolean arguments.""" 23*9c5db199SXin Li 24*9c5db199SXin Li def _make_parser(self, option, default): 25*9c5db199SXin Li parser = cmdparse._ArgumentParser() 26*9c5db199SXin Li parser.add_boolean_argument(option, default) 27*9c5db199SXin Li return parser 28*9c5db199SXin Li 29*9c5db199SXin Li def test_conflicting_options_raises_error_with_false_default(self): 30*9c5db199SXin Li """Test handling when both the true and false options are used.""" 31*9c5db199SXin Li # By default, when there's a command line syntax error, 32*9c5db199SXin Li # `argparse.ArgumentParser` prints messages on sys.stderr and 33*9c5db199SXin Li # then calls `sys.exit()`. So, take the time to catch/suppress 34*9c5db199SXin Li # those behaviors. 35*9c5db199SXin Li with _suppress_error_output(): 36*9c5db199SXin Li parser = self._make_parser('option', False) 37*9c5db199SXin Li with self.assertRaises(SystemExit): 38*9c5db199SXin Li parser.parse_args(['--option', '--nooption']) 39*9c5db199SXin Li with self.assertRaises(SystemExit): 40*9c5db199SXin Li parser.parse_args(['--nooption', '--option']) 41*9c5db199SXin Li 42*9c5db199SXin Li def test_conflicting_options_raises_error_with_true_default(self): 43*9c5db199SXin Li """Test handling when both the true and false options are used.""" 44*9c5db199SXin Li # By default, when there's a command line syntax error, 45*9c5db199SXin Li # `argparse.ArgumentParser` prints messages on sys.stderr and 46*9c5db199SXin Li # then calls `sys.exit()`. So, take the time to catch/suppress 47*9c5db199SXin Li # those behaviors. 48*9c5db199SXin Li with _suppress_error_output(): 49*9c5db199SXin Li parser = self._make_parser('option', True) 50*9c5db199SXin Li with self.assertRaises(SystemExit): 51*9c5db199SXin Li parser.parse_args(['--option', '--nooption']) 52*9c5db199SXin Li with self.assertRaises(SystemExit): 53*9c5db199SXin Li parser.parse_args(['--nooption', '--option']) 54*9c5db199SXin Li 55*9c5db199SXin Li def test_no_option_wth_false_default(self): 56*9c5db199SXin Li """Test option handling when no option is provided.""" 57*9c5db199SXin Li parser = self._make_parser('option', False) 58*9c5db199SXin Li arguments = parser.parse_args([]) 59*9c5db199SXin Li self.assertFalse(arguments.option) 60*9c5db199SXin Li 61*9c5db199SXin Li def test_no_option_wth_true_default(self): 62*9c5db199SXin Li """Test option handling when no option is provided.""" 63*9c5db199SXin Li parser = self._make_parser('option', True) 64*9c5db199SXin Li arguments = parser.parse_args([]) 65*9c5db199SXin Li self.assertTrue(arguments.option) 66*9c5db199SXin Li 67*9c5db199SXin Li def test_true_option_returns_true_with_false_default(self): 68*9c5db199SXin Li """Test option handling when only the true option is provided.""" 69*9c5db199SXin Li parser = self._make_parser('option', False) 70*9c5db199SXin Li arguments = parser.parse_args(['--option']) 71*9c5db199SXin Li self.assertTrue(arguments.option) 72*9c5db199SXin Li 73*9c5db199SXin Li def test_true_option_returns_true_with_true_default(self): 74*9c5db199SXin Li """Test option handling when only the true option is provided.""" 75*9c5db199SXin Li parser = self._make_parser('option', True) 76*9c5db199SXin Li arguments = parser.parse_args(['--option']) 77*9c5db199SXin Li self.assertTrue(arguments.option) 78*9c5db199SXin Li 79*9c5db199SXin Li def test_false_option_returns_false_with_false_default(self): 80*9c5db199SXin Li """Test option handling when only the false option is provided.""" 81*9c5db199SXin Li parser = self._make_parser('option', False) 82*9c5db199SXin Li arguments = parser.parse_args(['--nooption']) 83*9c5db199SXin Li self.assertFalse(arguments.option) 84*9c5db199SXin Li 85*9c5db199SXin Li def test_false_option_returns_false_with_true_default(self): 86*9c5db199SXin Li """Test option handling when only the false option is provided.""" 87*9c5db199SXin Li parser = self._make_parser('option', True) 88*9c5db199SXin Li arguments = parser.parse_args(['--nooption']) 89*9c5db199SXin Li self.assertFalse(arguments.option) 90*9c5db199SXin Li 91*9c5db199SXin Li 92*9c5db199SXin Lidef _test_parse_command(argv): 93*9c5db199SXin Li return cmdparse.parse_command(['command'] + argv) 94*9c5db199SXin Li 95*9c5db199SXin Li 96*9c5db199SXin Liclass _CommandParserTestCase(unittest.TestCase): 97*9c5db199SXin Li _ALL_SUBCOMMANDS = ['servo', 'firmware', 'test-image', 'repair'] 98*9c5db199SXin Li 99*9c5db199SXin Li def _check_common_defaults(self, arguments): 100*9c5db199SXin Li self.assertIsNone(arguments.web) 101*9c5db199SXin Li self.assertIsNone(arguments.logdir) 102*9c5db199SXin Li self.assertFalse(arguments.dry_run) 103*9c5db199SXin Li self.assertIsNone(arguments.board) 104*9c5db199SXin Li self.assertIsNone(arguments.build) 105*9c5db199SXin Li self.assertIsNone(arguments.hostname_file) 106*9c5db199SXin Li self.assertEquals(arguments.hostnames, []) 107*9c5db199SXin Li 108*9c5db199SXin Li def test_web_option(self): 109*9c5db199SXin Li """Test handling of `--web`, both long and short forms.""" 110*9c5db199SXin Li opt_arg = 'servername' 111*9c5db199SXin Li for option in ['-w', '--web']: 112*9c5db199SXin Li argv = [option, opt_arg] 113*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 114*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 115*9c5db199SXin Li self.assertEquals(arguments.web, opt_arg) 116*9c5db199SXin Li 117*9c5db199SXin Li def test_logdir_option(self): 118*9c5db199SXin Li """Test handling of `--dir`, both long and short forms.""" 119*9c5db199SXin Li opt_arg = 'dirname' 120*9c5db199SXin Li for option in ['-d', '--dir']: 121*9c5db199SXin Li argv = [option, opt_arg] 122*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 123*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 124*9c5db199SXin Li self.assertEquals(arguments.logdir, opt_arg) 125*9c5db199SXin Li 126*9c5db199SXin Li def test_dry_run_option(self): 127*9c5db199SXin Li """Test handling of `--dry-run`, both long and short forms.""" 128*9c5db199SXin Li # assert False 129*9c5db199SXin Li for option in ['-n', '--dry-run']: 130*9c5db199SXin Li argv = [option] 131*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 132*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 133*9c5db199SXin Li self.assertTrue(arguments.dry_run) 134*9c5db199SXin Li 135*9c5db199SXin Li def test_build_option(self): 136*9c5db199SXin Li """Test handling of `--build`, both long and short forms.""" 137*9c5db199SXin Li opt_arg = 'R66-10447.0.0' 138*9c5db199SXin Li for option in ['-i', '--build']: 139*9c5db199SXin Li argv = [option, opt_arg] 140*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 141*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 142*9c5db199SXin Li self.assertEquals(arguments.build, opt_arg) 143*9c5db199SXin Li 144*9c5db199SXin Li def test_hostname_file_option(self): 145*9c5db199SXin Li """Test handling of `--hostname_file`, both long and short forms.""" 146*9c5db199SXin Li opt_arg = 'hostfiles.csv' 147*9c5db199SXin Li for option in ['-f', '--hostname_file']: 148*9c5db199SXin Li argv = [option, opt_arg] 149*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 150*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 151*9c5db199SXin Li self.assertEquals(arguments.hostname_file, opt_arg) 152*9c5db199SXin Li 153*9c5db199SXin Li def test_upload_option(self): 154*9c5db199SXin Li """Test handling of `--upload`, both long and short forms.""" 155*9c5db199SXin Li argv = ['--upload'] 156*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 157*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 158*9c5db199SXin Li self.assertTrue(arguments.upload) 159*9c5db199SXin Li 160*9c5db199SXin Li def test_noupload_option(self): 161*9c5db199SXin Li """Test handling of `--noupload`, both long and short forms.""" 162*9c5db199SXin Li argv = ['--noupload'] 163*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 164*9c5db199SXin Li arguments = _test_parse_command([subcmd] + argv) 165*9c5db199SXin Li self.assertFalse(arguments.upload) 166*9c5db199SXin Li 167*9c5db199SXin Li def test_board_option(self): 168*9c5db199SXin Li """Test the `--board` option for subcommands.""" 169*9c5db199SXin Li opt_arg = 'board' 170*9c5db199SXin Li for option in ['-b', '--board']: 171*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 172*9c5db199SXin Li arguments = _test_parse_command([subcmd, option, opt_arg]) 173*9c5db199SXin Li self.assertEquals(arguments.board, opt_arg) 174*9c5db199SXin Li 175*9c5db199SXin Li def test_model_option(self): 176*9c5db199SXin Li """Test the `--model` option for subcommands.""" 177*9c5db199SXin Li opt_arg = 'model' 178*9c5db199SXin Li for option in ['-m', '--model']: 179*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 180*9c5db199SXin Li arguments = _test_parse_command([subcmd, option, opt_arg]) 181*9c5db199SXin Li self.assertEquals(arguments.model, opt_arg) 182*9c5db199SXin Li 183*9c5db199SXin Li def test_hostname_arguments(self): 184*9c5db199SXin Li """Test hostname arguments for subcommands.""" 185*9c5db199SXin Li argument = 'hostname' 186*9c5db199SXin Li for subcmd in self._ALL_SUBCOMMANDS: 187*9c5db199SXin Li arguments = _test_parse_command([subcmd, argument]) 188*9c5db199SXin Li self.assertEquals(arguments.hostnames, [argument]) 189*9c5db199SXin Li 190*9c5db199SXin Li def test_servo_defaults(self): 191*9c5db199SXin Li """Test argument defaults for `deploy servo`.""" 192*9c5db199SXin Li arguments = _test_parse_command(['servo']) 193*9c5db199SXin Li self._check_common_defaults(arguments) 194*9c5db199SXin Li self.assertTrue(arguments.stageusb) 195*9c5db199SXin Li self.assertFalse(arguments.install_firmware) 196*9c5db199SXin Li self.assertFalse(arguments.install_test_image) 197*9c5db199SXin Li self.assertFalse(arguments.reinstall_test_image) 198*9c5db199SXin Li 199*9c5db199SXin Li def test_firmware_defaults(self): 200*9c5db199SXin Li """Test argument defaults for `deploy firmware`.""" 201*9c5db199SXin Li arguments = _test_parse_command(['firmware']) 202*9c5db199SXin Li self._check_common_defaults(arguments) 203*9c5db199SXin Li self.assertFalse(arguments.stageusb) 204*9c5db199SXin Li self.assertFalse(arguments.reinstall_test_image) 205*9c5db199SXin Li self.assertTrue(arguments.install_firmware) 206*9c5db199SXin Li self.assertTrue(arguments.install_test_image) 207*9c5db199SXin Li 208*9c5db199SXin Li def test_test_image_defaults(self): 209*9c5db199SXin Li """Test argument defaults for `deploy test-image`.""" 210*9c5db199SXin Li arguments = _test_parse_command(['test-image']) 211*9c5db199SXin Li self._check_common_defaults(arguments) 212*9c5db199SXin Li self.assertFalse(arguments.stageusb) 213*9c5db199SXin Li self.assertFalse(arguments.install_firmware) 214*9c5db199SXin Li self.assertFalse(arguments.reinstall_test_image) 215*9c5db199SXin Li self.assertTrue(arguments.install_test_image) 216*9c5db199SXin Li 217*9c5db199SXin Li def test_repair_defaults(self): 218*9c5db199SXin Li """Test argument defaults for `deploy repair`.""" 219*9c5db199SXin Li arguments = _test_parse_command(['repair']) 220*9c5db199SXin Li self._check_common_defaults(arguments) 221*9c5db199SXin Li self.assertFalse(arguments.stageusb) 222*9c5db199SXin Li self.assertFalse(arguments.install_firmware) 223*9c5db199SXin Li self.assertFalse(arguments.install_test_image) 224*9c5db199SXin Li self.assertTrue(arguments.reinstall_test_image) 225*9c5db199SXin Li 226*9c5db199SXin Li 227*9c5db199SXin Liif __name__ == '__main__': 228*9c5db199SXin Li unittest.main() 229