Skip to content

Commit

Permalink
automations:split tests into 2 workflows (#558)
Browse files Browse the repository at this point in the history
* automations:split tests into 2 workflows

reduce waiting time for PR checks, codecov will merge both reports since we use flags

* bump utils

* tweak

* tweak

* required utils 0.1.0
  • Loading branch information
JarbasAl authored Oct 13, 2024
1 parent 6e81054 commit 4049e4b
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 133 deletions.
83 changes: 83 additions & 0 deletions .github/workflows/end2end_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Run End2End tests
on:
pull_request:
branches:
- dev
paths-ignore:
- 'ovos_core/version.py'
- 'examples/**'
- '.github/**'
- '.gitignore'
- 'LICENSE'
- 'CHANGELOG.md'
- 'MANIFEST.in'
- 'readme.md'
- 'scripts/**'
push:
branches:
- master
paths-ignore:
- 'ovos_core/version.py'
- 'requirements/**'
- 'examples/**'
- '.github/**'
- '.gitignore'
- 'LICENSE'
- 'CHANGELOG.md'
- 'MANIFEST.in'
- 'readme.md'
- 'scripts/**'
workflow_dispatch:

jobs:
end2end_tests:
strategy:
max-parallel: 3
matrix:
python-version: [3.9]
runs-on: ubuntu-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@v2
- name: Set up python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install System Dependencies
run: |
sudo apt-get update
sudo apt install python3-dev swig libssl-dev
python -m pip install build wheel
- name: Install test dependencies
run: |
pip install -r requirements/tests.txt
pip install ./test/unittests/common_query/ovos_tskill_fakewiki
pip install ./test/end2end/skill-ovos-hello-world
pip install ./test/end2end/skill-ovos-fallback-unknown
pip install ./test/end2end/skill-ovos-slow-fallback
pip install ./test/end2end/skill-converse_test
pip install ./test/end2end/skill-ovos-schedule
pip install ./test/end2end/skill-new-stop
pip install ./test/end2end/skill-old-stop
pip install ./test/end2end/skill-fake-fm
pip install ./test/end2end/skill-fake-fm-legacy
pip install ./test/end2end/skill-ovos-fakewiki
pip install ./test/end2end/metadata-test-plugin
- name: Install core repo
run: |
pip install -e .[plugins]
- name: Run end2end tests
run: |
pytest --cov-append --cov=ovos_core --cov-report xml test/end2end
- name: Upload coverage
env:
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: ./coverage/reports/
fail_ci_if_error: true
files: ./coverage.xml,!./cache
flags: end2end
name: codecov-end2end
verbose: true
23 changes: 2 additions & 21 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,15 @@ jobs:
run: |
pip install -r requirements/tests.txt
pip install ./test/unittests/common_query/ovos_tskill_fakewiki
pip install ./test/end2end/skill-ovos-hello-world
pip install ./test/end2end/skill-ovos-fallback-unknown
pip install ./test/end2end/skill-ovos-slow-fallback
pip install ./test/end2end/skill-converse_test
pip install ./test/end2end/skill-ovos-schedule
pip install ./test/end2end/skill-new-stop
pip install ./test/end2end/skill-old-stop
pip install ./test/end2end/skill-fake-fm
pip install ./test/end2end/skill-fake-fm-legacy
pip install ./test/end2end/skill-ovos-fakewiki
pip install ./test/end2end/metadata-test-plugin
- name: Install core repo
run: |
pip install -e .[mycroft,deprecated]
pip install -e .[mycroft,plugins]
- name: Run unittests
run: |
pytest --cov=ovos_core --cov-report xml test/unittests
# NOTE: additional pytest invocations should also add the --cov-append flag
# or they will overwrite previous invocations' coverage reports
# (for an example, see OVOS Skill Manager's workflow)
- name: Run full core unittests
run: |
pytest --cov-append --cov=ovos_core --cov-report xml test/end2end
- name: Run integration tests
run: |
pytest --cov-append --cov=ovos_core --cov-report xml test/integrationtests
Expand All @@ -85,12 +71,7 @@ jobs:
- name: Run unittests with padatious
run: |
pytest --cov-append --cov=ovos_core --cov-report xml test/unittests/skills
- name: Run unittests with utils 0.0.38
run: |
pip install ovos-utils==0.0.38
pytest --cov-append --cov=ovos_core --cov-report xml test/end2end
- name: Upload coverage
if: "${{ matrix.python-version == '3.9' }}"
env:
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
uses: codecov/codecov-action@v3
Expand All @@ -100,5 +81,5 @@ jobs:
fail_ci_if_error: true
files: ./coverage.xml,!./cache
flags: unittests
name: codecov-umbrella
name: codecov-unittests
verbose: true
98 changes: 12 additions & 86 deletions ovos_core/intent_services/ocp_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,99 +3,25 @@
import threading
from dataclasses import dataclass
from os.path import join, dirname
from threading import Lock, RLock
from threading import RLock
from typing import List, Tuple, Optional, Union

import time
from padacioso import IntentContainer

from ovos_bus_client.apis.ocp import ClassicAudioServiceInterface
from ovos_bus_client.apis.ocp import OCPInterface, OCPQuery
from ovos_bus_client.message import Message, dig_for_message
from ovos_bus_client.session import SessionManager
from ovos_bus_client.util import wait_for_reply
from ovos_plugin_manager.ocp import available_extractors
from ovos_plugin_manager.templates.pipeline import IntentMatch
from ovos_utils import classproperty
from ovos_utils.gui import is_gui_connected, is_gui_running
from ovos_utils.log import LOG
from ovos_utils.messagebus import FakeBus
from ovos_utils.ocp import MediaType, PlaybackType, PlaybackMode, PlayerState, OCP_ID, \
MediaEntry, Playlist, MediaState, TrackState, dict2entry, PluginStream
from ovos_workshop.app import OVOSAbstractApplication
from padacioso import IntentContainer

from ovos_plugin_manager.ocp import available_extractors
from ovos_plugin_manager.templates.pipeline import IntentMatch

try:
from ovos_utils.ocp import MediaType, PlaybackType, PlaybackMode, PlayerState, OCP_ID, \
MediaEntry, Playlist, MediaState, TrackState, dict2entry, PluginStream
from ovos_bus_client.apis.ocp import OCPInterface, OCPQuery
except ImportError:
from ovos_workshop.backwards_compat import MediaType, PlaybackType, PlaybackMode, PlayerState, OCP_ID, \
MediaEntry, Playlist, MediaState, TrackState, dict2entry, PluginStream
from ovos_bus_client.apis.ocp import OCPInterface as _OIF, OCPQuery as _OQ


class OCPInterface(_OIF):

# needs utils 0.1.0 in ovos-bus-client
@classmethod
def norm_tracks(cls, tracks: list):
"""ensures a list of tracks contains only MediaEntry or Playlist items"""
assert isinstance(tracks, list)
# support Playlist and MediaEntry objects in tracks
for idx, track in enumerate(tracks):
if isinstance(track, dict):
tracks[idx] = MediaEntry.from_dict(track)
if isinstance(track, list) and not isinstance(track, Playlist):
tracks[idx] = cls.norm_tracks(track)
elif not isinstance(track, MediaEntry):
# TODO - support string uris
# let it fail in next assert
# log all bad entries before failing
LOG.error(f"Bad track, invalid type: {track}")
assert all(isinstance(t, (MediaEntry, Playlist)) for t in tracks)
return tracks


class OCPQuery(_OQ):
cast2audio = [
MediaType.MUSIC,
MediaType.PODCAST,
MediaType.AUDIOBOOK,
MediaType.RADIO,
MediaType.RADIO_THEATRE,
MediaType.VISUAL_STORY,
MediaType.NEWS
]

# needs utils 0.1.0 in ovos-bus-client
def __init__(self, query, bus, media_type=MediaType.GENERIC, config=None):
LOG.debug(f"Created {media_type.name} query: {query}")
self.query = query
self.media_type = media_type
self.bus = bus
self.config = config or {}
self.reset()

def wait(self):
# if there is no match type defined, lets increase timeout a bit
# since all skills need to search
if self.media_type == MediaType.GENERIC:
timeout = self.config.get("max_timeout", 15) + 3 # timeout bonus
else:
timeout = self.config.get("max_timeout", 15)
while self.searching and time.time() - self.search_start <= timeout:
time.sleep(0.1)
self.searching = False
self.remove_events()

def reset(self):
self.active_skills = {}
self.active_skills_lock = Lock()
self.query_replies = []
self.searching = False
self.search_start = 0
self.query_timeouts = self.config.get("min_timeout", 5)
if self.config.get("playback_mode") in [PlaybackMode.AUDIO_ONLY]:
self.has_gui = False
else:
self.has_gui = is_gui_running() or is_gui_connected(self.bus)


@dataclass
Expand Down Expand Up @@ -480,10 +406,10 @@ def _process_play_query(self, utterance: str, lang: str, match: dict = None,
if not phrase:
# let the error intent handler take action
return IntentMatch(intent_service="OCP_intents",
intent_type="ocp:search_error",
intent_data=match,
skill_id=OCP_ID,
utterance=utterance)
intent_type="ocp:search_error",
intent_data=match,
skill_id=OCP_ID,
utterance=utterance)

sess = SessionManager.get(message)
# if a skill was explicitly requested, search it first
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ combo-lock>=0.2.2, <0.3
padacioso>=0.1.0,<1.0.0
adapt-parser>=1.0.0, <2.0.0

ovos-utils>=0.0.38,<1.0.0
ovos-utils>=0.1.0,<1.0.0
ovos_bus_client>=0.1.0,<1.0.0
ovos-plugin-manager>=0.0.26,<1.0.0
ovos-config>=0.0.13,<1.0.0
Expand Down
26 changes: 1 addition & 25 deletions requirements/tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,4 @@ coveralls==1.8.2
flake8==3.7.9
pytest==5.2.4
pytest-cov==2.8.1
cov-core==1.15.0
sphinx==2.2.1
sphinx-rtd-theme==0.4.3
mock_msm~=0.9.2

mycroft-messagebus-client
#ovos-stt-plugin-selene>=0.0.3a3
ovos-stt-plugin-vosk>=0.1.3
python-vlc==1.1.2

# ovos modules for compat with mycroft namespace
ovos_PHAL<0.1.0, >=0.0.2
ovos-audio~=0.0, >=0.0.2a10
ovos-listener~=0.0, >=0.0.3a2
ovos-gui~=0.0, >=0.0.2
ovos-messagebus~=0.0

# provides plugins and classic machine learning framework
ovos-classifiers<0.1.0, >=0.0.0a53

# Support OCP tests
ovos_bus_client>=0.0.9a15
ovos-utils>=0.1.0a16

ovos-utterance-plugin-cancel>=0.0.1a3
cov-core==1.15.0

0 comments on commit 4049e4b

Please sign in to comment.