示例#1
0
def run(args: List[str]) -> int:
    """
    Run the program.

    :arg args: A list of command line arguments.  Typically :python:`sys.argv`.
    :returns: A program return code.  0 for success, integers for any errors.  These are documented
        in :func:`main`.
    """
    flog = mlog.fields(func='run')
    flog.fields(raw_args=args).info('Enter')

    program_name = os.path.basename(args[0])
    try:
        args: argparse.Namespace = parse_args(program_name, args[1:])
    except InvalidArgumentError as e:
        print(e)
        return 2

    cfg = load_config(args.config_file)
    flog.fields(config=cfg).info('Config loaded')

    context_data = app_context.create_contexts(args=args, cfg=cfg)
    with app_context.app_and_lib_context(context_data) as (app_ctx, dummy_):
        twiggy.dict_config(app_ctx.logging_cfg.dict())
        flog.debug('Set logging config')

        return ARGS_MAP[args.command]()
示例#2
0
    def run(self):
        """
        Run the program.  This is the main entrypoint to the magnate client
        """
        # Create the statedir if it doesn't exist
        if not os.path.exists(self.cfg['state_dir']):
            os.makedirs(self.cfg['state_dir'])

        twiggy.dict_config(self.cfg['logging'])

        # Base data attributes
        self._load_data_definitions()

        ui_plugins = load('magnate.ui', subclasses=UserInterface)
        for UIClass in ui_plugins:  #pylint: disable=invalid-name
            if UIClass.__module__.startswith('magnate.ui.{}'.format(
                    self.cfg['ui_plugin'])):
                break
        else:
            print('Unknown user ui: {}'.format(self.cfg['ui_plugin']))
            return 1

        # Try using uvloop instead of the asyncio event loop
        if self.cfg['use_uvloop']:
            try:
                import uvloop
            except Exception:
                print(
                    'Could not import uvloop.  Falling back on asyncio event loop'
                )
            try:
                asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
            except Exception:
                print(
                    'Could not set uvloop to be the event loop.  Falling back on asyncio event loop'
                )

        loop = asyncio.get_event_loop()
        self.pubpen = PubPen(loop)
        self._setup_markets()
        self.dispatcher = Dispatcher(self, self.markets)

        # UIClass is always available because we'd have already returned (via
        # the for-else) if UIClass was not defined
        try:
            user_interface = UIClass(self.pubpen, self.cfg['ui_args'])  # pylint: disable=undefined-loop-variable
            return user_interface.run()
        except Exception as e:
            mlog.trace('error').error(
                'Exception raised while running the user interface')
            raise
示例#3
0
def test_dict_config_incremental_true(mocker):
    def return_how_called(*args, **kwargs):
        return (args, kwargs)

    cfg = copy.deepcopy(VALID_CONFIG)
    del cfg['emitters']['some']
    cfg['incremental'] = True

    add_emitters = mocker.patch('twiggy.add_emitters')
    mocker.patch('twiggy.emitters')
    emitters_dict_clear = mocker.patch('twiggy.emitters.clear')
    mocker.patch('twiggy.filters.names', return_how_called)

    twiggy.dict_config(cfg)

    assert emitters_dict_clear.call_args_list == []

    assert len(add_emitters.call_args_list) == 1
    assert len(add_emitters.call_args_list[0][0]) == 1

    cfg = copy.deepcopy(VALID_CONFIG)
    del cfg['emitters']['all']
    cfg['incremental'] = True

    twiggy.dict_config(cfg)

    assert emitters_dict_clear.call_args_list == []

    assert len(add_emitters.call_args_list) == 2
    assert len(add_emitters.call_args_list[0][0]) == 1
    assert len(add_emitters.call_args_list[1][0]) == 1

    # call_args_list is nested like this: [call(positional_args(first_emitter)),]
    # We expect to have called add_emitters twice with one positional arg each time
    all_emitter = add_emitters.call_args_list[0][0][0]
    some_emitter = add_emitters.call_args_list[1][0][0]

    assert all_emitter[0] == 'all'
    assert all_emitter[1] == twiggy.levels.DEBUG
    assert all_emitter[2] is None
    assert isinstance(all_emitter[3], twiggy.outputs.StreamOutput)
    assert all_emitter[3]._format == twiggy.formats.line_format
    assert all_emitter[3].stream == 'testing1'

    assert some_emitter[0] == 'some'
    assert some_emitter[1] == twiggy.levels.WARNING
    assert some_emitter[2] == [(('a', 'b'), {}), (('c', 'd'), {})]
    assert isinstance(some_emitter[3], twiggy.outputs.StreamOutput)
    assert some_emitter[3]._format == twiggy.formats.shell_format
    assert some_emitter[3].stream == 'testing2'
示例#4
0
def test_dict_config_incremental_false_contents(mocker):
    def return_how_called(*args, **kwargs):
        return (args, kwargs)

    cfg = copy.deepcopy(VALID_CONFIG)
    del cfg['emitters']['some']

    add_emitters = mocker.patch('twiggy.add_emitters')
    mocker.patch('twiggy.emitters')
    emitters_dict_clear = mocker.patch('twiggy.emitters.clear')
    mocker.patch('twiggy.filters.names', return_how_called)

    twiggy.dict_config(cfg)

    assert emitters_dict_clear.call_args_list == [mocker.call()]

    assert len(add_emitters.call_args_list) == 1
    assert len(add_emitters.call_args_list[0][0]) == 1

    the_emitter = add_emitters.call_args_list[0][0][0]

    assert the_emitter[0] == 'all'
    assert the_emitter[1] == twiggy.levels.DEBUG
    assert the_emitter[2] is None
    assert isinstance(the_emitter[3], twiggy.outputs.StreamOutput)
    assert the_emitter[3]._format == twiggy.formats.line_format
    assert the_emitter[3].stream == 'testing1'

    cfg = copy.deepcopy(VALID_CONFIG)
    del cfg['emitters']['all']

    twiggy.dict_config(cfg)

    # Note: This does not check that the clear call happens before the add_emitters call.
    # The test_dict_config_incremental_false_order() check takes care of that.
    assert emitters_dict_clear.call_args_list == [mocker.call(), mocker.call()]

    assert len(add_emitters.call_args_list) == 2
    assert len(add_emitters.call_args_list[1][0]) == 1

    the_emitter = add_emitters.call_args_list[1][0][0]

    assert the_emitter[0] == 'some'
    assert the_emitter[1] == twiggy.levels.WARNING
    assert the_emitter[2] == [(('a', 'b'), {}), (('c', 'd'), {})]
    assert isinstance(the_emitter[3], twiggy.outputs.StreamOutput)
    assert the_emitter[3]._format == twiggy.formats.shell_format
    assert the_emitter[3].stream == 'testing2'
示例#5
0
def test_dict_config_incremental_false_order(mocker):
    """
    With incremental=false it is important that the dictionary is cleared before the emitter is
    added.  We'll do this by testing the emitters dict instead of a mock
    """
    cfg = copy.deepcopy(VALID_CONFIG)
    del cfg['emitters']['some']

    twiggy.dict_config(cfg)

    assert len(twiggy.emitters) == 1
    assert 'all' in twiggy.emitters

    cfg = copy.deepcopy(VALID_CONFIG)
    del cfg['emitters']['all']

    twiggy.dict_config(cfg)

    assert len(twiggy.emitters) == 1
    assert 'some' in twiggy.emitters
示例#6
0
def test_dict_config_valid(mocker):
    def return_how_called(*args, **kwargs):
        return (args, kwargs)

    cfg = copy.deepcopy(VALID_CONFIG)

    add_emitters = mocker.patch('twiggy.add_emitters')
    mocker.patch('twiggy.emitters')
    emitters_dict_clear = mocker.patch('twiggy.emitters.clear')
    mocker.patch('twiggy.filters.names', return_how_called)

    twiggy.dict_config(cfg)

    assert emitters_dict_clear.call_args_list == [mocker.call()]

    assert len(add_emitters.call_args_list) == 1
    assert len(add_emitters.call_args_list[0][0]) == 2

    # call_args_list is nested like this: [call(positional_args(first_emitter)),]
    # We expect to have called add_emitters once with two positional args which are
    # themselves tuples
    if add_emitters.call_args_list[0][0][0][0] == 'all':
        all_emitter = add_emitters.call_args_list[0][0][0]
        some_emitter = add_emitters.call_args_list[0][0][1]
    else:
        some_emitter = add_emitters.call_args_list[0][0][0]
        all_emitter = add_emitters.call_args_list[0][0][1]

    assert all_emitter[0] == 'all'
    assert all_emitter[1] == twiggy.levels.DEBUG
    assert all_emitter[2] is None
    assert isinstance(all_emitter[3], twiggy.outputs.StreamOutput)
    assert all_emitter[3]._format == twiggy.formats.line_format
    assert all_emitter[3].stream == 'testing1'

    assert some_emitter[0] == 'some'
    assert some_emitter[1] == twiggy.levels.WARNING
    assert some_emitter[2] == [(('a', 'b'), {}), (('c', 'd'), {})]
    assert isinstance(some_emitter[3], twiggy.outputs.StreamOutput)
    assert some_emitter[3]._format == twiggy.formats.shell_format
    assert some_emitter[3].stream == 'testing2'
示例#7
0
    def test_twiggy_smoketest(self, mocker):
        cfg = c._read_config(tuple())
        m = mocker.mock_open()
        mocker.patch('builtins.open', m)

        twiggy.dict_config(cfg['logging'])
示例#8
0
def test_dict_config_invalid(internal_log):
    with pytest.raises(ValueError) as excinfo:
        twiggy.dict_config({})
        assert excinfo.value.message == "Config dict must contain a 'version' key"