def test_reset_converse(self):
        """Check that a blank stt sends the reset signal to the skills."""
        print(self.intent_service.active_skills)
        reset_msg = Message('mycroft.speech.recognition.unknown',
                            data={'lang': 'en-US'})
        t = Thread(target=self.intent_service.reset_converse,
                   args=(reset_msg, ))
        t.start()
        time.sleep(0.5)
        self.intent_service.handle_converse_error(
            Message('converse.error', {
                'skill_id': 'c64_skill',
                'error': 'skill id does not exist'
            }))
        time.sleep(0.5)
        self.intent_service.handle_converse_response(
            Message('converse.response', {
                'skill_id': 'atari_skill',
                'result': False
            }))

        # Check send messages
        c64_message = self.intent_service.bus.emit.call_args_list[0][0][0]
        self.assertTrue(check_converse_request(c64_message, 'c64_skill'))
        atari_message = self.intent_service.bus.emit.call_args_list[1][0][0]
        self.assertTrue(check_converse_request(atari_message, 'atari_skill'))
Пример #2
0
        def response(message, return_msg_type):
            c64 = Message(return_msg_type, {'skill_id': 'c64_skill',
                                            'result': False})
            atari = Message(return_msg_type, {'skill_id': 'atari_skill',
                                              'result': True})
            msgs = {'c64_skill': c64, 'atari_skill': atari}

            return msgs[message.data['skill_id']]
Пример #3
0
 def initialize(self):
     """ Perform any final setup needed for the skill here.
     This function is invoked after the skill is fully constructed and
     registered with the system. Intents will be registered and Skill
     settings will be available."""
     my_setting = self.settings.get('my_setting')
     self.bus.emit(Message("test"))
     self.bus.emit(Message("test2"))
    def test_play_internals(self, play_wav_mock, play_ogg_mock, play_mp3_mock):
        bus = mock.Mock()
        process_mock = mock.Mock(name='process')

        completed = False

        def wait_for_completion():
            nonlocal completed
            if not completed:
                return None
            else:
                completed = False
                return True

        process_mock.poll.side_effect = wait_for_completion
        play_wav_mock.return_value = process_mock
        play_ogg_mock.return_value = process_mock
        play_mp3_mock.return_value = process_mock

        service = simple.SimpleAudioService(config, bus)
        tracks = ['a.mp3', ['b.ogg', 'audio/ogg'], ['c.wav', 'audio/wav']]
        service.add_list(tracks)
        service.play()

        thread = Thread(target=service._play, args=[Message('plaything')])
        thread.daemon = True
        thread.start()
        time.sleep(0.1)

        play_mp3_mock.assert_called_with('a.mp3')
        completed = True
        time.sleep(1)
        self.assertEqual(service.index, 1)
        thread.join()

        thread = Thread(target=service._play, args=[Message('plaything')])
        thread.daemon = True
        thread.start()
        time.sleep(0.1)
        play_ogg_mock.assert_called_with('b.ogg')

        service.pause()
        process_mock.send_signal.assert_called_with(signal.SIGSTOP)
        self.assertEqual(service._paused, True)
        service.resume()
        self.assertEqual(service._paused, False)
        completed = True
        thread.join()

        thread = Thread(target=service._play, args=[Message('plaything')])
        thread.daemon = True
        thread.start()
        time.sleep(0.2)
        play_wav_mock.assert_called_with('c.wav')

        service.stop()
        thread.join()
Пример #5
0
 def test_get_no_match_after_detach_skill(self):
     """Check that a removed skill's intent doesn't match."""
     self.setup_simple_adapt_intent()
     # Check that no intent is matched
     msg = Message('detach_intent', data={'skill_id': 'skill'})
     self.intent_service.handle_detach_skill(msg)
     msg = Message('intent.service.adapt.get', data={'utterance': 'test'})
     self.intent_service.handle_get_adapt(msg)
     reply = get_last_message(self.intent_service.bus)
     self.assertEqual(reply.data['intent'], None)
Пример #6
0
 def test_common_test_skill_action(self):
     """Test that the optional action is triggered."""
     query_action = self.bus.on.call_args_list[-1][0][1]
     query_action(Message('query:action', data={
         'phrase': 'What\'s the meaning of life',
         'skill_id': 'asdf'}))
     self.skill.CQS_action.assert_not_called()
     query_action(Message('query:action', data={
         'phrase': 'What\'s the meaning of life',
         'skill_id': 'CQSTest'}))
     self.skill.CQS_action.assert_called_once_with(
         'What\'s the meaning of life', None)
Пример #7
0
        def response(message, return_msg_type):
            c64 = Message(return_msg_type, {'skill_id': 'c64_skill',
                                            'result': False})
            amiga = Message(return_msg_type,
                            {'skill_id': 'amiga_skill',
                             'error': 'skill id does not exist'})
            atari = Message(return_msg_type, {'skill_id': 'atari_skill',
                                              'result': False})
            msgs = {'c64_skill': c64,
                    'atari_skill': atari,
                    'amiga_skill': amiga}

            return msgs[message.data['skill_id']]
Пример #8
0
    def test_stop(self, check_for_signal_mock, tts_factory_mock, config_mock):
        """Ensure the stop handler signals stop correctly."""
        setup_mocks(config_mock, tts_factory_mock)
        bus = mock.Mock()
        config_mock.get.return_value = {'tts': {'module': 'test'}}
        speech.init(bus)

        speech._last_stop_signal = 0
        check_for_signal_mock.return_value = False
        speech.handle_stop(Message('mycroft.stop'))
        self.assertEqual(speech._last_stop_signal, 0)

        check_for_signal_mock.return_value = True
        speech.handle_stop(Message('mycroft.stop'))
        self.assertNotEqual(speech._last_stop_signal, 0)
Пример #9
0
 def _communicate_load_status(self):
     if self.loaded:
         message = Message('mycroft.skills.loaded',
                           data=dict(path=self.skill_directory,
                                     id=self.skill_id,
                                     name=self.instance.name,
                                     modified=self.last_modified))
         self.bus.emit(message)
         LOG.info('Skill {} loaded successfully'.format(self.skill_id))
     else:
         message = Message('mycroft.skills.loading_failure',
                           data=dict(path=self.skill_directory,
                                     id=self.skill_id))
         self.bus.emit(message)
         LOG.error('Skill {} failed to load'.format(self.skill_id))
Пример #10
0
    def setup_simple_adapt_intent(self):
        msg = create_vocab_msg('testKeyword', 'test')
        self.intent_service.handle_register_vocab(msg)

        intent = IntentBuilder('skill:testIntent').require('testKeyword')
        msg = Message('register_intent', intent.__dict__)
        self.intent_service.handle_register_intent(msg)
Пример #11
0
def before_all(context):
    log = create_voight_kampff_logger()
    bus = InterceptAllBusClient()
    bus_connected = Event()
    bus.once('open', bus_connected.set)

    create_daemon(bus.run_forever)

    context.msm = MycroftSkillsManager()
    # Wait for connection
    log.info('Waiting for messagebus connection...')
    bus_connected.wait()

    log.info('Waiting for skills to be loaded...')
    start = monotonic()
    while True:
        response = bus.wait_for_response(Message('mycroft.skills.all_loaded'))
        if response and response.data['status']:
            break
        elif monotonic() - start >= 2 * 60:
            raise Exception('Timeout waiting for skills to become ready.')
        else:
            sleep(1)

    context.bus = bus
    context.matched_message = None
    context.log = log
Пример #12
0
 def test_get_adapt_intent_manifest(self):
     """Make sure the manifest returns a list of Intent Parser objects."""
     self.setup_simple_adapt_intent()
     msg = Message('intent.service.adapt.manifest.get')
     self.intent_service.handle_adapt_manifest(msg)
     reply = get_last_message(self.intent_service.bus)
     self.assertEqual(reply.data['intents'][0]['name'], 'skill:testIntent')
Пример #13
0
def when_user_says(context, text):
    context.bus.emit(Message('recognizer_loop:utterance',
                             data={'utterances': [text],
                                   'lang': context.lang,
                                   'session': '',
                                   'ident': time.time()},
                             context={'client_name': 'mycroft_listener'}))
Пример #14
0
    def deactivate_deprecated(self, message=None):
        # Deactivate official skill
        # TODO depending on https://github.com/MycroftAI/skill-speak/issues/24
        # code bellow can be removed

        skills_config = self.config_core.get("skills", {})
        blacklisted_skills = skills_config.get("blacklisted_skills", [])
        config = LocalConf(USER_CONFIG)
        blacklisted_skills += config.get("skills",
                                         {}).get("blacklisted_skills", [])
        store = False
        for skill in ["skill-repeat-recent", "mycroft-speak.mycroftai"]:
            if skill not in blacklisted_skills:
                self.log.info("Parrot skill blacklisted conflicting skill " +
                              skill)
                self.bus.emit(
                    Message('skillmanager.deactivate', {"skill": skill}))
                blacklisted_skills.append(skill)
                if "skills" not in config:
                    config["skills"] = {}
                if "blacklisted_skills" not in config["skills"]:
                    config["skills"]["blacklisted_skills"] = []
                config["skills"]["blacklisted_skills"] += blacklisted_skills
                store = True
        if store:
            config.store()
Пример #15
0
    def test_audio_service_queue_methods(self, mock_load_services):
        """Check that backend methods are called during playback."""
        backend, second_backend = setup_mock_backends(mock_load_services,
                                                      self.emitter)
        mock_load_services.return_value = [backend, second_backend]

        service = audio_service.AudioService(self.emitter)
        service.load_services_callback()

        service.default = backend

        # Check that play doesn't play unsupported media uri type
        # Test queueing starts playback if stopped
        backend.play.reset_mock()
        backend.add_list.reset_mock()
        m = Message('audio.service.queue', data={'tracks': ['http://hello']})
        service._queue(m)
        backend.add_list.called_with(['http://hello'])
        self.assertTrue(backend.play.called)

        # Test queuing doesn't call play if play is in progress
        backend.play.reset_mock()
        backend.add_list.reset_mock()
        service._queue(m)
        backend.add_list.called_with(['http://hello'])
        self.assertFalse(backend.play.called)

        service.shutdown()
Пример #16
0
    def test_reset_converse(self):
        """Check that a blank stt sends the reset signal to the skills."""
        def response(message, return_msg_type):
            c64 = Message(return_msg_type,
                          {'skill_id': 'c64_skill',
                           'error': 'skill id does not exist'})
            atari = Message(return_msg_type, {'skill_id': 'atari_skill',
                                              'result': False})
            msgs = {'c64_skill': c64, 'atari_skill': atari}

            return msgs[message.data['skill_id']]

        reset_msg = Message('mycroft.speech.recognition.unknown',
                            data={'lang': 'en-US'})
        self.intent_service.bus.wait_for_response.side_effect = response

        self.intent_service.reset_converse(reset_msg)
        # Check send messages
        wait_for_response_mock = self.intent_service.bus.wait_for_response
        c64_message = wait_for_response_mock.call_args_list[0][0][0]
        self.assertTrue(check_converse_request(c64_message, 'c64_skill'))
        atari_message = wait_for_response_mock.call_args_list[1][0][0]
        self.assertTrue(check_converse_request(atari_message, 'atari_skill'))
        first_active_skill = self.intent_service.active_skills[0][0]
        self.assertEqual(first_active_skill, 'atari_skill')
Пример #17
0
    def test_handle_start_playback(self):
        """Test common play start method."""
        self.skill.audioservice.is_playing = True
        start_playback = self.bus.on.call_args_list[-1][0][1]

        phrase = 'Don\'t open until doomsday'
        start_playback(Message('play:start', data={'phrase': phrase,
                                                   'skill_id': 'asdf'}))
        self.skill.CPS_start.assert_not_called()

        self.bus.emit.reset_mock()
        start_playback(Message('play:start',
                               data={'phrase': phrase,
                                     'skill_id': self.skill.skill_id}))
        self.audioservice.stop.assert_called_once_with()
        self.skill.CPS_start.assert_called_once_with(phrase, None)
Пример #18
0
    def test_converse(self):
        """Check that the _converse method reports if the utterance is handled.

        Also check that the skill that handled the query is moved to the
        top of the active skill list.
        """
        def response(message, return_msg_type):
            c64 = Message(return_msg_type, {'skill_id': 'c64_skill',
                                            'result': False})
            atari = Message(return_msg_type, {'skill_id': 'atari_skill',
                                              'result': True})
            msgs = {'c64_skill': c64, 'atari_skill': atari}

            return msgs[message.data['skill_id']]

        self.intent_service.bus.wait_for_response.side_effect = response

        hello = ['hello old friend']
        utterance_msg = Message('recognizer_loop:utterance',
                                data={'lang': 'en-US',
                                      'utterances': hello})
        result = self.intent_service._converse(hello, 'en-US', utterance_msg)

        # Check that the active skill list was updated to set the responding
        # Skill first.
        first_active_skill = self.intent_service.active_skills[0][0]
        self.assertEqual(first_active_skill, 'atari_skill')

        # Check that a skill responded that it could handle the message
        self.assertTrue(result)
Пример #19
0
    def wrapper(message):
        stopwatch = Stopwatch()
        try:
            # TODO: Fix for real in mycroft-messagebus-client
            # Makes sure the message type is consistent with the type declared
            # in mycroft.messagebus and isinstance will work.
            message = Message(message.msg_type,
                              data=message.data,
                              context=message.context)

            message = unmunge_message(message, skill_id)
            if on_start:
                on_start(message)

            with stopwatch:
                if len(signature(handler).parameters) == 0:
                    handler()
                else:
                    handler(message)

        except Exception as e:
            if on_error:
                on_error(e)
        finally:
            if on_end:
                on_end(message)

            # Send timing metrics
            context = message.context
            if context and 'ident' in context:
                report_timing(context['ident'], 'skill_handler', stopwatch, {
                    'handler': handler.__name__,
                    'skill_id': skill_id
                })
Пример #20
0
def patch_config(context, patch):
    """Apply patch to config and wait for it to take effect.

    Args:
        context: Behave context for test
        patch: patch to apply
    """
    context.log.info('Patching config with {}'.format(patch))
    # If this is first patch in scenario
    if not hasattr(context, 'original_config'):
        context.original_config = {}

    # store originals in context
    for key in patch:
        # If this patch is redefining an already changed key don't update
        if key not in context.original_config:
            context.original_config[key] = context.config.get(key)

    # Patch config
    patch_config_msg = Message('configuration.patch', {'config': patch})
    context.bus.emit(patch_config_msg)

    context.add_cleanup(reset_config, context)

    # Wait until one of the keys has been updated
    key = list(patch.keys())[0]
    wait_for_config_change(context, key, patch[key])
Пример #21
0
 def test_get_intent_manifest(self):
     """Check that if the intent doesn't match at all None is returned."""
     self.setup_simple_adapt_intent()
     # Check that no intent is matched
     msg = Message('intent.service.intent.get', data={'utterance': 'five'})
     self.intent_service.handle_get_intent(msg)
     reply = get_last_message(self.intent_service.bus)
     self.assertEqual(reply.data['intent'], None)
Пример #22
0
def then_user_follow_up(context, text):
    time.sleep(2)
    wait_while_speaking()
    context.bus.emit(Message('recognizer_loop:utterance',
                             data={'utterances': [text],
                                   'lang': context.lang,
                                   'session': '',
                                   'ident': time.time()},
                             context={'client_name': 'mycroft_listener'}))
Пример #23
0
    def test_get_adapt_intent(self):
        self.setup_simple_adapt_intent()
        # Check that the intent is returned
        msg = Message('intent.service.adapt.get', data={'utterance': 'test'})
        self.intent_service.handle_get_adapt(msg)

        reply = get_last_message(self.intent_service.bus)
        self.assertEqual(reply.data['intent']['intent_type'],
                         'skill:testIntent')
Пример #24
0
 def test_get_adapt_vocab_manifest(self):
     self.setup_simple_adapt_intent()
     msg = Message('intent.service.adapt.vocab.manifest.get')
     self.intent_service.handle_vocab_manifest(msg)
     reply = get_last_message(self.intent_service.bus)
     value = reply.data['vocab'][0]['start']
     keyword = reply.data['vocab'][0]['end']
     self.assertEqual(keyword, 'testKeyword')
     self.assertEqual(value, 'test')
Пример #25
0
 def CPS_send_status(self, artist='', track='', image=''):
     data = {
         'skill': self.name,
         'artist': artist,
         'track': track,
         'image': image,
         'status': None  # TODO Add status system
     }
     self.bus.emit(Message('play:status', data))
Пример #26
0
    def on_message(self, _, message):
        """Extends normal operation by storing the received message.

        Args:
            message (Message): message from the Mycroft bus
        """
        with self.message_lock:
            self.messages.append(Message.deserialize(message))
        self.new_message_available.set()
        super().on_message(_, message)
Пример #27
0
def reset_config(context):
    """Cleanup callback to reset patched configuration

    Args:
        context (Context): Behave context of current scenario
    """
    context.log.info('Resetting patched configuration...')
    context.bus.emit(Message('configuration.patch.clear'))
    key = list(context.original_config)[0]
    wait_for_config_change(context, key, context.original_config[key])
Пример #28
0
def reset_config(context):
    """Reset configuration with changes stored in original_config of context.
    """
    context.log.info('Resetting patched configuration...')

    context.bus.emit(Message('configuration.patch.clear'))
    key = list(context.original_config)[0]
    while context.config[key] != context.original_config[key]:
        sleep(0.5)
    context.original_config = {}
Пример #29
0
    def test_keyword_backwards_compatibility(self):
        self.setup_simple_adapt_intent(
            create_old_style_vocab_msg('testKeyword', 'test'))

        # Check that the intent is returned
        msg = Message('intent.service.adapt.get', data={'utterance': 'test'})
        self.intent_service.handle_get_adapt(msg)

        reply = get_last_message(self.intent_service.bus)
        self.assertEqual(reply.data['intent']['intent_type'],
                         'skill:testIntent')
    def test_converse(self):
        """Check that the _converse method reports if the utterance is handled.

        Also check that the skill that handled the query is moved to the
        top of the active skill list.
        """
        result = None

        def runner(utterances, lang, message):
            nonlocal result
            result = self.intent_service._converse(utterances, lang, message)

        hello = ['hello old friend']
        utterance_msg = Message('recognizer_loop:utterance',
                                data={
                                    'lang': 'en-US',
                                    'utterances': hello
                                })
        t = Thread(target=runner, args=(hello, 'en-US', utterance_msg))
        t.start()
        time.sleep(0.5)
        self.intent_service.handle_converse_response(
            Message('converse.response', {
                'skill_id': 'c64_skill',
                'result': False
            }))
        time.sleep(0.5)
        self.intent_service.handle_converse_response(
            Message('converse.response', {
                'skill_id': 'atari_skill',
                'result': True
            }))
        t.join()

        # Check that the active skill list was updated to set the responding
        # Skill first.
        first_active_skill = self.intent_service.active_skills[0][0]
        self.assertEqual(first_active_skill, 'atari_skill')

        # Check that a skill responded that it could handle the message
        self.assertTrue(result)