# -*- coding: utf-8 -*- import random import pytest import os from flaky import flaky from pytest import approx from glob import glob def dist(a, b, m=2): assert len(a) == len(b) s = 0 for c1, c2 in zip(a, b): s += (c1 - c2) ** 2 return s ** (1 / m) @pytest.fixture(scope="module") def py_router(stars_path): from ed_lrr_gui import PyRouter stars_path, names = stars_path router = PyRouter(lambda status: None) router.load(stars_path) resolved_systems = router.resolve_systems(*names) for name in names: err = "Failed to resolve {}".format(name) assert name in resolved_systems, err yield router, resolved_systems def idf(name): return lambda val: "{}:{}".format(name, val) # class Test_PyShip(object): # folder = os.path.dirname(__file__) # ships = glob(os.path.join(folder,"data","ships","*.json")) # ship_data=[] # ship_ids=[] # for ship in ships: # with open(ship,"r",encoding="utf-8") as fh: # ship_data.append(fh.read()) # ship_ids.append(os.path.splitext(os.path.basename(ship))[0]) # @pytest.mark.parametrize("ship_data", ship_data, ids=ship_ids) # def test_ship_from_json(self, ship_data): # import json # from _ed_lrr import PyShip # loadout = json.loads(ship_data) # ship = PyShip.from_loadout(ship_data) # ship_dict = ship.to_dict() # booster = ship_dict.get("fsd", {}).get("guardian_booster") # assert booster is not None # rel = None # if booster != approx(0.0): # rel = 0.01 # assert ship.max_range() == approx(loadout["MaxJumpRange"], rel) class Test_PyRouter(object): # noqa: H601 beam_widths = [256, 512, 1024, 0] greedyness = [0, 0.5, 1] n_workers = [0, 1, 2, os.cpu_count()] ranges = [30, 50] @pytest.mark.dependency() @flaky(max_runs=10, min_passes=5) def test_load_and_resolve(self, stars_path): stars_path, names = stars_path from ed_lrr_gui import PyRouter router = PyRouter(lambda status: None) router.load(stars_path) resolved_systems = router.resolve_systems(*names) for name in names: err = "Failed to resolve {}".format(name) assert name in resolved_systems, err @pytest.mark.dependency(depends=["Test_ED_LRR::test_load_and_resolve"]) @pytest.mark.parametrize( "greedyness", greedyness, ids=lambda v: "greedyness:{}".format(v) ) @flaky(max_runs=10, min_passes=5) def test_zero_range_fails(self, py_router, greedyness): r, resolved_systems = py_router waypoints = random.sample(list(resolved_systems.values()), k=2) err = pytest.raises(RuntimeError, r.route, waypoints, 0, greedyness) err.match(r"No route from .* to .* found!") @pytest.mark.dependency(depends=["Test_ED_LRR::test_load_and_resolve"]) @flaky(max_runs=10, min_passes=2) @pytest.mark.parametrize("workers", n_workers, ids=idf("workers")) @pytest.mark.parametrize("jump_range", ranges, ids=idf("range")) @pytest.mark.parametrize("greedyness", greedyness, ids=idf("greedyness")) @pytest.mark.parametrize("beam_width", beam_widths, ids=idf("beam_width")) def test_route(self, py_router, jump_range, workers, greedyness, beam_width): r, resolved_systems = py_router waypoints = random.choices(list(resolved_systems.values()), k=2) args = waypoints, jump_range, greedyness, beam_width, workers err = "Failed to route for waypoints: {}".format(waypoints) route = r.route(*args) assert len(route) != 0, err del r hops = [h["id"] for h in route] for wp in waypoints: assert wp in hops, "System id {} not found in route".format(wp) for a, b in zip(route, route[1:]): d = dist(a["pos"], b["pos"]) msg = "jump from {} to {} seems impossible".format(a["system"], b["system"]) assert d <= jump_range * a["mult"], msg