def test_deregister_unknown_module(self):
        """
        When deregistering a hook
            When the module is not known
                No exceptions are raised
                An appropriate message is logged
        """
        hooks = ModuleHookRegistry()
        module_hook = mock.Mock()

        # Ensure we do not have the module registered
        module_name = "test.module.name"
        assert module_name not in hooks.hooks

        with mock.patch("ddtrace.internal.import_hooks.log") as log_mock:
            # Deregistering the hook has no side effects
            hooks.deregister(module_name, module_hook)

        # Ensure we didn't do anything weird
        assert module_name not in hooks.hooks

        # Ensure a log message is generated
        log_mock.debug.assert_has_calls([
            mock.call("No hooks registered for module %r", "test.module.name")
        ])
    def test_deregister_unknown_hook(self):
        """
        When deregistering a hook
            When the module is not known
                No exceptions are raised
                A log entry is generated
        """
        hooks = ModuleHookRegistry()
        module_hook = mock.Mock()

        # Ensure we do not have the module registered
        module_name = "test.module.name"
        hooks.register(module_name, module_hook)

        # Ensure our hook was registered
        assert hooks.hooks[module_name] == set([module_hook])

        # Deregistering a different hook
        unknown_hook = mock.Mock()

        with mock.patch("ddtrace.internal.import_hooks.log") as log_mock:
            hooks.deregister(module_name, unknown_hook)

        # Ensure we didn't remove the other hook of ours
        assert hooks.hooks[module_name] == set([module_hook])

        # Ensure a log message is generated
        log_mock.debug.assert_has_calls([
            mock.call("No hook %r registered for module %r", mock.ANY,
                      "test.module.name")
        ])
    def test_deregister(self):
        """
        When deregistering a hook
            The hook is removed from the registry
            The hook is not called when the registry hooks call
        """
        hooks = ModuleHookRegistry()
        module_hook = mock.Mock()

        # Register the hook
        module_name = "tests.test_module"
        hooks.register(module_name, module_hook)
        assert hooks.hooks[module_name] == set([module_hook])

        # Deregister the hook
        hooks.deregister(module_name, module_hook)

        # Ensure it was removed
        assert hooks.hooks[module_name] == set()

        import tests.test_module

        hooks.call(module_name, module=tests.test_module)

        # Ensure it was not called
        module_hook.assert_not_called()