[svn] commit: r116 - in /experiments/likun-bigtool: README lib/bigtool.py lib/command.py lib/exception.py lib/moduleinfo.py test_bigtool.py test_command.py
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Oct 24 12:37:08 UTC 2009
Author: zhanglikun
Date: Sat Oct 24 12:37:08 2009
New Revision: 116
Log:
Commit code of version2.
Main Changes:
1. Add help information.
2. Change command line syntax.
Modified:
experiments/likun-bigtool/README
experiments/likun-bigtool/lib/bigtool.py
experiments/likun-bigtool/lib/command.py
experiments/likun-bigtool/lib/exception.py
experiments/likun-bigtool/lib/moduleinfo.py
experiments/likun-bigtool/test_bigtool.py
experiments/likun-bigtool/test_command.py
Modified: experiments/likun-bigtool/README
==============================================================================
--- experiments/likun-bigtool/README (original)
+++ experiments/likun-bigtool/README Sat Oct 24 12:37:08 2009
@@ -1,4 +1,8 @@
1. Run the bigtool mock-up by input "python3 test_bigtool.py"
+
+
+TODO:
+ 1. Add multilingual internationalization services.
Modified: experiments/likun-bigtool/lib/bigtool.py
==============================================================================
--- experiments/likun-bigtool/lib/bigtool.py (original)
+++ experiments/likun-bigtool/lib/bigtool.py Sat Oct 24 12:37:08 2009
@@ -1,67 +1,83 @@
import sys
import readline
+import collections
from cmd import Cmd
from lib.exception import *
from lib.moduleinfo import ModuleInfo
from lib.command import BigToolCmd
+CONST_BIGTOOL_HELP = """Bigtool, verstion 0.1
+usage: <module name> <command name> [param1 = value1 [, param2 = value2]]
+Type Tab character to get the hint of module/command/paramters.
+Type \"help(? h)\" for help on bigtool.
+Type \"<module_name> help\" for help on the specific module.
+Type \"<module_name> <command_name> help\" for help on the specific command.
+\nAvailable module names: """
+
class BigTool(Cmd):
- """simple bigtool command example."""
-
- doc_leader = ""
- doc_header = "sub commands (type help <topic>):"
+ """simple bigtool command example."""
def __init__(self):
Cmd.__init__(self)
self.prompt = '> '
self.ruler = '-'
- self.modules = {}
- self.complete_hint = []
-
- def parse_cmd(self, line):
- try:
- cmd = BigToolCmd(line)
- self._validate_cmd(cmd)
- self._handle_cmd(cmd)
- except BigToolException as e:
- print(e)
-
-
- def _validate_cmd(self, cmd):
- if not cmd.module_name in self.modules:
- raise UnknownModule(cmd.module_name)
-
- module_info = self.modules[cmd.module_name]
- if not module_info.has_command_with_name(cmd.command_name):
- raise UnknownCmd(cmd.module_name, cmd.command_name)
-
- command_info = module_info.get_command_with_name(cmd.command_name)
- support_params = command_info.get_parameter_names()
- if not cmd.parameters and support_params:
- raise MissingParameter(cmd.module_name, cmd.command_name, support_params[0])
- elif cmd.parameters and not support_params:
- raise UnknownParameter(cmd.module_name, cmd.command_name, list(cmd.parameters.keys())[0])
- elif cmd.parameters:
- for param in cmd.parameters:
- if not param in support_params:
- raise UnknownParameter(cmd.module_name, cmd.command_name, param)
- for param in support_params:
- if not param in cmd.parameters:
- raise MissingParameter(cmd.module_name, cmd.command_name, param)
-
+ self.modules = collections.OrderedDict()
+ self.add_module_info(ModuleInfo("help", desc = "Get help for bigtool"))
+
+
+ def validate_cmd(self, cmd):
+ if not cmd.module in self.modules:
+ raise CmdUnknownModuleSyntaxError(cmd.module)
+
+ module_info = self.modules[cmd.module]
+ if not module_info.has_command_with_name(cmd.command):
+ raise CmdUnknownCmdSyntaxError(cmd.module, cmd.command)
+
+ command_info = module_info.get_command_with_name(cmd.command)
+ manda_params = command_info.get_mandatory_param_names()
+ all_params = command_info.get_param_names()
+ if command_info.need_instance_param():
+ inst_name = module_info.get_instance_param_name()
+ if inst_name:
+ manda_params.append(inst_name)
+ all_params.append(inst_name)
+
+ # If help is inputed, don't do further paramters validation.
+ for val in cmd.params.keys():
+ if val == "help":
+ return
+
+ params = cmd.params.copy()
+ if not params and manda_params:
+ raise CmdMissParamSyntaxError(cmd.module, cmd.command, manda_params[0])
+ elif params and not all_params:
+ raise CmdUnknownParamSyntaxError(cmd.module, cmd.command,
+ list(params.keys())[0])
+ elif params:
+ for name in params:
+ if not name in all_params:
+ raise CmdUnknownParamSyntaxError(cmd.module, cmd.command, name)
+ for name in manda_params:
+ if not name in params:
+ raise CmdMissParamSyntaxError(cmd.module, cmd.command, name)
+
def _handle_cmd(self, cmd):
#to do, consist xml package and send to bind10
- pass
-
- def add_module_info(self, module_info):
- if not isinstance(module_info, ModuleInfo):
- raise UnknownModule(type(module_info))
+ if cmd.command == "help" or ("help" in cmd.params.keys()):
+ self._handle_help(cmd)
+ else:
+ self._temp_print_parse_result(cmd)
+
+ def add_module_info(self, module_info):
self.modules[module_info.name] = module_info
+
+ def get_module_names(self):
+ return list(self.modules.keys())
#override methods in cmd
- def default(self, line):
- self.parse_cmd(line)
+ def default(self, line):
+ self._parse_cmd(line)
def emptyline(self):
pass
@@ -72,67 +88,146 @@
except KeyboardInterrupt:
return True
- def do_help(self, module_name):
- if module_name in self.modules.keys():
- print(self.modules[module_name].desc)
- else:
- print("Unknow module")
+ def do_help(self, name):
+ print(CONST_BIGTOOL_HELP)
+ for k in self.modules.keys():
+ print("\t", self.modules[k])
+
def onecmd(self, line):
if line == 'EOF'or line.lower() == "quit":
return True
+
+ if line == 'h':
+ line = 'help'
+
Cmd.onecmd(self, line)
def complete(self, text, state):
if 0 == state:
- self.complete_hint = []
- current_input_line = readline.get_line_buffer()
+ text = text.strip()
+ hints = []
+ cur_line = readline.get_line_buffer()
try:
- cmd = BigToolCmd(current_input_line)
- if cmd.parameters:
- self.complete_hint = self._get_support_parameters_startswith_name(cmd.module_name, cmd.command_name, text)
- else:
- self.complete_hint = self._get_support_commands_startswith_name(cmd.module_name, text)
+ cmd = BigToolCmd(cur_line)
+ if not cmd.params and text:
+ hints = self._get_command_startswith(cmd.module, text)
+ else:
+ hints = self._get_param_startswith(cmd.module, cmd.command,
+ text)
+ except CmdModuleNameFormatError:
+ if not text:
+ hints = list(self.modules.keys())
-
- except CmdWithoutModuleName:
- self.complete_hint = list(self.modules.keys())
-
- except CmdWithoutCommandName as e:
- if e.module_name in self.modules and text == "":
- self.complete_hint = self.modules[e.module_name].get_command_names()
- else:
- self.complete_hint = self._get_support_modules_startswith_name(text)
-
- except CmdParameterFormatError as e:
- self.complete_hint = self._get_support_parameters_startswith_name(e.module_name, e.command_name, text)
+ except CmdMissCommandNameFormatError as e:
+ if not text.strip(): # command name is empty
+ hints = self.modules[e.module].get_command_names()
+ else:
+ hints = self._get_module_startswith(text)
+
+ except CmdCommandNameFormatError as e:
+ if e.module in self.modules:
+ hints = self._get_command_startswith(e.module, text)
+
+ except CmdParamFormatError as e:
+ hints = self._get_param_startswith(e.module, e.command, text)
except BigToolException:
- self.complete_hint = []
-
- if state < len(self.complete_hint):
- return self.complete_hint[state]
+ hints = []
+
+ self.hint = hints
+ self._append_space_to_hint()
+
+ if state < len(self.hint):
+ return self.hint[state]
else:
return None
-
- def _get_support_modules_startswith_name(self, full_or_partial_module_name):
- return [module_name for module_name in self.modules if module_name.startswith(full_or_partial_module_name)]
-
-
- def _get_support_commands_startswith_name(self, module_name, full_or_partial_command_name):
- if module_name in self.modules:
- return [command_name
- for command_name in self.modules[module_name].get_command_names()
- if command_name.startswith(full_or_partial_command_name)]
+
+
+ def _get_module_startswith(self, text):
+ return [module
+ for module in self.modules
+ if module.startswith(text)]
+
+
+ def _get_command_startswith(self, module, text):
+ if module in self.modules:
+ return [command
+ for command in self.modules[module].get_command_names()
+ if command.startswith(text)]
+
+ return []
+
+
+ def _get_param_startswith(self, module, command, text):
+ if module in self.modules:
+ module_info = self.modules[module]
+ if command in module_info.get_command_names():
+ cmd_info = module_info.get_command_with_name(command)
+ params = cmd_info.get_param_names()
+ if cmd_info.need_instance_param():
+ inst_name = module_info.get_instance_param_name()
+ if inst_name:
+ params.append(inst_name)
+
+ hint = []
+ if text:
+ hint = [val for val in params if val.startswith(text)]
+ else:
+ hint = list(params)
+
+ if len(hint) == 1 and hint[0] != "help":
+ hint[0] = hint[0] + " ="
+
+ return hint
+
+ return []
+
+
+ def _parse_cmd(self, line):
+ try:
+ cmd = BigToolCmd(line)
+ self.validate_cmd(cmd)
+ self._handle_cmd(cmd)
+ except BigToolException as e:
+ print("Error! ", e)
+ self._print_correct_usage(e)
+
+
+ def _print_correct_usage(self, ept):
+ if isinstance(ept, CmdUnknownModuleSyntaxError):
+ self.do_help(None)
+
+ elif isinstance(ept, CmdUnknownCmdSyntaxError):
+ self.modules[ept.module].module_help()
+
+ elif isinstance(ept, CmdMissParamSyntaxError) or \
+ isinstance(ept, CmdUnknownParamSyntaxError):
+ self.modules[ept.module].command_help(ept.command)
+
+
+ def _temp_print_parse_result(self, cmd):
+ print("command line is parsed:\nmodule_name: %s\ncommand_name: %s\n"\
+ "paramters:" % (cmd.module, cmd.command))
+
+ for name in cmd.params.keys():
+ print("\t%s \t%s" % (name, cmd.params[name]))
+
+
+ def _append_space_to_hint(self):
+ """Append one space at the end of complete hint."""
+
+ self.hint = [(val + " ") for val in self.hint]
+
+
+ def _handle_help(self, cmd):
+ if cmd.command == "help":
+ self.modules[cmd.module].module_help()
else:
- return []
-
- def _get_support_parameters_startswith_name(self, module_name, command_name, full_or_partial_parameter_name):
- if module_name in self.modules:
- if command_name in self.modules[module_name].get_command_names():
- command_info = self.modules[module_name].get_command_with_name(command_name)
- return [param for param in command_info.get_parameter_names() if param.startswith(full_or_partial_parameter_name)]
- return []
-
-
-
+ self.modules[cmd.module].command_help(cmd.command)
+
+
+
+
+
+
Modified: experiments/likun-bigtool/lib/command.py
==============================================================================
--- experiments/likun-bigtool/lib/command.py (original)
+++ experiments/likun-bigtool/lib/command.py Sat Oct 24 12:37:08 2009
@@ -1,51 +1,98 @@
import re
+import collections
from lib.exception import *
-CMD_WITH_PARAMETER_PATTERN = re.compile("^\s*([\d\w_]*)\s*([\d\w_]*)\s*,(.*)$")
-CMD_WITHOUT_PARAMETER_PATTERN = re.compile("^\s*([\d\w_]*)\s*([\d\w_]*)\s*$")
-PARAMETER_PATTERN = re.compile("^\s*([\d\w_\"\']+)\s*=\s*([\d\w_\.\"\']+)\s*$")
-
+param_name_str = "^\s*(?P<param_name>[\w]+)\s*=\s*"
+param_value_str = "(?P<param_value>[\w\.]+)"
+param_value_with_quota_str = "[\"\'](?P<param_value>[\w\., ]+)[\"\']"
+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 +
+ next_params_str)
+PARAM_PATTERN = re.compile(param_name_str + param_value_str + next_params_str)
+
+# Used for module and command name
+MODULE_CMD_NAME_PATTERN = re.compile("^\s*(?P<name>[\w]+)(?P<blank>\s*)(?P<others>.*)$")
+
class BigToolCmd:
""" This class will parse the command line usr input into three part
module name, cmmand, parameters
- the first two parts are strings and parameter is one hash and parameter part is optional
- example: zone reload, zone_name=example.com
- module_name == zone
- command_name == reload
- parameters == {'zone_name' = 'example.com'}
+ the first two parts are strings and parameter is one hash,
+ parameter part is optional
+
+ Example: zone reload, zone_name=example.com
+ module == zone
+ command == reload
+ params == [zone_name = 'example.com']
"""
+
def __init__(self, cmd):
+ self.params = collections.OrderedDict()
+ self.module = ''
+ self.command = ''
self._parse_cmd(cmd)
- def _parse_cmd(self, cmd):
- cmd_with_parameter = cmd.find(",") != -1
- cmd_group = (cmd_with_parameter and CMD_WITH_PARAMETER_PATTERN or CMD_WITHOUT_PARAMETER_PATTERN).match(cmd)
- if not cmd_group:
- raise CmdFormatError
+ def _parse_cmd(self, text_str):
+ # Get module name
+ groups = MODULE_CMD_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:
+ raise CmdMissCommandNameFormatError(self.module)
+
+ # Get command name
+ groups = MODULE_CMD_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:
+ if not groups.group('blank'):
+ raise CmdCommandNameFormatError(self.module)
- if not cmd_group.group(1):
- raise CmdWithoutModuleName
- self.module_name = cmd_group.group(1)
+ self._parse_params(param_str)
- if not cmd_group.group(2):
- raise CmdWithoutCommandName(cmd_group.group(1))
- self.command_name = cmd_group.group(2)
- self.parameters = None
- if cmd_with_parameter:
- self._parse_parameters(cmd_group.group(3))
+ def _parse_params(self, param_text):
+ """convert a=b,c=d into one hash """
+
+ # Check parameter name "help"
+ param = MODULE_CMD_NAME_PATTERN.match(param_text)
+ if param and param.group('name') == "help":
+ self.params["help"] = "help"
+ return
+
+ 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:
+ raise CmdParamFormatError(self.module, self.command)
+ else:
+ self.params[groups.group('param_name')] = groups.group('param_value')
+ param_text = groups.group('next_params')
+ if not param_text or (not param_text.strip()):
+ break
- def _parse_parameters(self, parameters):
- """convert a=b,c=d into one hash """
- key_value_pairs = parameters.split(",")
- if len(key_value_pairs) == 0:
- raise CmdParameterFormatError(self.module_name, self.command_name, "empty parameters")
+ if not groups.group('blank') and \
+ not groups.group('comma'):
+ raise CmdParamFormatError(self.module, self.command)
+
+
+
+
+
+
- self.parameters = {}
- for kv in key_value_pairs:
- key_value = PARAMETER_PATTERN.match(kv)
- if not key_value or not key_value.group(1) or not key_value.group(2):
- raise CmdParameterFormatError(self.module_name, self.command_name, "parameter format should looks like (key = value)")
- self.parameters[key_value.group(1)] = key_value.group(2)
-
Modified: experiments/likun-bigtool/lib/exception.py
==============================================================================
--- experiments/likun-bigtool/lib/exception.py (original)
+++ experiments/likun-bigtool/lib/exception.py Sat Oct 24 12:37:08 2009
@@ -2,82 +2,102 @@
"""Abstract base class shared by all bigtool exceptions"""
def __str__(self):
return "Big tool has problem"
- pass
+# Begin define Format exception
class CmdFormatError(BigToolException):
"""Command is malformed"""
def __str__(self):
return "Command is malformed"
-class CmdWithoutModuleName(CmdFormatError):
- """Command is malformed which doesn't have module name"""
- def __str__(self):
- return "Command doesn't have module name"
-
-class CmdWithoutCommandName(CmdFormatError):
- """Command is malformed which donesn't have command name"""
- def __init__(self, module_name):
- super(CmdWithoutCommandName, self).__init__(self)
- self.module_name = module_name
+
+class CmdModuleNameFormatError(CmdFormatError):
+ """module name format error"""
def __str__(self):
- return "No command name is speicfied for module "\
- + "\"" + self.module_name + "\""
+ return "Module name format error: the charater of name can only be '0-9a-zA-Z_'"
+
+
+class CmdCommandNameFormatError(CmdFormatError):
+ """command name format error"""
+
+ def __init__(self, module):
+ self.module = module
+
+ def __str__(self):
+ return "Command name format error: the charater of name can only be '0-9a-zA-Z_'"
+
+
+class CmdMissCommandNameFormatError(CmdFormatError):
+ """Module name isn't finished"""
+
+ def __init__(self, module):
+ self.module = module
+
+ def __str__(self):
+ return "command name is missed"
-class CmdParameterFormatError(CmdFormatError):
+
+class CmdParamFormatError(CmdFormatError):
"""Command is malformed which parameter isn't key value pair"""
- def __init__(self, module_name, command_name, error_reason):
- super(CmdParameterFormatError, self).__init__(self)
- self.module_name = module_name
- self.command_name = command_name
- self.error_reason = error_reason
+
+ def __init__(self, module, command):
+ self.module = module
+ self.command = command
def __str__(self):
- return "Parameter belongs to command " + "\"" + self.command_name + "\""\
- + " in module " + "\"" + self.module_name + "\""\
- + " has error : " + "\"" + self.error_reason + "\""
+ return "Parameter format error, it should like 'key = value'"
+
+# Begin define the exception for syntax
-class UnknownModule(BigToolException):
+class CmdSyntaxError(BigToolException):
+ """Command line has syntax error"""
+
+ def __str__(self):
+ return "Command line has syntax error"
+
+
+class CmdUnknownModuleSyntaxError(CmdSyntaxError):
"""Command is unknown"""
- def __init__(self, module_name):
- self.module_name = module_name
+ def __init__(self, module):
+ self.module = module
def __str__(self):
- return "Module " + "\"" + self.module_name + "\"" + " is unknown"
+ return str("Unknown module '%s'" % self.module)
+
-class UnknownCmd(BigToolException):
+class CmdUnknownCmdSyntaxError(CmdSyntaxError):
"""Command is unknown"""
- def __init__(self, module_name, command_name):
- self.module_name = module_name
- self.command_name = command_name
+ def __init__(self, module, command):
+ self.module = module
+ self.command = command
def __str__(self):
- return "Module " + "\"" + self.module_name + "\""\
- + " doesn't has command " + "\"" + self.command_name + "\""
+ return str("Unknown command '%s' to module '%s'" %
+ (self.command, self.module))
+
-class UnknownParameter(BigToolException):
+class CmdUnknownParamSyntaxError(CmdSyntaxError):
"""The parameter of command is unknown"""
- def __init__(self, module_name, command_name, parameter_name):
- self.module_name = module_name
- self.command_name = command_name
- self.parameter_name = parameter_name
+ def __init__(self, module, command, param):
+ self.module = module
+ self.command = command
+ self.param = param
def __str__(self):
- return "Command " + "\"" + self.command_name + "\""\
- + " in module " + "\"" + self.module_name + "\"" \
- + " doesn't has parameter " + "\"" + self.parameter_name + "\""
+ return str("Unknown parameter '%s' to command '%s' of module '%s'" %
+ (self.param, self.command, self.module))
+
-
-class MissingParameter(BigToolException):
+class CmdMissParamSyntaxError(CmdSyntaxError):
"""The parameter of one command is missed"""
- def __init__(self, module_name, command_name, parameter_name):
- self.module_name = module_name
- self.command_name = command_name
- self.parameter_name = parameter_name
+ def __init__(self, module, command, param):
+ self.module = module
+ self.command = command
+ self.param = param
def __str__(self):
- return "Command " + "\"" + self.command_name + "\"" + \
- " in module " + "\"" + self.module_name + "\"" + \
- " is missing parameter " + "\"" + self.parameter_name + "\""
-
+ return str("Parameter '%s' is missed for command '%s' of moudule '%s'" %
+ (self.param, self.command, self.module))
+
+
Modified: experiments/likun-bigtool/lib/moduleinfo.py
==============================================================================
--- experiments/likun-bigtool/lib/moduleinfo.py (original)
+++ experiments/likun-bigtool/lib/moduleinfo.py Sat Oct 24 12:37:08 2009
@@ -1,67 +1,167 @@
+import collections
+
+# Define value type
+STRING_TYPE = "string"
+LIST_TYPE = "list"
+INT_TYPE = "int"
+
class ParamInfo:
"""The parameter of one command
each command parameter have four attributes,
parameter name, parameter type, parameter value, and parameter description
"""
- def __init__(self, name, type, value, desc):
+ def __init__(self, name, desc = '', type = STRING_TYPE,
+ optional = False, value = ''):
self.name = name
self.type = type
- self.value = value
+ self.value = value #Save parameter's value
self.desc = desc
+ self.optional = optional
+
+ def is_optional(self):
+ return self.optional
+
+ def __str__(self):
+ return str("\t%s <type: %s> \t(%s)" % (self.name, self.type, self.desc))
+
class CommandInfo:
- """One command which provide by one bind10 module, it has zero or more parameters"""
+ """One command which provide by one bind10 module, it has zero or
+ more parameters
+ """
- def __init__(self, name, desc):
+ def __init__(self, name, desc = "", need_inst_param = True):
self.name = name
+ # Wether command needs parameter "instance_name"
+ self.need_inst_param = need_inst_param
self.desc = desc
- self.params = {}
+ self.params = collections.OrderedDict()
+ # Set default parameter "help"
+ self.add_param(ParamInfo("help",
+ desc = "Get help for command",
+ optional = True))
+
+ def __str__(self):
+ return str("%s \t(%s)" % (self.name, self.desc))
+
- def add_parameter(self, paraminfo):
- if not isinstance(paraminfo, ParamInfo):
- raise UnknowParamType
+ def add_param(self, paraminfo):
+ self.params[paraminfo.name] = paraminfo
+
- self.params[paraminfo.name] = paraminfo
+ def has_param_with_name(self, param_name):
+ return param_name in self.params
+
- def has_parameter_with_name(self, param_name):
- return param_name in self.params
+ def get_param_with_name(self, param_name):
+ return self.params[param_name]
+
- def get_parameter_with_name(self, param_name):
- return self.params[param_name]
+ def get_params(self):
+ return list(self.params.values())
+
- def get_parameters(self):
- return list(self.params.values())
+ def get_param_names(self):
+ return list(self.params.keys())
+
+
+ def get_mandatory_param_names(self):
+ all_names = self.params.keys()
+ return [name for name in all_names
+ if not self.params[name].is_optional()]
+
+
+ def need_instance_param(self):
+ return self.need_inst_param
+
- def get_parameter_names(self):
- return list(self.params.keys())
-
-
+ def command_help(self, inst_name, inst_type, inst_desc):
+ print("Command ", self)
+ print("\t\thelp (Get help for command)")
+
+ params = self.params.copy()
+ del params["help"]
+ if self.need_inst_param:
+ params[inst_name] = ParamInfo(name = inst_name, type = inst_type,
+ desc = inst_desc)
+ if len(params) == 0:
+ print("\tNo parameters for the command")
+ return
+
+ print("\n\tMandatory parameters:")
+ find_optional = False
+ for info in params.values():
+ if not info.is_optional():
+ print("\t", info)
+ else:
+ find_optional = True
+
+ if find_optional:
+ print("\n\tOptional parameters:")
+ for info in params.values():
+ if info.is_optional():
+ print("\t", info)
class ModuleInfo:
"""Define the information of one module, include module name,
- module supporting commands
+ module supporting commands, instance name and the value type of instance name
"""
- def __init__(self, name, desc):
+ def __init__(self, name, inst_name = "", inst_type = STRING_TYPE,
+ inst_desc = "", desc = ""):
self.name = name
+ self.inst_name = inst_name
+ self.inst_type = inst_type
+ self.inst_desc = inst_desc
self.desc = desc
- self.commands = {}
+ self.commands = collections.OrderedDict()
+ # Add defaut help command
+ self.add_command(CommandInfo(name = "help",
+ desc = "Get help for module",
+ need_inst_param = False))
- def add_command(self, commandInfo):
- if not isinstance(commandInfo, CommandInfo):
- raise UnknownCmdType
+ def __str__(self):
+ return str("%s \t%s" % (self.name, self.desc))
+
+ def add_command(self, commandInfo):
self.commands[commandInfo.name] = commandInfo
+
def has_command_with_name(self, command_name):
return command_name in self.commands
+
def get_command_with_name(self, command_name):
return self.commands[command_name]
+
def get_commands(self):
return list(self.commands.values())
+
def get_command_names(self):
return list(self.commands.keys())
+
+ def get_instance_param_name(self):
+ return self.inst_name
+
+
+ def get_instance_param_type(self):
+ return self.inst_type
+
+
+ def module_help(self):
+ print("Module ", self, "\nAvailable commands:")
+ for k in self.commands.keys():
+ print("\t", self.commands[k])
+
+
+ def command_help(self, command):
+ self.commands[command].command_help(self.inst_name,
+ self.inst_type,
+ self.inst_desc)
+
+
+
Modified: experiments/likun-bigtool/test_bigtool.py
==============================================================================
--- experiments/likun-bigtool/test_bigtool.py (original)
+++ experiments/likun-bigtool/test_bigtool.py Sat Oct 24 12:37:08 2009
@@ -1,23 +1,34 @@
from lib import *
+from lib.moduleinfo import *
def _prepare_fake_data(bigtool):
#module zone, has two command :
# zone load, zone_name = ""
- # zone set, zone_name = "", attr_name = "", attr_value = ""
- zone_name_param = moduleinfo.ParamInfo("zone_name", "string", "", "specify the zone name")
- zone_file_param = moduleinfo.ParamInfo("zone_file", "string", "", "specify the data source")
- load_cmd = moduleinfo.CommandInfo("load", "load one zone")
- load_cmd.add_parameter(zone_name_param)
- load_cmd.add_parameter(zone_file_param)
+ # zone set, zone_name = "", master = "", allow_update = ""
+ zone_file_param = ParamInfo(name = "zone_file",
+ desc = "specify the data source")
+ load_cmd = CommandInfo(name = "load", desc = "load one zone")
+ load_cmd.add_param(zone_file_param)
- attr_name_param = moduleinfo.ParamInfo("attr_name", "string", "", "specify attribute name")
- attr_value_param = moduleinfo.ParamInfo("attr_value", "string", "", "specify attribute value")
- set_cmd = moduleinfo.CommandInfo("set", "set the master of one zone")
- set_cmd.add_parameter(attr_name_param)
- set_cmd.add_parameter(attr_value_param)
- set_cmd.add_parameter(zone_name_param)
-
- zone_module = moduleinfo.ModuleInfo("zone", "manage all the zones")
+ set_param_master = ParamInfo(name = "master",
+ desc = "mater of the server",
+ optional = True)
+
+ set_param_allow_update = ParamInfo(name = "allow_update",
+ desc = "The addresses allowed to update ",
+ type = LIST_TYPE,
+ optional = True)
+
+ set_cmd = CommandInfo(name = "set", desc = "set attributes of one zone")
+ set_cmd.add_param(set_param_master)
+ set_cmd.add_param(set_param_allow_update)
+
+ zone_module = ModuleInfo(name = "zone",
+ inst_name = "zone_name",
+ inst_type = STRING_TYPE,
+ inst_desc = "the name of one zone",
+ desc = "manage all the zones")
+
zone_module.add_command(load_cmd)
zone_module.add_command(set_cmd)
bigtool.add_module_info(zone_module)
@@ -25,22 +36,33 @@
#module log, has two command
#log change_level, module_name = "", level = ""
#log close
- name_param = moduleinfo.ParamInfo("module_name", "string", "", "module name")
- level_param = moduleinfo.ParamInfo("level", "int", "", "module's new log level")
- change_level_cmd = moduleinfo.CommandInfo("change_level", "change module's log level")
- change_level_cmd.add_parameter(name_param)
- change_level_cmd.add_parameter(level_param)
+ level_param = ParamInfo(name = "level",
+ desc = "module's new log level",
+ type = INT_TYPE)
+ change_level_cmd = CommandInfo(name = "change_level",
+ desc = "change module's log level")
+ change_level_cmd.add_param(level_param)
- log_close_cmd = moduleinfo.CommandInfo("close", "close log system")
- log_module = moduleinfo.ModuleInfo("log", "manage log system")
+ log_close_cmd = CommandInfo(name = "close",
+ desc = "close log system")
+
+ log_module = ModuleInfo(name = "log",
+ inst_name = "log_module",
+ inst_desc = "log module's name" ,
+ desc = "manage log system")
+
log_module.add_command(change_level_cmd)
log_module.add_command(log_close_cmd)
bigtool.add_module_info(log_module)
- #module config, has one command
+ #module config, has one command "reload", and the command has no parameters
#config reload
- config_module = moduleinfo.ModuleInfo("config", "config manager")
- reload_cmd = moduleinfo.CommandInfo("reload", "reload configuration")
+ reload_cmd = CommandInfo(name = "reload",
+ desc = "reload configuration",
+ need_inst_param = False)
+
+ config_module = ModuleInfo(name = "config",
+ desc = "config manager")
config_module.add_command(reload_cmd)
bigtool.add_module_info(config_module)
Modified: experiments/likun-bigtool/test_command.py
==============================================================================
--- experiments/likun-bigtool/test_command.py (original)
+++ experiments/likun-bigtool/test_command.py Sat Oct 24 12:37:08 2009
@@ -1,37 +1,188 @@
import unittest
from lib import command
+from lib import bigtool
from lib import exception
-class TestCommand(unittest.TestCase):
+from lib.moduleinfo import *
+from lib.exception import *
+
+
+class TestBigToolCmd(unittest.TestCase):
+
+ def my_assert_raise(self, exception_type, cmd_line):
+ self.assertRaises(exception_type, command.BigToolCmd, cmd_line)
+
def testCommandWithoutParameter(self):
cmd = command.BigToolCmd("zone add")
- assert cmd.module_name == "zone"
- assert cmd.command_name == "add"
- assert cmd.parameters == None
+ assert cmd.module == "zone"
+ assert cmd.command == "add"
+ self.assertEqual(len(cmd.params), 0)
+
+
+ def testCommandWithParameters(self):
+ lines = {"zone add zone_name = cnnic.cn, file = cnnic.cn.file master=1.1.1.1",
+ "zone add zone_name = \"cnnic.cn\", file ='cnnic.cn.file' master=1.1.1.1 ",
+ "zone add zone_name = 'cnnic.cn\", file ='cnnic.cn.file' master=1.1.1.1, " }
+
+ for cmd_line in lines:
+ cmd = command.BigToolCmd(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'
+
+
+ def testCommandWithListParam(self):
+ cmd = command.BigToolCmd("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'
+
+
+ def testCommandWithHelpParam(self):
+ cmd = command.BigToolCmd("zone add help")
+ assert cmd.params["help"] == "help"
+
+ cmd = command.BigToolCmd("zone add help *&)&)*&&$#$^%")
+ assert cmd.params["help"] == "help"
+ self.assertEqual(len(cmd.params), 1)
+
- def testCommandWithParameters(self):
- cmd = command.BigToolCmd("zone add, zone_name = example.com, file = db.example.com.info")
- assert cmd.module_name == "zone"
- assert cmd.command_name == "add"
- assert cmd.parameters["zone_name"] == "example.com"
- assert cmd.parameters["file"] == "db.example.com.info"
+ def testCmdModuleNameFormatError(self):
+ self.my_assert_raise(CmdModuleNameFormatError, "zone=good")
+ self.my_assert_raise(CmdModuleNameFormatError, "zo/ne")
+ self.my_assert_raise(CmdModuleNameFormatError, "")
+ self.my_assert_raise(CmdModuleNameFormatError, "=zone")
+ self.my_assert_raise(CmdModuleNameFormatError, "zone,")
+
+
+ def testCmdMissCommandNameFormatError(self):
+ self.my_assert_raise(CmdMissCommandNameFormatError, "zone")
+ self.my_assert_raise(CmdMissCommandNameFormatError, "zone ")
+ self.my_assert_raise(CmdMissCommandNameFormatError, "help ")
+
+
+ def testCmdCommandNameFormatError(self):
+ self.my_assert_raise(CmdCommandNameFormatError, "zone =d")
+ self.my_assert_raise(CmdCommandNameFormatError, "zone z=d")
+ self.my_assert_raise(CmdCommandNameFormatError, "zone z-d ")
+ self.my_assert_raise(CmdCommandNameFormatError, "zone zdd/")
+ self.my_assert_raise(CmdCommandNameFormatError, "zone zdd/ \"")
+
+
+ def testCmdParamFormatError(self):
+ self.my_assert_raise(CmdParamFormatError, "zone load load")
+ self.my_assert_raise(CmdParamFormatError, "zone load load=")
+ self.my_assert_raise(CmdParamFormatError, "zone load load==dd")
+ self.my_assert_raise(CmdParamFormatError, "zone load , zone_name=dd zone_file=d" )
+ self.my_assert_raise(CmdParamFormatError, "zone load zone_name=dd zone_file" )
+ self.my_assert_raise(CmdParamFormatError, "zone zdd \"")
+
+
+class TestValidateCmd(unittest.TestCase):
- def testCommandWithFormatError(self):
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zone=good")
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zo/ne")
- self.assertRaises(exception.CmdWithoutModuleName, command.BigToolCmd, "")
-
- self.assertRaises(exception.CmdWithoutCommandName, command.BigToolCmd, "zone")
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zone i-s")
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zone i=good")
-
-
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zone load load")
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zone file=db.exmaple.info,load")
- self.assertRaises(exception.CmdFormatError, command.BigToolCmd, "zone file=db.exmaple.info load")
-
- self.assertRaises(exception.CmdParameterFormatError, command.BigToolCmd, "zone load, file=db.exmaple.info load")
-
+ def _create_bigtool(self):
+ """Create one bigtool"""
+
+ tool = bigtool.BigTool()
+ zone_file_param = ParamInfo(name = "zone_file")
+ load_cmd = CommandInfo(name = "load")
+ load_cmd.add_param(zone_file_param)
+
+ param_master = ParamInfo(name = "master", optional = True)
+ param_allow_update = ParamInfo(name = "allow_update", optional = True)
+ set_cmd = CommandInfo(name = "set")
+ set_cmd.add_param(param_master)
+ set_cmd.add_param(param_allow_update)
+
+ reload_all_cmd = CommandInfo(name = "reload_all", need_inst_param = False)
+
+ zone_module = ModuleInfo(name = "zone", inst_name = "zone_name")
+ zone_module.add_command(load_cmd)
+ zone_module.add_command(set_cmd)
+ zone_module.add_command(reload_all_cmd)
+
+ tool.add_module_info(zone_module)
+ return tool
+
+
+ def setUp(self):
+ self.bigtool = self._create_bigtool()
+
+
+ def no_assert_raise(self, cmd_line):
+ cmd = command.BigToolCmd(cmd_line)
+ self.bigtool.validate_cmd(cmd)
+
+
+ def my_assert_raise(self, exception_type, cmd_line):
+ cmd = command.BigToolCmd(cmd_line)
+ self.assertRaises(exception_type, self.bigtool.validate_cmd, cmd)
+
+
+ def testValidateSuccess(self):
+ self.no_assert_raise("zone load zone_file='cn' zone_name='cn'")
+ self.no_assert_raise("zone load zone_file='cn', zone_name='cn', ")
+ self.no_assert_raise("zone help ")
+ self.no_assert_raise("zone load help ")
+ 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.no_assert_raise("zone reload_all")
+
+
+ def testCmdUnknownModuleSyntaxError(self):
+ self.my_assert_raise(CmdUnknownModuleSyntaxError, "zoned d")
+ self.my_assert_raise(CmdUnknownModuleSyntaxError, "dd dd ")
+
+
+ def testCmdUnknownCmdSyntaxError(self):
+ 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 ")
+
+ def testCmdUnknownParamSyntaxError(self):
+ self.my_assert_raise(CmdUnknownParamSyntaxError, "zone load zone_d='cn'")
+ self.my_assert_raise(CmdUnknownParamSyntaxError, "zone reload_all zone_name = 'cn'")
+
+
+class TestNameSequence(unittest.TestCase):
+ """
+ Test if the module/command/parameters is saved in the order creation
+ """
+
+ def _create_bigtool(self):
+ """Create one bigtool"""
+
+ self._cmd = CommandInfo(name = "load")
+ self.module = ModuleInfo(name = "zone")
+ self.tool = bigtool.BigTool()
+ for random_str in self.random_names:
+ self._cmd.add_param(ParamInfo(name = random_str))
+ self.module.add_command(CommandInfo(name = random_str))
+ self.tool.add_module_info(ModuleInfo(name = random_str))
+
+ def setUp(self):
+ self.random_names = ['1erdfeDDWsd', '3fe', '2009erd', 'Fe231', 'tere142', 'rei8WD']
+ self._create_bigtool()
+
+ def testSequence(self):
+ param_names = self._cmd.get_param_names()
+ cmd_names = self.module.get_command_names()
+ module_names = self.tool.get_module_names()
+
+ i = 0
+ while i < len(self.random_names):
+ assert self.random_names[i] == param_names[i+1]
+ assert self.random_names[i] == cmd_names[i+1]
+ assert self.random_names[i] == module_names[i+1]
+ i = i + 1
+
+
if __name__== "__main__":
unittest.main()
+
More information about the bind10-changes
mailing list