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)
Exemple #5
0
    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"))
Exemple #6
0
    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
Exemple #7
0
    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"])
Exemple #9
0
    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)
Exemple #15
0
    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)
Exemple #19
0
    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("", [])
Exemple #21
0
    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)
Exemple #23
0
    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)
Exemple #24
0
    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"])