From 93043172a47f328560e473b79717a9f39a5279ad Mon Sep 17 00:00:00 2001 From: Cyril Danilevski <cyril.danilevski@xfel.eu> Date: Thu, 18 Feb 2021 12:37:20 +0100 Subject: [PATCH] Add webservice.parse_config test --- tests/test_webservice.py | 29 ++++++++++++++++++++++++++++- webservice/webservice.py | 24 +++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/tests/test_webservice.py b/tests/test_webservice.py index 7a67cf530..bd482d4e8 100644 --- a/tests/test_webservice.py +++ b/tests/test_webservice.py @@ -4,7 +4,7 @@ from pathlib import Path import pytest sys.path.insert(0, Path(__file__).parent / 'webservice') -from webservice.webservice import check_files, merge # noqa +from webservice.webservice import check_files, merge, parse_config # noqa def test_check_files(): @@ -36,3 +36,30 @@ def test_merge(): 'number': 1}}, 'completely': 'different'} assert ret == expected + + +def test_parse_config(): + cmd = ['whatever'] + config = {'somebool': True, + 'notsomebool': False, + 'alist': [1, 2, 3], + 'some_empty_key': '""', + 'other_empty_key': "''", + 'brian': 'scone'} + + expected = ['whatever', '--somebool', '--alist', '1', '2', '3', + '--some_empty_key', '', '--other_empty_key', '', + '--brian', 'scone'] + + config = parse_config(cmd, config) + + assert config == expected + assert '--notsomebool' not in config + + with pytest.raises(ValueError): + config = {'some key': 'value'} + config = parse_config(cmd, config) + + with pytest.raises(ValueError): + config = {'somekey': 'a value'} + config = parse_config(cmd, config) diff --git a/webservice/webservice.py b/webservice/webservice.py index 3ec8b64fa..0f2d28a23 100644 --- a/webservice/webservice.py +++ b/webservice/webservice.py @@ -13,7 +13,7 @@ import urllib.parse from asyncio import get_event_loop, shield from datetime import datetime from pathlib import Path -from typing import List +from typing import Any, Dict, List import yaml import zmq @@ -128,9 +128,8 @@ async def upload_config(socket, config, yaml, instrument, cycle, proposal): socket.send(Success.UPLOADED_CONFIG.format(cycle, proposal).encode()) -def merge(source, destination): - """ - Deep merge two dictionaries +def merge(source: Dict, destination: Dict) -> Dict: + """Deep merge two dictionaries. :param source: source dictionary to merge into destination :param destination: destination dictionary which is being merged in @@ -284,16 +283,27 @@ async def query_rid(conn, socket, rid): socket.send(msg.encode()) -def parse_config(cmd, config): +def parse_config(cmd: List[str], config: Dict[str, Any]) -> List[str]: + """Convert a dictionary to a list of arguments. + + Values that are not strings will be cast. + Lists will be converted to several strings following their `--key` + flag. + Booleans will be converted to a `--key` flag, where `key` is the + dictionary key. + """ for key, value in config.items(): + if ' ' in key or (isinstance(value, str) and ' ' in value): + raise ValueError('Spaces are not allowed', key, value) + if isinstance(value, list): - cmd += ["--{}".format(key)] + cmd.append(f"--{key}") cmd += [str(v) for v in value] elif isinstance(value, bool): if value: cmd += ["--{}".format(key)] else: - if value == '""' or value == "''": + if value in ['""', "''"]: value = "" cmd += ["--{}".format(key), str(value)] -- GitLab