示例#1
0
def test_create_two_with_different_type_component():
    """
    Create two component with different type with the following cli :
    --sub toto --name titi --sub tutu --name tete

    test if the result is :
    {sub:{'titi' : {'type': 'toto'}, 'tete': {'type': 'tutu'}}}

    """
    parser = MainParser(help_arg=False)

    subparser = ComponentSubParser('toto')
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('sub', subparser)

    subparser = ComponentSubParser('tutu')
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('sub', subparser)

    check_parsing_result(
        parser, '--sub toto --name titi --sub tutu --name tete',
        {'sub': {
            'titi': {
                'type': 'toto'
            },
            'tete': {
                'type': 'tutu'
            }
        }})
示例#2
0
def test_create_two_component():
    """
    Create two component of the same type with the following cli :
    --sub toto --name titi --sub toto -b --name tutu

    test if the result is :
    {sub:{'titi' : {'type': 'toto'}, 'tutu': {'type': 'toto', 'b':True}}}

    """
    parser = MainParser(help_arg=False)

    subparser = ComponentSubParser('toto')
    subparser.add_argument('b', flag=True, action=store_true)
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('sub', subparser)

    check_parsing_result(parser,
                         '--sub toto --name titi --sub toto -b --name tutu', {
                             'sub': {
                                 'titi': {
                                     'type': 'toto'
                                 },
                                 'tutu': {
                                     'type': 'toto',
                                     'b': True
                                 }
                             }
                         })
示例#3
0
def test_add_component_subparser_that_aldready_exists2():
    """
    Add a component_subparser with no argument 'name'
    test if a SubParserWithoutNameArgumentException is raised
    """
    parser = MainParser(help_arg=False)
    subparser = ComponentSubParser('titi')

    with pytest.raises(SubParserWithoutNameArgumentException):
        parser.add_actor_subparser('toto', subparser)
示例#4
0
def test_add_actor_subparser_that_aldready_exists():
    """
    Add a component_subparser that already exists to a parser and test if an
    AlreadyAddedArgumentException is raised
    """
    parser = MainParser(help_arg=False)
    subparser = ComponentSubParser('titi')
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('toto', subparser)
    subparser2 = ComponentSubParser('titi')
    subparser2.add_argument('n', 'name')

    with pytest.raises(AlreadyAddedArgumentException):
        parser.add_actor_subparser('toto', subparser2)
示例#5
0
def test_actor_subparser():
    """
    test to parse strings with a parser and retrieve the following results :

    - "" : {}
    - "-z" : UnknowArgException(z)
    - "-a" : {a: True}
    - "-a --sub toto -b" : NoNameSpecifiedForComponentException
    - "-a --sub toto -b --name titi" : {a:True, sub: { titi: { 'type': 'toto', b: True}}}
    - "-b" : BadContextException(b, [toto])

    Parser description :

    - base parser arguments : -a
    - subparser toto binded to the argument sub with sub arguments : -b and --name
    """
    parser = MainParser(help_arg=False)
    parser.add_argument('a', flag=True, action=store_true)

    subparser = ComponentSubParser('toto')
    subparser.add_argument('b', flag=True, action=store_true)
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('sub', subparser)

    check_parsing_result(parser, '', {})

    with pytest.raises(UnknowArgException):
        check_parsing_result(parser, '-z', None)

    check_parsing_result(parser, '-a', {'a': True})

    with pytest.raises(NoNameSpecifiedForComponentException):
        check_parsing_result(parser, '-a --sub toto -b', {})

    check_parsing_result(parser, '-a --sub toto -b --name titi', {
        'a': True,
        'sub': {
            'titi': {
                'type': 'toto',
                'b': True
            }
        }
    })

    with pytest.raises(BadContextException):
        check_parsing_result(parser, '-b', None)
示例#6
0
def test_create_component_that_already_exist():
    """
    Create two component with the same name with the following cli
    --sub toto --name titi --sub toto --name titi

    test if an ComponentAlreadyExistException is raised
    """
    parser = MainParser(help_arg=False)

    subparser = ComponentSubParser('toto')
    subparser.add_argument('b', flag=True, action=store_true)
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('sub', subparser)

    with pytest.raises(ComponentAlreadyExistException):
        check_parsing_result(parser,
                             '--sub toto --name titi --sub toto --name titi',
                             None)
示例#7
0
def test_add_actor_subparser_with_two_name():
    """
    add a component subparser with one short name and one long name
    parse a string and test if the value is only bind to the long name
    """
    parser = MainParser(help_arg=False)
    subparser = ComponentSubParser('titi')
    subparser.add_argument('a',
                           'aaa',
                           flag=True,
                           action=store_true,
                           default=False)
    subparser.add_argument('n', 'name')
    parser.add_actor_subparser('sub', subparser)
    check_parsing_result(parser, '--sub titi -a --name tutu',
                         {'sub': {
                             'tutu': {
                                 'aaa': True,
                                 'type': 'titi'
                             }
                         }})
示例#8
0
class MainConfigParser(ConfigParser):
    """
    Parser abstraction for the configuration
    """
    def __init__(self):
        ConfigParser.__init__(self)
        self.subparser = {}
        self.cli_parser = MainParser()

    def add_subparser(self, name, subparser: SubConfigParser, help=''):
        """
        Add a SubParser to call when <name> is encoutered
        When name is encoutered, the subarpser such as subparser.name match conf[name].type

        """
        if name in self.subparser:
            if subparser.name in list(self.subparser[name]):
                raise AlreadyAddedSubparserException(name)
        else:
            self.subparser[name] = {}

        self.subparser[name][subparser.name] = subparser

        self.cli_parser.add_actor_subparser(name, subparser.cli_parser, help)

    def _parse_cli(self, cli_line):
        return self.cli_parser.parse(cli_line)

    @staticmethod
    def _parse_file(filename):
        config_file = open(filename, 'r')
        conf = json.load(config_file)
        return conf

    def _validate(self, conf: Dict):
        """ Check the parsed configuration"""

        # Check that all the mandatory arguments are precised
        mandatory_args = self._get_mandatory_args()
        for arg in mandatory_args:
            if arg not in conf:
                raise MissingArgumentException(arg)

        # check types
        for args, value in conf.items():
            is_an_arg = False
            if args in self.subparser:
                for _, dic_value in value.items():
                    self.subparser[args][dic_value["type"]].validate(dic_value)
                    is_an_arg = True

            for _, waited_value in self.args.items():
                if args in waited_value.names:
                    is_an_arg = True
                    # check type
                    if not isinstance(
                            value,
                            waited_value.type) and not waited_value.is_flag:
                        raise BadTypeException(args, waited_value.type)

            if not is_an_arg:
                raise UnknowArgException(args)

        for args, value in self.args.items():
            is_precised = False
            for name in value.names:
                if name in conf:
                    is_precised = True
                    break
            if not is_precised and value.default_value is not None:
                conf[args] = value.default_value

        return conf

    def parse(self, args=None):
        """
        Find the configuration method (CLI or config file)
        Call the method to produce a configuration dictionnary
        check the configuration
        """

        if args is None:
            args = sys.argv
        i = 0
        filename = None
        for s in args:
            if s == '--config-file':
                if i + 1 == len(args):
                    logging.error(
                        "CLI Error: config file path needed with argument --config-file"
                    )
                    sys.exit(-1)
                filename = args[i + 1]
            i += 1

        try:
            if filename is not None:
                conf = self._parse_file(filename)
            else:
                conf = self._parse_cli(args[1:])
            conf = self._validate(conf)

        except MissingValueException as exn:
            msg = 'CLI error: argument ' + exn.argument_name + ': expect a value'
            logging.error(msg)
            sys.exit(-1)

        except BadTypeException as exn:
            msg = "Configuration error: " + exn.msg
            logging.error(msg)
            sys.exit(-1)

        except UnknowArgException as exn:
            msg = 'Configuration error: unknow argument ' + exn.argument_name
            logging.error(msg)
            sys.exit(-1)

        except BadContextException as exn:
            msg = 'CLI error: argument ' + exn.argument_name
            msg += ' not used in the correct context\nUse it with the following arguments:'
            for main_arg_name, context_name in exn.context_list:
                msg += '\n  --' + main_arg_name + ' ' + context_name
            logging.error(msg)
            sys.exit(-1)

        except FileNotFoundError:
            logging.error("Configuration Error: configuration file not found")
            sys.exit(-1)

        except json.JSONDecodeError as exn:
            logging.error('Configuration Error: JSON Error: ' + exn.msg +
                          ' at line' + exn.lineno + ' colomn ' + exn.colno)
            sys.exit(-1)

        except MissingArgumentException as exn:
            logging.error("Configuration Error: " + exn.msg)
            sys.exit(-1)

        return conf