def test_parse_empty_string_default_value(): parser = MainParser(help_arg=False) parser.add_argument('a', default=1) result = parser.parse(''.split()) assert len(result) == 1 assert 'a' in result assert result['a'] == 1
def test_component_subparser(): """ test to parse strings with a formula parser and retrieve the following results : - "" : {} - "--sub toto -b" : {a:True, sub: {'toto' : {b: True}}} - "-b" : BadContextException(b, [toto]) Parser description : - formula subparser toto binded to the argument sub with sub arguments : -b and --name """ parser = MainParser(help_arg=False) subparser = ComponentSubParser('toto') subparser.add_argument('b', flag=True, action=store_true) parser.add_component_subparser('sub', subparser) check_parsing_result(parser, '', {}) check_parsing_result(parser, '--sub toto -b', {'sub': { 'toto': { 'b': True } }}) with pytest.raises(BadContextException): check_parsing_result(parser, '-b', None)
def test_main_parser(): """ test to parse strings with a parser and retrieve the following results : - "" : {} - "-z" : UnknowArgException(z) - "-a" : {a: True} - "-a --sub toto -b" : UnknowArgException(sub) - "-b" : UnknowArgException(b) Parser description : - base parser arguments : -a - subparser toto binded to the argument sub with sub arguments : None """ parser = MainParser(help_arg=False) parser.add_argument('a', flag=True, action=store_true) check_parsing_result(parser, '', {}) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-z', None) check_parsing_result(parser, '-a', {'a': True}) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-a --sub toto -b', None) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-b', None)
def test_add_two_short_name(): """ Add an argument to a parser with two long name and test if the parser raise an exception TooManyArgumentNamesException """ parser = MainParser(help_arg=False) with pytest.raises(TooManyArgumentNamesException): parser.add_argument('coco', 'dodo')
def __init__(self): MainParser.__init__(self) self.add_argument('v', 'verbose', flag=True, action=enable_log, default=logging.NOTSET, help='enable verbose mode') self.add_argument('s', 'stream', flag=True, action=store_true, default=False, help='enable stream mode') subparser_mongo_input = ComponentSubParser('mongodb') subparser_mongo_input.add_argument('u', 'uri', help='sepcify MongoDB uri') subparser_mongo_input.add_argument( 'd', 'db', help='specify MongoDB database name') subparser_mongo_input.add_argument( 'c', 'collection', help='specify MongoDB database collection') subparser_mongo_input.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='hwpc_report') subparser_mongo_output = ComponentSubParser('mongodb') subparser_mongo_output.add_argument('u', 'uri', help='sepcify MongoDB uri') subparser_mongo_output.add_argument( 'd', 'db', help='specify MongoDB database name') subparser_mongo_output.add_argument( 'c', 'collection', help='specify MongoDB database collection') subparser_mongo_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='power_report') self.add_component_subparser( 'output', subparser_mongo_output, help_str= 'specify a database output : --db_output database_name ARG1 ARG2 ...' ) self.add_component_subparser( 'input', subparser_mongo_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' )
def test_short_and_long_name_val(): """ Add an argument to a parser with two name long and short and test if the value is only bind to the long name in the parsing result """ parser = MainParser(help_arg=False) parser.add_argument('c', 'coco') check_parsing_result(parser, '-c 1', {'coco': '1'})
def test_add_argument_short(): """ Add a short argument to the parser Test if the argument was added to the short_arg string """ parser = MainParser(help_arg=False) assert parser.short_arg == '' parser.add_argument('a') assert parser.short_arg == 'a:'
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)
def test_add_argument_flag(): """ Add a short flag to the parser Test if the argument was added to the short_arg string """ parser = MainParser(help_arg=False) assert parser.short_arg == '' parser.add_argument('a', flag=True) assert parser.short_arg == 'a'
def test_add_argument_long(): """ Add a long argument to the parser Test if the argument was added to the long_arg list """ parser = MainParser(help_arg=False) assert parser.long_arg == [] parser.add_argument('aaa') assert parser.long_arg == ['aaa=']
def test_add_component_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_component_subparser('sub', subparser) check_parsing_result(parser, '--sub titi -a --name tutu', {'sub': {'titi': {'tutu': {'aaa': True, 'name': 'tutu'}}}})
def test_default_type(): """ add an argument without specifing the type it must catch. Parse a string that contains only this argument and test if the value contained in the result is a string """ parser = MainParser(help_arg=False) parser.add_argument('a') result = parser.parse('-a 1'.split()) assert len(result) == 1 assert 'a' in result assert isinstance(result['a'], str)
def test_other_type(): """ add an argument that must catch an int value, Parse a string that contains only this argument and test if the value contained in the result is an int """ parser = MainParser(help_arg=False) parser.add_argument('a', type=int) result = parser.parse('-a 1'.split()) assert len(result) == 1 assert 'a' in result assert isinstance(result['a'], int)
def test_empty_parser(): """ test to parse strings with a parser and retrieve the following results : - "" : {} - "-z" : UnknowArgException(z) - "-a" : UnknowArgException(a) - "-a --sub toto -b" : UnknowArgException(a) - "-b" : UnknowArgException(b) Parser description : - base parser arguments : None - subparser toto binded to the argument sub with sub arguments : None """ parser = MainParser(help_arg=False) check_parsing_result(parser, '', {}) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-z', None) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-a', None) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-a --sub toto -b', None) with pytest.raises(UnknowArgException): check_parsing_result(parser, '-b', None)
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:{'toto' : {'titi': {'name': 'titi'}, 'tutu': {'name': 'tutu', 'b':False}}}} """ parser = MainParser(help_arg=False) subparser = ComponentSubParser('toto') subparser.add_argument('b', flag=True, action=store_true) subparser.add_argument('n', 'name') parser.add_component_subparser('sub', subparser) check_parsing_result(parser, '--sub toto --name titi --sub toto -b --name tutu', {'sub': {'toto': {'titi': {'name': 'titi'}, 'tutu': {'name': 'tutu', 'b': True}}}})
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)
def test_argument_with_val(): """ test to parse strings with a parser and retrieve the following results : - "-c" : MissingValue(c) - "-c 1" : {c : 1} Parser description : - base parser arguments : -c (not flag) """ parser = MainParser(help_arg=False) parser.add_argument('c') with pytest.raises(MissingValueException): check_parsing_result(parser, '-c', None) check_parsing_result(parser, '-c 1', {'c': '1'})
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' } }})
def test_cant_convert_to_type(): """ add an argument that must catch an int value, Parse a string that contains only this argument with a value that is not an int test if an """ parser = MainParser(help_arg=False) parser.add_argument('a', type=int) with pytest.raises(BadTypeException): parser.parse('-a a'.split())
def test_add_two_short_name(): """ Parse an argument with a value that doesn't respect the check function of this argument. Test if a BadValueException is raised """ parser = MainParser(help_arg=False) parser.add_argument('coco', type=int, check=lambda x: x > 2) with pytest.raises(BadValueException): parser.parse('--coco 1'.split())
def test_add_argument_2_short(): """ Add two short argument (an argument and a flag) to the parser Test if the arguments was added to the short_arg string """ parser = MainParser(help_arg=False) assert parser.short_arg == '' parser.add_argument('a', flag=True) assert parser.short_arg == 'a' parser.add_argument('b') assert parser.short_arg == 'ab:'
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)
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)
def __init__(self): ConfigParser.__init__(self) self.subparser = {} self.cli_parser = MainParser()
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
def __init__(self): MainParser.__init__(self) self.add_argument('v', 'verbose', flag=True, action=enable_log, default=logging.NOTSET, help='enable verbose mode') self.add_argument('s', 'stream', flag=True, action=store_true, default=False, help='enable stream mode') subparser_mongo_input = ComponentSubParser('mongodb') subparser_mongo_input.add_argument('u', 'uri', help='sepcify MongoDB uri') subparser_mongo_input.add_argument( 'd', 'db', help='specify MongoDB database name', ) subparser_mongo_input.add_argument( 'c', 'collection', help='specify MongoDB database collection') subparser_mongo_input.add_argument('n', 'name', help='specify puller name', default='puller_mongodb') subparser_mongo_input.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='HWPCReport') self.add_component_subparser( 'input', subparser_mongo_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_socket_input = ComponentSubParser('socket') subparser_socket_input.add_argument( 'p', 'port', help='specify port to bind the socket') subparser_socket_input.add_argument('n', 'name', help='specify puller name', default='puller_socket') subparser_socket_input.add_argument( 'm', 'model', help='specify data type that will be sent through the socket', default='HWPCReport') self.add_component_subparser( 'input', subparser_socket_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_csv_input = ComponentSubParser('csv') subparser_csv_input.add_argument( 'f', 'files', help='specify input csv files with this format : file1,file2,file3', action=extract_file_names, default=[], check=check_csv_files, check_msg='one or more csv files couldn\'t be read') subparser_csv_input.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='HWPCReport') subparser_csv_input.add_argument('n', 'name', help='specify puller name', default='puller_csv') self.add_component_subparser( 'input', subparser_csv_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_mongo_output = ComponentSubParser('mongodb') subparser_mongo_output.add_argument('u', 'uri', help='sepcify MongoDB uri') subparser_mongo_output.add_argument( 'd', 'db', help='specify MongoDB database name') subparser_mongo_output.add_argument( 'c', 'collection', help='specify MongoDB database collection') subparser_mongo_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_mongo_output.add_argument('n', 'name', help='specify puller name', default='pusher_mongodb') self.add_component_subparser( 'output', subparser_mongo_output, help_str= 'specify a database output : --db_output database_name ARG1 ARG2 ...' ) subparser_csv_output = ComponentSubParser('csv') subparser_csv_output.add_argument( 'd', 'directory', help= 'specify directory where where output csv files will be writen') subparser_csv_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_csv_output.add_argument('n', 'name', help='specify puller name', default='pusher_csv') self.add_component_subparser( 'output', subparser_csv_output, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_influx_output = ComponentSubParser('influxdb') subparser_influx_output.add_argument('u', 'uri', help='sepcify InfluxDB uri') subparser_influx_output.add_argument( 'd', 'db', help='specify InfluxDB database name') subparser_influx_output.add_argument( 'p', 'port', help='specify InfluxDB connection port', type=int) subparser_influx_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_influx_output.add_argument('n', 'name', help='specify puller name', default='pusher_influxdb') self.add_component_subparser( 'output', subparser_influx_output, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_opentsdb_output = ComponentSubParser('opentsdb') subparser_opentsdb_output.add_argument('u', 'uri', help='sepcify openTSDB host') subparser_opentsdb_output.add_argument( 'p', 'port', help='specify openTSDB connection port', type=int) subparser_opentsdb_output.add_argument('metric_name', help='specify metric name') subparser_opentsdb_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_opentsdb_output.add_argument('n', 'name', help='specify puller name', default='pusher_opentsdb') self.add_component_subparser( 'output', subparser_opentsdb_output, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' )
def __init__(self): MainParser.__init__(self) self.add_argument('v', 'verbose', flag=True, action=enable_log, default=logging.NOTSET, help='enable verbose mode') self.add_argument('s', 'stream', flag=True, action=store_true, default=False, help='enable stream mode') subparser_mongo_input = ComponentSubParser('mongodb') subparser_mongo_input.add_argument('u', 'uri', help='specify MongoDB uri') subparser_mongo_input.add_argument( 'd', 'db', help='specify MongoDB database name', ) subparser_mongo_input.add_argument( 'c', 'collection', help='specify MongoDB database collection') subparser_mongo_input.add_argument('n', 'name', help='specify puller name', default='puller_mongodb') subparser_mongo_input.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='HWPCReport') self.add_component_subparser( 'input', subparser_mongo_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_socket_input = ComponentSubParser('socket') subparser_socket_input.add_argument( 'p', 'port', help='specify port to bind the socket') subparser_socket_input.add_argument('n', 'name', help='specify puller name', default='puller_socket') subparser_socket_input.add_argument( 'm', 'model', help='specify data type that will be sent through the socket', default='HWPCReport') self.add_component_subparser( 'input', subparser_socket_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_daemon_input = ComponentSubParser('tcp') subparser_daemon_input.add_argument('p', 'port', help='specify the port to connect') subparser_daemon_input.add_argument('n', 'name', help='specify puller name', default="puller_tcp") subparser_daemon_input.add_argument( 'u', 'uri', help='specify the address of the puller', default='localhost') subparser_daemon_input.add_argument( 'm', 'model', help='specify data type that will be sent through the socket', default='HWPCReport') self.add_component_subparser( 'input', subparser_daemon_input, help_str='specify a tcp input : -p 8000 -a localhost ... ') subparser_csv_input = ComponentSubParser('csv') subparser_csv_input.add_argument( 'f', 'files', help='specify input csv files with this format : file1,file2,file3', action=extract_file_names, default=[], check=check_csv_files, check_msg='one or more csv files couldn\'t be read') subparser_csv_input.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='HWPCReport') subparser_csv_input.add_argument('n', 'name', help='specify puller name', default='puller_csv') self.add_component_subparser( 'input', subparser_csv_input, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_mongo_output = ComponentSubParser('mongodb') subparser_mongo_output.add_argument('u', 'uri', help='specify MongoDB uri') subparser_mongo_output.add_argument( 'd', 'db', help='specify MongoDB database name') subparser_mongo_output.add_argument( 'c', 'collection', help='specify MongoDB database collection') subparser_mongo_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_mongo_output.add_argument('n', 'name', help='specify puller name', default='pusher_mongodb') self.add_component_subparser( 'output', subparser_mongo_output, help_str= 'specify a database output : --db_output database_name ARG1 ARG2 ...' ) subparser_prom_output = ComponentSubParser('prom') subparser_prom_output.add_argument('a', 'addr', help='specify server address') subparser_prom_output.add_argument('p', 'port', help='specify server port', type=int) subparser_prom_output.add_argument('M', 'metric_name', help='speify metric name') subparser_prom_output.add_argument('d', 'metric_description', help='specify metric description', default='energy consumption') subparser_prom_output.add_argument( 'A', 'aggregation_period', help= 'specify number of second for the value must be aggregated before compute statistics on them', default=15, type=int) subparser_prom_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_prom_output.add_argument('n', 'name', help='specify puller name', default='pusher_prom') self.add_component_subparser( 'output', subparser_prom_output, help_str= 'specify a database output : --db_output database_name ARG1 ARG2 ...' ) subparser_csv_output = ComponentSubParser('csv') subparser_csv_output.add_argument( 'd', 'directory', help= 'specify directory where where output csv files will be writen') subparser_csv_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_csv_output.add_argument('n', 'name', help='specify puller name', default='pusher_csv') self.add_component_subparser( 'output', subparser_csv_output, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_influx_output = ComponentSubParser('influxdb') subparser_influx_output.add_argument('u', 'uri', help='specify InfluxDB uri') subparser_influx_output.add_argument( 'd', 'db', help='specify InfluxDB database name') subparser_influx_output.add_argument( 'p', 'port', help='specify InfluxDB connection port', type=int) subparser_influx_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_influx_output.add_argument('n', 'name', help='specify puller name', default='pusher_influxdb') self.add_component_subparser( 'output', subparser_influx_output, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_opentsdb_output = ComponentSubParser('opentsdb') subparser_opentsdb_output.add_argument('u', 'uri', help='specify openTSDB host') subparser_opentsdb_output.add_argument( 'p', 'port', help='specify openTSDB connection port', type=int) subparser_opentsdb_output.add_argument('metric_name', help='specify metric name') subparser_opentsdb_output.add_argument( 'm', 'model', help='specify data type that will be storen in the database', default='PowerReport') subparser_opentsdb_output.add_argument('n', 'name', help='specify puller name', default='pusher_opentsdb') self.add_component_subparser( 'output', subparser_opentsdb_output, help_str= 'specify a database input : --db_output database_name ARG1 ARG2 ... ' ) subparser_tcp_output = ComponentSubParser('tcp') subparser_tcp_output.add_argument('p', 'port', help="the port to bind") subparser_tcp_output.add_argument('u', 'uri', help="the address to bind", default="0.0.0.0") subparser_tcp_output.add_argument( 'm', 'model', help='specify data type that will be send in the stream', default='PowerReport') subparser_tcp_output.add_argument('n', 'name', help='specify pusher name', default='pusher_tcp') self.add_component_subparser( 'output', subparser_tcp_output, help_str='specify a tcp output : -p 8001 -m PowerReport ... ')