def test_set_strict_with_subgroups_and_tags(hook_name): def handler(): pass main_group_name = hook_name.partition(".")[0] gossip.register(handler, hook_name) with pytest.raises(UndefinedHook): gossip.get_or_create_group(main_group_name).set_strict() hook = gossip.define(hook_name, tags=("some_tag", "other_tag")) illegal_tags_hook = gossip.define(".".join([hook.group.full_name, "hook_with_illegal_tags"])) gossip.register(handler, illegal_tags_hook.full_name, tags=("fake_tag")) with pytest.raises(UnsupportedHookTags): gossip.get_or_create_group(main_group_name).set_strict() illegal_tags_hook.unregister_all() gossip.get_or_create_group(main_group_name).set_strict() with pytest.raises(UnsupportedHookTags): @gossip.register(hook_name, tags=("fake_tag",)) def handler2(): # pylint: disable=unused-variable pass with pytest.raises(UnsupportedHookTags): gossip.trigger_with_tags(hook_name, tags=("fake_tag",)) gossip.trigger_with_tags(hook_name, tags=("some_tag", "other_tag"))
def test_register_hook_before_defining(doc_string): @register('hook_a') def hook_a_registration(**_): # pylint: disable=unused-variable pass tags = ('my', 'tags') hook_a = define('hook_a', tags=tags, arg_names=('x', 'y'), deprecated=True, doc=doc_string, can_be_muted=False) hook_b = define('hook_b', tags=tags, arg_names=('z', 'y'), deprecated=True, doc=doc_string, can_be_muted=False) @register('hook_b') def hook_b_registration(**_): # pylint: disable=unused-variable pass for hook in (hook_a, hook_b): assert hook.tags == tags assert hook.doc == doc_string assert not hook.can_be_muted() assert hook.deprecated assert hook_a.get_argument_names() == ('x', 'y') assert hook_b.get_argument_names() == ('z', 'y')
def test_inherit_policy_changing_parent(): gossip.define("group.hook") group = gossip.get_group("group") for policy in (gossip.RaiseImmediately(), gossip.RaiseDefer(), gossip.IgnoreExceptions()): gossip.set_exception_policy(policy) assert group.get_exception_policy() is policy
def test_single_set_tags_per_hook(): some_hook = gossip.define('group.some_hook') other_hook = gossip.define('group.other_hook', tags=("other_tag",)) some_hook.set_tags(('some_tag',)) with pytest.raises(AssertionError): some_hook.set_tags(('some_other_tag',)) with pytest.raises(AssertionError): other_hook.set_tags(('some_other_tag',))
def mute_other_sub_group(): hook_1 = gossip.define("a.b.c") hook_2 = gossip.define("a.c.d") hook_3 = gossip.define("a.c.e") gossip.get_group("a.b").forbid_muting() hook_3.forbid_muting() assert not hook_1.can_be_muted() assert not hook_3.can_be_muted() assert hook_2.can_be_muted()
def test_get_registrations_include_empty(hook_name, include_empty): gossip.define(hook_name) @gossip.register(hook_name) def handler(): pass hook = gossip.get_hook(hook_name) hook.register_no_op() expected = 2 if include_empty else 1 assert len(hook.get_registrations(include_empty=include_empty)) == expected
def test_unsupported_hook_params(): unsupported_params = {'unkown_param_a': 1, 'unkown_param_b': 2} with pytest.raises(UnsupportedHookParams) as caught: define('hook_name', **unsupported_params) assert all(param_name in str(caught.value) for param_name in unsupported_params) hook = define('other_hook') with pytest.raises(UnsupportedHookParams) as caught: hook.configure(**unsupported_params) assert all(param_name in str(caught.value) for param_name in unsupported_params)
def test_undefine(hook_name): gossip.define(hook_name) @gossip.register(hook_name) def handler(): pass hook = gossip.get_hook(hook_name) hook.register_no_op() hook.undefine() gossip.define(hook_name) assert not gossip.get_hook(hook_name).get_registrations() assert not gossip.get_hook(hook_name).get_registrations(include_empty=True)
def test_pre_trigger_callback(checkpoint): called_args = [] hook = define('somehook') @hook.add_pre_trigger_callback def pre_trigger_callback(registration, kwargs): # pylint: disable=unused-variable called_args.append((registration, kwargs)) assert not called_args trigger('somehook') assert not called_args @register('somehook') def callback(**kwargs): # pylint: disable=unused-argument checkpoint() assert not called_args trigger('somehook', x=1, y=2, z=3) assert len(called_args) == 1 assert called_args[0][-1] == {'x': 1, 'y': 2, 'z': 3} assert called_args[0][0].func is callback
def test_strict_hook_without_argument_defs_doesnt_validate(request): group = gossip.get_or_create_group('somegroup') group.set_strict() request.addfinalizer(group.undefine) hook = gossip.define('somegroup.somehook') request.addfinalizer(hook.undefine) hook.trigger(kwargs={'bla': 2, 'some': 'string', 'and_an': object()})
def setup_hook(is_defined, is_strict, specify_tags, register_before_define, create_group_before_define): # note: the combination of register before define *and* create strict group # before define is guaranteed to create an error if register_before_define: if not is_strict or not create_group_before_define: gossip.register(_HOOK_NAME)(lambda: None) if create_group_before_define: _get_or_create_group(is_strict) if is_defined: if specify_tags: gossip.define(_HOOK_NAME, tags=_ACCEPTED_TAGS) else: gossip.define(_HOOK_NAME) if not create_group_before_define: _get_or_create_group(is_strict)
def validating_hook(request): group = gossip.get_or_create_group('some_strict_group') group.set_strict() request.addfinalizer(group.undefine) hook = gossip.define('some_strict_group.some_hook', arg_names={'x': None, 'y': int, 'z': (str, float)}) request.addfinalizer(hook.undefine) return hook
def test_remove_pre_trigger_callback(): # pylint: disable=protected-access hook = define('hook') @hook.add_pre_trigger_callback def callback(): pass assert len(hook._pre_trigger_callbacks) == 1 hook.remove_pre_trigger_callback(callback) assert not hook._pre_trigger_callbacks
def test_deprecated_hook(): with python_warnings_recording() as recorded: hook = gossip.define('hook', deprecated=True) assert recorded == [] @hook.register def handler(): # pylint: disable=unused-variable pass [rec] = recorded assert rec.filename == __file__
def test_mute_hook(checkpoint): @gossip.register('a.b.c') def handler(): checkpoint() hook = gossip.define('a.b.d') hook.forbid_muting() assert not hook.can_be_muted() with gossip.mute_context(['a.b.c']): gossip.trigger('a.b.c') assert not checkpoint.called
def validating_hook(request): group = gossip.get_or_create_group('some_strict_group') group.set_strict() request.addfinalizer(group.undefine) hook = gossip.define('some_strict_group.some_hook', arg_names={ 'x': None, 'y': int, 'z': (str, float) }) request.addfinalizer(hook.undefine) return hook
def test_get_hook(hook_name): with pytest.raises(LookupError): gossip.get_hook(hook_name) hook = gossip.define(hook_name) assert gossip.get_hook(hook_name) is hook
def test_define_twice(hook_name): gossip.define(hook_name) with pytest.raises(NameAlreadyUsed): gossip.define(hook_name)
def test_hook_documentation(): docstring = "fdkjfkdjfd" gossip.define("some_hook", doc=docstring) assert gossip.get_hook("some_hook").doc == docstring
def _define(hook_name, **kwargs): hook = gossip.define("slash.{0}".format(hook_name), **kwargs) globals()[hook_name] = hook return hook
def test_non_strict_hook_doesnt_validate(request): hook = gossip.define('somegroup.somehook', arg_names={'x': None, 'y': int}) request.addfinalizer(hook.undefine) hook.trigger(kwargs={})
def _define_hook(ctx): gossip.define("group.defined_hook") ctx.defined_hook = True
def _install_hooks(): import gossip # Define systems objects operation hooks obj_type_name = set(tag for sys in (InfiniBox, IZBox) for obj_cls in sys.OBJECT_TYPES for tag in obj_cls._get_tags_for_object_operations(sys)) for hook_name_template in (_SDK_HOOK('pre_object_{0}'), _SDK_HOOK('post_object_{0}')): for operation in ('creation', 'deletion', 'update'): full_hook_name = hook_name_template.format(operation) gossip.define(full_hook_name, tags=obj_type_name) gossip.define(_SDK_HOOK('object_operation_failure'), tags=obj_type_name) gossip.define(_SDK_HOOK('object_creation_failure'), tags=obj_type_name) gossip.define(_SDK_HOOK("begin_fork"), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK("cancel_fork"), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK("finish_fork"), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('pre_data_restore'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('post_data_restore'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('data_restore_failure'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('pre_creation_data_validation'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('pre_fields_update'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_cons_group_add_member'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_cons_group_add_member'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_snapshot_created'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_after_change_role'), tags=['infinibox']) gossip.define(_SDK_HOOK('before_api_request')) gossip.define(_SDK_HOOK('after_api_request')) gossip.define(_SDK_HOOK('after_login')) gossip.get_or_create_group('infinidat.sdk').set_strict()
def test_trigger_hook_with_unsupported_tags(): gossip.define('group.some_hook', tags=("some_tag",)) gossip.trigger('group.some_hook', tags=("fake_tag",)) gossip.get_or_create_group('group').set_strict() with pytest.raises(UnsupportedHookTags): gossip.trigger_with_tags('group.some_hook', tags=("fake_tag",))
def _make_define_hook(ctx): gossip.define("group.defined_hook", tags=ctx.defined_tags) ctx.defined_hook = True
import gossip step_hook_group = gossip.create_group("step") step_hook_group.set_strict() step_start = gossip.define('slash.step_start') step_success = gossip.define('slash.step_success') step_error = gossip.define('slash.step_error') step_end = gossip.define('slash.step_end')
def _install_hooks(): import gossip # Define systems objects operation hooks. TreeQ is explicitly added separately, as, being a special type of object, # it is not in OBJECT_TYPES. obj_type_names = set( tag for sys in (InfiniBox, ) for obj_cls in sys.OBJECT_TYPES + [TreeQ] for tag in obj_cls.get_tags_for_object_operations(sys)) for hook_name_template in (_SDK_HOOK('pre_object_{}'), _SDK_HOOK('post_object_{}'), _SDK_HOOK('object_{}_failure')): for operation in ('creation', 'deletion', 'update'): full_hook_name = hook_name_template.format(operation) gossip.define(full_hook_name, tags=obj_type_names) gossip.define(_SDK_HOOK('object_operation_failure'), tags=obj_type_names) gossip.define(_SDK_HOOK('pre_treeq_creation'), tags=['infinibox', 'treeq']) gossip.define(_SDK_HOOK('post_treeq_creation'), tags=['infinibox', 'treeq']) gossip.define(_SDK_HOOK('treeq_creation_failure'), tags=['infinibox', 'treeq']) gossip.define(_SDK_HOOK("begin_fork"), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK("cancel_fork"), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK("finish_fork"), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('pre_data_restore'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('post_data_restore'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('data_restore_failure'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('pre_object_restore'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('post_object_restore'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('object_restore_failure'), tags=['infinibox', 'volume', 'filesystem']) gossip.define(_SDK_HOOK('pre_pool_move'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('post_pool_move'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('pool_move_failure'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('pre_cons_group_deletion'), tags=['infinibox', 'cons_group']) gossip.define(_SDK_HOOK('post_cons_group_deletion'), tags=['infinibox', 'cons_group']) gossip.define(_SDK_HOOK('cons_group_deletion_failure'), tags=['infinibox', 'cons_group']) gossip.define(_SDK_HOOK('pre_entity_child_creation'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('post_entity_child_creation'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('entity_child_creation_failure'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('pre_creation_data_validation'), tags=obj_type_names) gossip.define(_SDK_HOOK('pre_fields_update'), tags=obj_type_names) gossip.define(_SDK_HOOK('pre_cons_group_add_member'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_cons_group_add_member'), tags=['infinibox']) gossip.define(_SDK_HOOK('cons_group_add_member_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_cons_group_remove_member'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_cons_group_remove_member'), tags=['infinibox']) gossip.define(_SDK_HOOK('cons_group_remove_member_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_snapshot_created'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_deleted'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_replication_snapshot_expose'), tags=['volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('post_replication_snapshot_expose'), tags=['volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('replication_snapshot_expose_failure'), tags=['volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('pre_replica_suspend'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_replica_suspend'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_suspend_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_replica_resume'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_replica_resume'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_resume_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_replica_change_type'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_replica_change_type'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_change_type_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_replica_switch_role'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_replica_switch_role'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_switch_role_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_replica_change_role'), tags=['infinibox']) gossip.define(_SDK_HOOK('post_replica_change_role'), tags=['infinibox']) gossip.define(_SDK_HOOK('replica_change_role_failure'), tags=['infinibox']) gossip.define(_SDK_HOOK('pre_refresh_snapshot'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('post_refresh_snapshot'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('refresh_snapshot_failure'), tags=['infinibox', 'volume', 'filesystem', 'cons_group']) gossip.define(_SDK_HOOK('pre_pool_lock'), tags=['infinibox', 'pool']) gossip.define(_SDK_HOOK('post_pool_lock'), tags=['infinibox', 'pool']) gossip.define(_SDK_HOOK('pool_lock_failure'), tags=['infinibox', 'pool']) gossip.define(_SDK_HOOK('pre_pool_unlock'), tags=['infinibox', 'pool']) gossip.define(_SDK_HOOK('post_pool_unlock'), tags=['infinibox', 'pool']) gossip.define(_SDK_HOOK('pool_unlock_failure'), tags=['infinibox', 'pool']) gossip.define(_SDK_HOOK('pre_qos_policy_assign'), tags=['infinibox', 'qos_policy']) gossip.define(_SDK_HOOK('post_qos_policy_assign'), tags=['infinibox', 'qos_policy']) gossip.define(_SDK_HOOK('qos_policy_assign_failure'), tags=['infinibox', 'qos_policy']) gossip.define(_SDK_HOOK('pre_qos_policy_unassign'), tags=['infinibox', 'qos_policy']) gossip.define(_SDK_HOOK('post_qos_policy_unassign'), tags=['infinibox', 'qos_policy']) gossip.define(_SDK_HOOK('qos_policy_unassign_failure'), tags=['infinibox', 'qos_policy']) gossip.define(_SDK_HOOK('before_api_request')) gossip.define(_SDK_HOOK('after_api_request')) gossip.define(_SDK_HOOK('after_login')) gossip.get_or_create_group('infinidat.sdk').set_strict()
def hook(hook_name): return gossip.define(hook_name)
def _define(hook_name, **kwargs): hook = gossip.define("slash.{}".format(hook_name), **kwargs) globals()[hook_name] = hook return hook