Skip to content

Commit 9b915c9

Browse files
committed
Improve Python tests, coverage, and contributor docs
- Increased Python test covergage: build configuration, OCP solutions, affine spaces, ROS configuration, and Y set calculation. - Updated changelog
1 parent 15164e8 commit 9b915c9

5 files changed

Lines changed: 320 additions & 15 deletions

File tree

docs/content/contributing.mdx

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,18 +268,18 @@ cd python
268268
python3 -m venv venv
269269
source venv/bin/activate
270270
python -m pip install --upgrade pip
271-
pip install -e .
271+
pip install -e '.[dev]'
272272
```
273273

274274
If you plan to run the benchmark suite as well, install the extra dependency:
275275

276276
```bash
277-
pip install pytest-benchmark[histogram]
277+
pip install "pytest-benchmark[histogram]"
278278
```
279279

280280
### Run the Rust tests
281281

282-
From the repository root, run:
282+
From the repository root, run:
283283

284284
```bash
285285
cargo test
@@ -300,7 +300,15 @@ cargo check
300300

301301
### Run the Python and code-generation tests
302302

303-
From within `python/`, run the following tests after you activate `venv`
303+
From within `python/`, run the following tests after you activate `venv`.
304+
The package's optional development dependencies include `pytest`, so the
305+
recommended install command is:
306+
307+
```bash
308+
pip install -e '.[dev]'
309+
```
310+
311+
You can keep using the existing `unittest` commands:
304312

305313
```bash
306314
# Activate venv first
@@ -309,6 +317,14 @@ python -W ignore test/test.py -v
309317
python -W ignore test/test_ocp.py -v
310318
```
311319

320+
or execute the same files with `pytest`:
321+
322+
```bash
323+
pytest test/test_constraints.py
324+
pytest test/test.py
325+
pytest test/test_ocp.py
326+
```
327+
312328
The ROS2 tests should normally be run from an environment where ROS2 is already
313329
installed and configured, for example a dedicated `micromamba` environment.
314330
They should not be assumed to run from the plain `venv` above unless that
@@ -337,3 +353,78 @@ cargo clippy --all-targets
337353

338354
Before opening a pull request, please run the tests that are relevant to the
339355
part of the codebase you changed and make sure they pass locally.
356+
357+
### Run the benchmarks
358+
359+
The Python benchmark suite uses `pytest-benchmark`. If you have not already
360+
installed the development dependencies, do:
361+
362+
```bash
363+
cd python
364+
source venv/bin/activate
365+
pip install -e '.[dev]'
366+
pip install pytest-benchmark[histogram]
367+
```
368+
369+
Before running the benchmarks, generate the benchmarkable optimizers:
370+
371+
```bash
372+
python test/prepare_benchmarks.py
373+
```
374+
375+
Then run the benchmark suite with `pytest`:
376+
377+
```bash
378+
pytest test/benchmark_open.py --benchmark-only
379+
```
380+
381+
To generate a histogram report, pass an output prefix:
382+
383+
```bash
384+
pytest test/benchmark_open.py --benchmark-histogram=out
385+
```
386+
387+
This will produce a file such as `out.svg` in the current directory.
388+
389+
### Produce coverage reports
390+
391+
For Python coverage reports, activate your virtual environment in `python/`
392+
and install `coverage` if needed:
393+
394+
```bash
395+
cd python
396+
source venv/bin/activate
397+
pip install coverage
398+
```
399+
400+
Then run the main Python test suite under coverage and print a summary:
401+
402+
```bash
403+
coverage erase
404+
coverage run --source=opengen test/test_constraints.py
405+
coverage run -a --source=opengen test/test.py
406+
coverage run -a --source=opengen test/test_ocp.py
407+
coverage report -m
408+
```
409+
410+
To generate an HTML report, run:
411+
412+
```bash
413+
coverage html
414+
```
415+
416+
This writes the report to `python/htmlcov/index.html`.
417+
418+
For Rust coverage reports, install `cargo-llvm-cov` once:
419+
420+
```bash
421+
cargo install cargo-llvm-cov
422+
```
423+
424+
Then, from `rust/`, run:
425+
426+
```bash
427+
cargo llvm-cov --html
428+
```
429+
430+
The HTML report will be written to `rust/target/llvm-cov/html/index.html`.

python/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Note: This is the Changelog file of `opengen` - the Python interface of OpEn
1515
- ROS2 package generation support via `BuildConfiguration.with_ros2(...)`, including auto-generated ROS2 templates, launcher, messages, and package wrapper code
1616
- Dedicated ROS2 tests covering package generation, build configuration behavior, rendered custom package settings, and end-to-end execution of a generated ROS2 node
1717
- More informative TCP solver error payloads, including clearer dimension/parameter validation failures and propagated solver-side failure messages
18+
- Additional unit tests for `BuildConfiguration`, `OcpSolution`, `AffineSpace`, `RosConfiguration`, and `SetYCalculator`, increasing Python coverage to 93%
1819

1920
### Changed
2021

@@ -24,6 +25,17 @@ Note: This is the Changelog file of `opengen` - the Python interface of OpEn
2425
- Updated generated TCP server and C interface templates to work with the richer Rust solver error model and expose better failure information to clients. Updated auto-generated `CMakeLists.txt` file. Tighter unit tests.
2526
- ROS2 generated packages now publish detailed `error_code` and `error_message` fields, plus `STATUS_INVALID_REQUEST`, so invalid requests and solver failures are reported explicitly instead of being silently ignored
2627
- Extended GitHub Actions CI to run Python, OCP, and generated-code tests on Windows, and fixed multiple Windows-specific code generation, path, encoding, TCP, and C/CMake compatibility issues.
28+
- ROS/ROS2 messages: using `uint64` instead of `uint8` to avoid overflow
29+
- Tighter checks of provided arguments in build configuration
30+
- Added `pytest` to the optional `dev` dependencies and documented local test, benchmark, and coverage workflows for Python and Rust contributors
31+
32+
### Fixed
33+
34+
- Generated ROS and ROS2 wrappers now accept any meaningful positive `initial_penalty` instead of requiring values greater than `1.0`
35+
- Generated ROS and ROS2 result messages now use wide iteration counters so `inner_iterations` and `outer_iterations` cannot overflow
36+
- ROS2 generated packages now use `uint16` for `error_code`, matching the current positive error-code range while keeping the wire format compact
37+
- MATLAB-related Python docs now reference the new `python/` package layout instead of the removed `open-codegen/` path
38+
- ROS2 integration tests now clean stale nested `colcon` build artifacts and preserve the active shell environment more reliably in micromamba/conda setups
2739

2840

2941
## [0.10.1] - 2026-03-25

python/opengen/config/build_config.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from opengen.config.tcp_server_config import TcpServerConfiguration
22
from opengen.config.ros_config import RosConfiguration
3+
from opengen.config.meta import SEMVER_PATTERN
34
import random
45
import string
56
from enum import Enum
@@ -234,6 +235,13 @@ def with_open_version(self, open_version="*", local_path=None):
234235
235236
:return: current instance of BuildConfiguration
236237
"""
238+
if open_version != "*" and (
239+
not isinstance(open_version, str) or not SEMVER_PATTERN.match(open_version)
240+
):
241+
raise ValueError(
242+
"invalid OpEn version {!r}; expected '*' or a Semantic Version "
243+
"such as '0.1.0' or '1.2.3-alpha.1'".format(open_version)
244+
)
237245
self.__open_version = open_version
238246
self.__local_path = None if local_path is None else str(local_path)
239247
return self
@@ -320,6 +328,10 @@ def with_allocator(self, allocator: RustAllocator):
320328
321329
:return: current instance of BuildConfiguration
322330
"""
331+
if not isinstance(allocator, RustAllocator):
332+
raise ValueError(
333+
"allocator must be an instance of RustAllocator"
334+
)
323335
self.__allocator = allocator
324336
return self
325337

python/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Changelog = "https://github.com/alphaville/optimization-engine/blob/master/pytho
5454
[project.optional-dependencies]
5555
dev = [
5656
"build>=1",
57+
"pytest>=8",
5758
"twine>=5",
5859
]
5960

0 commit comments

Comments
 (0)