Esempio n. 1
0
 def warning(self, message):
     """
     Simple wrapper around the standard Python logger's warning method.
     Fires the `eva.logger.warning` trigger.
     """
     self.logger.warning(message)
     gossip.trigger('eva.logger.warning', message=message)
Esempio n. 2
0
 def info(self, message):
     """
     Simple wrapper around the standard Python logger's info method.
     Fires the `eva.logger.info` trigger.
     """
     self.logger.info(message)
     gossip.trigger('eva.logger.info', message=message)
Esempio n. 3
0
 def critical(self, message):
     """
     Simple wrapper around the standard Python logger's critical method.
     Fires the `eva.logger.critical` trigger.
     """
     self.logger.critical(message)
     gossip.trigger('eva.logger.critical', message=message)
Esempio n. 4
0
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
Esempio n. 5
0
    def set_input_audio(self, audio, content_type):
        """
        Same as :func:`set_input_text` except it works for the input audio and
        content type. Not very many plugins will end up using this as it involves
        modifying the audio query or command that was sent by the Eva client.

        This method fires the ``eva.pre_set_input_audio`` and
        ``eva.post_set_input_audio`` triggers.

        :param audio: The audio to be set as the input audio for this interaction.
        :type audio: binary string
        :param content_type: The content type of this binary audio data.
        :type content_type: string
        """
        plugin_id = get_calling_plugin()
        gossip.trigger('eva.pre_set_input_audio',
                       audio=audio,
                       content_type=content_type,
                       plugin_id=plugin_id,
                       context=self)
        self.input_audio = audio
        self.input_audio_content_type = content_type
        gossip.trigger('eva.post_set_input_audio',
                       audio=audio,
                       content_type=content_type,
                       plugin_id=plugin_id,
                       context=self)
Esempio n. 6
0
 def error(self, message):
     """
     Simple wrapper around the standard Python logger's error method.
     Fires the `eva.logger.error` trigger.
     """
     self.logger.error(message)
     gossip.trigger('eva.logger.error', message=message)
Esempio n. 7
0
def job_succeeded(event):
    """
    A callback function that gets called when an
    `APScheduler <https://apscheduler.readthedocs.io/en/latest/>`_ job succeeds.

    Currently will simply fire the `eva.scheduler.job_succeeded` trigger with the
    success event object.
    """
    gossip.trigger('eva.scheduler.job_succeeded', event=event)
Esempio n. 8
0
def test_non_reentrant_hooks(counter):
    hook_name = 'nonreentrant_hook'

    @gossip.register(hook_name, reentrant=False)
    def handler():  # pylint: disable=unused-variable
        counter.add(1)
        gossip.trigger(hook_name)

    gossip.trigger(hook_name)
    assert counter == 1
Esempio n. 9
0
def test_token_unregister_from_hook(checkpoint, token, hook_name):
    # pylint: disable=unused-variable

    @gossip.register(hook_name, token=token)
    def handler():
        gossip.unregister_token(token)
    gossip.register(hook_name)(checkpoint)

    gossip.trigger(hook_name)
    assert checkpoint.called
Esempio n. 10
0
def test_uninstall(blueprint, checkpoint):

    blueprint.register('a')(checkpoint)
    blueprint.install()
    gossip.trigger('a')
    assert checkpoint.called
    checkpoint.reset()
    blueprint.uninstall()
    gossip.trigger('a')
    assert not checkpoint.called
Esempio n. 11
0
def test_normal_hooks_can_reenter(counter):
    counter.set(5)

    @gossip.register('reentrant_hook')
    def handler():  # pylint: disable=unused-variable
        counter.sub(1)
        if counter:
            gossip.trigger('reentrant_hook')

    gossip.trigger('reentrant_hook')
    assert counter == 0
Esempio n. 12
0
def test_token_unregister_from_hook(checkpoint, token, hook_name):
    # pylint: disable=unused-variable

    @gossip.register(hook_name, token=token)
    def handler():
        gossip.unregister_token(token)

    gossip.register(hook_name)(checkpoint)

    gossip.trigger(hook_name)
    assert checkpoint.called
Esempio n. 13
0
def boot():
    """
    The function that runs the Eva boot sequence and loads all the plugins.

    Fires the `eva.pre_boot` and `eva.post_boot` triggers.
    """
    log.info('Beginning Eva boot sequence')
    gossip.trigger('eva.pre_boot')
    load_plugins()
    gossip.trigger('eva.post_boot')
    log.info('Eva booted successfully')
Esempio n. 14
0
def test_non_reentrant_hooks(counter):
    hook_name = 'nonreentrant_hook'


    @gossip.register(hook_name, reentrant=False)
    def handler(): # pylint: disable=unused-variable
        counter.add(1)
        gossip.trigger(hook_name)

    gossip.trigger(hook_name)
    assert counter == 1
Esempio n. 15
0
def test_normal_hooks_can_reenter(counter):
    counter.set(5)

    @gossip.register('reentrant_hook')
    def handler(): # pylint: disable=unused-variable
        counter.sub(1)
        if counter:
            gossip.trigger('reentrant_hook')

    gossip.trigger('reentrant_hook')
    assert counter == 0
Esempio n. 16
0
def test_mute_group(checkpoint):

    @gossip.register('a.b.c')
    def handler():
        checkpoint()

    gossip.get_group("a").forbid_muting()

    with pytest.raises(CannotMuteHooks):
        with gossip.mute_context(['a.b.c']):
            gossip.trigger('a.b.c')
    assert not checkpoint.called
Esempio n. 17
0
def test_token_unregister_from_hook_multiple_token_registrants(checkpoint, token, hook_name):
    # pylint: disable=unused-variable

    @gossip.register(hook_name, token=token)
    def handler():
        gossip.unregister_token(token)
    gossip.register(hook_name)(checkpoint)
    # the second token registration should not be called!
    gossip.register(hook_name, token=token)(checkpoint)

    gossip.trigger(hook_name)
    assert checkpoint.num_times == 1
Esempio n. 18
0
def test_unregister_no_op_remove_dependencies(timeline):
    timeline.register(needs=['1'], provides=['0'])
    timeline.register(needs=['2'], provides=['1'])

    hook = timeline.get_hook()
    registration = hook.register_no_op(provides=['2'])
    timeline.trigger()

    registration.unregister()
    with pytest.raises(CannotResolveDependencies) as caught:
        gossip.trigger(hook.full_name)
    assert caught.value.unmet_dependencies == set(['2'])
Esempio n. 19
0
    def session_end(self):
        if time.time() - self._session_start_time < config.root.plugin_config.notifications.notification_threshold:
            return

        result = "successfully" if session.results.is_success() else "unsuccessfully"
        hostname = socket.gethostname().split(".")[0]
        body = "{0}\n\n{1}".format(session.results, session.id)

        message = Message("Slash session in {0} ended {1}".format(hostname, result), body)
        gossip.trigger("slash-gossip.prepare_notification", message=message)

        self._notify(message.title, message.body)
Esempio n. 20
0
def test_unregister_no_op_remove_dependencies(timeline):
    timeline.register(needs=['1'], provides=['0'])
    timeline.register(needs=['2'], provides=['1'])

    hook = timeline.get_hook()
    registration = hook.register_no_op(provides=['2'])
    timeline.trigger()

    registration.unregister()
    with pytest.raises(CannotResolveDependencies) as caught:
        gossip.trigger(hook.full_name)
    assert caught.value.unmet_dependencies == set(['2'])
Esempio n. 21
0
def test_registers_on_none(restore_plugins_on_cleanup, checkpoint):
    @slash.plugins.active  # pylint: disable=unused-variable
    class SamplePlugin(PluginInterface):
        def get_name(self):
            return 'sample'

        @plugins.registers_on(None)
        def some_method_here(self):
            checkpoint()

    gossip.trigger('slash.some_method_here')
    assert not checkpoint.called
Esempio n. 22
0
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
Esempio n. 23
0
def test_blueprint(blueprint, checkpoint):
    @blueprint.register('a.b')
    def handler():  # pylint: disable=unused-variable
        checkpoint()

    gossip.trigger('a.b')

    assert not checkpoint.called

    blueprint.install()

    gossip.trigger('a.b')
    assert checkpoint.called
Esempio n. 24
0
def test_registers_on_with_private_methods(restore_plugins_on_cleanup,
                                           checkpoint):
    @slash.plugins.active  # pylint: disable=unused-variable
    class SamplePlugin(PluginInterface):
        def get_name(self):
            return 'sample'

        @plugins.registers_on('some_hook')
        def _handler(self):
            checkpoint()

    assert not checkpoint.called
    gossip.trigger('some_hook')
    assert checkpoint.called
Esempio n. 25
0
def test_token_unregister_from_hook_multiple_token_registrants(
        checkpoint, token, hook_name):
    # pylint: disable=unused-variable

    @gossip.register(hook_name, token=token)
    def handler():
        gossip.unregister_token(token)

    gossip.register(hook_name)(checkpoint)
    # the second token registration should not be called!
    gossip.register(hook_name, token=token)(checkpoint)

    gossip.trigger(hook_name)
    assert checkpoint.num_times == 1
Esempio n. 26
0
def test_mute_trigger(checkpoint):

    @gossip.register('a.b.c')
    def handler():
        checkpoint()

    with gossip.mute_context(['a.b.c']):
        gossip.trigger('a.b.c')

    assert not checkpoint.called

    gossip.trigger('a.b.c')

    assert checkpoint.called
Esempio n. 27
0
def test_registers_on_none(restore_plugins_on_cleanup, checkpoint):

    @slash.plugins.active
    class SamplePlugin(PluginInterface):

        def get_name(self):
            return 'sample'

        @plugins.registers_on(None)
        def some_method_here(self):
            checkpoint()

    gossip.trigger('slash.some_method_here')
    assert not checkpoint.called
Esempio n. 28
0
def test_multiple_functions_same_hook(blueprint, checkpoint):  # pylint: disable=unused-argument

    called = set()

    @blueprint.register('a')
    def handler1():  # pylint: disable=unused-variable
        called.add(1)

    @blueprint.register('a')
    def handler2():  # pylint: disable=unused-variable
        called.add(2)

    blueprint.install()
    gossip.trigger('a')
    assert called == set([1, 2])
Esempio n. 29
0
def test_registers_on_with_private_methods(restore_plugins_on_cleanup, checkpoint):

    @slash.plugins.active
    class SamplePlugin(PluginInterface):

        def get_name(self):
            return 'sample'

        @plugins.registers_on('some_hook')
        def _handler(self):
            checkpoint()

    assert not checkpoint.called
    gossip.trigger('some_hook')
    assert checkpoint.called
Esempio n. 30
0
def pytest_runtest_setup(item):
    logging.debug(
        f"\n<---------runtest_setup {'.'.join(item.listnames()[-2:])}---------------->\n"
    )
    gossip.trigger("runtest_setup")
    configured_hw = configured_hardware(item._request)
    if not configured_hw:
        hardware = dict()
        hardware['machines'] = get_local_config(
            item.config.getoption("--hardware"))
        item.session.__initialized_hardware = hardware

    hardware = configured_hardware(item._request)
    assert hardware, "Couldnt find configured hardware in pytest_runtest_setup"
    first_machine = next(iter(hardware['machines'].values()))
    hut_conn_format = "HUT connection string:\n\n{}\n\n"
    if first_machine.get('password', None):
        conn_string = f"sshpass -p {next(iter(hardware['machines'].values()))['password']} ssh -o StrictHostKeyChecking=no {next(iter(hardware['machines'].values()))['user']}@{next(iter(hardware['machines'].values()))['ip']}"
    else:
        conn_string = f"ssh -i {os.path.expanduser('~')}/.ssh/anyvision-devops.pem {first_machine['user']}@{first_machine['ip']}"
    logging.info(hut_conn_format.format(conn_string))
    outcome = yield  # This will now go to base_config fixture function
    try:
        outcome.get_result()
    except Exception as e:
        try:
            base_config = item._request.getfixturevalue('base_config')
            item.funcargs['base_config'] = base_config
        except FixtureLookupError as fe:
            # We got an exception trying to init base_config fixture
            logging.error("error trying to init base_config fixture")
        # We got an exception trying to init some other fixture, so base_config is available
        raise e
    base_config = item.funcargs['base_config']
    logging.debug("cleaning between tests..")
    init_cluster_structure(base_config, item.function.__cluster_config)
    if base_config.clusters:
        concurrently.run([(cluster.clear_plugins)
                          for _, cluster in base_config.clusters.items()])
    concurrently.run([(host.clear_plugins)
                      for _, host in base_config.hosts.items()])
    _trigger_stage_hooks(base_config, item._request, "setup")
    logging.debug("done runtest_setup")
    logging.debug("\n-----------------runtest call---------------\n")
Esempio n. 31
0
def test_blueprint_register_prefix(blueprint, checkpoint):
    @gossip.register('a')
    def handler():  # pylint: disable=unused-variable
        pass

    @blueprint.register('a')
    def handler():  # pylint: disable=function-redefined
        checkpoint()

    assert len(gossip.get_all_registrations()) == 1

    blueprint.install(group='group')

    gossip.trigger('a')
    assert not checkpoint.called

    gossip.trigger('group.a')

    assert checkpoint.called
Esempio n. 32
0
def load_plugins():
    """
    The function that is called during Eva's boot sequence.
    Will fetch the plugin directory , load all of the plugins' info files, load
    all of the plugin's configurations, and enable all the required plugins and
    their dependencies specified in Eva's configuration file.

    Fires the `eva.plugins_loaded` trigger.
    """
    # Get all plugins.
    plugin_dir = get_plugin_directory()
    load_plugin_directory(plugin_dir)
    # Get all user-defined configurations.
    config_dir = conf['eva']['config_directory']
    if '~' in config_dir: config_dir = os.path.expanduser(config_dir)
    load_plugin_configs(config_dir)
    # Enable all necessary plugins.
    enable_plugins()
    gossip.trigger('eva.plugins_loaded')
    log.info('Plugins loaded successfully')
Esempio n. 33
0
    def set_output_text(self, text, responding=True):
        """
        The bread and butter method of the context object.

        This method is used by nearly every plugin as it's used to tell Eva what
        the response to the client should be.

        This method fires the ``eva.pre_set_output_text`` and
        ``eva.post_set_output_text`` triggers.

        :param text: The text to be set as output for the client.
        :type text: string
        :param responding: ``True`` if the text provided is a response to the client.
            ``False`` if you're simply modifying the output text without claiming to be
            the primary plugin to respond to the query or command.

            Leaving this as ``True`` means other plugins will be able to tell that the
            client's query has already been answered (by checking the boolean variable
            returned by :func:`response_ready`).

            If a plugin is simply prepending/appending text or making slight
            modifications to the output, it should use ``responding=False`` so as to
            allow follow-up questions to be routed to the appropriate plugin.
        :type responding: boolean
        """
        plugin_id = get_calling_plugin()
        gossip.trigger('eva.pre_set_output_text',
                       text=text,
                       responding=responding,
                       plugin_id=plugin_id,
                       context=self)
        self.output_text = text
        self.responded = responding
        gossip.trigger('eva.post_set_output_text',
                       text=text,
                       responding=responding,
                       plugin_id=plugin_id,
                       context=self)
Esempio n. 34
0
    def set_output_audio(self, audio, content_type):
        """
        Similar to :func:`set_output_text` except for the audio data and content
        type. This method will be used primarily by the text-to-speech plugins.

        :param audio: The audio binary data to send back to the client.
        :type audio: binary string
        :param content_type: The content type of the binary audio data.
        :type content_type: string
        """
        plugin_id = get_calling_plugin()
        gossip.trigger('eva.pre_set_output_audio',
                       audio=audio,
                       content_type=content_type,
                       plugin_id=plugin_id,
                       context=self)
        self.output_audio = audio
        self.output_audio_content_type = content_type
        gossip.trigger('eva.post_set_output_audio',
                       audio=audio,
                       content_type=content_type,
                       plugin=plugin,
                       context=self)
Esempio n. 35
0
    def set_input_text(self, text):
        """
        Method used to set the input text of the current interaction.

        This function is primarily used by voice recognition plugins to convert
        input audio into input text when clients don't provide any.

        This method fires the ``eva.pre_set_input_text`` and ``eva.post_set_input_text``
        triggers.

        :param text: The text that will now become the input text from the client.
        :type text: string
        """
        plugin_id = get_calling_plugin()
        gossip.trigger('eva.pre_set_input_text',
                       text=text,
                       plugin_id=plugin_id,
                       context=self)
        self.input_text = text
        gossip.trigger('eva.post_set_input_text',
                       text=text,
                       plugin_id=plugin_id,
                       context=self)
Esempio n. 36
0
def test_registers_on_kwargs(class_level_needs, class_level_provides):

    needs_decorator = plugins.needs('other_requirement')
    provides_decorator = plugins.provides('another_provided_requirement')

    @slash.plugins.active  # pylint: disable=unused-variable
    @maybe_decorate(needs_decorator, class_level_needs)
    @maybe_decorate(provides_decorator, class_level_provides)
    class SamplePlugin(PluginInterface):
        def get_name(self):
            return 'sample'

        @plugins.registers_on('some.hook',
                              provides=['provided_requirement'],
                              needs=['some_requirement'],
                              tags=['tag'])
        @maybe_decorate(needs_decorator, not class_level_needs)
        @maybe_decorate(provides_decorator, not class_level_provides)
        def plugin_method(self):
            pass

    @gossip.register('some.hook',
                     provides=['some_requirement', 'other_requirement'])
    def _unused():
        pass

    gossip.trigger('some.hook')
    hook = gossip.get_hook('some.hook')
    [registration] = [
        reg for reg in hook.get_registrations()
        if reg.func.__name__ == 'plugin_method'
    ]
    assert registration.tags == {'tag'}
    assert registration.needs == frozenset(
        ['some_requirement', 'other_requirement'])
    assert registration.provides == frozenset(
        ['provided_requirement', 'another_provided_requirement'])
Esempio n. 37
0
def publish(message, channel='eva_messages'):
    """
    A helper function used to broadcast messages to all available Eva clients.

    :todo: Needs to be thoroughly tested (especially with audio data).
    :param message: The message to send to clients.
    :type message: string
    :param channel: The channel to publish in. The default channel that clients
        should be listening on is called 'eva_messages'.
    :type channel: string
    """
    log.info('Ready to publish message')
    gossip.trigger('eva.pre_publish', message=message)
    pubsub = get_pubsub()
    log.info('Publishing message: %s' %message)
    gossip.trigger('eva.publish', message=message)
    pubsub.publish(channel, message)
    gossip.trigger('eva.post_publish', message=message)
Esempio n. 38
0
def test_toggle_hooks(should_raise):

    events = []

    toggle = gossip.Toggle()
    assert toggle.is_off()

    @gossip.register('start')
    def malicious():
        events.append('malicious')
        if should_raise:
            raise CustomException()

    @gossip.register('start', toggles_on=toggle)
    def start():
        events.append('start')

    @gossip.register('end', toggles_off=toggle)
    def end():
        events.append('end')

    if should_raise:
        with pytest.raises(CustomException):
            gossip.trigger('start')
    else:
        gossip.trigger('start')

    assert toggle.is_on() == (not should_raise)

    gossip.trigger('end')

    assert toggle.is_off()

    assert len(events) == len(set(events))
    if should_raise:
        assert 'start' not in events
        assert 'end' not in events
    else:
        assert events.index('malicious') < events.index('start')
        assert 'end' in events
Esempio n. 39
0
 def trigger(self):
     gossip.trigger(self.hook_name)
Esempio n. 40
0
 def trigger(self):
     gossip.trigger(self.name, **self.kwargs)
Esempio n. 41
0
 def _after_login(self):
     self.components.system_component.refresh()
     gossip.trigger('infinidat.sdk.after_login', system=self)
Esempio n. 42
0
def test_trigger_no_hook_registered():
    result = gossip.trigger("unregistered")  # pylint: disable=assignment-from-no-return
    assert result is None
Esempio n. 43
0
    def _request(self, http_method, path, assert_success=True, **kwargs):
        """
        Sends a request to the system API interface

        :returns: :class:`.Response`
        """
        check_version = kwargs.pop("check_version", True)
        if check_version and not self._checked_version and config.root.check_version_compatibility:
            self._checked_version = True
            try:
                self.system.check_version()
            except:
                self._checked_version = False
                raise

        returned = None
        kwargs.setdefault("timeout", self._default_request_timeout)
        raw_data = kwargs.pop("raw_data", False)
        data = kwargs.pop("data", NOTHING)
        sent_json_object = None
        headers = kwargs.pop('headers', None)
        if headers is None:
            headers = {}
        else:
            headers = headers.copy()

        if data is not NOTHING:
            headers['Content-type'] = 'application/json'
            if raw_data:
                sent_json_object = data
            else:
                data = translate_special_values(data)
                sent_json_object = data
                data = json.dumps(data)
        else:
            assert raw_data is False, "Cannot handle raw_data with no data"

        url_params = kwargs.pop('params', None)
        if url_params is not None:
            url_params = translate_special_values(url_params)

        specified_address = kwargs.pop("address", None)
        urls = self._get_possible_urls(specified_address)

        for url in urls:
            full_url = _join_path(url, URL(path))

            if http_method != "get" and not self._interactive and not path.startswith("/api/internal/"):
                full_url = self._with_approved(full_url)

            hostname = full_url.hostname
            api_request = requests.Request(http_method, full_url, data=data if data is not NOTHING else None, params=url_params, headers=headers)
            for preprocessor in self._preprocessors:
                preprocessor(api_request)


            _logger.debug("{0} <-- {1} {2}", hostname, http_method.upper(), api_request.url)
            if data is not NOTHING:
                if data != api_request.data:
                    sent_json_object = json.loads(api_request.data)
                self._log_sent_data(hostname, data, sent_json_object)

            prepared = self._session.prepare_request(api_request)
            gossip.trigger('infinidat.sdk.before_api_request', request=prepared)
            start_time = flux.current_timeline.time()
            try:
                response = self._session.send(prepared, **kwargs)
            except Exception as e:
                e.api_request_obj = api_request
                raise
            end_time = flux.current_timeline.time()
            gossip.trigger('infinidat.sdk.after_api_request', request=prepared, response=response)
            response.start_time = start_time
            response.end_time = end_time

            elapsed = get_timedelta_total_seconds(response.elapsed)
            _logger.debug("{0} --> {1} {2} (took {3:.04f}s)", hostname, response.status_code, response.reason, elapsed)
            returned = Response(response, data)
            resp_data = "..." if self._no_reponse_logs else returned.get_json()
            if self._use_pretty_json and returned.get_json() is not None:
                logged_response_data = json.dumps(
                    returned.get_json(),
                    indent=4, separators=(',', ': '))
            else:
                logged_response_data = resp_data
            _logger.debug("{0} --> {1}", hostname, logged_response_data)
            if response.status_code != httplib.SERVICE_UNAVAILABLE:
                if specified_address is None: # need to remember our next API target
                    self._active_url = url
                break
        return returned
Esempio n. 44
0
 def test_end(self):
     self.current_test.report_end()
     gossip.trigger('backslash.report_test_end', ended_test=self.current_test)
     self.current_test = None
Esempio n. 45
0
 def test_start(self):
     self.current_test = self.current_session.report_test_start(
         test_logical_id=context.test.__slash__.id, name=str(context.test))
     gossip.trigger('backslash.report_test_start', started_test=self.current_test)
Esempio n. 46
0
 def handler(): # pylint: disable=unused-variable
     counter.sub(1)
     if counter:
         gossip.trigger('reentrant_hook')
Esempio n. 47
0
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",))
Esempio n. 48
0
 def handler(): # pylint: disable=unused-variable
     counter.add(1)
     gossip.trigger(hook_name)
Esempio n. 49
0
    def session_start(self):
        self.client = BackslashClient(self.server_address)

        self.current_session = self.client.report_session_start(
            logical_id=context.session.id)
        gossip.trigger('backslash.report_session_start', started_session=self.current_session)