import os import socket from multiprocessing import Process import coverage import pytest import requests from funcy import retry from image_prediction.flask import make_prediction_server, run_prediction_server from image_prediction.locations import COVERAGERC # os.environ['COVERAGE_PROCESS_START'] = COVERAGERC @pytest.fixture def host(): return "127.0.0.1" def get_free_port(host): sock = socket.socket() sock.bind((host, 0)) return sock.getsockname()[1] @pytest.fixture def port(host): return get_free_port(host) @pytest.fixture def url(host, port): return f"http://{host}:{port}" @pytest.fixture def predict_fn(): def predict(_): return 42 return predict @pytest.fixture def server(predict_fn): server = make_prediction_server(predict_fn) return server @pytest.fixture def host_and_port(host, port, server): return {"host": host, "port": port} @retry(tries=5, timeout=1) def server_ready(url): response = requests.get(f"{url}/ready") response.raise_for_status() return response.status_code == 200 @pytest.fixture(autouse=True, scope="function") def server_process(server, host_and_port, url): def get_server_process(): coverage.process_startup() return Process(target=run_prediction_server, kwargs={"app": server, **host_and_port}) server = get_server_process() server.start() if server_ready(url): yield server.kill() server.join() server.close() def test_server_predict(url): response = requests.post(url) response.raise_for_status() assert response.json() == 42 def test_server_health_check(url): response = requests.get(f"{url}/health") response.raise_for_status() assert response.status_code == 200 def test_server_ready_check(url): assert server_ready(url)