added more tests for double elimination and seeding

added eq and nq functions for Position class in de
fixed error in de function that would occur if the game has not started yet
This commit is contained in:
Joel Klimont 2022-10-01 19:11:04 +02:00
parent c325a2c7c2
commit f6b27971c4
3 changed files with 88 additions and 12 deletions

View file

@ -8,6 +8,7 @@ import requests
logger = logging.getLogger("seeding-api") logger = logging.getLogger("seeding-api")
API_URL = os.getenv("API_URL", "http://localhost:5000/") + "api/" API_URL = os.getenv("API_URL", "http://localhost:5000/") + "api/"
CONF_URL = os.getenv("API_URL", "http://localhost:5000/") + "config/"
api_override = os.getenv("API_FORCE", "") api_override = os.getenv("API_FORCE", "")

View file

@ -44,11 +44,19 @@ class Position:
self.degrees = degrees self.degrees = degrees
def __repr__(self): def __repr__(self):
return "{x=%s, y=%s, degrees=%s}" % self.x, self.y, self.degrees return "{x=%s, y=%s, degrees=%s}" % (self.x, self.y, self.degrees)
def __str__(self): def __str__(self):
return f"Position(x={round(self.x, 5)}, y={round(self.y, 5)}, degrees={round(self.degrees, 5)})" return f"Position(x={round(self.x, 5)}, y={round(self.y, 5)}, degrees={round(self.degrees, 5)})"
def __eq__(self, o: object) -> bool:
if isinstance(o, Position):
return self.x == o.x and self.y == o.y and self.degrees == o.degrees
return False
def __ne__(self, o: object) -> bool:
return not self.__eq__(o)
@staticmethod @staticmethod
def position_from_json(json_str: Dict): def position_from_json(json_str: Dict):
return Position(json_str["x"], json_str["y"], json_str["degrees"]) return Position(json_str["x"], json_str["y"], json_str["degrees"])
@ -59,7 +67,7 @@ class DoubleElim:
""" """
@staticmethod @staticmethod
def get_position() -> Tuple[Position, int]: def get_pos() -> Tuple[Position, int]:
"""Makes the /api/getPos call to the api. """Makes the /api/getPos call to the api.
:return: A Position object with robot position :return: A Position object with robot position
:rtype: Tuple[Position, int] :rtype: Tuple[Position, int]
@ -68,7 +76,9 @@ class DoubleElim:
if res.status_code == 408: if res.status_code == 408:
logger.error(f"DoubleElim.get_position timeout. API={API_URL_GET_POS}") logger.error(f"DoubleElim.get_position timeout. API={API_URL_GET_POS}")
time.sleep(RETRY_TIMEOUT) time.sleep(RETRY_TIMEOUT)
return DoubleElim.get_position() return DoubleElim.get_pos()
elif res.status_code == 503:
return Position(0, 0, -1), 503
response = json.loads(res.content) response = json.loads(res.content)
logger.debug(f"DoubleElim.get_position = {response}, status code = {res.status_code}") logger.debug(f"DoubleElim.get_position = {response}, status code = {res.status_code}")
@ -85,6 +95,8 @@ class DoubleElim:
logger.error(f"DoubleElim.get_opponent timeout. API={API_URL_GET_OP}") logger.error(f"DoubleElim.get_opponent timeout. API={API_URL_GET_OP}")
time.sleep(RETRY_TIMEOUT) time.sleep(RETRY_TIMEOUT)
return DoubleElim.get_opponent() return DoubleElim.get_opponent()
elif res.status_code == 503:
return Position(0, 0, -1), 503
response = json.loads(res.content) response = json.loads(res.content)
logger.debug(f"DoubleElim.get_opponent = x:{response}, status code = {res.status_code}") logger.debug(f"DoubleElim.get_opponent = x:{response}, status code = {res.status_code}")
@ -101,6 +113,8 @@ class DoubleElim:
logger.error(f"DoubleElim.get_goal timeout. API={API_URL_GET_GOAL}") logger.error(f"DoubleElim.get_goal timeout. API={API_URL_GET_GOAL}")
time.sleep(RETRY_TIMEOUT) time.sleep(RETRY_TIMEOUT)
return DoubleElim.get_goal() return DoubleElim.get_goal()
elif res.status_code == 503:
return Position(0, 0, -1), 503
response = json.loads(res.content) response = json.loads(res.content)
logger.debug(f"DoubleElim.get_goal = {response}, status code = {res.status_code}") logger.debug(f"DoubleElim.get_goal = {response}, status code = {res.status_code}")

View file

@ -1,5 +1,7 @@
import os import json
import unittest import unittest
import requests
import compLib.Seeding as Seeding import compLib.Seeding as Seeding
import compLib.Api as SeedingApi import compLib.Api as SeedingApi
import compLib.DoubleElimination as De import compLib.DoubleElimination as De
@ -16,9 +18,44 @@ class SeedingTest(unittest.TestCase):
self.assertEqual(gamestate.get_material_deliveries(), [[3, 1], [0, 3], [3, 1], [3, 1]]) self.assertEqual(gamestate.get_material_deliveries(), [[3, 1], [0, 3], [3, 1], [3, 1]])
def util_get_info():
res = requests.get(SeedingApi.CONF_URL + "getInfo")
return json.loads(res.text)
def util_set_seeding():
res = requests.get(SeedingApi.CONF_URL + "setToSeeding")
return res.status_code == 200
def util_set_de():
res = requests.get(SeedingApi.CONF_URL + "setToDoubleElim")
return res.status_code == 200
def util_start_match():
res = requests.get(SeedingApi.CONF_URL + "startMatch")
return res.status_code == 200
def util_reset_state():
res = requests.get(SeedingApi.CONF_URL + "resetState")
return res.status_code == 200
def util_set_seed(seed):
res = requests.get(SeedingApi.CONF_URL + "resetState", params={"seed": seed})
return res.status_code == 200
class SeedingApiTest(unittest.TestCase): class SeedingApiTest(unittest.TestCase):
def test_api_seeding(self): def test_api_seeding_extensive(self):
gamestate = Seeding.Gamestate(0) self.assertTrue(util_set_seeding())
self.assertTrue(util_get_info()["is_seeding"])
for seed in range(0, 256):
print(f"Testing seed: {seed}")
gamestate = Seeding.Gamestate(seed)
self.assertTrue(util_set_seed(seed))
seeding_api = SeedingApi.Seeding() seeding_api = SeedingApi.Seeding()
self.assertEqual(seeding_api.get_heuballen(), gamestate.get_heuballen()) self.assertEqual(seeding_api.get_heuballen(), gamestate.get_heuballen())
self.assertEqual(seeding_api.get_logistic_plan(), gamestate.get_logistic_plan()) self.assertEqual(seeding_api.get_logistic_plan(), gamestate.get_logistic_plan())
@ -27,9 +64,33 @@ class SeedingApiTest(unittest.TestCase):
class DeApiTest(unittest.TestCase): class DeApiTest(unittest.TestCase):
def test_api_de(self): def test_api_de(self):
self.assertTrue(util_set_de())
self.assertTrue(util_reset_state())
self.assertFalse(util_get_info()["is_seeding"])
de = De.DoubleElim() de = De.DoubleElim()
print(de.get_goal()) self.assertEqual(de.get_pos(), (De.Position(0, 0, -1), 503))
#self.assertEqual(de.get_goal(), ) self.assertEqual(de.get_opponent(), (De.Position(0, 0, -1), 503))
self.assertEqual(de.get_goal(), (De.Position(0, 0, -1), 503))
self.assertEqual(de.get_items(), ([], 503))
self.assertEqual(de.get_scores(), ({"self": 0, "opponent": 0}, 503))
self.assertTrue(util_start_match())
self.assertLessEqual(util_get_info()["timeleft"], 120)
self.assertEqual(de.get_pos()[1], 200)
self.assertEqual(de.get_opponent()[1], 200)
self.assertEqual(de.get_goal()[1], 200)
self.assertEqual(de.get_items()[1], 200)
self.assertEqual(de.get_scores()[1], 200)
self.assertTrue(0 <= de.get_pos()[0].x <= 250)
self.assertTrue(0 <= de.get_pos()[0].y <= 250)
self.assertTrue(0 <= de.get_pos()[0].degrees <= 360)
self.assertEqual(de.get_items(), ([], 200))
self.assertTrue(util_reset_state())
if __name__ == '__main__': if __name__ == '__main__':