Skip to content

Commit 08ea21e

Browse files
authored
Merge pull request #82 from altor/release_0.6.2
feat: add component name in parsed config
2 parents d1aa7bc + 3b6a631 commit 08ea21e

File tree

6 files changed

+199
-75
lines changed

6 files changed

+199
-75
lines changed

powerapi/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@
2727
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929

30-
__version__ = "0.6.2"
30+
__version__ = "0.6.3"

powerapi/cli/parser.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ def __init__(self, argument_name):
6767
self.argument_name = argument_name
6868

6969

70+
class NoNameSpecifiedForComponentException(ParserException):
71+
"""
72+
Exception raised when attempting to parse substring thant describe a component which not contains the component name
73+
"""
74+
75+
76+
class ComponentAlreadyExistException(ParserException):
77+
"""
78+
Exception raised when attempting to parse a substring to create a component with a name that already exist
79+
"""
80+
81+
7082
class BadValueException(ParserException):
7183
"""
7284
Exception raised when attempting to parse a value that doens't respect the
@@ -77,6 +89,12 @@ def __init__(self, argument_name, msg):
7789
self.msg = msg
7890

7991

92+
class SubParserWithoutNameArgumentException(PowerAPIException):
93+
"""
94+
Exception raised when a subparser without argument name is added to a parser
95+
"""
96+
97+
8098
class TooManyArgumentNamesException(ParserException):
8199
"""
82100
Exception raised when attemtping to add an argument with too much names
@@ -437,11 +455,11 @@ def add_argument(self, *names, flag=False, action=store_val, default=None,
437455
type=type)
438456
self._add_argument_names(names, flag)
439457

440-
def add_component_subparser(self, component_name, subparser, help_str=''):
458+
def add_component_subparser(self, component_type, subparser, help_str=''):
441459
"""
442460
Add a subparser that will be used by the argument *component_name*
443461
444-
:param str component_name:
462+
:param str component_type:
445463
:param ComponentSubParser subparser:
446464
447465
:raise AlreadyAddedArgumentException: when attempting to add an
@@ -454,17 +472,31 @@ def _action(arg, val, args, acc):
454472

455473
subparser = self.subparsers_group[arg].get_subparser(val)
456474
args, subparse_result = subparser.subparse(args)
457-
acc[arg][subparser.name] = subparse_result
475+
476+
if 'name' not in subparse_result:
477+
raise NoNameSpecifiedForComponentException(component_type)
478+
479+
component_name = subparse_result['name']
480+
481+
if subparser.name not in acc[arg]:
482+
acc[arg][subparser.name] = {}
483+
484+
if component_name in acc[arg][subparser.name]:
485+
raise ComponentAlreadyExistException(component_name)
486+
487+
acc[arg][subparser.name][component_name] = subparse_result
458488
return args, acc
459489

460-
if component_name not in self.subparsers_group:
461-
self.subparsers_group[component_name] = SubParserGroup(component_name, help_str=help_str)
462-
self.add_argument(component_name, action=_action, help=help_str)
490+
if 'name' not in subparser.actions:
491+
raise SubParserWithoutNameArgumentException()
492+
if component_type not in self.subparsers_group:
493+
self.subparsers_group[component_type] = SubParserGroup(component_type, help_str=help_str)
494+
self.add_argument(component_type, action=_action, help=help_str)
463495
else:
464-
if self.subparsers_group[component_name].contains(subparser.name):
496+
if self.subparsers_group[component_type].contains(subparser.name):
465497
raise AlreadyAddedArgumentException(subparser.name)
466498

467-
self.subparsers_group[component_name].add_subparser(subparser.name, subparser)
499+
self.subparsers_group[component_type].add_subparser(subparser.name, subparser)
468500

469501
for action_name, action in subparser.actions.items():
470502
self._add_argument_names([action_name], action.is_flag)

powerapi/cli/tools.py

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,15 @@ def generate(self, config):
170170

171171
actors = {}
172172

173-
for component_name, component_config in config[self.component_group_name].items():
174-
try:
175-
actors[component_config['name']] = self._gen_actor(component_name, component_config, config)
176-
except KeyError as exn:
177-
msg = 'CLI error : argument ' + exn.args[0]
178-
msg += ' needed with --output ' + component_name
179-
print(msg, file=sys.stderr)
180-
sys.exit()
173+
for component_type, components_list in config[self.component_group_name].items():
174+
for component_name, component_config in components_list.items():
175+
try:
176+
actors[component_name] = self._gen_actor(component_type, component_config, config)
177+
except KeyError as exn:
178+
msg = 'CLI error : argument ' + exn.args[0]
179+
msg += ' needed with --output ' + component_type
180+
print(msg, file=sys.stderr)
181+
sys.exit()
181182

182183
return actors
183184

@@ -203,26 +204,8 @@ def __init__(self, component_group_name):
203204
}
204205

205206
def _generate_db(self, db_name, db_config, main_config):
206-
try:
207-
return self.db_factory[db_name](db_config)
208-
except KeyError as exn:
209-
arg = exn.args[0]
210-
211-
# if an argument is missing, look if it exist in another component group
212-
for group_name, group in main_config.items():
213-
if group_name == self.component_group_name:
214-
pass
215-
216-
elif not isinstance(group, dict):
217-
pass
218-
219-
elif db_name not in group:
220-
pass
207+
return self.db_factory[db_name](db_config)
221208

222-
elif arg in group[db_name]:
223-
db_config[arg] = group[db_name][arg]
224-
return self._generate_db(db_name, db_config, main_config)
225-
raise exn
226209

227210
def _gen_actor(self, db_name, db_config, main_config):
228211
db = self._generate_db(db_name, db_config, main_config)

tests/acceptation/test_simple_architecture_csv.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ def test_run(files, supervisor):
133133

134134
config = {'verbose': LOG_LEVEL,
135135
'stream': False,
136-
'input': { 'csv' : {'files': FILES,
136+
'input': {'csv': {'puller' : {'files': FILES,
137137
'model': 'hwpc_report',
138138
'name': 'puller',
139-
}},
140-
'output': {'csv': {'model': 'power_report', 'name': 'pusher', 'directory': ROOT_PATH}}}
139+
}}},
140+
'output': {'csv': {'pusher': {'model': 'power_report', 'name': 'pusher', 'directory': ROOT_PATH}}}}
141141

142142
# Pusher
143143
pusher_generator = PusherGenerator()

tests/unit/cli/test_parser.py

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
from powerapi.cli.parser import Parser, MainParser, ComponentSubParser
3636
from powerapi.cli.parser import store_true
3737
from powerapi.cli.parser import AlreadyAddedArgumentException, BadTypeException
38-
from powerapi.cli.parser import UnknowArgException, BadContextException, MissingValueException
38+
from powerapi.cli.parser import UnknowArgException, BadContextException, MissingValueException, ComponentAlreadyExistException
39+
from powerapi.cli.parser import SubParserWithoutNameArgumentException, NoNameSpecifiedForComponentException
3940
from powerapi.cli.parser import TooManyArgumentNamesException, BadValueException
4041

4142

@@ -200,19 +201,21 @@ def test_subparser():
200201
- "" : {}
201202
- "-z" : UnknowArgException(z)
202203
- "-a" : {a: True}
203-
- "-a --sub toto -b" : {a:True, sub: {'toto' : {b: True}}}
204+
- "-a --sub toto -b" : NoNameSpecifiedForComponentException
205+
- "-a --sub toto -b --name titi" : {a:True, sub: { titi: {'toto' : {b: True}}}}
204206
- "-b" : BadContextException(b, [toto])
205207
206208
Parser description :
207209
208210
- base parser arguments : -a
209-
- subparser toto binded to the argument sub with sub arguments : -b
211+
- subparser toto binded to the argument sub with sub arguments : -b and --name
210212
"""
211213
parser = MainParser(help_arg=False)
212214
parser.add_argument('a', flag=True, action=store_true)
213215

214216
subparser = ComponentSubParser('toto')
215217
subparser.add_argument('b', flag=True, action=store_true)
218+
subparser.add_argument('n', 'name')
216219
parser.add_component_subparser('sub', subparser)
217220

218221
check_parsing_result(parser, '', {})
@@ -222,13 +225,53 @@ def test_subparser():
222225

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

225-
check_parsing_result(parser, '-a --sub toto -b',
226-
{'a': True, 'sub': {'toto': { 'b': True}}})
228+
with pytest.raises(NoNameSpecifiedForComponentException):
229+
check_parsing_result(parser, '-a --sub toto -b', {})
230+
231+
check_parsing_result(parser, '-a --sub toto -b --name titi', {'a': True, 'sub': {'toto': {'titi': {'name': 'titi', 'b': True}}}})
227232

228233
with pytest.raises(BadContextException):
229234
check_parsing_result(parser, '-b', None)
230235

231236

237+
def test_create_two_component():
238+
"""
239+
Create two component of the same type with the following cli :
240+
--sub toto --name titi --sub toto -b --name tutu
241+
242+
test if the result is :
243+
{sub:{'toto' : {'titi': {'name': 'titi'}, 'tutu': {'name': 'tutu', 'b':False}}}}
244+
245+
"""
246+
parser = MainParser(help_arg=False)
247+
248+
subparser = ComponentSubParser('toto')
249+
subparser.add_argument('b', flag=True, action=store_true)
250+
subparser.add_argument('n', 'name')
251+
parser.add_component_subparser('sub', subparser)
252+
253+
check_parsing_result(parser, '--sub toto --name titi --sub toto -b --name tutu', {'sub': {'toto': {'titi': {'name': 'titi'}, 'tutu': {'name': 'tutu', 'b': True}}}})
254+
255+
256+
def test_create_component_that_already_exist():
257+
"""
258+
Create two component with the same name with the following cli
259+
--sub toto --name titi --sub toto --name titi
260+
261+
test if an ComponentAlreadyExistException is raised
262+
263+
264+
"""
265+
parser = MainParser(help_arg=False)
266+
267+
subparser = ComponentSubParser('toto')
268+
subparser.add_argument('b', flag=True, action=store_true)
269+
subparser.add_argument('n', 'name')
270+
parser.add_component_subparser('sub', subparser)
271+
272+
with pytest.raises(ComponentAlreadyExistException):
273+
check_parsing_result(parser, '--sub toto --name titi --sub toto --name titi', None)
274+
232275
def test_argument_with_val():
233276
"""
234277
test to parse strings with a parser and retrieve the following results :
@@ -348,9 +391,11 @@ def test_add_component_subparser_that_aldready_exists():
348391
"""
349392
parser = MainParser(help_arg=False)
350393
subparser = ComponentSubParser('titi')
394+
subparser.add_argument('n', 'name')
351395
parser.add_component_subparser('toto', subparser)
352396
subparser2 = ComponentSubParser('titi')
353-
397+
subparser2.add_argument('n', 'name')
398+
354399
with pytest.raises(AlreadyAddedArgumentException):
355400
parser.add_component_subparser('toto', subparser2)
356401

@@ -363,8 +408,21 @@ def test_add_component_subparser_with_two_name():
363408
parser = MainParser(help_arg=False)
364409
subparser = ComponentSubParser('titi')
365410
subparser.add_argument('a', 'aaa', flag=True, action=store_true, default=False)
411+
subparser.add_argument('n', 'name')
366412
parser.add_component_subparser('sub', subparser)
367-
check_parsing_result(parser, '--sub titi -a', {'sub': {'titi': {'aaa': True}}})
413+
check_parsing_result(parser, '--sub titi -a --name tutu', {'sub': {'titi': {'tutu': {'aaa': True, 'name': 'tutu'}}}})
414+
415+
416+
def test_add_component_subparser_that_aldready_exists():
417+
"""
418+
Add a component_subparser with no argument 'name'
419+
test if a SubParserWithoutNameArgumentException is raised
420+
"""
421+
parser = MainParser(help_arg=False)
422+
subparser = ComponentSubParser('titi')
423+
424+
with pytest.raises(SubParserWithoutNameArgumentException):
425+
parser.add_component_subparser('toto', subparser)
368426

369427

370428
def test_parse_empty_string_default_value():

0 commit comments

Comments
 (0)