From bab93360c9e551ce7c101501a25474d164365c56 Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Silva Date: Fri, 10 Nov 2023 19:33:41 +0000 Subject: [PATCH 1/5] Refactored get_collection_coverage tests Using pytest's parametrize mark. This makes it easier to isolate test cases in order to fix the errors that are showing up when running under Python3.8 --- tests/test_api.py | 99 +++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 64 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index cd6070ad2..725bbf986 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1413,97 +1413,68 @@ def test_get_collection_coverage_rangetype(config, api_): assert rangetype['field'][0]['uom']['code'] == '[C]' -def test_get_collection_coverage(config, api_): - req = mock_request() - rsp_headers, code, response = api_.get_collection_coverage( - req, 'obs') - - assert code == HTTPStatus.BAD_REQUEST - - req = mock_request({'properties': '12'}) - rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') - - assert code == HTTPStatus.BAD_REQUEST - - req = mock_request({'subset': 'bad_axis(10:20)'}) - rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') - - assert code == HTTPStatus.BAD_REQUEST - - req = mock_request({'f': 'blah'}) - rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') - - assert code == HTTPStatus.BAD_REQUEST - - req = mock_request({'f': 'html'}) +@pytest.mark.parametrize('request_, collection, expected_code, expected_headers', [ + pytest.param(mock_request(), 'obs', HTTPStatus.BAD_REQUEST, None), + pytest.param(mock_request({'properties': '12'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, None), + pytest.param(mock_request({'subset': 'bad_axis(10:20)'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, None), + pytest.param(mock_request({'f': 'blah'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, None), + pytest.param(mock_request({'f': 'html'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, {'Content-Type': 'text/html'}), + pytest.param(mock_request(HTTP_ACCEPT='text/html'), 'gdps-temperature', HTTPStatus.OK, None), + pytest.param(mock_request({'subset': 'lat(1:2)'}), 'cmip5', HTTPStatus.NO_CONTENT, None), +]) +def test_get_collection_coverage( + config, api_, request_, collection, expected_code, expected_headers): rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') + request_, collection) + assert code == expected_code + for expected_header_name, expected_header_value in (expected_headers or {}).items(): + assert rsp_headers.get(expected_header_name) == expected_header_value - assert code == HTTPStatus.BAD_REQUEST - assert rsp_headers['Content-Type'] == 'text/html' - - req = mock_request(HTTP_ACCEPT='text/html') - rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') +def test_get_collection_coverage_subset_temporal(api_): + req = mock_request({ + 'subset': 'time("2006-07-01T06:00:00":"2007-07-01T06:00:00")' + }) + rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') assert code == HTTPStatus.OK - assert rsp_headers['Content-Type'] == 'application/prs.coverage+json' + assert isinstance(json.loads(response), dict) + +def test_get_collection_coverage_subset(api_): req = mock_request({'subset': 'Lat(5:10),Long(5:10)'}) rsp_headers, code, response = api_.get_collection_coverage( req, 'gdps-temperature') assert code == HTTPStatus.OK content = json.loads(response) - assert content['domain']['axes']['x']['num'] == 35 assert content['domain']['axes']['y']['num'] == 35 assert 'TMP' in content['parameters'] assert 'TMP' in content['ranges'] assert content['ranges']['TMP']['axisNames'] == ['y', 'x'] - req = mock_request({'bbox': '-79,45,-75,49'}) - rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') - - assert code == HTTPStatus.OK - content = json.loads(response) - - assert content['domain']['axes']['x']['start'] == -79.0 - assert content['domain']['axes']['x']['stop'] == -75.0 - assert content['domain']['axes']['y']['start'] == 49.0 - assert content['domain']['axes']['y']['stop'] == 45.0 +def test_get_collection_coverage_subset_grib_output(api_): req = mock_request({ 'subset': 'Lat(5:10),Long(5:10)', 'f': 'GRIB' }) rsp_headers, code, response = api_.get_collection_coverage( req, 'gdps-temperature') - assert code == HTTPStatus.OK assert isinstance(response, bytes) - # req = mock_request({ - # 'subset': 'time("2006-07-01T06:00:00":"2007-07-01T06:00:00")' - # }) - # rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') - # - # assert code == HTTPStatus.OK - # assert isinstance(json.loads(response), dict) - - # req = mock_request({'subset': 'lat(1:2'}) - # rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') - # - # assert code == HTTPStatus.BAD_REQUEST - # - # req = mock_request({'subset': 'lat(1:2)'}) - # rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') - # - # assert code == HTTPStatus.NO_CONTENT + +def test_get_collection_coverage_bbox(api_): + req = mock_request({'bbox': '-79,45,-75,49'}) + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + assert code == HTTPStatus.OK + content = json.loads(response) + assert content['domain']['axes']['x']['start'] == -79.0 + assert content['domain']['axes']['x']['stop'] == -75.0 + assert content['domain']['axes']['y']['start'] == 49.0 + assert content['domain']['axes']['y']['stop'] == 45.0 def test_get_collection_map(config, api_): From b82bff7e96522372e51057da22a785ece36a5a69 Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Silva Date: Mon, 13 Nov 2023 10:45:22 +0000 Subject: [PATCH 2/5] Add Python 3.8 to the CI matrix --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9575a7bb4..bfe531adf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.7 architecture: x64 - name: Checkout pygeoapi uses: actions/checkout@master @@ -39,6 +39,7 @@ jobs: strategy: matrix: include: + - python-version: 3.7 - python-version: 3.8 env: PYGEOAPI_CONFIG: "$(pwd)/pygeoapi-config.yml" From 5207935744ca25b2129dc39677cd29df02f7618f Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Silva Date: Wed, 13 Dec 2023 10:35:49 +0000 Subject: [PATCH 3/5] Reverted tests back to non-parametrized form --- tests/test_api.py | 99 ++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 35 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 725bbf986..cd6070ad2 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1413,68 +1413,97 @@ def test_get_collection_coverage_rangetype(config, api_): assert rangetype['field'][0]['uom']['code'] == '[C]' -@pytest.mark.parametrize('request_, collection, expected_code, expected_headers', [ - pytest.param(mock_request(), 'obs', HTTPStatus.BAD_REQUEST, None), - pytest.param(mock_request({'properties': '12'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, None), - pytest.param(mock_request({'subset': 'bad_axis(10:20)'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, None), - pytest.param(mock_request({'f': 'blah'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, None), - pytest.param(mock_request({'f': 'html'}), 'gdps-temperature', HTTPStatus.BAD_REQUEST, {'Content-Type': 'text/html'}), - pytest.param(mock_request(HTTP_ACCEPT='text/html'), 'gdps-temperature', HTTPStatus.OK, None), - pytest.param(mock_request({'subset': 'lat(1:2)'}), 'cmip5', HTTPStatus.NO_CONTENT, None), -]) -def test_get_collection_coverage( - config, api_, request_, collection, expected_code, expected_headers): +def test_get_collection_coverage(config, api_): + req = mock_request() rsp_headers, code, response = api_.get_collection_coverage( - request_, collection) - assert code == expected_code - for expected_header_name, expected_header_value in (expected_headers or {}).items(): - assert rsp_headers.get(expected_header_name) == expected_header_value + req, 'obs') + assert code == HTTPStatus.BAD_REQUEST -def test_get_collection_coverage_subset_temporal(api_): - req = mock_request({ - 'subset': 'time("2006-07-01T06:00:00":"2007-07-01T06:00:00")' - }) - rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') - assert code == HTTPStatus.OK - assert isinstance(json.loads(response), dict) + req = mock_request({'properties': '12'}) + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + + assert code == HTTPStatus.BAD_REQUEST + + req = mock_request({'subset': 'bad_axis(10:20)'}) + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + assert code == HTTPStatus.BAD_REQUEST + + req = mock_request({'f': 'blah'}) + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + + assert code == HTTPStatus.BAD_REQUEST + + req = mock_request({'f': 'html'}) + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + + assert code == HTTPStatus.BAD_REQUEST + assert rsp_headers['Content-Type'] == 'text/html' + + req = mock_request(HTTP_ACCEPT='text/html') + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + + assert code == HTTPStatus.OK + assert rsp_headers['Content-Type'] == 'application/prs.coverage+json' -def test_get_collection_coverage_subset(api_): req = mock_request({'subset': 'Lat(5:10),Long(5:10)'}) rsp_headers, code, response = api_.get_collection_coverage( req, 'gdps-temperature') assert code == HTTPStatus.OK content = json.loads(response) + assert content['domain']['axes']['x']['num'] == 35 assert content['domain']['axes']['y']['num'] == 35 assert 'TMP' in content['parameters'] assert 'TMP' in content['ranges'] assert content['ranges']['TMP']['axisNames'] == ['y', 'x'] + req = mock_request({'bbox': '-79,45,-75,49'}) + rsp_headers, code, response = api_.get_collection_coverage( + req, 'gdps-temperature') + + assert code == HTTPStatus.OK + content = json.loads(response) + + assert content['domain']['axes']['x']['start'] == -79.0 + assert content['domain']['axes']['x']['stop'] == -75.0 + assert content['domain']['axes']['y']['start'] == 49.0 + assert content['domain']['axes']['y']['stop'] == 45.0 -def test_get_collection_coverage_subset_grib_output(api_): req = mock_request({ 'subset': 'Lat(5:10),Long(5:10)', 'f': 'GRIB' }) rsp_headers, code, response = api_.get_collection_coverage( req, 'gdps-temperature') + assert code == HTTPStatus.OK assert isinstance(response, bytes) - -def test_get_collection_coverage_bbox(api_): - req = mock_request({'bbox': '-79,45,-75,49'}) - rsp_headers, code, response = api_.get_collection_coverage( - req, 'gdps-temperature') - assert code == HTTPStatus.OK - content = json.loads(response) - assert content['domain']['axes']['x']['start'] == -79.0 - assert content['domain']['axes']['x']['stop'] == -75.0 - assert content['domain']['axes']['y']['start'] == 49.0 - assert content['domain']['axes']['y']['stop'] == 45.0 + # req = mock_request({ + # 'subset': 'time("2006-07-01T06:00:00":"2007-07-01T06:00:00")' + # }) + # rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') + # + # assert code == HTTPStatus.OK + # assert isinstance(json.loads(response), dict) + + # req = mock_request({'subset': 'lat(1:2'}) + # rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') + # + # assert code == HTTPStatus.BAD_REQUEST + # + # req = mock_request({'subset': 'lat(1:2)'}) + # rsp_headers, code, response = api_.get_collection_coverage(req, 'cmip5') + # + # assert code == HTTPStatus.NO_CONTENT def test_get_collection_map(config, api_): From 5a73c5cc7c922ae97db696d1110c38c571b98ef0 Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Silva Date: Wed, 13 Dec 2023 10:42:02 +0000 Subject: [PATCH 4/5] Dropped Python 3.7 from main github CI workflow --- .github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bfe531adf..9575a7bb4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v1 with: - python-version: 3.7 + python-version: 3.8 architecture: x64 - name: Checkout pygeoapi uses: actions/checkout@master @@ -39,7 +39,6 @@ jobs: strategy: matrix: include: - - python-version: 3.7 - python-version: 3.8 env: PYGEOAPI_CONFIG: "$(pwd)/pygeoapi-config.yml" From 4ecc7ae526267c5382c11f022939324fe4fceeb3 Mon Sep 17 00:00:00 2001 From: Ricardo Garcia Silva Date: Wed, 13 Dec 2023 11:24:56 +0000 Subject: [PATCH 5/5] replaced ubuntu 20.04 with ubuntu 22.04 in CI workflow files --- .github/workflows/containers.yml | 4 ++-- .github/workflows/main.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index ee8fbb623..67544fed2 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -18,7 +18,7 @@ env: jobs: on-success: name: Build, Test and Push Docker Image to DockerHub - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} permissions: packages: write @@ -80,7 +80,7 @@ jobs: platforms: linux/arm64, linux/amd64 on-failure: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: ${{ github.event.workflow_run.conclusion == 'failure' }} steps: - name: Print Test Fail diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9575a7bb4..e491b2098 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ on: jobs: flake8_py3: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Setup Python uses: actions/setup-python@v1 @@ -35,7 +35,7 @@ jobs: main: needs: [flake8_py3] - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: matrix: include: