def test_commands_PillarSet_run_dry_run(patch_logging, mocker): # TODO IMPROVE OR TODO DOC # - PillarSet uses isinstance and it fails for PillarInputBase mocks: # TypeError: isinstance() arg 2 must be a type or tuple of types # options: mock only just 'from_args' method # - with autospec=True fails since classmethods # mocks are not callable for older version of mocker # - WORKS with autospec=False from_args_m = mocker.patch.object( commands.inputs.PillarInputBase, 'from_args' ) pillar_updater_m = mocker.patch.object( commands, 'PillarUpdater', autospec=True ) set_cmd = commands.PillarSet() keypath, value, fpath = '1/2/3', 456, '789.sls' # inputs as first arg object input_data = set_cmd.input_type(keypath, value, fpath=fpath) set_cmd.run(input_data, dry_run=True) from_args_m.assert_not_called() pillar_updater_m.assert_not_called() # inputs as a set of attrs set_cmd.run(keypath, value, fpath=fpath, dry_run=True) from_args_m.assert_called_once_with(keypath, value, fpath=fpath) pillar_updater_m.assert_not_called()
def test_commands_PillarSet_run_happy_path(patch_logging, mocker): pillar_updater_m = mocker.patch.object( commands, 'PillarUpdater', autospec=True ) keypath, value, fpath = '1/2/3', 456, '789.sls' targets = 'some-target' inputs = commands.inputs.PillarInputBase(keypath, value, fpath=fpath) set_cmd = commands.PillarSet() set_cmd.run(inputs, targets=targets) # TODO IMPROVE review mock call API for more accurate verification assert pillar_updater_m.mock_calls == [ mocker.call(targets), mocker.call().update(inputs), mocker.call().apply(), ]
def test_commands_PillarSet_run_fail_pillar_apply(mocker, rollback_exc): mock_manager = mocker.MagicMock() logger_m = mocker.patch.object( commands, 'logger', autospec=False ) pillar_updater_m = mocker.patch.object( commands, 'PillarUpdater', autospec=True ) mock_manager.attach_mock(logger_m, 'logger') mock_manager.attach_mock(pillar_updater_m, 'pillar_updater') exc = ValueError('someerror') pillar_updater_m.return_value.apply.side_effect = [exc, mocker.DEFAULT] if rollback_exc: pillar_updater_m.return_value.rollback.side_effect = rollback_exc inputs = commands.inputs.PillarInputBase('1/2/3', 456, fpath='789.sls') targets = 'some-target' set_cmd = commands.PillarSet() with pytest.raises(PillarSetError) as excinfo: set_cmd.run(inputs, targets=targets) assert excinfo.value.reason is exc assert excinfo.value.rollback_error is rollback_exc expected_calls = [ mocker.call.pillar_updater(targets), mocker.call.pillar_updater().update(inputs), mocker.call.pillar_updater().apply(), mocker.call.pillar_updater().rollback(), mocker.call.logger.exception('Pillar set failed'), ] if rollback_exc is None: expected_calls.insert(-1, mocker.call.pillar_updater().apply()) # TODO IMPROVE review mock call API for more accurate verification assert mock_manager.mock_calls == expected_calls