async def test_get_status_404(): """Test that get_status reports that a query is not running.""" con_mock = AMock() con_mock.get_url = CoroutineMock( side_effect=FileNotFoundError("DUMMY_404")) status_returned = await get_status(connection=con_mock, query_id="foo") assert status_returned == "not_running"
async def test_get_geojson_result(): con_mock = AMock() con_mock.post_json = CoroutineMock(return_value=Mock( status_code=202, json=Mock(return_value=dict(msg="DUMMY_ERROR"), ), headers=dict(Location="DUMMY"), ), ) con_mock.get_url = CoroutineMock(side_effect=[ Mock( status_code=303, headers=dict(Location="DUMMY"), ), Mock( status_code=200, headers=dict(Location="DUMMY"), json=Mock(return_value=dict(query_result=[{ "0": 1 }])), ), ]) assert (await get_geojson_result(connection=con_mock, query_spec="foo")) == { "query_result": [{ "0": 1 }] }
async def test_wait_until_ready(monkeypatch): """ Test that wait_until_ready polls until query_is_ready returns True """ reply_mock = Mock(json=Mock( return_value={ "status": "executing", "progress": { "eligible": 0, "queued": 0, "running": 0 }, })) ready_mock = CoroutineMock(side_effect=[ ( False, reply_mock, ), (True, reply_mock), ]) monkeypatch.setattr("flowclient.async_client.query_is_ready", ready_mock) connection_mock = AMock() connection_mock.post_json = CoroutineMock(return_value=Mock( status_code=202, headers={"Location": "DUMMY_LOCATION/DUMMY_ID"})) query = ASyncAPIQuery(connection=connection_mock, parameters={"query_kind": "dummy_query"}) await query.run() await query.wait_until_ready() assert 2 == ready_mock.call_count
def dummy_zmq_server(monkeypatch): """ A fixture which provides a dummy zero mq socket which records the json it is asked to send and monkeypatches the zmq asyncio context to return it. Parameters ---------- monkeypatch Yields ------ asynctest.Mock The dummy zeromq socket """ dummy = AMock() dummy.socket.return_value = dummy def f(*args, **kwargs): print("Making dummy zmq.") return dummy monkeypatch.setattr(zmq.asyncio.Context, "instance", f) yield dummy
async def test_get_json_dataframe_raises(): """Test that get_json_dataframe raises an error.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock( status_code=500, json=Mock(return_value=dict(msg="DUMMY_ERROR")))) with pytest.raises(FlowclientConnectionError, match=r".*Reason: DUMMY_ERROR"): await get_json_dataframe(connection=con_mock, location="foo")
async def test_query_ready_reports_false(): """Test that status code 202 is interpreted as query running.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=AMock( status_code=202, json=Mock( return_value={ "status": "completed", "progress": { "eligible": 0, "queued": 0, "running": 0 }, }), )) is_ready, reply = await query_is_ready(connection=con_mock, query_id="foo") assert not is_ready
async def test_get_json_dataframe(): """Test that get_json_dataframe returns results.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock( status_code=200, json=Mock(return_value=dict(query_result=[{ "0": 1 }])))) assert (await get_json_dataframe(connection=con_mock, location="foo")).values.tolist() == [[1]]
async def test_get_result_location_from_id_when_ready(): """ Any unexpected http code should raise an exception. """ connection_mock = AMock() connection_mock.get_url = CoroutineMock(return_value=Mock( status_code=303, headers=dict(Location="/api/0/DUMMY_LOCATION"))) assert (await get_result_location_from_id_when_ready( connection=connection_mock, query_id="DUMMY_ID") == "DUMMY_LOCATION")
async def test_run_query_raises(): con_mock = AMock() con_mock.post_json = CoroutineMock(return_value=Mock( status_code=500, json=Mock(return_value=dict(msg="DUMMY_ERROR")))) with pytest.raises( FlowclientConnectionError, match="Error running the query: DUMMY_ERROR. Status code: 500.", ): await run_query(connection=con_mock, query_spec="foo")
async def test_run_query_raises_with_default_error(): con_mock = AMock() con_mock.post_json = CoroutineMock( return_value=Mock(status_code=500, json=Mock(return_value=dict()))) with pytest.raises( FlowclientConnectionError, match="Error running the query: Unknown error. Status code: 500.", ): await run_query(connection=con_mock, query_spec="foo")
async def test_get_geography(token): """ Test that getting geography returns the returned dict """ connection_mock = AMock() connection_mock.get_url = CoroutineMock(return_value=Mock( status_code=200, json=Mock(return_value={"some": "json"}))) gj = await get_geography(connection=connection_mock, aggregation_unit="DUMMY_AGGREGATION") assert {"some": "json"} == gj
async def test_get_status_raises_without_status(): """Test that get_status raises an error if the status field is absent.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock( status_code=202, json=Mock(return_value=dict( progress=dict(queued=0, running=0, eligible=0))), )) with pytest.raises(FlowclientConnectionError, match="No status reported"): await get_status(connection=con_mock, query_id="foo")
async def test_available_dates(arg, expected): """ Dates should be returned and filtered. """ connection_mock = AMock() connection_mock.get_url = CoroutineMock(return_value=Mock( status_code=200, json=Mock(return_value=dict(available_dates=dict(DUMMY=1, DUMMY_2=1))), )) assert (await get_available_dates(connection=connection_mock, event_types=arg) == expected)
async def test_get_geojson_result_by_query_id_raises(monkeypatch): """Test that get_geojson_result_by_query_id raises an error.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock( status_code=500, json=Mock(return_value=dict(msg="DUMMY_ERROR")))) monkeypatch.setattr( "flowclient.async_client.get_result_location_from_id_when_ready", CoroutineMock(return_value="DUMMY"), ) with pytest.raises(FlowclientConnectionError, match=r".*Reason: DUMMY_ERROR"): await get_geojson_result_by_query_id(connection=con_mock, query_id="foo")
async def test_get_geography_no_msg_error(token): """ A response with an unexpected http code and no "msg" should raise a FlowclientConnectionError. """ connection_mock = AMock() connection_mock.get_url = CoroutineMock( return_value=Mock(status_code=404, json=Mock(return_value={}))) with pytest.raises( FlowclientConnectionError, match=f"Could not get result. API returned with status code: 404.", ): await get_geography(connection=connection_mock, aggregation_unit="DUMMY_AGGREGATION")
async def test_query_run(): """ Test that the 'run' method runs the query and records the query ID internally. """ connection_mock = AMock() connection_mock.post_json = CoroutineMock(return_value=Mock( status_code=202, headers={"Location": "DUMMY_LOCATION/DUMMY_ID"})) query_spec = {"query_kind": "dummy_query"} query = ASyncAPIQuery(connection=connection_mock, parameters=query_spec) assert not hasattr(query, "_query_id") await query.run() connection_mock.post_json.assert_called_once_with(route="run", data=query_spec) assert query._query_id == "DUMMY_ID"
async def test_available_dates_error(http_code): """ Any unexpected http code should raise an exception. """ connection_mock = AMock() connection_mock.get_url = CoroutineMock(return_value=Mock( status_code=http_code, json=Mock(return_value=dict(msg="MESSAGE")))) with pytest.raises( FlowclientConnectionError, match= f"Could not get available dates. API returned with status code: {http_code}. Reason: MESSAGE", ): await get_available_dates(connection=connection_mock, event_types=["FOOBAR"])
async def test_get_geography_error(http_code, token): """ Any unexpected http code should raise an exception. """ connection_mock = AMock() connection_mock.get_url = CoroutineMock(return_value=Mock( status_code=http_code, json=Mock(return_value={"msg": "MESSAGE"}))) with pytest.raises( FlowclientConnectionError, match= f"Could not get result. API returned with status code: {http_code}. Reason: MESSAGE", ): await get_geography(connection=connection_mock, aggregation_unit="DUMMY_AGGREGATION")
async def test_query_get_result_runs(monkeypatch): """ Test that get_result runs the query if it's not already running. """ get_result_mock = CoroutineMock(return_value="DUMMY_RESULT") monkeypatch.setattr(f"flowclient.async_api_query.get_result_by_query_id", get_result_mock) connection_mock = AMock() query_spec = {"query_kind": "dummy_query"} connection_mock.post_json = CoroutineMock(return_value=Mock( status_code=202, headers={"Location": "DUMMY_LOCATION/DUMMY_ID"})) query = ASyncAPIQuery(connection=connection_mock, parameters=query_spec) await query.get_result() connection_mock.post_json.assert_called_once_with(route="run", data=query_spec)
async def test_get_status_reports_running(running_status): """Test that status code 202 is interpreted as query running or queued.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock( status_code=202, json=Mock( return_value={ "status": running_status, "progress": { "eligible": 0, "queued": 0, "running": 0 }, }), )) status = await get_status(connection=con_mock, query_id="foo") assert status == running_status
async def test_query_get_result_pandas(monkeypatch, format, function): get_result_mock = CoroutineMock(return_value="DUMMY_RESULT") monkeypatch.setattr(f"flowclient.async_api_query.{function}", get_result_mock) connection_mock = AMock() connection_mock.post_json = CoroutineMock(return_value=Mock( status_code=202, headers={"Location": "DUMMY_LOCATION/DUMMY_ID"})) query = ASyncAPIQuery(connection=connection_mock, parameters={"query_kind": "dummy_query"}) await query.run() assert "DUMMY_RESULT" == await query.get_result(format=format, poll_interval=2) get_result_mock.assert_called_once_with( connection=connection_mock, disable_progress=None, query_id="DUMMY_ID", poll_interval=2, )
async def test_query_status(): """ Test that the 'status' property returns the status reported by the API. """ connection_mock = AMock() connection_mock.post_json = CoroutineMock(return_value=Mock( status_code=202, headers={"Location": "DUMMY_LOCATION/DUMMY_ID"})) connection_mock.get_url = CoroutineMock(return_value=Mock( status_code=202, json=Mock( return_value={ "status": "executing", "progress": { "eligible": 0, "queued": 0, "running": 0 }, }), )) query = ASyncAPIQuery(connection=connection_mock, parameters={"query_kind": "dummy_query"}) await query.run() assert await query.status == "executing"
async def test_query_ready_raises(): """Test that status codes other than 202, 303, 401, and 404 raise a generic error.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=AMock(status_code=999)) with pytest.raises(FlowclientConnectionError): await query_is_ready(connection=con_mock, query_id="foo")
async def test_query_ready_reports_true(): """Test that status code 303 is interpreted as query ready.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=AMock(status_code=303)) is_ready, reply = await query_is_ready(connection=con_mock, query_id="foo") assert is_ready
async def test_get_status_reports_finished(): """Test that status code 303 is interpreted as query finished.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock(status_code=303)) status = await get_status(connection=con_mock, query_id="foo") assert status == "completed"
async def test_get_status_raises(): """Test that get_status raises an error for a status code other than 202, 303 or 404.""" con_mock = AMock() con_mock.get_url = CoroutineMock(return_value=Mock(status_code=500)) with pytest.raises(FlowclientConnectionError): await get_status(connection=con_mock, query_id="foo")