Skip to content

Commit b334b61

Browse files
authored
Merge pull request #820 from simvue-io/kzscisoft/test-fixes
🧪 Fix and Update Test System to be Compatible with CI
2 parents 48cc152 + 9e70cb5 commit b334b61

File tree

18 files changed

+742
-315
lines changed

18 files changed

+742
-315
lines changed

.github/workflows/test_client_ubuntu.yml

Lines changed: 98 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ concurrency:
1818
cancel-in-progress: true
1919

2020
jobs:
21-
online_unit_tests:
21+
object_retrieval:
2222
runs-on: ubuntu-latest
23-
timeout-minutes: 40
23+
timeout-minutes: 30
2424
steps:
2525
- uses: actions/checkout@v4
2626
- name: Set up Python 3.13
@@ -40,12 +40,12 @@ jobs:
4040
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
4141
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
4242
run: >-
43-
python -m pytest tests/unit/ -x
44-
-m online -c /dev/null -p no:warnings
43+
python -m pytest -x
44+
-m object_retrieval -c /dev/null -p no:warnings
4545
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
46-
offline_unit_tests:
46+
object_removal:
4747
runs-on: ubuntu-latest
48-
timeout-minutes: 40
48+
timeout-minutes: 30
4949
steps:
5050
- uses: actions/checkout@v4
5151
- name: Set up Python 3.13
@@ -65,12 +65,12 @@ jobs:
6565
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
6666
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
6767
run: >-
68-
python -m pytest tests/unit/ -x
69-
-m offline -c /dev/null -p no:warnings
68+
python -m pytest -x
69+
-m object_removal -c /dev/null -p no:warnings
7070
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
71-
online_functional_tests:
71+
dispatch_tests:
7272
runs-on: ubuntu-latest
73-
timeout-minutes: 40
73+
timeout-minutes: 30
7474
steps:
7575
- uses: actions/checkout@v4
7676
- name: Set up Python 3.13
@@ -82,20 +82,19 @@ jobs:
8282
python -m pip install poetry
8383
poetry self add poetry-plugin-export
8484
poetry export -f requirements.txt --with dev -o requirements.txt --all-extras
85-
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
8685
python -m pip install -r requirements.txt
8786
python -m pip install .
8887
- name: Test with pytest
8988
env:
9089
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
9190
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
9291
run: >-
93-
python -m pytest tests/functional/ -x
94-
-m online -m "not eco" -c /dev/null -p no:warnings
92+
python -m pytest -x
93+
-m dispatch -c /dev/null -p no:warnings
9594
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
96-
offline_functional_tests:
95+
run_tests_online:
9796
runs-on: ubuntu-latest
98-
timeout-minutes: 40
97+
timeout-minutes: 30
9998
steps:
10099
- uses: actions/checkout@v4
101100
- name: Set up Python 3.13
@@ -115,12 +114,12 @@ jobs:
115114
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
116115
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
117116
run: >-
118-
python -m pytest tests/functional/ -x
119-
-m offline -c /dev/null -p no:warnings
117+
python -m pytest -x
118+
-m run -m online -c /dev/null -p no:warnings
120119
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
121-
other_unit_tests:
120+
run_tests_offline:
122121
runs-on: ubuntu-latest
123-
timeout-minutes: 40
122+
timeout-minutes: 30
124123
steps:
125124
- uses: actions/checkout@v4
126125
- name: Set up Python 3.13
@@ -140,13 +139,84 @@ jobs:
140139
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
141140
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
142141
run: >-
143-
python -m pytest tests/unit/ -x
144-
-m 'not offline' -m 'not online'
145-
-m 'not scenario' -c /dev/null
146-
-p no:warnings -n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
147-
other_functional_tests:
142+
python -m pytest -x
143+
-m run -m offline -c /dev/null -p no:warnings
144+
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
145+
config_tests:
148146
runs-on: ubuntu-latest
149-
timeout-minutes: 40
147+
timeout-minutes: 30
148+
steps:
149+
- uses: actions/checkout@v4
150+
- name: Set up Python 3.13
151+
uses: actions/setup-python@v5
152+
with:
153+
python-version: "3.13"
154+
- name: Install dependencies
155+
run: |
156+
python -m pip install poetry
157+
poetry self add poetry-plugin-export
158+
poetry export -f requirements.txt --with dev -o requirements.txt --all-extras
159+
python -m pip install -r requirements.txt
160+
python -m pip install .
161+
- name: Test with pytest
162+
env:
163+
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
164+
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
165+
run: >-
166+
python -m pytest -x
167+
-m config -c /dev/null -p no:warnings
168+
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
169+
executor_tests:
170+
runs-on: ubuntu-latest
171+
timeout-minutes: 30
172+
steps:
173+
- uses: actions/checkout@v4
174+
- name: Set up Python 3.13
175+
uses: actions/setup-python@v5
176+
with:
177+
python-version: "3.13"
178+
- name: Install dependencies
179+
run: |
180+
python -m pip install poetry
181+
poetry self add poetry-plugin-export
182+
poetry export -f requirements.txt --with dev -o requirements.txt --all-extras
183+
python -m pip install -r requirements.txt
184+
python -m pip install .
185+
- name: Test with pytest
186+
env:
187+
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
188+
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
189+
run: >-
190+
python -m pytest -x
191+
-m executor -c /dev/null -p no:warnings
192+
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
193+
api_tests:
194+
runs-on: ubuntu-latest
195+
timeout-minutes: 30
196+
steps:
197+
- uses: actions/checkout@v4
198+
- name: Set up Python 3.13
199+
uses: actions/setup-python@v5
200+
with:
201+
python-version: "3.13"
202+
- name: Install dependencies
203+
run: |
204+
python -m pip install poetry
205+
poetry self add poetry-plugin-export
206+
poetry export -f requirements.txt --with dev -o requirements.txt --all-extras
207+
python -m pip install -r requirements.txt
208+
python -m pip install .
209+
- name: Test with pytest
210+
env:
211+
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
212+
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
213+
run: >-
214+
python -m pytest -x
215+
-m api -c /dev/null -p no:warnings
216+
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
217+
local_tests:
218+
runs-on: ubuntu-latest
219+
timeout-minutes: 30
150220
steps:
151221
- uses: actions/checkout@v4
152222
- name: Set up Python 3.13
@@ -158,15 +228,13 @@ jobs:
158228
python -m pip install poetry
159229
poetry self add poetry-plugin-export
160230
poetry export -f requirements.txt --with dev -o requirements.txt --all-extras
161-
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
162231
python -m pip install -r requirements.txt
163232
python -m pip install .
164233
- name: Test with pytest
165234
env:
166235
SIMVUE_URL: ${{ secrets.SIMVUE_URL }}
167236
SIMVUE_TOKEN: ${{ secrets.SIMVUE_TOKEN }}
168237
run: >-
169-
python -m pytest tests/functional/ -x
170-
-m 'not offline' -m 'not online'
171-
-m 'not scenario' -c /dev/null
172-
-p no:warnings -n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache
238+
python -m pytest -x
239+
-m local -c /dev/null -p no:warnings
240+
-n 0 -v -o cache_dir=${GITHUB_WORKSPACE}/.pytest-cache

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
* Fixed bug in pagination whereby the count value specified by the user is ignored.
55
* Fixed bug where uploading larger files timed out leading to file of size 0B.
66
* Fixed bug where if the range or threshold of an alert is zero the alert type validation fails.
7+
* Fixed bug in `Folder.ids` where `kwargs` were not being passed to `GET`.
8+
* Ensured all threads have `daemon=True` to prevent hanging on termination.
9+
* Added error when `close()` method is called within the `simvue.Run` context manager.
710
## [v2.1.1](https://github.com/simvue-io/client/releases/tag/v2.1.1) - 2025-04-25
811
* Changed from CO2 Signal to ElectricityMaps
912
* Fixed a number of bugs in how offline mode is handled with emissions

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ testpaths = [
9797
markers = [
9898
"eco: tests for emission metrics",
9999
"client: tests of Simvue client",
100-
"converters: tests for Simvue object converters",
101100
"dispatch: test data dispatcher",
102101
"run: test the simvue Run class",
103102
"utilities: test simvue utilities module",
@@ -107,10 +106,11 @@ markers = [
107106
"api: tests of RestAPI functionality",
108107
"unix: tests for UNIX systems only",
109108
"metadata: tests of metadata gathering functions",
110-
"proxies: tests for remote/offline Simvue proxies",
111109
"online: tests for online functionality",
112110
"offline: tests for offline functionality",
113-
"local: tests of functionality which do not involve a server or writing to an offline cache file"
111+
"local: tests of functionality which do not involve a server or writing to an offline cache file",
112+
"object_retrieval: tests relating to retrieval of objects from the server",
113+
"object_removal: tests relating to removal of objects from the server",
114114
]
115115

116116
[tool.interrogate]

simvue/api/objects/base.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def ids(
365365
"""
366366
_class_instance = cls(_read_only=True, _local=True)
367367
_count: int = 0
368-
for response in cls._get_all_objects(offset, count=count):
368+
for response in cls._get_all_objects(offset, count=count, **kwargs):
369369
if (_data := response.get("data")) is None:
370370
raise RuntimeError(
371371
f"Expected key 'data' for retrieval of {_class_instance.__class__.__name__.lower()}s"
@@ -412,6 +412,10 @@ def get(
412412
f"Expected key 'data' for retrieval of {_class_instance.__class__.__name__.lower()}s"
413413
)
414414

415+
# If data is an empty list
416+
if not _data:
417+
return
418+
415419
for entry in _data:
416420
_id = entry["id"]
417421
yield _id, cls(_read_only=True, identifier=_id, _local=True, **entry)
@@ -473,7 +477,7 @@ def read_only(self, is_read_only: bool) -> None:
473477
if not self._read_only:
474478
self._staging = self._get_local_staged()
475479

476-
def commit(self) -> None:
480+
def commit(self) -> dict | None:
477481
"""Send updates to the server, or if offline, store locally."""
478482
if self._read_only:
479483
raise AttributeError("Cannot commit object in 'read-only' mode")
@@ -485,22 +489,26 @@ def commit(self) -> None:
485489
self._cache()
486490
return
487491

492+
_response: dict | None = None
493+
488494
# Initial commit is creation of object
489495
# if staging is empty then we do not need to use PUT
490496
if not self._identifier or self._identifier.startswith("offline_"):
491497
self._logger.debug(
492498
f"Posting from staged data for {self._label} '{self.id}': {self._staging}"
493499
)
494-
self._post(**self._staging)
500+
_response = self._post(**self._staging)
495501
elif self._staging:
496502
self._logger.debug(
497503
f"Pushing updates from staged data for {self._label} '{self.id}': {self._staging}"
498504
)
499-
self._put(**self._staging)
505+
_response = self._put(**self._staging)
500506

501507
# Clear staged changes
502508
self._clear_staging()
503509

510+
return _response
511+
504512
@property
505513
def id(self) -> str | None:
506514
"""The identifier for this object if applicable.
@@ -686,3 +694,15 @@ def staged(self) -> dict[str, typing.Any] | None:
686694
the locally staged data if available.
687695
"""
688696
return self._staging or None
697+
698+
def __str__(self) -> str:
699+
"""String representation of Simvue object."""
700+
return f"{self.__class__.__name__}({self.id=})"
701+
702+
def __repr__(self) -> str:
703+
_out_str = f"{self.__class__.__module__}.{self.__class__.__qualname__}("
704+
_out_str += ", ".join(
705+
f"{property}={getattr(self, property)!r}" for property in self._properties
706+
)
707+
_out_str += ")"
708+
return _out_str

simvue/api/url.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ def __truediv__(self, other: str) -> Self:
3737
_new /= other
3838
return _new
3939

40+
def __repr__(self) -> str:
41+
"""Representation of URL"""
42+
_out_str = f"{self.__class__.__module__}.{self.__class__.__qualname__}"
43+
return f"{_out_str}(url={self.__str__()!r})"
44+
4045
@pydantic.validate_call
4146
def __itruediv__(self, other: str) -> Self:
4247
"""Define URL extension through use of '/'"""

0 commit comments

Comments
 (0)