Browse Source

Add code for BigTool

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/f2f200910@186 e5f2f494-b856-4b98-b285-d166d9295462
Likun Zhang 15 years ago
parent
commit
25ccb97afb

+ 10 - 0
src/bin/bigtool/run_bigtool

@@ -0,0 +1,10 @@
+#! /bin/sh
+
+PYTHON_EXEC=/usr/bin/python3
+BIGTOOL_PATH=.
+
+PYTHONPATH=../../lib/cc/python:../../lib/cc/python/ISC:../../lib/cc/python/ISC/CC:../../lib/cc/python/ISC/Util:../../lib/bigtool/
+export PYTHONPATH
+
+cd ${BIGTOOL_PATH}
+exec ${PYTHON_EXEC} -O run_bigtool.py $*

+ 26 - 0
src/bin/bigtool/run_bigtool.py

@@ -0,0 +1,26 @@
+from moduleinfo  import *
+from bigtool import *
+
+
+def _prepare_fake_data(bigtool):
+    add_cmd = CommandInfo(name = "add", desc = "add one zone")
+    remove_cmd = CommandInfo(name = 'remove', desc = 'remove one zone')
+    list_cmd = CommandInfo(name = 'list', desc = 'list all zones', need_inst_param = False)
+
+    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(add_cmd)
+    zone_module.add_command(remove_cmd)
+    zone_module.add_command(list_cmd)
+    bigtool.add_module_info(zone_module)
+    
+
+if __name__ == '__main__':
+    tool = BigTool()
+    _prepare_fake_data(tool)   
+    tool.cmdloop()
+

+ 1 - 0
src/lib/bigtool/__init__.py

@@ -0,0 +1 @@
+__all__ = ['mycollections', 'exception', 'moduleinfo', 'command', 'bigtool']

+ 242 - 0
src/lib/bigtool/bigtool.py

@@ -0,0 +1,242 @@
+import sys
+import readline
+from cmd import Cmd
+from exception import *
+from moduleinfo import ModuleInfo
+from moduleinfo import ParamInfo
+from command import BigToolCmd
+from xml.dom import minidom
+import ISC
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from mycollections import OrderedDict
+
+
+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: """
+
+CONST_COMMAND_NODE = "command"
+
+class BigTool(Cmd):
+    """simple bigtool example."""    
+
+    def __init__(self):
+        Cmd.__init__(self)
+        self.prompt = '> '
+        self.ruler = '-'
+        self.modules = OrderedDict()
+        self.add_module_info(ModuleInfo("help", desc = "Get help for bigtool"))
+        try:
+            self.cc = ISC.CC.Session()
+            self.cc.group_subscribe("BigTool")
+            self.cc.group_subscribe("ConfigManager")
+        except ISC.CC.SessionError:
+            print("Failed to create cchannel session")
+            return
+
+    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 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
+        if cmd.command == "help" or ("help" in cmd.params.keys()):
+            self._handle_help(cmd)
+        else:
+            self.apply_cmd(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 emptyline(self):
+        pass
+    
+    def cmdloop(self):
+        try:
+            Cmd.cmdloop(self)
+        except KeyboardInterrupt:
+            return True
+            
+    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:
+            text = text.strip()
+            hints = []
+            cur_line = readline.get_line_buffer()            
+            try:
+                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 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:
+                hints = []
+            
+            self.hint = hints
+            self._append_space_to_hint()
+
+        if state < len(self.hint):
+            return self.hint[state]
+        else:
+            return None
+            
+
+    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() 
+                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 _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:
+            self.modules[cmd.module].command_help(cmd.command)
+
+            
+    def apply_cmd(self, cmd):
+        try:
+            msg ={"command": [cmd.module, cmd.command, list(cmd.params.values())[0]]}
+            print("begin to send the message...")
+           
+            self.cc.group_sendmsg(msg, "ConfigManager")
+            print("waiting for configure manager reply...")
+
+            reply, env = self.cc.group_recvmsg(False)
+            print("received reply:", reply)
+        except ISC.CC.SessionError:
+            print("Error commucation with configure manager")
+
+
+

+ 100 - 0
src/lib/bigtool/command.py

@@ -0,0 +1,100 @@
+import re
+from exception import *
+try:
+    from collections import OrderedDict
+except ImportError:
+    from mycollections import OrderedDict
+
+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
+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, 
+    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 = OrderedDict()
+        self.module = ''
+        self.command = ''
+        self._parse_cmd(cmd)
+
+    def _parse_cmd(self, text_str):    
+        # 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:            
+            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:
+            if not groups.group('blank'):
+                raise CmdCommandNameFormatError(self.module)
+
+            self._parse_params(param_str)
+
+
+    def _parse_params(self, param_text):
+        """convert a=b,c=d into one hash """
+        
+        # Check parameter name "help"
+        param = 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
+
+                if not groups.group('blank') and \
+                   not groups.group('comma'):
+                    raise CmdParamFormatError(self.module, self.command)
+                    
+                
+            
+            
+            
+    
+

+ 103 - 0
src/lib/bigtool/exception.py

@@ -0,0 +1,103 @@
+class BigToolException(Exception):
+    """Abstract base class shared by all bigtool exceptions"""
+    def __str__(self):
+        return "Big tool has problem"
+
+# Begin define Format exception
+
+class CmdFormatError(BigToolException):
+    """Command is malformed"""
+    def __str__(self):
+        return "Command is malformed"
+
+        
+class CmdModuleNameFormatError(CmdFormatError):
+    """module name format error"""
+
+    def __str__(self):
+        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 CmdParamFormatError(CmdFormatError):
+    """Command is malformed which parameter isn't key value pair"""
+    
+    def __init__(self, module, command):        
+        self.module = module
+        self.command = command        
+
+    def __str__(self):
+        return  "Parameter format error, it should like 'key = value'"         
+        
+# Begin define the exception for syntax
+
+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):
+        self.module = module
+
+    def __str__(self):
+        return str("Unknown module '%s'" % self.module)
+        
+
+class CmdUnknownCmdSyntaxError(CmdSyntaxError):
+    """Command is unknown"""
+    def __init__(self, module, command):
+        self.module = module
+        self.command = command
+
+    def __str__(self):
+        return str("Unknown command '%s' to module '%s'" % 
+                    (self.command, self.module))
+                    
+
+class CmdUnknownParamSyntaxError(CmdSyntaxError):
+    """The parameter of command is unknown"""
+    def __init__(self, module, command, param):
+        self.module = module
+        self.command = command
+        self.param = param
+
+    def __str__(self):
+        return str("Unknown parameter '%s' to command '%s' of module '%s'" %
+                   (self.param, self.command, self.module))
+                   
+
+class CmdMissParamSyntaxError(CmdSyntaxError):
+    """The parameter of one command is missed"""
+    def __init__(self, module, command, param):
+        self.module = module
+        self.command = command
+        self.param = param
+
+    def __str__(self):
+        return str("Parameter '%s' is missed for command '%s' of moudule '%s'" % 
+                   (self.param, self.command, self.module))
+                   
+   

+ 189 - 0
src/lib/bigtool/moduleinfo.py

@@ -0,0 +1,189 @@
+try:
+    from collections import OrderedDict
+except ImportError:
+    from mycollections import OrderedDict
+
+# Define value type
+STRING_TYPE = "string"
+LIST_TYPE = "list"
+INT_TYPE = "int"
+
+MODULE_NODE_NAME = 'module'
+COMMAND_NODE_NAME = 'command'
+PARAM_NODE_NAME = 'param'
+
+
+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, desc = '', type = STRING_TYPE, 
+                 optional = False, value = '', default_value = ''):
+        self.name = name
+        self.type = type
+        self.value = value
+        self.default_value = default_value                           
+        self.desc = desc
+        self.is_optional = optional
+    
+    def __str__(self):        
+        return str("\t%s <type: %s> \t(%s)" % (self.name, self.type, self.desc))
+
+    def write_xml(xmldoc, name, value):
+        node = xmldoc.createElement(PARAM_NODE_NAME)
+        node.setAttribute('name', name)
+        node.setAttribute('value', value)                             
+        return node                                              
+
+class CommandInfo:
+    """One command which provide by one bind10 module, it has zero or 
+    more parameters
+    """
+
+    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 = 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_param(self, paraminfo):
+        self.params[paraminfo.name] = paraminfo
+        
+
+    def has_param_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_params(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 write_xml(self, xmldoc, command_name):
+        node = xmldoc.createElement(COMMAND_NODE_NAME)
+        node.setAttribute('name', command_name)
+        return node 
+        
+
+    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 len(params) == 0:
+            print("\tNo parameters for the command")
+            return
+        
+        print("\n\tMandatory parameters:")
+        mandatory_infos = []
+        for info in params.values():            
+            if not info.is_optional:
+                print("\t", info)
+                mandatory_infos.append(info)
+
+        optional_infos = [info for info in params.values() 
+                          if info not in mandatory_infos]
+        if len(optional_infos) > 0:
+            print("\n\tOptional parameters:")      
+            for info in optional_infos:
+                    print("\t", info)
+
+
+class ModuleInfo:
+    """Define the information of one module, include module name, 
+    module supporting commands, instance name and the value type of instance name
+    """    
+    
+    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 = OrderedDict()         
+        self.add_command(CommandInfo(name = "help", 
+                                     desc = "Get help for module",
+                                     need_inst_param = False))
+        
+    def __str__(self):
+        return str("%s \t%s" % (self.name, self.desc))
+        
+    def add_command(self, command_info):        
+        self.commands[command_info.name] = command_info
+        if command_info.need_instance_param():
+            command_info.add_param(ParamInfo(name = self.inst_name, 
+                                             type = self.inst_type,
+                                             desc = self.inst_desc))
+
+        
+    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)
+    
+    def write_xml(self, xmldoc, module_name):
+        node = xmldoc.createElement(MODULE_NODE_NAME)
+        node.setAttribute('name', module_name)
+        return node
+    
+

+ 67 - 0
src/lib/bigtool/mycollections.py

@@ -0,0 +1,67 @@
+from collections import MutableMapping
+
+class OrderedDict(dict, MutableMapping):
+
+    # Methods with direct access to underlying attributes
+
+    def __init__(self, *args, **kwds):
+        if len(args) > 1:
+            raise TypeError('expected at 1 argument, got %d', len(args))
+        if not hasattr(self, '_keys'):
+            self._keys = []
+        self.update(*args, **kwds)
+
+    def clear(self):
+        del self._keys[:]
+        dict.clear(self)
+
+    def __setitem__(self, key, value):
+        if key not in self:
+            self._keys.append(key)
+        dict.__setitem__(self, key, value)
+
+    def __delitem__(self, key):
+        dict.__delitem__(self, key)
+        self._keys.remove(key)
+
+    def __iter__(self):
+        return iter(self._keys)
+
+    def __reversed__(self):
+        return reversed(self._keys)
+
+    def popitem(self):
+        if not self:
+            raise KeyError
+        key = self._keys.pop()
+        value = dict.pop(self, key)
+        return key, value
+
+    def __reduce__(self):
+        items = [[k, self[k]] for k in self]
+        inst_dict = vars(self).copy()
+        inst_dict.pop('_keys', None)
+        return (self.__class__, (items,), inst_dict)
+
+    # Methods with indirect access via the above methods
+
+    setdefault = MutableMapping.setdefault
+    update = MutableMapping.update
+    pop = MutableMapping.pop
+    keys = MutableMapping.keys
+    values = MutableMapping.values
+    items = MutableMapping.items
+
+    def __repr__(self):
+        pairs = ', '.join(map('%r: %r'.__mod__, self.items()))
+        return '%s({%s})' % (self.__class__.__name__, pairs)
+
+    def copy(self):
+        return self.__class__(self)
+
+    @classmethod
+    def fromkeys(cls, iterable, value=None):
+        d = cls()
+        for key in iterable:
+            d[key] = value
+        return d

+ 10 - 0
src/lib/bigtool/run_unittest

@@ -0,0 +1,10 @@
+#! /bin/sh
+
+PYTHON_EXEC=/usr/bin/python3
+BIGTOOL_PATH=.
+
+PYTHONPATH=../../lib/cc/python:../../lib/cc/python/ISC:../../lib/cc/python/ISC/CC:../../lib/cc/python/ISC/Util:../../lib/bigtool/
+export PYTHONPATH
+
+cd ${BIGTOOL_PATH}
+exec ${PYTHON_EXEC} -O unittest_bigtool.py $*

+ 189 - 0
src/lib/bigtool/unittest_bigtool.py

@@ -0,0 +1,189 @@
+import unittest
+import command
+import bigtool
+from moduleinfo import *
+from exception import *    
+try:
+    from collections import OrderedDict
+except ImportError:
+    from mycollections import OrderedDict
+
+class TestCmdLex(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 == "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 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 TestCmdSyntax(unittest.TestCase):
+    
+    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()
+