def regenerate_usage_contents(force=False): """Get CLI usage strings for all COT commands and write them to file.""" COT_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) logger.info("COT path: " + COT_path) sys.path.insert(0, COT_path) from COT.ui.cli import CLI # Don't use our actual terminal width as it may vary. # Instead, use 79 chars minus the 8-character indent used in man pages. cli = CLI(terminal_width=71) for subcommand in [ "cot", "add-disk", "add-file", "deploy", "deploy-esxi", "edit-hardware", "edit-product", "edit-properties", "info", "inject-config", "install-helpers", "remove-file", ]: dirpath = os.path.join(os.path.dirname(__file__), "_autogenerated", subcommand) if os.path.exists(dirpath): if not force: logger.warning( "Directory {0} already exists, skipping '{1}'. ".format( dirpath, subcommand)) continue shutil.rmtree(dirpath) os.makedirs(dirpath) if subcommand == "cot": logger.debug("Getting top-level help for 'cot'...") help = cli.parser.format_help() else: logger.debug("Getting help for 'cot {0}'...".format(subcommand)) help = cli.subparser_lookup[subcommand].format_help() assert help, "help is empty!" logger.debug("Converting help string to reStructuredText...") help_text_to_rst(help, dirpath) logger.info("Done updating help rst files")
def setUp(self): """Test case setup function called automatically prior to each test.""" self.cli = CLI(terminal_width=80) self.maxDiff = None super(TestCOTCLI, self).setUp()
class TestCOTCLI(COTTestCase): """Parent class for CLI test cases.""" @staticmethod def creating_network_warning(net_name): """Warning log message for creating a new network entry. Args: net_name (str): Name of new network Returns: dict: kwargs suitable for passing into :meth:`assertLogged` """ return { 'levelname': 'WARNING', 'msg': "Automatically agreeing to '%s'", 'args': ("Network {0} is not currently defined. Create it?" .format(net_name), ), } def setUp(self): """Test case setup function called automatically prior to each test.""" self.cli = CLI(terminal_width=80) self.maxDiff = None super(TestCOTCLI, self).setUp() def tearDown(self): """Test case cleanup function called automatically after each test.""" # If we set the verbosity of the CLI directly, the CLI logger is on. # The CLI normally turns the logger back off at the end of cli.main() # but in some of our CLI test cases we don't call cli.main(), so # to prevent leakage of logs, we clean up manually if needed. if self.cli.master_logger: self.cli.master_logger.removeHandler(self.cli.handler) self.cli.master_logger = None self.cli.handler.close() self.cli.handler = None super(TestCOTCLI, self).tearDown() def set_terminal_width(self, width): """Modify the width of the virtual terminal.""" self.cli._terminal_width = width # pylint: disable=protected-access def call_cot(self, argv, result=0, fixup_args=True): """Invoke COT CLI, capturing stdout and stderr, and check the rc. In the case of an incorrect rc, the test will fail. Otherwise, will return the combined stdout/stderr. """ rc = -1 if fixup_args: argv = ['--quiet'] + argv with mock.patch('sys.stdin'), \ mock.patch('sys.stdout', new_callable=StringIO.StringIO) as _so, \ mock.patch('sys.stderr', new_callable=StringIO.StringIO) as _se: try: rc = self.cli.run(argv) except SystemExit as exc: try: rc = int(exc.code) except (TypeError, ValueError): print(exc.code, file=sys.stderr) rc = 1 stdout = _so.getvalue() stderr = _se.getvalue() self.assertEqual(rc, result, "\nargv: \n{0}\nstdout:\n{1}\nstderr:\n{2}" .format(" ".join(argv), stdout, stderr)) return stdout
class TestCOTCLI(COTTestCase): """Parent class for CLI test cases.""" @staticmethod def creating_network_warning(net_name): """Warning log message for creating a new network entry. Args: net_name (str): Name of new network Returns: dict: kwargs suitable for passing into :meth:`assertLogged` """ return { 'levelname': 'WARNING', 'msg': "Automatically agreeing to '%s'", 'args': ("Network {0} is not currently defined. Create it?".format( net_name), ), } def setUp(self): """Test case setup function called automatically prior to each test.""" self.cli = CLI(terminal_width=80) self.maxDiff = None super(TestCOTCLI, self).setUp() def tearDown(self): """Test case cleanup function called automatically after each test.""" # If we set the verbosity of the CLI directly, the CLI logger is on. # The CLI normally turns the logger back off at the end of cli.main() # but in some of our CLI test cases we don't call cli.main(), so # to prevent leakage of logs, we clean up manually if needed. if self.cli.master_logger: self.cli.master_logger.removeHandler(self.cli.handler) self.cli.master_logger = None self.cli.handler.close() self.cli.handler = None super(TestCOTCLI, self).tearDown() def set_terminal_width(self, width): """Modify the width of the virtual terminal.""" self.cli._terminal_width = width # pylint: disable=protected-access def call_cot(self, argv, result=0, fixup_args=True): """Invoke COT CLI, capturing stdout and stderr, and check the rc. In the case of an incorrect rc, the test will fail. Otherwise, will return the combined stdout/stderr. """ rc = -1 if fixup_args: argv = ['--quiet'] + argv with mock.patch('sys.stdin'), \ mock.patch('sys.stdout', new_callable=StringIO.StringIO) as _so, \ mock.patch('sys.stderr', new_callable=StringIO.StringIO) as _se: try: rc = self.cli.run(argv) except SystemExit as exc: try: rc = int(exc.code) except (TypeError, ValueError): print(exc.code, file=sys.stderr) rc = 1 stdout = _so.getvalue() stderr = _se.getvalue() self.assertEqual( rc, result, "\nargv: \n{0}\nstdout:\n{1}\nstderr:\n{2}".format( " ".join(argv), stdout, stderr)) return stdout