xref: /aosp_15_r20/external/autotest/site_utils/deployment/cmdparse_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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