From 7c188a90b0dd487cc9587431bb0f8699bd59ac93 Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Thu, 19 Oct 2023 17:46:28 +0100 Subject: [PATCH] unittests/event_scheduler --- .github/workflows/coverage.yml | 1 + .github/workflows/unit_tests.yml | 1 + test/end2end/session/minicroft.py | 5 +- .../session/skill-ovos-schedule/MANIFEST.in | 7 + .../session/skill-ovos-schedule/__init__.py | 14 ++ .../locale/en-us/dialog/done.dialog | 1 + .../locale/en-us/dialog/trigger.dialog | 1 + .../locale/en-us/vocab/Schedule.voc | 1 + .../session/skill-ovos-schedule/setup.py | 45 ++++ test/end2end/session/test_complete_failure.py | 3 + test/end2end/session/test_converse.py | 12 +- test/end2end/session/test_fallback.py | 3 + test/end2end/session/test_fallback_v1.py | 4 +- test/end2end/session/test_get_response.py | 40 ++-- test/end2end/session/test_sched.py | 226 ++++++++++++++++++ test/end2end/session/test_session.py | 6 +- 16 files changed, 342 insertions(+), 28 deletions(-) create mode 100644 test/end2end/session/skill-ovos-schedule/MANIFEST.in create mode 100644 test/end2end/session/skill-ovos-schedule/__init__.py create mode 100644 test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/done.dialog create mode 100644 test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/trigger.dialog create mode 100644 test/end2end/session/skill-ovos-schedule/locale/en-us/vocab/Schedule.voc create mode 100755 test/end2end/session/skill-ovos-schedule/setup.py create mode 100644 test/end2end/session/test_sched.py diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 242385a904fe..eda5f37ad1e1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -29,6 +29,7 @@ jobs: pip install -r requirements/tests.txt pip install ./test/unittests/common_query/ovos_tskill_fakewiki pip install ./test/end2end/session/skill-ovos-hello-world + pip install ./test/end2end/session/skill-ovos-schedule pip install ./test/end2end/session/skill-ovos-fallback-unknown pip install ./test/end2end/session/skill-ovos-fallback-unknownv1 pip install ./test/end2end/session/skill-converse_test diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 618795d129c0..16ead4001999 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -59,6 +59,7 @@ jobs: pip install ./test/end2end/session/skill-ovos-fallback-unknown pip install ./test/end2end/session/skill-ovos-fallback-unknownv1 pip install ./test/end2end/session/skill-converse_test + pip install ./test/end2end/session/skill-ovos-schedule - name: Run unittests run: | pytest --cov=ovos_core --cov-report xml test/unittests diff --git a/test/end2end/session/minicroft.py b/test/end2end/session/minicroft.py index d178b332294a..237227f7c734 100644 --- a/test/end2end/session/minicroft.py +++ b/test/end2end/session/minicroft.py @@ -1,5 +1,7 @@ from time import sleep + from ovos_bus_client.session import SessionManager, Session +from ovos_bus_client.util.scheduler import EventScheduler from ovos_core.intent_services import IntentService from ovos_core.skill_manager import SkillManager from ovos_plugin_manager.skills import find_skill_plugins @@ -15,6 +17,7 @@ def __init__(self, skill_ids, *args, **kwargs): super().__init__(bus, *args, **kwargs) self.skill_ids = skill_ids self.intent_service = self._register_intent_services() + self.scheduler = EventScheduler(bus, schedule_file="/tmp/schetest.json") def _register_intent_services(self): """Start up the all intent services and connect them as needed. @@ -52,6 +55,7 @@ def run(self): def stop(self): super().stop() + self.scheduler.shutdown() SessionManager.bus = None SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") @@ -66,4 +70,3 @@ def get_minicroft(skill_id): while croft1.status.state != ProcessState.READY: sleep(0.2) return croft1 - diff --git a/test/end2end/session/skill-ovos-schedule/MANIFEST.in b/test/end2end/session/skill-ovos-schedule/MANIFEST.in new file mode 100644 index 000000000000..b9ecb5807a59 --- /dev/null +++ b/test/end2end/session/skill-ovos-schedule/MANIFEST.in @@ -0,0 +1,7 @@ +recursive-include dialog * +recursive-include vocab * +recursive-include locale * +recursive-include res * +recursive-include ui * +include *.json +include *.txt \ No newline at end of file diff --git a/test/end2end/session/skill-ovos-schedule/__init__.py b/test/end2end/session/skill-ovos-schedule/__init__.py new file mode 100644 index 000000000000..f19464791d6d --- /dev/null +++ b/test/end2end/session/skill-ovos-schedule/__init__.py @@ -0,0 +1,14 @@ +from ovos_utils.intents import IntentBuilder +from ovos_workshop.decorators import intent_handler +from ovos_workshop.skills import OVOSSkill + + +class ScheduleSkill(OVOSSkill): + + def handle_event(self, message): + self.speak_dialog("trigger") + + @intent_handler(IntentBuilder("ScheduleIntent").require("Schedule")) + def handle_sched_intent(self, message): + self.speak_dialog("done") + self.schedule_event(self.handle_event, 3, name="my_event") diff --git a/test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/done.dialog b/test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/done.dialog new file mode 100644 index 000000000000..3fc393638315 --- /dev/null +++ b/test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/done.dialog @@ -0,0 +1 @@ +it has been scheduled \ No newline at end of file diff --git a/test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/trigger.dialog b/test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/trigger.dialog new file mode 100644 index 000000000000..b711e1a1c8db --- /dev/null +++ b/test/end2end/session/skill-ovos-schedule/locale/en-us/dialog/trigger.dialog @@ -0,0 +1 @@ +this is the event triggering \ No newline at end of file diff --git a/test/end2end/session/skill-ovos-schedule/locale/en-us/vocab/Schedule.voc b/test/end2end/session/skill-ovos-schedule/locale/en-us/vocab/Schedule.voc new file mode 100644 index 000000000000..5864a517f9ac --- /dev/null +++ b/test/end2end/session/skill-ovos-schedule/locale/en-us/vocab/Schedule.voc @@ -0,0 +1 @@ +schedule event \ No newline at end of file diff --git a/test/end2end/session/skill-ovos-schedule/setup.py b/test/end2end/session/skill-ovos-schedule/setup.py new file mode 100755 index 000000000000..19be23c9b5fc --- /dev/null +++ b/test/end2end/session/skill-ovos-schedule/setup.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +from os import walk, path + +from setuptools import setup + +URL = "https://github.com/OpenVoiceOS/skill-ovos-schedule" +SKILL_CLAZZ = "ScheduleSkill" # needs to match __init__.py class name + +# below derived from github url to ensure standard skill_id +SKILL_AUTHOR, SKILL_NAME = URL.split(".com/")[-1].split("/") +SKILL_PKG = SKILL_NAME.lower().replace('-', '_') +PLUGIN_ENTRY_POINT = f'{SKILL_NAME.lower()}.{SKILL_AUTHOR.lower()}={SKILL_PKG}:{SKILL_CLAZZ}' + + +# skill_id=package_name:SkillClass + + +def find_resource_files(): + resource_base_dirs = ("locale", "ui", "vocab", "dialog", "regex", "skill") + base_dir = path.dirname(__file__) + package_data = ["*.json"] + for res in resource_base_dirs: + if path.isdir(path.join(base_dir, res)): + for (directory, _, files) in walk(path.join(base_dir, res)): + if files: + package_data.append( + path.join(directory.replace(base_dir, "").lstrip('/'), + '*')) + return package_data + + +setup( + name="ovos-skill-schedule", + version="0.0.0", + long_description="test", + description='OVOS schedule skill plugin', + author_email='jarbasai@mailfence.com', + license='Apache-2.0', + package_dir={SKILL_PKG: ""}, + package_data={SKILL_PKG: find_resource_files()}, + packages=[SKILL_PKG], + include_package_data=True, + keywords='ovos skill plugin', + entry_points={'ovos.plugin.skill': PLUGIN_ENTRY_POINT} +) diff --git a/test/end2end/session/test_complete_failure.py b/test/end2end/session/test_complete_failure.py index 760fbe8908a3..d10174789d21 100644 --- a/test/end2end/session/test_complete_failure.py +++ b/test/end2end/session/test_complete_failure.py @@ -13,6 +13,9 @@ def setUp(self): self.skill_id = "skill-ovos-hello-world.openvoiceos" self.core = get_minicroft(self.skill_id) + def tearDown(self) -> None: + self.core.stop() + def test_complete_failure(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") diff --git a/test/end2end/session/test_converse.py b/test/end2end/session/test_converse.py index 5b3742c2435a..f041d8dce872 100644 --- a/test/end2end/session/test_converse.py +++ b/test/end2end/session/test_converse.py @@ -1,6 +1,6 @@ import time from time import sleep -from unittest import TestCase, skip +from unittest import TestCase from ovos_bus_client.message import Message from ovos_bus_client.session import SessionManager, Session @@ -14,6 +14,9 @@ def setUp(self): self.other_skill_id = "skill-ovos-hello-world.openvoiceos" self.core = get_minicroft([self.skill_id, self.other_skill_id]) + def tearDown(self) -> None: + self.core.stop() + def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") @@ -162,7 +165,7 @@ def hello_world(): # verify that "lang" is injected by converse.ping # (missing in utterance message) and kept in all messages - self.assertEqual(messages[1].msg_type, f"{self.skill_id}.converse.ping") + self.assertEqual(messages[1].msg_type, f"{self.skill_id}.converse.ping") # verify "pong" answer from converse test skill self.assertEqual(messages[2].msg_type, "skill.converse.pong") @@ -263,7 +266,7 @@ def skill_converse_yes(): # converse self.assertEqual(messages[1].msg_type, f"{self.other_skill_id}.converse.ping") self.assertEqual(messages[2].msg_type, "skill.converse.pong") - self.assertEqual(messages[2].data["skill_id"],messages[2].context["skill_id"]) + self.assertEqual(messages[2].data["skill_id"], messages[2].context["skill_id"]) self.assertFalse(messages[2].data["can_handle"]) self.assertEqual(messages[3].msg_type, f"{self.skill_id}.converse.ping") self.assertEqual(messages[4].msg_type, "skill.converse.pong") @@ -356,7 +359,7 @@ def converse_capture(): # converse self.assertEqual(messages[1].msg_type, f"{self.skill_id}.converse.ping") self.assertEqual(messages[2].msg_type, "skill.converse.pong") - self.assertEqual(messages[2].data["skill_id"],messages[2].context["skill_id"]) + self.assertEqual(messages[2].data["skill_id"], messages[2].context["skill_id"]) self.assertTrue(messages[2].data["can_handle"]) self.assertEqual(messages[3].msg_type, f"{self.other_skill_id}.converse.ping") self.assertEqual(messages[4].msg_type, "skill.converse.pong") @@ -480,4 +483,3 @@ def external_activate(): messages = [] external_activate() - diff --git a/test/end2end/session/test_fallback.py b/test/end2end/session/test_fallback.py index 44c485efaead..3b6643895f86 100644 --- a/test/end2end/session/test_fallback.py +++ b/test/end2end/session/test_fallback.py @@ -13,6 +13,9 @@ def setUp(self): self.skill_id = "skill-ovos-fallback-unknown.openvoiceos" self.core = get_minicroft(self.skill_id) + def tearDown(self) -> None: + self.core.stop() + def test_fallback(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") diff --git a/test/end2end/session/test_fallback_v1.py b/test/end2end/session/test_fallback_v1.py index 37538583b362..75073925fb28 100644 --- a/test/end2end/session/test_fallback_v1.py +++ b/test/end2end/session/test_fallback_v1.py @@ -13,6 +13,9 @@ def setUp(self): self.skill_id = "skill-ovos-fallback-unknownv1.openvoiceos" self.core = get_minicroft(self.skill_id) + def tearDown(self) -> None: + self.core.stop() + def test_fallback_v1(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") @@ -166,4 +169,3 @@ def wait_for_n_messages(n): for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") self.assertEqual(m.context["session"]["active_skills"][0][0], self.skill_id) - diff --git a/test/end2end/session/test_get_response.py b/test/end2end/session/test_get_response.py index e7ffeefa22c0..05c8408f53db 100644 --- a/test/end2end/session/test_get_response.py +++ b/test/end2end/session/test_get_response.py @@ -4,7 +4,6 @@ from ovos_bus_client.message import Message from ovos_bus_client.session import SessionManager, Session -from ovos_utils.log import LOG from .minicroft import get_minicroft @@ -15,6 +14,9 @@ def setUp(self): self.other_skill_id = "skill-ovos-hello-world.openvoiceos" self.core = get_minicroft([self.skill_id, self.other_skill_id]) + def tearDown(self) -> None: + self.core.stop() + def test_no_response(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") @@ -56,7 +58,7 @@ def on_speak(msg): "recognizer_loop:utterance", # no session # skill selected - "intent.service.skills.activated", # default session injected + "intent.service.skills.activated", # default session injected f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", @@ -95,9 +97,9 @@ def on_speak(msg): for m in messages[1:]: print(m.msg_type, m.context["session"]["session_id"]) self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-us") - # verify skill is activated by intent service (intent pipeline matched) + # verify skill is activated by intent service (intent pipeline matched) self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") self.assertEqual(messages[1].data["skill_id"], self.skill_id) self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") @@ -694,7 +696,7 @@ def answer_get_response(msg): "recognizer_loop:utterance", # no session # skill selected - "intent.service.skills.activated", # default session injected + "intent.service.skills.activated", # default session injected f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response_cascade.intent", @@ -802,33 +804,33 @@ def answer_get_response(msg): self.assertEqual(messages[6].data["utterance"], "give me items") self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) - responses = ["A", "B", "C", "cancel"] + responses = ["A", "B", "C", "cancel"] for response in responses: i = 6 + responses.index(response) * 12 # enable get_response for this session - self.assertEqual(messages[i+1].msg_type, "skill.converse.get_response.enable") - self.assertEqual(messages[i+2].msg_type, "ovos.session.update_default") + self.assertEqual(messages[i + 1].msg_type, "skill.converse.get_response.enable") + self.assertEqual(messages[i + 2].msg_type, "ovos.session.update_default") # 3 sound prompts (no dialog in this test) - self.assertEqual(messages[i+3].msg_type, "mycroft.mic.listen") + self.assertEqual(messages[i + 3].msg_type, "mycroft.mic.listen") # check utterance goes through converse cycle - self.assertEqual(messages[i+4].msg_type, "recognizer_loop:utterance") - self.assertEqual(messages[i+5].msg_type, f"{self.skill_id}.converse.ping") - self.assertEqual(messages[i+6].msg_type, "skill.converse.pong") + self.assertEqual(messages[i + 4].msg_type, "recognizer_loop:utterance") + self.assertEqual(messages[i + 5].msg_type, f"{self.skill_id}.converse.ping") + self.assertEqual(messages[i + 6].msg_type, "skill.converse.pong") # captured utterance sent to get_response handler that is waiting - self.assertEqual(messages[i+7].msg_type, f"{self.skill_id}.converse.get_response") - self.assertEqual(messages[i+7].data["utterances"], [response]) + self.assertEqual(messages[i + 7].msg_type, f"{self.skill_id}.converse.get_response") + self.assertEqual(messages[i + 7].data["utterances"], [response]) # converse pipeline activates the skill last_used timestamp - self.assertEqual(messages[i+8].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[i+9].msg_type, f"{self.skill_id}.activate") - self.assertEqual(messages[i+10].msg_type, "ovos.session.update_default") + self.assertEqual(messages[i + 8].msg_type, "intent.service.skills.activated") + self.assertEqual(messages[i + 9].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[i + 10].msg_type, "ovos.session.update_default") # disable get_response for this session - self.assertEqual(messages[i+11].msg_type, "skill.converse.get_response.disable") - self.assertEqual(messages[i+12].msg_type, "ovos.session.update_default") + self.assertEqual(messages[i + 11].msg_type, "skill.converse.get_response.disable") + self.assertEqual(messages[i + 12].msg_type, "ovos.session.update_default") # intent return self.assertEqual(messages[55].msg_type, "skill_items") diff --git a/test/end2end/session/test_sched.py b/test/end2end/session/test_sched.py new file mode 100644 index 000000000000..a9674be9cc48 --- /dev/null +++ b/test/end2end/session/test_sched.py @@ -0,0 +1,226 @@ +import time +from time import sleep +from unittest import TestCase + +from ovos_bus_client.message import Message +from ovos_bus_client.session import SessionManager, Session +from .minicroft import get_minicroft + + +class TestSessions(TestCase): + + def setUp(self): + self.skill_id = "skill-ovos-schedule.openvoiceos" + self.core = get_minicroft(self.skill_id) + + def test_no_session(self): + SessionManager.sessions = {} + SessionManager.default_session = SessionManager.sessions["default"] = Session("default") + SessionManager.default_session.lang = "en-us" + + messages = [] + + def new_msg(msg): + nonlocal messages + m = Message.deserialize(msg) + if m.msg_type in ["ovos.skills.settings_changed"]: + return # skip these, only happen in 1st run + messages.append(m) + print(len(messages), msg) + + def wait_for_n_messages(n): + nonlocal messages + t = time.time() + while len(messages) < n: + sleep(0.1) + if time.time() - t > 10: + raise RuntimeError("did not get the number of expected messages under 10 seconds") + + self.core.bus.on("message", new_msg) + + utt = Message("recognizer_loop:utterance", + {"utterances": ["schedule event"]}) + self.core.bus.emit(utt) + + # confirm all expected messages are sent + expected_messages = [ + "recognizer_loop:utterance", # no session + "intent.service.skills.activated", # default session injected + f"{self.skill_id}.activate", + f"{self.skill_id}:ScheduleIntent", + "mycroft.skill.handler.start", + "enclosure.active_skill", + "speak", + "mycroft.scheduler.schedule_event", + "mycroft.skill.handler.complete", + "ovos.session.update_default", + # event triggering after 3 seconds + "skill-ovos-schedule.openvoiceos:my_event", + "enclosure.active_skill", + "speak" + ] + wait_for_n_messages(len(expected_messages)) + + self.assertEqual(len(expected_messages), len(messages)) + + mtypes = [m.msg_type for m in messages] + for m in expected_messages: + self.assertTrue(m in mtypes) + + # verify that "session" and "lang" is injected + # (missing in utterance message) and kept in all messages + for m in messages[1:]: + self.assertEqual(m.context["session"]["session_id"], "default") + self.assertEqual(m.context["lang"], "en-us") + + # verify skill is activated by intent service (intent pipeline matched) + self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") + self.assertEqual(messages[1].data["skill_id"], self.skill_id) + self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + + # verify intent triggers + self.assertEqual(messages[3].msg_type, f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[3].data["intent_type"], f"{self.skill_id}:ScheduleIntent") + # verify skill_id is now present in every message.context + for m in messages[3:]: + self.assertEqual(m.context["skill_id"], self.skill_id) + + # verify intent execution + self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[4].data["name"], "ScheduleSkill.handle_sched_intent") + self.assertEqual(messages[5].msg_type, "enclosure.active_skill") + self.assertEqual(messages[5].data["skill_id"], self.skill_id) + self.assertEqual(messages[6].msg_type, "speak") + self.assertEqual(messages[6].data["lang"], "en-us") + self.assertFalse(messages[6].data["expect_response"]) + self.assertEqual(messages[6].data["meta"]["dialog"], "done") + self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[7].msg_type, "mycroft.scheduler.schedule_event") + self.assertEqual(messages[8].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[8].data["name"], "ScheduleSkill.handle_sched_intent") + + # verify default session is now updated + self.assertEqual(messages[9].msg_type, "ovos.session.update_default") + self.assertEqual(messages[9].data["session_data"]["session_id"], "default") + # test deserialization of payload + sess = Session.deserialize(messages[9].data["session_data"]) + self.assertEqual(sess.session_id, "default") + + # test that active skills list has been updated + self.assertEqual(sess.active_skills[0][0], self.skill_id) + self.assertEqual(messages[9].data["session_data"]["active_skills"][0][0], self.skill_id) + + # ensure context in triggered event is the same from message that triggered the intent + intent_context = messages[3].context + self.assertEqual(messages[10].msg_type, "skill-ovos-schedule.openvoiceos:my_event") + self.assertEqual(messages[10].context, intent_context) + self.assertEqual(messages[11].msg_type, "enclosure.active_skill") + self.assertEqual(messages[11].context, intent_context) + self.assertEqual(messages[12].msg_type, "speak") + self.assertEqual(messages[12].data["lang"], "en-us") + self.assertFalse(messages[12].data["expect_response"]) + self.assertEqual(messages[12].data["meta"]["dialog"], "trigger") + self.assertEqual(messages[12].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[12].context, intent_context) + + def test_explicit_session(self): + SessionManager.sessions = {} + SessionManager.default_session = SessionManager.sessions["default"] = Session("default") + SessionManager.default_session.lang = "en-us" + + messages = [] + + def new_msg(msg): + nonlocal messages + m = Message.deserialize(msg) + if m.msg_type in ["ovos.skills.settings_changed"]: + return # skip these, only happen in 1st run + messages.append(m) + print(len(messages), msg) + + def wait_for_n_messages(n): + nonlocal messages + t = time.time() + while len(messages) < n: + sleep(0.1) + if time.time() - t > 10: + raise RuntimeError("did not get the number of expected messages under 10 seconds") + + self.core.bus.on("message", new_msg) + + sess = Session() + utt = Message("recognizer_loop:utterance", + {"utterances": ["schedule event"]}, + {"session": sess.serialize()}) + self.core.bus.emit(utt) + + # confirm all expected messages are sent + expected_messages = [ + "recognizer_loop:utterance", + "intent.service.skills.activated", + f"{self.skill_id}.activate", + f"{self.skill_id}:ScheduleIntent", + "mycroft.skill.handler.start", + "enclosure.active_skill", + "speak", + "mycroft.scheduler.schedule_event", + "mycroft.skill.handler.complete", + # event triggering after 3 seconds + "skill-ovos-schedule.openvoiceos:my_event", + "enclosure.active_skill", + "speak" + ] + wait_for_n_messages(len(expected_messages)) + + self.assertEqual(len(expected_messages), len(messages)) + + mtypes = [m.msg_type for m in messages] + for m in expected_messages: + self.assertTrue(m in mtypes) + + # verify that "session" is the same in all message + # (missing in utterance message) and kept in all messages + for m in messages: + self.assertEqual(m.context["session"]["session_id"], sess.session_id) + + # verify skill is activated by intent service (intent pipeline matched) + self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") + self.assertEqual(messages[1].data["skill_id"], self.skill_id) + self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + + # verify intent triggers + self.assertEqual(messages[3].msg_type, f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[3].data["intent_type"], f"{self.skill_id}:ScheduleIntent") + # verify skill_id is now present in every message.context + for m in messages[3:]: + self.assertEqual(m.context["skill_id"], self.skill_id) + + # verify intent execution + self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[4].data["name"], "ScheduleSkill.handle_sched_intent") + self.assertEqual(messages[5].msg_type, "enclosure.active_skill") + self.assertEqual(messages[5].data["skill_id"], self.skill_id) + self.assertEqual(messages[6].msg_type, "speak") + self.assertEqual(messages[6].data["lang"], "en-us") + self.assertFalse(messages[6].data["expect_response"]) + self.assertEqual(messages[6].data["meta"]["dialog"], "done") + self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[7].msg_type, "mycroft.scheduler.schedule_event") + self.assertEqual(messages[8].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[8].data["name"], "ScheduleSkill.handle_sched_intent") + + # ensure context in triggered event is the same from message that triggered the intent + intent_context = messages[3].context + self.assertEqual(messages[9].msg_type, "skill-ovos-schedule.openvoiceos:my_event") + self.assertEqual(messages[9].context, intent_context) + self.assertEqual(messages[10].msg_type, "enclosure.active_skill") + self.assertEqual(messages[10].context, intent_context) + self.assertEqual(messages[11].msg_type, "speak") + self.assertEqual(messages[11].data["lang"], "en-us") + self.assertFalse(messages[11].data["expect_response"]) + self.assertEqual(messages[11].data["meta"]["dialog"], "trigger") + self.assertEqual(messages[11].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[11].context, intent_context) + + def tearDown(self) -> None: + self.core.stop() diff --git a/test/end2end/session/test_session.py b/test/end2end/session/test_session.py index 148ab83ae48b..0b155182d599 100644 --- a/test/end2end/session/test_session.py +++ b/test/end2end/session/test_session.py @@ -1,6 +1,6 @@ import time from time import sleep -from unittest import TestCase, skip +from unittest import TestCase from ovos_bus_client.message import Message from ovos_bus_client.session import SessionManager, Session @@ -13,6 +13,9 @@ def setUp(self): self.skill_id = "skill-ovos-hello-world.openvoiceos" self.core = get_minicroft(self.skill_id) + def tearDown(self) -> None: + self.core.stop() + def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") @@ -308,4 +311,3 @@ def wait_for_n_messages(n): self.assertNotEqual(sess.active_skills[0][1], now) # test that default session remains unchanged self.assertEqual(SessionManager.default_session.active_skills, []) -