def testGetHelpSingleCommand(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler( "noop", self._noop_handler, "No operation.\nI.e., do nothing.", prefix_aliases=["n", "NOOP"]) registry.register_command_handler( "cols", self._echo_screen_cols, "Show screen width in number of columns.", prefix_aliases=["c"]) # Get help info for one of the two commands, using full prefix. help_lines = registry.get_help("cols").lines self.assertTrue(help_lines[0].endswith("cols")) self.assertTrue(help_lines[1].endswith("Aliases: c")) self.assertFalse(help_lines[2]) self.assertTrue(help_lines[3].endswith( "Show screen width in number of columns.")) # Get help info for one of the two commands, using alias. help_lines = registry.get_help("c").lines self.assertTrue(help_lines[0].endswith("cols")) self.assertTrue(help_lines[1].endswith("Aliases: c")) self.assertFalse(help_lines[2]) self.assertTrue(help_lines[3].endswith( "Show screen width in number of columns.")) # Get help info for a nonexistent command. help_lines = registry.get_help("foo").lines self.assertEqual("Invalid command prefix: \"foo\"", help_lines[0])
def testGetHelpFull(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler( "noop", self._noop_handler, "No operation.\nI.e., do nothing.", prefix_aliases=["n", "NOOP"]) registry.register_command_handler( "cols", self._echo_screen_cols, "Show screen width in number of columns.", prefix_aliases=["c"]) help_lines = registry.get_help().lines # The help info should list commands in alphabetically sorted order, # regardless of order in which the commands are reigstered. self.assertEqual("cols", help_lines[0]) self.assertTrue(help_lines[1].endswith("Aliases: c")) self.assertFalse(help_lines[2]) self.assertTrue(help_lines[3].endswith( "Show screen width in number of columns.")) self.assertFalse(help_lines[4]) self.assertFalse(help_lines[5]) # The default help command should appear in the help output. self.assertEqual("help", help_lines[6]) self.assertEqual("noop", help_lines[12]) self.assertTrue(help_lines[13].endswith("Aliases: n, NOOP")) self.assertFalse(help_lines[14]) self.assertTrue(help_lines[15].endswith("No operation.")) self.assertTrue(help_lines[16].endswith("I.e., do nothing."))
def testRegisterEmptyCommandPrefix(self): registry = debugger_cli_common.CommandHandlerRegistry() # Attempt to register an empty-string as a command prefix should trigger # an exception. with self.assertRaisesRegexp(ValueError, "Empty command prefix"): registry.register_command_handler("", self._noop_handler, "")
def testHelpCommandWithoutIntro(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler( "noop", self._noop_handler, "No operation.\nI.e., do nothing.", prefix_aliases=["n", "NOOP"]) registry.register_command_handler( "cols", self._echo_screen_cols, "Show screen width in number of columns.", prefix_aliases=["c"]) # Get help for all commands. output = registry.dispatch_command("help", []) self.assertEqual(["cols", " Aliases: c", "", " Show screen width in number of columns.", "", "", "help", " Aliases: h", "", " Print this help message.", "", "", "noop", " Aliases: n, NOOP", "", " No operation.", " I.e., do nothing.", "", ""], output.lines) # Get help for one specific command prefix. output = registry.dispatch_command("help", ["noop"]) self.assertEqual(["noop", " Aliases: n, NOOP", "", " No operation.", " I.e., do nothing."], output.lines) # Get help for a nonexistent command prefix. output = registry.dispatch_command("help", ["foo"]) self.assertEqual(["Invalid command prefix: \"foo\""], output.lines)
def testRegisterDuplicateAliases(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("noop", self._noop_handler, "", prefix_aliases=["n"]) # Clash with existing alias. with self.assertRaisesRegexp( ValueError, "clashes with existing prefixes or aliases"): registry.register_command_handler("cols", self._echo_screen_cols, "", prefix_aliases=["n"]) # The name clash should have prevent the handler from being registered. self.assertFalse(registry.is_registered("cols")) # Aliases can also clash with command prefixes. with self.assertRaisesRegexp( ValueError, "clashes with existing prefixes or aliases"): registry.register_command_handler("cols", self._echo_screen_cols, "", prefix_aliases=["noop"]) self.assertFalse(registry.is_registered("cols"))
def __init__(self): self._screen_init() self._screen_refresh_size() # TODO(cais): Error out if the size of the screen is too small. # Initialize some UI component size and locations. self._init_layout() self._command_handler_registry = ( debugger_cli_common.CommandHandlerRegistry()) self._command_history_store = debugger_cli_common.CommandHistory() # Active list of command history, used in history navigation. # _command_handler_registry holds all the history commands the CLI has # received, up to a size limit. _active_command_history is the history # currently being navigated in, e.g., using the Up/Down keys. The latter # can be different from the former during prefixed or regex-based history # navigation, e.g., when user enter the beginning of a command and hit Up. self._active_command_history = [] # Pointer to the current position in the history sequence. # 0 means it is a new command being keyed in. self._command_pointer = 0 self._command_history_limit = 100 self._pending_command = "" # State related to screen output. self._curr_unwrapped_output = None self._curr_wrapped_output = None
def setUpClass(cls): cls._dump_root = tempfile.mkdtemp() with session.Session() as sess: # 2400 elements should exceed the default threshold (2000). x = constant_op.constant(np.zeros([300, 8]), name="large_tensors/x") run_options = config_pb2.RunOptions(output_partition_graphs=True) debug_utils.watch_graph(run_options, sess.graph, debug_ops=["DebugIdentity"], debug_urls="file://%s" % cls._dump_root) # Invoke Session.run(). run_metadata = config_pb2.RunMetadata() sess.run(x, options=run_options, run_metadata=run_metadata) cls._debug_dump = debug_data.DebugDumpDir( cls._dump_root, partition_graphs=run_metadata.partition_graphs) # Construct the analyzer. cls._analyzer = analyzer_cli.DebugAnalyzer(cls._debug_dump) # Construct the handler registry. cls._registry = debugger_cli_common.CommandHandlerRegistry() # Register command handler. cls._registry.register_command_handler( "print_tensor", cls._analyzer.print_tensor, cls._analyzer.get_help("print_tensor"), prefix_aliases=["pt"])
def setUpClass(cls): cls._dump_root = tempfile.mkdtemp() cls._is_gpu_available = test.is_gpu_available() if cls._is_gpu_available: cls._main_device = "/job:localhost/replica:0/task:0/gpu:0" else: cls._main_device = "/job:localhost/replica:0/task:0/cpu:0" with session.Session() as sess: x_init_val = np.array([5.0, 3.0]) x_init = constant_op.constant(x_init_val, shape=[2]) x = variables.Variable(x_init, name="control_deps/x") y = math_ops.add(x, x, name="control_deps/y") y = control_flow_ops.with_dependencies( [x], y, name="control_deps/ctrl_dep_y") z = math_ops.mul(x, y, name="control_deps/z") z = control_flow_ops.with_dependencies( [x, y], z, name="control_deps/ctrl_dep_z") x.initializer.run() run_options = config_pb2.RunOptions(output_partition_graphs=True) debug_utils.watch_graph(run_options, sess.graph, debug_ops=["DebugIdentity"], debug_urls="file://%s" % cls._dump_root) # Invoke Session.run(). run_metadata = config_pb2.RunMetadata() sess.run(z, options=run_options, run_metadata=run_metadata) debug_dump = debug_data.DebugDumpDir( cls._dump_root, partition_graphs=run_metadata.partition_graphs) # Construct the analyzer. analyzer = analyzer_cli.DebugAnalyzer(debug_dump) # Construct the handler registry. cls._registry = debugger_cli_common.CommandHandlerRegistry() # Register command handlers. cls._registry.register_command_handler("node_info", analyzer.node_info, analyzer.get_help("node_info"), prefix_aliases=["ni"]) cls._registry.register_command_handler( "list_inputs", analyzer.list_inputs, analyzer.get_help("list_inputs"), prefix_aliases=["li"]) cls._registry.register_command_handler( "list_outputs", analyzer.list_outputs, analyzer.get_help("list_outputs"), prefix_aliases=["lo"])
def __init__(self, on_ui_exit=None): """Constructor of CursesUI. Args: on_ui_exit: (Callable) Callback invoked when the UI exits. """ self._screen_init() self._screen_refresh_size() # TODO(cais): Error out if the size of the screen is too small. # Initialize some UI component size and locations. self._init_layout() self._command_handler_registry = ( debugger_cli_common.CommandHandlerRegistry()) # Create tab completion registry and register the empty-str (top-level) # tab-completion context with it. self._tab_completion_registry = debugger_cli_common.TabCompletionRegistry( ) # Create top-level tab-completion context and register the exit and help # commands. self._tab_completion_registry.register_tab_comp_context( [""], self.CLI_EXIT_COMMANDS + [debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND] + debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND_ALIASES) self._command_history_store = debugger_cli_common.CommandHistory() # Active list of command history, used in history navigation. # _command_handler_registry holds all the history commands the CLI has # received, up to a size limit. _active_command_history is the history # currently being navigated in, e.g., using the Up/Down keys. The latter # can be different from the former during prefixed or regex-based history # navigation, e.g., when user enter the beginning of a command and hit Up. self._active_command_history = [] # Pointer to the current position in the history sequence. # 0 means it is a new command being keyed in. self._command_pointer = 0 self._command_history_limit = 100 self._pending_command = "" # State related to screen output. self._output_pad = None self._output_pad_row = 0 self._output_array_pointer_indices = None self._curr_unwrapped_output = None self._curr_wrapped_output = None # Register signal handler for SIGINT. signal.signal(signal.SIGINT, self._interrupt_handler) # Configurable callbacks. self._on_ui_exit = on_ui_exit
def setUpClass(cls): cls._dump_root = tempfile.mkdtemp() cls._is_gpu_available = test.is_gpu_available() if cls._is_gpu_available: cls._main_device = "/job:localhost/replica:0/task:0/gpu:0" else: cls._main_device = "/job:localhost/replica:0/task:0/cpu:0" with session.Session() as sess: u_init_val = np.array([[5.0, 3.0], [-1.0, 0.0]]) v_init_val = np.array([[2.0], [-1.0]]) u_name = "simple_mul_add/u" v_name = "simple_mul_add/v" u_init = constant_op.constant(u_init_val, shape=[2, 2]) u = variables.Variable(u_init, name=u_name) v_init = constant_op.constant(v_init_val, shape=[2, 1]) v = variables.Variable(v_init, name=v_name) w = math_ops.matmul(u, v, name="simple_mul_add/matmul") x = math_ops.add(w, w, name="simple_mul_add/add") u.initializer.run() v.initializer.run() run_options = config_pb2.RunOptions(output_partition_graphs=True) debug_utils.watch_graph(run_options, sess.graph, debug_ops=["DebugIdentity"], debug_urls="file://%s" % cls._dump_root) # Invoke Session.run(). run_metadata = config_pb2.RunMetadata() sess.run(x, options=run_options, run_metadata=run_metadata) debug_dump = debug_data.DebugDumpDir( cls._dump_root, partition_graphs=run_metadata.partition_graphs) # Construct the analyzer. analyzer = analyzer_cli.DebugAnalyzer(debug_dump) # Construct the handler registry. cls._registry = debugger_cli_common.CommandHandlerRegistry() # Register command handlers. cls._registry.register_command_handler( "list_tensors", analyzer.list_tensors, analyzer.get_help("list_tensors"), prefix_aliases=["lt"]) cls._registry.register_command_handler("node_info", analyzer.node_info, analyzer.get_help("node_info"), prefix_aliases=["ni"])
def testInvokeHandlerWithScreenInfo(self): registry = debugger_cli_common.CommandHandlerRegistry() # Register and invoke a command handler that uses screen_info. registry.register_command_handler("cols", self._echo_screen_cols, "") cmd_output = registry.dispatch_command( "cols", [], screen_info={"cols": 100}) self.assertEqual(["cols = 100"], cmd_output.lines)
def testHandlerWithWrongReturnType(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("wrong_return", self._handler_returning_wrong_type, "") # If the command handler fails to return a RichTextLines instance, an error # should be triggered. with self.assertRaisesRegexp( ValueError, "Return value from command handler.*is not a RichTextLines instance"): registry.dispatch_command("wrong_return", [])
def testDispatchHandlerRaisingException(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("raise_exception", self._handler_raising_exception, "") # The registry should catch and wrap exceptions that occur during command # handling. cmd_output = registry.dispatch_command("raise_exception", []) self.assertEqual(2, len(cmd_output.lines)) self.assertTrue(cmd_output.lines[0].startswith( "Error occurred during handling of command")) self.assertTrue(cmd_output.lines[1].endswith(self._intentional_error_msg))
def testRegisterDuplicateHandlers(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("noop", self._noop_handler, "") # Registering the same command prefix more than once should trigger an # exception. with self.assertRaisesRegexp( ValueError, "A handler is already registered for command prefix"): registry.register_command_handler("noop", self._noop_handler, "") cmd_output = registry.dispatch_command("noop", []) self.assertEqual(["Done."], cmd_output.lines)
def __init__(self): self._screen_init() self._screen_refresh_size() # TODO(cais): Error out if the size of the screen is too small. # Initialize some UI component size and locations. self._init_layout() self._command_handler_registry = ( debugger_cli_common.CommandHandlerRegistry()) # Create tab completion registry and register the empty-str (top-level) # tab-completion context with it. self._tab_completion_registry = debugger_cli_common.TabCompletionRegistry( ) # Create top-level tab-completion context and register the exit and help # commands. self._tab_completion_registry.register_tab_comp_context( [""], self.CLI_EXIT_COMMANDS + [debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND] + debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND_ALIASES) self._command_history_store = debugger_cli_common.CommandHistory() # Active list of command history, used in history navigation. # _command_handler_registry holds all the history commands the CLI has # received, up to a size limit. _active_command_history is the history # currently being navigated in, e.g., using the Up/Down keys. The latter # can be different from the former during prefixed or regex-based history # navigation, e.g., when user enter the beginning of a command and hit Up. self._active_command_history = [] # Pointer to the current position in the history sequence. # 0 means it is a new command being keyed in. self._command_pointer = 0 self._command_history_limit = 100 self._pending_command = "" # State related to screen output. self._output_pad = None self._curr_unwrapped_output = None self._curr_wrapped_output = None # NamedTuple for rectangular locations on screen self.rectangle = collections.namedtuple("rectangle", "top left bottom right") # Register signal handler for SIGINT. signal.signal(signal.SIGINT, self._interrupt_handler)
def testDispatchHandlerRaisingException(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("raise_exception", self._handler_raising_exception, "") # The registry should catch and wrap exceptions that occur during command # handling. cmd_output = registry.dispatch_command("raise_exception", []) # The error output contains a stack trace. # So the line count should be >= 2. self.assertGreater(len(cmd_output.lines), 2) self.assertTrue(cmd_output.lines[0].startswith( "Error occurred during handling of command")) self.assertTrue(cmd_output.lines[1].endswith(self._intentional_error_msg))
def testRegisterAndInvokeHandlerWithAliases(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler( "noop", self._noop_handler, "", prefix_aliases=["n", "NOOP"]) # is_registered() should work for full prefix and aliases. self.assertTrue(registry.is_registered("noop")) self.assertTrue(registry.is_registered("n")) self.assertTrue(registry.is_registered("NOOP")) cmd_output = registry.dispatch_command("n", []) self.assertEqual(["Done."], cmd_output.lines) cmd_output = registry.dispatch_command("NOOP", []) self.assertEqual(["Done."], cmd_output.lines)
def testExitingHandler(self): """Test that exit exception is correctly raised.""" registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("exit", self._exiting_handler, "") self.assertTrue(registry.is_registered("exit")) exit_token = None try: registry.dispatch_command("exit", ["foo"]) except debugger_cli_common.CommandLineExit as e: exit_token = e.exit_token self.assertEqual("foo", exit_token)
def testHelpCommandWithIntro(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("noop", self._noop_handler, "No operation.\nI.e., do nothing.", prefix_aliases=["n", "NOOP"]) help_intro = ["Introductory comments.", ""] registry.set_help_intro(help_intro) output = registry.dispatch_command("help", []) self.assertEqual( help_intro + [ "help", " Aliases: h", "", " Print this help message.", "", "", "noop", " Aliases: n, NOOP", "", " No operation.", " I.e., do nothing.", "", "" ], output.lines)
def testRegisterAndInvokeHandler(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("noop", self._noop_handler, "") self.assertTrue(registry.is_registered("noop")) self.assertFalse(registry.is_registered("beep")) cmd_output = registry.dispatch_command("noop", []) self.assertEqual(["Done."], cmd_output.lines) # Attempt to invoke an unregistered command prefix should trigger an # exception. with self.assertRaisesRegexp(ValueError, "No handler is registered"): registry.dispatch_command("beep", []) # Empty command prefix should trigger an exception. with self.assertRaisesRegexp(ValueError, "Prefix is empty"): registry.dispatch_command("", [])
def setUpClass(cls): cls._dump_root = tempfile.mkdtemp() with session.Session() as sess: loop_var = constant_op.constant(0, name="while_loop_test/loop_var") cond = lambda loop_var: math_ops.less(loop_var, 10) body = lambda loop_var: math_ops.add(loop_var, 1) while_loop = control_flow_ops.while_loop(cond, body, [loop_var], parallel_iterations=1) run_options = config_pb2.RunOptions(output_partition_graphs=True) debug_url = "file://%s" % cls._dump_root watch_opts = run_options.debug_options.debug_tensor_watch_opts # Add debug tensor watch for "while/Identity". watch = watch_opts.add() watch.node_name = "while/Identity" watch.output_slot = 0 watch.debug_ops.append("DebugIdentity") watch.debug_urls.append(debug_url) # Invoke Session.run(). run_metadata = config_pb2.RunMetadata() sess.run(while_loop, options=run_options, run_metadata=run_metadata) cls._debug_dump = debug_data.DebugDumpDir( cls._dump_root, partition_graphs=run_metadata.partition_graphs) cls._analyzer = analyzer_cli.DebugAnalyzer(cls._debug_dump) cls._registry = debugger_cli_common.CommandHandlerRegistry() cls._registry.register_command_handler( "list_tensors", cls._analyzer.list_tensors, cls._analyzer.get_help("list_tensors"), prefix_aliases=["lt"]) cls._registry.register_command_handler( "print_tensor", cls._analyzer.print_tensor, cls._analyzer.get_help("print_tensor"), prefix_aliases=["pt"])
def testHelpCommandWithIntro(self): registry = debugger_cli_common.CommandHandlerRegistry() registry.register_command_handler("noop", self._noop_handler, "No operation.\nI.e., do nothing.", prefix_aliases=["n", "NOOP"]) help_intro = debugger_cli_common.RichTextLines( ["Introductory comments.", ""]) registry.set_help_intro(help_intro) output = registry.dispatch_command("help", []) self.assertEqual( help_intro.lines + [ "help", " Aliases: h", "", " Print this help message.", "", "", "noop", " Aliases: n, NOOP", "", " No operation.", " I.e., do nothing.", "", "", "version", " Aliases: ver", "", " Print the versions of TensorFlow and its key dependencies.", "", "" ], output.lines)
def __init__(self, on_ui_exit=None): """Constructor of the base class. Args: on_ui_exit: (`Callable`) the callback to be called when the UI exits. """ self._on_ui_exit = on_ui_exit self._command_handler_registry = ( debugger_cli_common.CommandHandlerRegistry()) self._tab_completion_registry = debugger_cli_common.TabCompletionRegistry( ) # Create top-level tab-completion context and register the exit and help # commands. self._tab_completion_registry.register_tab_comp_context( [""], self.CLI_EXIT_COMMANDS + [debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND] + debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND_ALIASES)
def __init__(self, on_ui_exit=None, config=None): """Constructor of the base class. Args: on_ui_exit: (`Callable`) the callback to be called when the UI exits. config: An instance of `cli_config.CLIConfig()` carrying user-facing configurations. """ self._on_ui_exit = on_ui_exit self._command_handler_registry = ( debugger_cli_common.CommandHandlerRegistry()) self._tab_completion_registry = debugger_cli_common.TabCompletionRegistry( ) # Create top-level tab-completion context and register the exit and help # commands. self._tab_completion_registry.register_tab_comp_context( [""], self.CLI_EXIT_COMMANDS + [debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND] + debugger_cli_common.CommandHandlerRegistry.HELP_COMMAND_ALIASES) self._config = config or cli_config.CLIConfig() self._config_argparser = argparse.ArgumentParser( description="config command", usage=argparse.SUPPRESS) subparsers = self._config_argparser.add_subparsers() set_parser = subparsers.add_parser("set") set_parser.add_argument("property_name", type=str) set_parser.add_argument("property_value", type=str) set_parser = subparsers.add_parser("show") self.register_command_handler("config", self._config_command_handler, self._config_argparser.format_help(), prefix_aliases=["cfg"])
def testRegisterNonCallableHandler(self): registry = debugger_cli_common.CommandHandlerRegistry() # Attempt to register a non-callable handler should fail. with self.assertRaisesRegexp(ValueError, "handler is not callable"): registry.register_command_handler("non_callable", 1, "")
def testRegisterHandlerWithInvalidHelpInfoType(self): registry = debugger_cli_common.CommandHandlerRegistry() with self.assertRaisesRegexp(ValueError, "help_info is not a str"): registry.register_command_handler("noop", self._noop_handler, ["foo"])