Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ A short description of the changes in this PR.
* [ ] `docker/service_version.txt` updated if publishing a release.
* [ ] Tests added/updated and passing.
* [ ] Documentation updated (if needed).
* [ ] Jira ticket updated with expected fixversion hoss-X.Y.Z
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## [unreleased] - 2025-10-20

### Changed

- Updated tests to be less dependent on architecture when comparing floats.
- Fixed test that modified a source file fixture.
- Changed infrastructure so that local and Docker runs of the tests produce output in same locations.
- GitHub once again captures the artifacts from the tests and coverage.


## [v1.1.12] - 2025-10-15

### Added
Expand Down
4 changes: 2 additions & 2 deletions bin/run-test
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ mkdir -p coverage
# Run the tests in a Docker container with mounted volumes for XML report
# output and test coverage reporting
docker run --platform linux/amd64 --rm \
-v $(pwd)/test-reports:/home/tests/reports \
-v $(pwd)/coverage:/home/tests/coverage \
-v $(pwd)/test-reports:/home/test-reports \
-v $(pwd)/coverage:/home/coverage \
ghcr.io/nasa/harmony-opendap-subsetter-test "$@"
12 changes: 5 additions & 7 deletions tests/pip_test_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
coverage~=7.9.2
pre-commit~=4.2.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we need to keep pre-commit?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it's not used in any of the images. It's a local dependency that you should install yourself. GitHub uses https://pre-commit.ci/ as a check.

Copy link
Member

@owenlittlejohns owenlittlejohns Oct 21, 2025

Choose a reason for hiding this comment

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

One other approach would be a separate dev_requirements.txt in the root of the repository. It feels like overkill for a single package, though.

Generally, pre-commit is now being used pretty much all the Python-based Harmony services DAS maintains. It should probably just be something that is manually installed by developers when setting up a new environment for a service.

Copy link
Member Author

Choose a reason for hiding this comment

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

I missed that it was called out in the README. I'll update that. I don't think we need it for any testing purposes in the images still

Copy link
Member Author

Choose a reason for hiding this comment

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

pycodestyle~=2.14.0
pylint ~= 3.3.7
pytest~=8.3.3
pytest-mock==3.14.0
unittest-xml-reporting~=3.2.0
pycodestyle ~= 2.14.0
pylint ~= 3.3.9
pytest ~= 8.3.3
pytest-mock == 3.14.0
pytest-cov == 7.0.0
15 changes: 6 additions & 9 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
####################################
#
# A script invoked by the test Dockerfile to run the Python `unittest` suite
Expand All @@ -16,21 +16,18 @@ STATUS=0

export HDF5_DISABLE_VERSION_CHECK=1

# Run all tests using pytest (will also run unittest tests), producing JUnit
# compatible output
echo "\nRunning tests..."
coverage run -m pytest tests/ --junitxml=tests/reports/pytest-results.xml -v
echo -e "\nRunning tests..."

pytest ./tests -s --cov=hoss --junitxml=test-reports/pytest-results.xml --cov-report=html:coverage --cov-report term

RESULT=$?

if [ "$RESULT" -ne "0" ]; then
STATUS=1
echo "ERROR: tests generated errors"
fi

echo "\n"
echo "Test Coverage Estimates"
coverage report --omit="tests/*"
coverage html --omit="tests/*" -d /home/tests/coverage
echo -e "\n"

# Run pylint
# Ignored errors/warnings:
Expand Down
10 changes: 5 additions & 5 deletions tests/unit/test_coordinate_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,15 +1165,15 @@ def test_get_dimension_order_and_dim_values(self):
self.lat_arr, self.lon_arr, row_indices, crs, is_row=True
)
self.assertEqual(y_x_order, True)
self.assertListEqual(dim_values, expected_dim_values)
np.testing.assert_allclose(dim_values, expected_dim_values, rtol=1e-7)
with self.subTest('Get y_x order when projected_dim is changing across column'):
col_indices = [[0, 0], [0, 9]]
expected_dim_values = [-17299990.048985746, 17213152.396759935]
y_x_order, dim_values = get_dimension_order_and_dim_values(
self.lat_arr, self.lon_arr, col_indices, crs, is_row=False
)
self.assertEqual(y_x_order, True)
self.assertListEqual(dim_values, expected_dim_values)
np.testing.assert_allclose(dim_values, expected_dim_values, rtol=1e-7)
with self.subTest('Get x_y order when projected_dim is changing across row'):
row_indices = [[0, 0], [4, 0]]
expected_dim_values = [-17299990.048985746, 17213152.396759935]
Expand All @@ -1185,7 +1185,7 @@ def test_get_dimension_order_and_dim_values(self):
is_row=True,
)
self.assertEqual(y_x_order, False)
self.assertListEqual(dim_values, expected_dim_values)
np.testing.assert_allclose(dim_values, expected_dim_values, rtol=1e-7)
with self.subTest('Get x_y order when projected_dim is changing across column'):
col_indices = [[0, 0], [0, 9]]
expected_dim_values = [7341677.255608977, -7341677.255608977]
Expand All @@ -1197,7 +1197,7 @@ def test_get_dimension_order_and_dim_values(self):
is_row=False,
)
self.assertEqual(y_x_order, False)
self.assertListEqual(dim_values, expected_dim_values)
np.testing.assert_allclose(dim_values, expected_dim_values, rtol=1e-7)
with self.subTest('Get y_x order when projected_dims are not varying'):
lat_arr = np.array(
[
Expand Down Expand Up @@ -1235,7 +1235,7 @@ def test_get_dimension_order_and_dim_values(self):
self.lat_arr_3d, self.lon_arr_3d, row_indices, crs, is_row=True
)
self.assertEqual(y_x_order, True)
self.assertListEqual(dim_values, expected_dim_values)
np.testing.assert_allclose(dim_values, expected_dim_values, rtol=1e-7)

def test_create_dimension_arrays_from_coordinates(
self,
Expand Down
7 changes: 6 additions & 1 deletion tests/unit/test_dimension_utilities.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from logging import getLogger
from os.path import exists
from pathlib import Path
from shutil import copy, rmtree
from tempfile import mkdtemp
from unittest import TestCase
Expand Down Expand Up @@ -677,8 +678,12 @@ def test_write_bounds(self):
and in a nested group.

"""

test_filename = Path(self.temp_dir) / 'ATL16_prefetch_group.nc4'
copy('tests/data/ATL16_prefetch_group.nc4', test_filename)

varinfo_prefetch = VarInfoFromDmr('tests/data/ATL16_prefetch_group.dmr')
prefetch_dataset = Dataset('tests/data/ATL16_prefetch_group.nc4', 'r+')
prefetch_dataset = Dataset(test_filename, 'r+')

# Expected variable contents in file.
expected_bounds_data = self.bounds_array
Expand Down
21 changes: 16 additions & 5 deletions tests/unit/test_projection_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ def read_geojson(geojson_base_name: str):

return geojson_content

def assertDictAlmostEqual(self, dict1, dict2, places=7):
"""Test the float values of dictionaries as almost equal."""
self.assertEqual(dict1.keys(), dict2.keys())
for key in dict1:
self.assertAlmostEqual(
dict1[key],
dict2[key],
places=places,
msg=f'Mismatch in {key}',
)

@patch('hoss.projection_utilities.get_grid_mapping_attributes')
def test_get_variable_crs(self, mock_get_grid_mapping_attributes):
"""Ensure a `pyproj.CRS` object can be instantiated from the given
Expand Down Expand Up @@ -359,15 +370,15 @@ def test_get_projected_x_y_extents(self):
}

with self.subTest('Bounding box input'):
self.assertDictEqual(
self.assertDictAlmostEqual(
get_projected_x_y_extents(
x_values, y_values, crs, bounding_box=bounding_box
),
expected_output,
)

with self.subTest('Shape file input'):
self.assertDictEqual(
self.assertDictAlmostEqual(
get_projected_x_y_extents(
x_values, y_values, crs, shape_file=polygon_path
),
Expand Down Expand Up @@ -403,15 +414,15 @@ def test_get_projected_x_y_extents_whole_earth(self):
'y_max': 12702440.710450241,
}
with self.subTest('Whole Earth LAEA - Bounding box input'):
self.assertDictEqual(
self.assertDictAlmostEqual(
get_projected_x_y_extents(
x_values, y_values, crs, bounding_box=whole_earth_bbox
),
expected_output,
)

with self.subTest('Whole Earth LAEA - Shape file input'):
self.assertDictEqual(
self.assertDictAlmostEqual(
get_projected_x_y_extents(
x_values, y_values, crs, shape_file=polygon_path
),
Expand Down Expand Up @@ -1160,7 +1171,7 @@ def test_get_x_y_extents_from_geographic_points(self):
'y_max': 1670250.0136418417,
}

self.assertDictEqual(
self.assertDictAlmostEqual(
get_x_y_extents_from_geographic_points(points, crs), expected_x_y_extents
)

Expand Down