Commit 9047de5e authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[master] Merge branch 'trac2254'

parents 26e55ce1 ae8740e0
......@@ -22,7 +22,7 @@ import sys
from cmd import Cmd
from bindctl.exception import *
from bindctl.moduleinfo import *
from bindctl.cmdparse import BindCmdParse
from bindctl.cmdparse import BindCmdParser
from bindctl import command_sets
from xml.dom import minidom
import isc
......@@ -48,20 +48,21 @@ except ImportError:
# if we have readline support, use that, otherwise use normal stdio
try:
import readline
# This is a fix for the problem described in
# http://bind10.isc.org/ticket/1345
# If '-' is seen as a word-boundary, the final completion-step
# (as handled by the cmd module, and hence outside our reach) can
# mistakenly add data twice, resulting in wrong completion results
# The solution is to remove it.
delims = readline.get_completer_delims()
delims = delims.replace('-', '')
readline.set_completer_delims(delims)
# Only consider spaces as word boundaries; identifiers can contain
# '/' and '[]', and configuration item names can in theory use any
# printable character. See the discussion in tickets #1345 and
# #2254 for more information.
readline.set_completer_delims(' ')
my_readline = readline.get_line_buffer
except ImportError:
my_readline = sys.stdin.readline
# Used for tab-completion of 'identifiers' (i.e. config values)
# If a command parameter has this name, the tab completion hints
# are derived from config data
CFGITEM_IDENTIFIER_PARAM = 'identifier'
CSV_FILE_NAME = 'default_user.csv'
CONFIG_MODULE_NAME = 'config'
CONST_BINDCTL_HELP = """
......@@ -463,41 +464,101 @@ class BindCmdInterpreter(Cmd):
Cmd.onecmd(self, line)
def remove_prefix(self, list, prefix):
"""Removes the prefix already entered, and all elements from the
list that don't match it"""
if prefix.startswith('/'):
prefix = prefix[1:]
new_list = []
for val in list:
if val.startswith(prefix):
new_val = val[len(prefix):]
if new_val.startswith("/"):
new_val = new_val[1:]
new_list.append(new_val)
return new_list
def _get_identifier_startswith(self, id_text):
"""Return the tab-completion hints for identifiers starting with
id_text.
Parameters:
id_text (string): the currently entered identifier part, which
is to be completed.
"""
# Strip starting "/" from id_text
if id_text.startswith('/'):
id_text = id_text[1:]
# Get all items from the given module (up to the first /)
list = self.config_data.get_config_item_list(
id_text.rpartition("/")[0], recurse=True)
# filter out all possibilities that don't match currently entered
# text part
hints = [val for val in list if val.startswith(id_text)]
return hints
def _cmd_has_identifier_param(self, cmd):
"""
Returns True if the given (parsed) command is known and has a
parameter which points to a config data identifier
Parameters:
cmd (cmdparse.BindCmdParser): command context, including given params
"""
if cmd.module not in self.modules:
return False
command = self.modules[cmd.module].get_command_with_name(cmd.command)
return command.has_param_with_name(CFGITEM_IDENTIFIER_PARAM)
def complete(self, text, state):
if 0 == state:
"""
Returns tab-completion hints. See the python documentation of the
readline and Cmd modules for more information.
The first time this is called (within one 'completer' action), it
has state 0, and a list of possible completions is made. This list
is stored; complete() will then be called with increasing values of
state, until it returns None. For each call it returns the state'th
element of the hints it collected in the first call.
The hints list contents depend on which part of the full command
line; if no module is given yet, it will list all modules. If a
module is given, but no command, it will complete with module
commands. If both have been given, it will create the hints based on
the command parameters.
If module and command have already been specified, and the command
has a parameter 'identifier', the configuration data is used to
create the hints list.
Parameters:
text (string): The text entered so far in the 'current' part of
the command (module, command, parameters)
state (int): state used in the readline tab-completion logic;
0 on first call, increasing by one until there are
no (more) hints to return.
Returns the string value of the hints list with index 'state',
or None if no (more) hints are available.
"""
if state == 0:
self._update_all_modules_info()
text = text.strip()
hints = []
cur_line = my_readline()
try:
cmd = BindCmdParse(cur_line)
cmd = BindCmdParser(cur_line)
if not cmd.params and text:
hints = self._get_command_startswith(cmd.module, text)
elif self._cmd_has_identifier_param(cmd):
# If the command has an argument that is a configuration
# identifier (currently, this is only a subset of
# the config commands), then don't tab-complete with
# hints derived from command parameters, but from
# possible configuration identifiers.
#
# This solves the issue reported in #2254, where
# there were hints such as 'argument' and 'identifier'.
#
# Since they are replaced, the tab-completion no longer
# adds 'help' as an option (but it still works)
#
# Also, currently, tab-completion does not work
# together with 'config go' (it does not take 'current
# position' into account). But config go currently has
# problems by itself, unrelated to completion.
hints = self._get_identifier_startswith(text)
else:
hints = self._get_param_startswith(cmd.module, cmd.command,
text)
if cmd.module == CONFIG_MODULE_NAME:
# grm text has been stripped of slashes...
my_text = self.location + "/" + cur_line.rpartition(" ")[2]
list = self.config_data.get_config_item_list(my_text.rpartition("/")[0], True)
hints.extend([val for val in list if val.startswith(my_text[1:])])
# remove the common prefix from the hints so we don't get it twice
hints = self.remove_prefix(hints, my_text.rpartition("/")[0])
except CmdModuleNameFormatError:
if not text:
hints = self.get_module_names()
......@@ -562,7 +623,7 @@ class BindCmdInterpreter(Cmd):
def _parse_cmd(self, line):
try:
cmd = BindCmdParse(line)
cmd = BindCmdParser(line)
self._validate_cmd(cmd)
self._handle_cmd(cmd)
except (IOError, http.client.HTTPException) as err:
......@@ -794,7 +855,7 @@ class BindCmdInterpreter(Cmd):
else:
print("Warning: ignoring unknown directive: " + line)
else:
cmd = BindCmdParse(line)
cmd = BindCmdParser(line)
self._validate_cmd(cmd)
self._handle_cmd(cmd)
except (isc.config.ModuleCCSessionError,
......
......@@ -42,16 +42,19 @@ def prepare_config_commands(tool):
cmd = CommandInfo(name = "show", desc = "Show configuration.")
param = ParamInfo(name = "argument", type = "string", optional=True, desc = "If you specify the argument 'all' (before the identifier), recursively show all child elements for the given identifier.")
cmd.add_param(param)
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=True, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "show_json", desc = "Show full configuration in JSON format.")
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd = CommandInfo(name="show_json",
desc="Show full configuration in JSON format.")
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=True, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "add", desc =
cmd = CommandInfo(name="add", desc=
"Add an entry to configuration list or a named set. "
"When adding to a list, the command has one optional argument, "
"a value to add to the list. The value must be in correct JSON "
......@@ -60,45 +63,53 @@ def prepare_config_commands(tool):
"parameter value, similar to when adding to a list. "
"In either case, when no value is given, an entry will be "
"constructed with default values.")
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=True, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
param = ParamInfo(name = "value_or_name", type = "string", optional=True, desc = "Specifies a value to add to the list, or the name when adding to a named set. It must be in correct JSON format and complete.")
param = ParamInfo(name="value_or_name", type="string", optional=True,
desc="Specifies a value to add to the list, or the name when adding to a named set. It must be in correct JSON format and complete.")
cmd.add_param(param)
module.add_command(cmd)
param = ParamInfo(name = "value_for_set", type = "string", optional=True, desc = "Specifies an optional value to add to the named map. It must be in correct JSON format and complete.")
param = ParamInfo(name="value_for_set", type="string", optional=True,
desc="Specifies an optional value to add to the named map. It must be in correct JSON format and complete.")
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "remove", desc = "Remove entry from configuration list or named set.")
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd = CommandInfo(name="remove", desc="Remove entry from configuration list or named set.")
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=True, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
param = ParamInfo(name = "value", type = "string", optional=True, desc = "When identifier is a list, specifies a value to remove from the list. It must be in correct JSON format and complete. When it is a named set, specifies the name to remove.")
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "set", desc = "Set a configuration value.")
param = ParamInfo(name = "identifier", type = "string", optional=True, desc = DEFAULT_IDENTIFIER_DESC)
cmd = CommandInfo(name="set", desc="Set a configuration value.")
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=True, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
param = ParamInfo(name = "value", type = "string", optional=False, desc = "Specifies a value to set. It must be in correct JSON format and complete.")
param = ParamInfo(name="value", type="string", optional=False,
desc="Specifies a value to set. It must be in correct JSON format and complete.")
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "unset", desc = "Unset a configuration value (i.e. revert to the default, if any).")
param = ParamInfo(name = "identifier", type = "string", optional=False, desc = DEFAULT_IDENTIFIER_DESC)
cmd = CommandInfo(name="unset", desc="Unset a configuration value (i.e. revert to the default, if any).")
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=False, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
cmd = CommandInfo(name = "diff", desc = "Show all local changes that have not been committed.")
cmd = CommandInfo(name="diff", desc="Show all local changes that have not been committed.")
module.add_command(cmd)
cmd = CommandInfo(name = "revert", desc = "Revert all local changes.")
cmd = CommandInfo(name="revert", desc="Revert all local changes.")
module.add_command(cmd)
cmd = CommandInfo(name = "commit", desc = "Commit all local changes.")
cmd = CommandInfo(name="commit", desc="Commit all local changes.")
module.add_command(cmd)
cmd = CommandInfo(name = "go", desc = "Go to a specific configuration part.")
param = ParamInfo(name = "identifier", type="string", optional=False, desc = DEFAULT_IDENTIFIER_DESC)
cmd = CommandInfo(name="go", desc="Go to a specific configuration part.")
param = ParamInfo(name=CFGITEM_IDENTIFIER_PARAM, type="string",
optional=False, desc=DEFAULT_IDENTIFIER_DESC)
cmd.add_param(param)
module.add_command(cmd)
......
......@@ -25,7 +25,7 @@ except ImportError:
param_name_str = "^\s*(?P<param_name>[\w]+)\s*=\s*"
# The value string can be a sequence without space or comma
# The value string can be a sequence without space or comma
# characters, or a string surroundedby quotation marks(such marks
# can be part of string in an escaped form)
#param_value_str = "(?P<param_value>[\"\'].+?(?<!\\\)[\"\']|[^\'\"][^, ]+)"
......@@ -34,8 +34,8 @@ param_value_with_quota_str = "[\"\'](?P<param_value>.+?)(?<!\\\)[\"\']"
next_params_str = "(?P<blank>\s*)(?P<comma>,?)(?P<next_params>.*)$"
PARAM_WITH_QUOTA_PATTERN = re.compile(param_name_str +
param_value_with_quota_str +
PARAM_WITH_QUOTA_PATTERN = re.compile(param_name_str +
param_value_with_quota_str +
next_params_str)
PARAM_PATTERN = re.compile(param_name_str + param_value_str + next_params_str)
# Used for module and command name
......@@ -83,52 +83,52 @@ def _remove_list_and_map_whitespace(text):
if map_count == 0:
result.append(_remove_unquoted_whitespace(text[cur_start_map_pos:pos + 1]))
start_pos = pos + 1
pos = pos + 1
if start_pos <= len(text):
result.append(text[start_pos:len(text)])
return "".join(result)
class BindCmdParse:
class BindCmdParser:
""" This class will parse the command line user input into three parts:
module name, command, parameters
the first two parts are strings and parameter is one hash,
the first two parts are strings and parameter is one hash,
parameters part is optional
Example: zone reload, zone_name=example.com
Example: zone reload, zone_name=example.com
module == zone
command == reload
params == [zone_name = 'example.com']
"""
def __init__(self, cmd):
self.params = OrderedDict()
self.module = ''
self.command = ''
self._parse_cmd(cmd)
def _parse_cmd(self, text_str):
def _parse_cmd(self, text_str):
'''Parse command line. '''
# Get module name
groups = NAME_PATTERN.match(text_str)
if not groups:
raise CmdModuleNameFormatError
self.module = groups.group('name')
cmd_str = groups.group('others')
if cmd_str:
if not groups.group('blank'):
raise CmdModuleNameFormatError
else:
else:
raise CmdMissCommandNameFormatError(self.module)
# Get command name
groups = NAME_PATTERN.match(cmd_str)
if (not groups):
raise CmdCommandNameFormatError(self.module)
self.command = groups.group('name')
param_str = groups.group('others')
if param_str:
......@@ -143,7 +143,7 @@ class BindCmdParse:
def _parse_params(self, param_text):
"""convert a=b,c=d into one hash """
param_text = _remove_list_and_map_whitespace(param_text)
# Check parameter name "help"
param = NAME_PATTERN.match(param_text)
if param and param.group('name') == "help":
......@@ -153,7 +153,7 @@ class BindCmdParse:
while True:
if not param_text.strip():
break
groups = PARAM_PATTERN.match(param_text) or \
PARAM_WITH_QUOTA_PATTERN.match(param_text)
if not groups:
......
......@@ -40,14 +40,14 @@ except ImportError:
class TestCmdLex(unittest.TestCase):
def my_assert_raise(self, exception_type, cmd_line):
self.assertRaises(exception_type, cmdparse.BindCmdParse, cmd_line)
self.assertRaises(exception_type, cmdparse.BindCmdParser, cmd_line)
def testCommandWithoutParameter(self):
cmd = cmdparse.BindCmdParse("zone add")
assert cmd.module == "zone"
assert cmd.command == "add"
self.assertEqual(len(cmd.params), 0)
cmd_parser = cmdparse.BindCmdParser("zone add")
assert cmd_parser.module == "zone"
assert cmd_parser.command == "add"
self.assertEqual(len(cmd_parser.params), 0)
def testCommandWithParameters(self):
......@@ -56,45 +56,51 @@ class TestCmdLex(unittest.TestCase):
"zone add zone_name = 'cnnic.cn\", file ='cnnic.cn.file' master=1.1.1.1, " }
for cmd_line in lines:
cmd = cmdparse.BindCmdParse(cmd_line)
assert cmd.module == "zone"
assert cmd.command == "add"
assert cmd.params["zone_name"] == "cnnic.cn"
assert cmd.params["file"] == "cnnic.cn.file"
assert cmd.params["master"] == '1.1.1.1'
cmd_parser = cmdparse.BindCmdParser(cmd_line)
assert cmd_parser.module == "zone"
assert cmd_parser.command == "add"
assert cmd_parser.params["zone_name"] == "cnnic.cn"
assert cmd_parser.params["file"] == "cnnic.cn.file"
assert cmd_parser.params["master"] == '1.1.1.1'
def testCommandWithParamters_2(self):
'''Test whether the parameters in key=value can be parsed properly.'''
cmd = cmdparse.BindCmdParse('zone cmd name = 1:34::2')
self.assertEqual(cmd.params['name'], '1:34::2')
cmd = cmdparse.BindCmdParse('zone cmd name = 1\"\'34**&2 value=44\"\'\"')
self.assertEqual(cmd.params['name'], '1\"\'34**&2')
self.assertEqual(cmd.params['value'], '44\"\'\"')
cmd = cmdparse.BindCmdParse('zone cmd name = 1\"\'34**&2 ,value= 44\"\'\"')
self.assertEqual(cmd.params['name'], '1\"\'34**&2')
self.assertEqual(cmd.params['value'], '44\"\'\"')
cmd = cmdparse.BindCmdParse('zone cmd name = 1\'34**&2value=44\"\'\" value = \"==============\'')
self.assertEqual(cmd.params['name'], '1\'34**&2value=44\"\'\"')
self.assertEqual(cmd.params['value'], '==============')
cmd = cmdparse.BindCmdParse('zone cmd name = \"1234, 567890 \" value ==&*/')
self.assertEqual(cmd.params['name'], '1234, 567890 ')
self.assertEqual(cmd.params['value'], '=&*/')
cmd_parser = cmdparse.BindCmdParser('zone cmd name = 1:34::2')
self.assertEqual(cmd_parser.params['name'], '1:34::2')
cmd_parser = cmdparse.BindCmdParser('zone cmd name = 1\"\'34**&2'
' value=44\"\'\"')
self.assertEqual(cmd_parser.params['name'], '1\"\'34**&2')
self.assertEqual(cmd_parser.params['value'], '44\"\'\"')
cmd_parser = cmdparse.BindCmdParser('zone cmd name = 1\"\'34**&2'
',value= 44\"\'\"')
self.assertEqual(cmd_parser.params['name'], '1\"\'34**&2')
self.assertEqual(cmd_parser.params['value'], '44\"\'\"')
cmd_parser = cmdparse.BindCmdParser('zone cmd name = 1\'34**&2'
'value=44\"\'\" value = '
'\"==============\'')
self.assertEqual(cmd_parser.params['name'], '1\'34**&2value=44\"\'\"')
self.assertEqual(cmd_parser.params['value'], '==============')
cmd_parser = cmdparse.BindCmdParser('zone cmd name = \"1234, '
'567890 \" value ==&*/')
self.assertEqual(cmd_parser.params['name'], '1234, 567890 ')
self.assertEqual(cmd_parser.params['value'], '=&*/')
def testCommandWithListParam(self):
cmd = cmdparse.BindCmdParse("zone set zone_name='cnnic.cn', master='1.1.1.1, 2.2.2.2'")
assert cmd.params["master"] == '1.1.1.1, 2.2.2.2'
cmd_parser = cmdparse.BindCmdParser("zone set zone_name='cnnic.cn', "
"master='1.1.1.1, 2.2.2.2'")
assert cmd_parser.params["master"] == '1.1.1.1, 2.2.2.2'
def testCommandWithHelpParam(self):
cmd = cmdparse.BindCmdParse("zone add help")
assert cmd.params["help"] == "help"
cmd_parser = cmdparse.BindCmdParser("zone add help")
assert cmd_parser.params["help"] == "help"
cmd = cmdparse.BindCmdParse("zone add help *&)&)*&&$#$^%")
assert cmd.params["help"] == "help"
self.assertEqual(len(cmd.params), 1)
cmd_parser = cmdparse.BindCmdParser("zone add help *&)&)*&&$#$^%")
assert cmd_parser.params["help"] == "help"
self.assertEqual(len(cmd_parser.params), 1)
def testCmdModuleNameFormatError(self):
......@@ -130,15 +136,20 @@ class TestCmdSyntax(unittest.TestCase):
int_spec = { 'item_type' : 'integer',
'item_optional' : False,
'item_default' : 10}
zone_file_param = ParamInfo(name = "zone_file", param_spec = string_spec)
zone_file_param = ParamInfo(name = "zone_file",
param_spec = string_spec)
zone_name = ParamInfo(name = 'zone_name', param_spec = string_spec)
load_cmd = CommandInfo(name = "load")
load_cmd.add_param(zone_file_param)
load_cmd.add_param(zone_name)
param_master = ParamInfo(name = "master", optional = True, param_spec = string_spec)
param_master = ParamInfo(name = "port", optional = True, param_spec = int_spec)
param_allow_update = ParamInfo(name = "allow_update", optional = True, param_spec = string_spec)
param_master = ParamInfo(name = "master", optional = True,
param_spec = string_spec)
param_master = ParamInfo(name = "port", optional = True,
param_spec = int_spec)
param_allow_update = ParamInfo(name = "allow_update",
optional = True,
param_spec = string_spec)
set_cmd = CommandInfo(name = "set")
set_cmd.add_param(param_master)
set_cmd.add_param(param_allow_update)
......@@ -160,13 +171,14 @@ class TestCmdSyntax(unittest.TestCase):
def no_assert_raise(self, cmd_line):
cmd = cmdparse.BindCmdParse(cmd_line)
self.bindcmd._validate_cmd(cmd)
cmd_parser = cmdparse.BindCmdParser(cmd_line)
self.bindcmd._validate_cmd(cmd_parser)
def my_assert_raise(self, exception_type, cmd_line):
cmd = cmdparse.BindCmdParse(cmd_line)
self.assertRaises(exception_type, self.bindcmd._validate_cmd, cmd)
cmd_parser = cmdparse.BindCmdParser(cmd_line)
self.assertRaises(exception_type, self.bindcmd._validate_cmd,
cmd_parser)
def testValidateSuccess(self):
......@@ -177,7 +189,8 @@ class TestCmdSyntax(unittest.TestCase):
self.no_assert_raise("zone help help='dd' ")
self.no_assert_raise("zone set allow_update='1.1.1.1' zone_name='cn'")
self.no_assert_raise("zone set zone_name='cn'")
self.my_assert_raise(isc.cc.data.DataTypeError, "zone set zone_name ='cn', port='cn'")
self.my_assert_raise(isc.cc.data.DataTypeError,
"zone set zone_name ='cn', port='cn'")
self.no_assert_raise("zone reload_all")
def testCmdUnknownModuleSyntaxError(self):
......@@ -188,15 +201,22 @@ class TestCmdSyntax(unittest.TestCase):
self.my_assert_raise(CmdUnknownCmdSyntaxError, "zone dd")
def testCmdMissParamSyntaxError(self):
self.my_assert_raise(CmdMissParamSyntaxError, "zone load zone_file='cn'")
self.my_assert_raise(CmdMissParamSyntaxError, "zone load zone_name='cn'")
self.my_assert_raise(CmdMissParamSyntaxError, "zone set allow_update='1.1.1.1'")
self.my_assert_raise(CmdMissParamSyntaxError, "zone set ")
self.my_assert_raise(CmdMissParamSyntaxError,
"zone load zone_file='cn'")
self.my_assert_raise(CmdMissParamSyntaxError,
"zone load zone_name='cn'")
self.my_assert_raise(CmdMissParamSyntaxError,
"zone set allow_update='1.1.1.1'")
self.my_assert_raise(CmdMissParamSyntaxError,
"zone set ")
def testCmdUnknownParamSyntaxError(self):
self.my_assert_raise(CmdUnknownParamSyntaxError, "zone load zone_d='cn'")
self.my_assert_raise(CmdUnknownParamSyntaxError, "zone reload_all zone_name = 'cn'")
self.my_assert_raise(CmdUnknownParamSyntaxError, "zone help a b c")
self.my_assert_raise(CmdUnknownParamSyntaxError,
"zone load zone_d='cn'")
self.my_assert_raise(CmdUnknownParamSyntaxError,
"zone reload_all zone_name = 'cn'")
self.my_assert_raise(CmdUnknownParamSyntaxError,
"zone help a b c")
class TestModuleInfo(unittest.TestCase):
......@@ -233,7 +253,8 @@ class TestNameSequence(unittest.TestCase):
self.tool.add_module_info(ModuleInfo(name = random_str))
def setUp(self):
self.random_names = ['1erdfeDDWsd', '3fe', '2009erd', 'Fe231', 'tere142', 'rei8WD']
self.random_names = ['1erdfeDDWsd', '3fe', '2009erd',
'Fe231', 'tere142', 'rei8WD']
self._create_bindcmd()
def testSequence(self):
......@@ -321,7 +342,8 @@ class TestConfigCommands(unittest.TestCase):
def precmd(line):
self.tool.precmd(line)
self.tool._update_all_modules_info = update_all_modules_info
# If line is equals to 'EOF', _update_all_modules_info() shouldn't be called
# If line is equals to 'EOF', _update_all_modules_info()
# shouldn't be called
precmd('EOF')
self.assertRaises(socket.error, precmd, 'continue')
......@@ -360,34 +382,41 @@ class TestConfigCommands(unittest.TestCase):
self.assertEqual((1, MultiConfigData.DEFAULT),
self.tool.config_data.get_value("/foo/an_int"))
cmd = cmdparse.BindCmdParse("config set identifier=\"foo/an_int\" value=\"5\"")
self.tool.apply_config_cmd(cmd)
cmd_parser = cmdparse.BindCmdParser('config set identifier='
'"foo/an_int" value="5"')
self.tool.apply_config_cmd(cmd_parser)
self.assertEqual((5, MultiConfigData.LOCAL),
self.tool.config_data.get_value("/foo/an_int"))
cmd = cmdparse.BindCmdParse("config unset identifier=\"foo/an_int\"")
self.tool.apply_config_cmd(cmd)
cmd_parser = cmdparse.BindCmdParser('config unset identifier='
'"foo/an_int"')
self.tool.apply_config_cmd(cmd_parser)
self.assertEqual((1, MultiConfigData.DEFAULT),
self.tool.config_data.get_value("/foo/an_int"))
# this should raise a NotFoundError
cmd = cmdparse.BindCmdParse("config set identifier=\"foo/bar\" value=\"[]\"")
self.assertRaises(isc.cc.data.DataNotFoundError, self.tool.apply_config_cmd, cmd)
cmd_parser = cmdparse.BindCmdParser('config set identifier='
'"foo/bar" value="[]"')
self.assertRaises(isc.cc.data.DataNotFoundError,
self.tool.apply_config_cmd, cmd_parser)
cmd = cmdparse.BindCmdParse("config unset identifier=\"foo/bar\"")
cmd_parser = cmdparse.BindCmdParser('config unset identifier='