Skip to content

Commit

Permalink
Merge pull request #25 from EURODEO/issue-17-covjson-conversion-test
Browse files Browse the repository at this point in the history
Issue 17 proto object to covjson conversion unit tests
  • Loading branch information
fjugipe authored Feb 2, 2024
2 parents 4f219e2 + e862c73 commit 4e89b76
Show file tree
Hide file tree
Showing 9 changed files with 846 additions and 0 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- "**"
tags:
- "[0-9]+.[0-9]+.[0-9]+"
pull_request:
branches:
- main

permissions:
contents: read
Expand Down Expand Up @@ -102,6 +105,59 @@ jobs:
if: always()
run: docker compose down --volumes

test-api:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write

strategy:
matrix:
python-version: ["3.11"]
steps:
- name: Checkout the repo
uses: actions/checkout@v4

- name: Python Setup
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install Dependencies
run: |
pip install --upgrade pip
pip install pytest-timeout
pip install pytest-cov
pip install -r ./api/requirements.txt
- name: Copy Protobuf file to api directory and build
run: |
mkdir ./api/protobuf
cp ./protobuf/datastore.proto ./api/protobuf/datastore.proto
python -m grpc_tools.protoc --proto_path=./api/protobuf --python_out=./api --grpc_python_out=./api ./api/protobuf/datastore.proto
- name: Run Tests
run: |
cd api
python -m pytest --timeout=60 --junitxml=pytest.xml --cov-report=term-missing --cov=. | tee pytest-coverage.txt
- name: Comment coverage
uses: MishaKav/pytest-coverage-comment@main
with:
pytest-coverage-path: ./api/pytest-coverage.txt
coverage-path-prefix: api/
title: API Unit Test Coverage Report
hide-badge: true
hide-report: false
create-new-comment: false
hide-comment: false
report-only-changed-files: false
remove-link-from-badge: false
junitxml-path: ./api/pytest.xml
junitxml-title: API Unit Test Coverage Summary


# TODO: These tests don't currently work. Uncomment once this is resolved.
# test-ingest:
# runs-on: ubuntu-latest
Expand Down
113 changes: 113 additions & 0 deletions api/test/test_covjson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import json

import datastore_pb2 as dstore
import pytest
from covjson_pydantic.coverage import Coverage
from covjson_pydantic.coverage import CoverageCollection
from fastapi import HTTPException
from formatters.covjson import Covjson
from google.protobuf.json_format import Parse


def test_single_parameter_convert():
test_data = load_json("test/test_data/test_single_proto.json")
compare_data = load_json("test/test_data/test_single_covjson.json")

response = create_mock_obs_response(test_data)
coverage_collection = Covjson().convert(response)

assert coverage_collection is not None

assert type(coverage_collection) is Coverage

# Assert that the coverage collection has the correct parameter
# TODO: Change parameter name when parameter names have been decided
assert "ff" in coverage_collection.parameters.keys()

# Check that correct values exist in the coverage collection
assert 9.21 in coverage_collection.ranges["ff"].values

assert len(coverage_collection.domain.axes.t.values) == 7

# Number of time points should match with the number of observation values
assert len(coverage_collection.domain.axes.t.values) == len(coverage_collection.ranges["ff"].values)

# compare the coverage collection with the compare data
# TODO: Modify compare data when parameter names have been decided
coverage_collection_json = json.loads(coverage_collection.model_dump_json(exclude_none=True))
assert coverage_collection_json == compare_data


def test_multiple_parameter_convert():
test_data = load_json("test/test_data/test_multiple_proto.json")
compare_data = load_json("test/test_data/test_multiple_covjson.json")

response = create_mock_obs_response(test_data)

coverage_collection = Covjson().convert(response)

assert coverage_collection is not None

assert type(coverage_collection) is Coverage

# Check that the coverage collection has the correct parameters
# TODO: Change parameter names when parameter names have been decided
assert set(["dd", "ff", "rh"]) == coverage_collection.parameters.keys()

# Check that correct values exist in the coverage collection
assert 230.7 in coverage_collection.ranges["dd"].values
assert 9.19 in coverage_collection.ranges["ff"].values
assert 88.0 in coverage_collection.ranges["rh"].values

# TODO: Modify compare data when parameter names have been decided
coverage_collection_json = json.loads(coverage_collection.model_dump_json(exclude_none=True))
assert coverage_collection_json == compare_data


def test_single_parameter_area_convert():
test_data = load_json("test/test_data/test_coverages_proto.json")
compare_data = load_json("test/test_data/test_coverages_covjson.json")

response = create_mock_obs_response(test_data)

coverage_collection = Covjson().convert(response)

assert coverage_collection is not None

assert type(coverage_collection) is CoverageCollection

assert len(coverage_collection.coverages) > 1

assert all([type(coverage) is Coverage for coverage in coverage_collection.coverages])

# Check that each coverage has the correct parameter
# TODO: Change parameter name when parameter names have been decided
assert all(["TA_P1D_AVG" in coverage.parameters.keys() for coverage in coverage_collection.coverages])

# TODO: Modify compare data when parameter names have been decided
coverage_collection_json = json.loads(coverage_collection.model_dump_json(exclude_none=True))
assert coverage_collection_json == compare_data


def test_empty_response_convert():
test_data = load_json("test/test_data/test_empty_proto.json")
response = create_mock_obs_response(test_data)

# Expect to get an HTTPException with status code of 404 and detail of
# "No data found" when converting an empty response
with pytest.raises(HTTPException) as exception_info:
Covjson().convert(response)

assert exception_info.value.detail == "No data found"
assert exception_info.value.status_code == 404


def create_mock_obs_response(json_data):
response = dstore.GetObsResponse()
Parse(json.dumps(json_data), response)
return response


def load_json(file_path):
with open(file_path, "r") as file:
return json.load(file)
178 changes: 178 additions & 0 deletions api/test/test_data/test_coverages_covjson.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{
"type": "CoverageCollection",
"coverages": [
{
"type": "Coverage",
"domain": {
"type": "Domain",
"domainType": "PointSeries",
"axes": {
"x": {
"values": [
22.19342704
]
},
"y": {
"values": [
59.86948983
]
},
"t": {
"values": [
"2022-12-31T00:00:00Z"
]
}
},
"referencing": [
{
"coordinates": [
"y",
"x"
],
"system": {
"type": "GeographicCRS",
"id": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
{
"coordinates": [
"z"
],
"system": {
"type": "TemporalRS",
"calendar": "Gregorian"
}
}
]
},
"parameters": {
"TA_P1D_AVG": {
"type": "Parameter",
"observedProperty": {
"label": {
"en": "TA_P1D_AVG"
}
},
"unit": {
"label": {
"en": "degC"
}
}
}
},
"ranges": {
"TA_P1D_AVG": {
"type": "NdArray",
"dataType": "float",
"axisNames": [
"t",
"y",
"x"
],
"shape": [
1,
1,
1
],
"values": [
5.2
]
}
}
},
{
"type": "Coverage",
"domain": {
"type": "Domain",
"domainType": "PointSeries",
"axes": {
"x": {
"values": [
24.3986218
]
},
"y": {
"values": [
60.41875496
]
},
"t": {
"values": [
"2022-12-31T00:00:00Z"
]
}
},
"referencing": [
{
"coordinates": [
"y",
"x"
],
"system": {
"type": "GeographicCRS",
"id": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
{
"coordinates": [
"z"
],
"system": {
"type": "TemporalRS",
"calendar": "Gregorian"
}
}
]
},
"parameters": {
"TA_P1D_AVG": {
"type": "Parameter",
"observedProperty": {
"label": {
"en": "TA_P1D_AVG"
}
},
"unit": {
"label": {
"en": "degC"
}
}
}
},
"ranges": {
"TA_P1D_AVG": {
"type": "NdArray",
"dataType": "float",
"axisNames": [
"t",
"y",
"x"
],
"shape": [
1,
1,
1
],
"values": [
3.7
]
}
}
}
],
"parameters": {
"TA_P1D_AVG": {
"type": "Parameter",
"observedProperty": {
"label": {
"en": "TA_P1D_AVG"
}
},
"unit": {
"label": {
"en": "degC"
}
}
}
}
}
Loading

2 comments on commit 4e89b76

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API Unit Test Coverage Report
FileStmtsMissCoverMissing
\_\_init\_\_.py00100% 
datastore_pb2.py524023%23–62
datastore_pb2_grpc.py43430%2–222
dependencies.py22220%1–33
grpc_getter.py880%1–16
locustfile.py15150%1–31
main.py22220%3–51
metadata_endpoints.py19190%1–70
formatters
   \_\_init\_\_.py12650%16–32
   base_formatter.py7186%18
   covjson.py52198%69
routers
   \_\_init\_\_.py00100% 
   edr.py46460%2–119
   records.py00100% 
test
   test_covjson.py600100% 
TOTAL35822338% 

API Unit Test Coverage Summary

Tests Skipped Failures Errors Time
4 0 💤 0 ❌ 0 🔥 0.877s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API Unit Test Coverage Report
FileStmtsMissCoverMissing
\_\_init\_\_.py00100% 
datastore_pb2.py524023%23–62
datastore_pb2_grpc.py43430%2–222
dependencies.py22220%1–33
grpc_getter.py880%1–16
locustfile.py15150%1–31
main.py22220%3–51
metadata_endpoints.py19190%1–70
formatters
   \_\_init\_\_.py12650%16–32
   base_formatter.py7186%18
   covjson.py52198%69
routers
   \_\_init\_\_.py00100% 
   edr.py46460%2–119
   records.py00100% 
test
   test_covjson.py600100% 
TOTAL35822338% 

API Unit Test Coverage Summary

Tests Skipped Failures Errors Time
4 0 💤 0 ❌ 0 🔥 0.870s ⏱️

Please sign in to comment.