Skip to content
Snippets Groups Projects
Commit ca02e5d6 authored by Chris Pastl's avatar Chris Pastl
Browse files

refactor: use enum for core mock functions

parent 8c09f36a
Branches
Tags
1 merge request!38Test cases for "src/aura_engine/core"
Pipeline #7977 failed
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
import logging import logging
from enum import StrEnum, auto
from time import sleep from time import sleep
from urllib.parse import urlparse from urllib.parse import urlparse
...@@ -30,9 +31,54 @@ from aura_engine.core.mixer import Mixer ...@@ -30,9 +31,54 @@ from aura_engine.core.mixer import Mixer
from aura_engine.events import EngineEventDispatcher from aura_engine.events import EngineEventDispatcher
# enums reflecting namespace, action and reponses
class Namespace(StrEnum):
MIXER = auto()
CHANNEL = auto()
@classmethod
def _missing_(cls, value):
# map 'mixer' to .MIXER and values of ChannelName to .CHANNEL
if isinstance(value, Namespace):
return cls(value)
elif value in ChannelName._value2member_map_.values():
return cls.CHANNEL
else:
raise TypeError
class MixerAction(StrEnum):
INPUTS = auto()
STATUS = auto()
VOLUME = auto()
SELECT = auto()
ACTIVATE = auto()
class ChannelAction(StrEnum):
PUSH = auto()
LOAD = auto()
URL = auto()
STATUS = auto()
START = auto()
STOP = auto()
CLEAR = auto()
ROLL = auto()
SET_TRACK_METADATA = auto()
class Response(StrEnum):
"""
Using custom reponse type since PlayoutStatusResponse.SUCCESS is list instead of single string.
"""
SUCCESS = "OK" # PlayoutStatusResponse.SUCCESS
INVALID_URL = "Invalid URL" # some arbitrary string which is not "OK" signaling failure
class CoreClientMock(CoreClient): class CoreClientMock(CoreClient):
""" """
Suppress unwanted behavior by subclassing and overriding. Suppress unwanted behavior by subclassing and overriding necessary functions.
""" """
instance = None instance = None
...@@ -41,6 +87,7 @@ class CoreClientMock(CoreClient): ...@@ -41,6 +87,7 @@ class CoreClientMock(CoreClient):
event_dispatcher = None event_dispatcher = None
conn = None conn = None
stream_url = None stream_url = None
resource_id = -1
volumes = [0, 0, 0, 0] volumes = [0, 0, 0, 0]
selections = [0, 0, 0, 0] selections = [0, 0, 0, 0]
...@@ -61,70 +108,109 @@ class CoreClientMock(CoreClient): ...@@ -61,70 +108,109 @@ class CoreClientMock(CoreClient):
CoreClientMock.instance = CoreClientMock(event_dispatcher) CoreClientMock.instance = CoreClientMock(event_dispatcher)
return CoreClientMock.instance return CoreClientMock.instance
def _validate_url(self, url: str) -> bool:
"""
Check url validity.
"""
parse = urlparse(url)
return all([parse.scheme, parse.netloc])
def _get_resource_id(self) -> int:
"""
Increment and return index starting with 0.
"""
self.resource_id += 1
return self.resource_id
@synchronized @synchronized
def connect(self): def connect(self):
sleep(0.5)
pass pass
@synchronized @synchronized
def disconnect(self): def disconnect(self):
sleep(0.5)
pass pass
@synchronized @synchronized
def exec(self, namespace: str, action: str, args: str = "") -> str: def exec(self, namespace: str, action: str, args: str = "") -> str:
self.logger.debug( log = self.logger.debug
f"Core mock namespace: '{namespace}', action: '{action}', args: '{args}'" log(f"Core mock request 'ns: {namespace}', action: '{action}', args: '{args}'")
)
if namespace == "mixer": response: str = None
if action == "inputs":
return f"{ChannelName.QUEUE_A} {ChannelName.QUEUE_B}" ns = Namespace(namespace)
elif action == "status": if ns is None:
chn = int(args) raise TypeError
vol = self.volumes[chn] match ns:
return f"ready=true selected=true single=false volume={vol}% remaining=0" case Namespace.MIXER:
elif action == "volume": act = MixerAction(action)
argv = args.split(" ") if act is None:
chn = int(argv[0]) raise TypeError
vol = self.volumes[chn] match act:
self.volumes[chn] = int(float(argv[1]) / 100.0) case MixerAction.INPUTS:
resp = f"volume={vol}% remaining=0" response = f"{ChannelName.QUEUE_A} {ChannelName.QUEUE_B}"
# print(resp) case MixerAction.STATUS:
return resp chn = int(args)
elif action == "select": vol = self.volumes[chn]
argv = args.split(" ") response = (
chn = int(argv[0]) f"ready=true selected=true single=false volume={vol}% remaining=0"
vol = self.volumes[chn] )
sel = 1 if argv[1] == "true" else 0 case MixerAction.VOLUME:
self.selections[chn] = sel argv = args.split(" ")
return f"volume={vol}% remaining=0 selected={sel}" chn = int(argv[0])
elif action == "activate": vol = self.volumes[chn]
return "OK" self.volumes[chn] = int(float(argv[1]) / 100.0)
elif namespace in ChannelName._value2member_map_.values(): response = f"volume={vol}% remaining=0"
if action == "push": case MixerAction.SELECT:
sleep(5) # simulate some loading time argv = args.split(" ")
return 1 # res id chn = int(argv[0])
elif action == "load": vol = self.volumes[chn]
sleep(3) # simulate some loading time sel = 1 if argv[1] == "true" else 0
return 2 # res id self.selections[chn] = sel
elif action == "url": response = f"volume={vol}% remaining=0 selected={sel}"
parse = urlparse(args) case MixerAction.ACTIVATE:
if all([parse.scheme, parse.netloc]): response = Response.SUCCESS
self.stream_url = args case Namespace.CHANNEL:
return "OK" act = ChannelAction(action)
else: if act is None:
return "Invalid URL" raise TypeError
elif action == "status": match act:
return PlayoutStatusResponse.STREAM_STATUS_CONNECTED.value + " " + self.stream_url case ChannelAction.PUSH:
elif action == "start": sleep(5)
sleep(1) # simulate small start delay resid = self._get_resource_id()
return "OK" response = str(resid)
elif action == "stop": case ChannelAction.LOAD:
return "OK" sleep(3)
elif action == "clear": resid = self._get_resource_id()
return "OK" response = str(resid)
elif action == "roll": case ChannelAction.URL:
return "OK" if self._validate_url(args):
elif action == "set_track_metadata": self.stream_url = args
return "OK" response = Response.SUCCESS
else:
response = Response.INVALID_URL
case ChannelAction.STATUS:
response = (
PlayoutStatusResponse.STREAM_STATUS_CONNECTED.value
+ " "
+ self.stream_url
)
case ChannelAction.START:
sleep(1)
response = Response.SUCCESS
case ChannelAction.STOP:
response = Response.SUCCESS
case ChannelAction.CLEAR:
response = Response.SUCCESS
case ChannelAction.ROLL:
response = Response.SUCCESS
case ChannelAction.SET_TRACK_METADATA:
response = Response.SUCCESS
if response is not None:
log(f"Core mock reponse '{response}'")
return response
raise Exception(f"Unhandled namespace: '{namespace}', action: '{action}', args: '{args}'") raise Exception(f"Unhandled namespace: '{namespace}', action: '{action}', args: '{args}'")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment