Add initial player tests.
This commit is contained in:
parent
a2d6f115e0
commit
168d44c66c
3 changed files with 104 additions and 3 deletions
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
|
@ -14,6 +14,13 @@
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "./launch_standalone.py",
|
"program": "./launch_standalone.py",
|
||||||
"console": "integratedTerminal"
|
"console": "integratedTerminal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Python: Launch Tests: Player",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"module": "tests.test_player",
|
||||||
|
"console": "integratedTerminal"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ from helpers.logging_manager import LoggingManager
|
||||||
|
|
||||||
PLAYBACK_END = USEREVENT + 1
|
PLAYBACK_END = USEREVENT + 1
|
||||||
# TODO ENUM
|
# TODO ENUM
|
||||||
VALID_MESSAGE_SOURCES = ["WEBSOCKET", "UI", "CONTROLLER", "ALL"]
|
VALID_MESSAGE_SOURCES = ["WEBSOCKET", "UI", "CONTROLLER", "TEST", "ALL"]
|
||||||
class Player():
|
class Player():
|
||||||
out_q: multiprocessing.Queue
|
out_q: multiprocessing.Queue
|
||||||
last_msg: str
|
last_msg: str
|
||||||
|
@ -603,6 +603,7 @@ class Player():
|
||||||
|
|
||||||
|
|
||||||
elif (self.last_msg == 'QUIT'):
|
elif (self.last_msg == 'QUIT'):
|
||||||
|
self._retMsg(True)
|
||||||
self.running = False
|
self.running = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -638,7 +639,7 @@ class Player():
|
||||||
|
|
||||||
self.logger.log.info("Quiting player " + str(channel))
|
self.logger.log.info("Quiting player " + str(channel))
|
||||||
self.quit()
|
self.quit()
|
||||||
self._retAll("EXIT")
|
self._retAll("QUIT")
|
||||||
del self.logger
|
del self.logger
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
|
|
93
tests/test_player.py
Normal file
93
tests/test_player.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
from queue import Empty
|
||||||
|
import unittest
|
||||||
|
import multiprocessing
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
from player import Player
|
||||||
|
from helpers.logging_manager import LoggingManager
|
||||||
|
# How long to wait (by default) in secs for the player to respond.
|
||||||
|
TIMEOUT_MSG_MAX_S = 10
|
||||||
|
TIMEOUT_QUIT_S = 10
|
||||||
|
class TestPlayer(unittest.TestCase):
|
||||||
|
|
||||||
|
player: multiprocessing.Process
|
||||||
|
player_from_q: multiprocessing.Queue
|
||||||
|
player_to_q: multiprocessing.Queue
|
||||||
|
logger: LoggingManager
|
||||||
|
|
||||||
|
# initialization logic for the test suite declared in the test module
|
||||||
|
# code that is executed before all tests in one test run
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.logger = LoggingManager("Test_Player")
|
||||||
|
|
||||||
|
# clean up logic for the test suite declared in the test module
|
||||||
|
# code that is executed after all tests in one test run
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# initialization logic
|
||||||
|
# code that is executed before each test
|
||||||
|
def setUp(self):
|
||||||
|
self.player_from_q = multiprocessing.Queue()
|
||||||
|
self.player_to_q = multiprocessing.Queue()
|
||||||
|
self.player = multiprocessing.Process(target=Player, args=(-1, self.player_to_q, self.player_from_q))
|
||||||
|
self.player.start()
|
||||||
|
|
||||||
|
# clean up logic
|
||||||
|
# code that is executed after each test
|
||||||
|
def tearDown(self):
|
||||||
|
# Try to kill it, waits the timeout.
|
||||||
|
if self._send_msg_and_wait("QUIT"):
|
||||||
|
self.player.join(timeout=TIMEOUT_QUIT_S)
|
||||||
|
self.logger.log.info("Player quit successfully.")
|
||||||
|
else:
|
||||||
|
self.logger.log.error("No response on teardown, terminating player.")
|
||||||
|
# It's brain dead :/
|
||||||
|
self.player.terminate()
|
||||||
|
|
||||||
|
def _send_msg(self, msg: str):
|
||||||
|
self.player_to_q.put("TEST:{}".format(msg))
|
||||||
|
|
||||||
|
def _wait_for_msg(self, msg: str, sources_filter=["TEST"], timeout:int = TIMEOUT_MSG_MAX_S):
|
||||||
|
elapsed = 0
|
||||||
|
got_anything = False
|
||||||
|
while elapsed < timeout:
|
||||||
|
try:
|
||||||
|
response: str = self.player_from_q.get_nowait()
|
||||||
|
if response:
|
||||||
|
self.logger.log.info("Received response: {}\nWas looking for {}:{}".format(response, sources_filter, msg))
|
||||||
|
got_anything = True
|
||||||
|
source = response[:response.index(":")]
|
||||||
|
if source in sources_filter:
|
||||||
|
if response.startswith("TEST:"+msg):
|
||||||
|
return response[len("TEST:"+msg):]
|
||||||
|
except Empty:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
time.sleep(0.1)
|
||||||
|
elapsed += 0.1
|
||||||
|
return False if got_anything else None
|
||||||
|
|
||||||
|
def _send_msg_and_wait(self, msg:str, sources_filter=["TEST"], timeout: int = TIMEOUT_MSG_MAX_S):
|
||||||
|
self._send_msg(msg)
|
||||||
|
return self._wait_for_msg(msg, sources_filter, timeout)
|
||||||
|
|
||||||
|
|
||||||
|
def test_player_running(self):
|
||||||
|
response = self._send_msg_and_wait("STATUS")
|
||||||
|
|
||||||
|
# assert the status code of the response
|
||||||
|
self.assertTrue(response)
|
||||||
|
|
||||||
|
|
||||||
|
# runs the unit tests in the module
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
unittest.main()
|
||||||
|
except Exception as e:
|
||||||
|
print("Tests failed :/", e)
|
||||||
|
else:
|
||||||
|
print("Tests passed!")
|
Loading…
Reference in a new issue