Skip to content

Fix two proto conformance bugs in GetInfo and the implicit server - #69

Merged
chrislupp merged 2 commits into
developfrom
bugfix/api_mismatches
Jul 27, 2026
Merged

Fix two proto conformance bugs in GetInfo and the implicit server#69
chrislupp merged 2 commits into
developfrom
bugfix/api_mismatches

Conversation

@chrislupp

Copy link
Copy Markdown
Collaborator

Fixes two spec-conformance bugs found while implementing
Philote-Rust against the same proto.

Closes #67
Closes #66

GetInfo was a generator on a unary RPC (#67)

The proto declares GetInfo as unary, but the server yielded and the client
indexed response[0]. gRPC cannot serialize a generator into a
DisciplineProperties, so every call failed with
StatusCode.INTERNAL | Failed to serialize response! — including Python client
to Python server.

Both sides had to change together: with the server alone fixed, response[0]
raises TypeError.

The server now also populates DisciplineProperties.name and .version, which
were previously always empty. Discipline gained _name / _version
attributes (default "") to back them.

ImplicitServer emitted an exclusive Array.end (#66)

Array.end is inclusive per the standard. The explicit server and both clients
encode and decode it that way; the implicit server wrote the exclusive bound
straight from get_chunk_indices, so the client sized its destination slice one
element longer than the payload.

Any implicit variable spanning more than one chunk failed with
could not broadcast input array from shape (n,) into shape (n+1,).
Single-chunk arrays survived by accident — the over-long slice was clipped by
NumPy to the array length, which happened to match the payload.

Why CI didn't catch either

Both bugs were invisible to the existing suite, so the tests are the substantive
part of this PR:

  • GetInfo was only ever tested through mocks shaped like the buggy
    implementation (the client mock returned a list), and nothing exercised it
    against a real server.
  • Every implicit variable in examples/ and tests/ is a scalar, so the
    multi-chunk path was never run.

Added:

  • test_get_discipline_info — end-to-end GetInfo against a real gRPC server,
    so the two sides can't drift again.
  • test_implicit_multi_chunk_transfer — a 5-element implicit variable at
    num_double=2 (3 chunks per variable, 13 for the 5×5 Jacobian), covering
    solve_residuals, compute_residuals, and residual_gradients.

Both were verified against the pre-fix code and reproduce the exact failures
from the issues.

Corrected the unit tests that encoded the buggy behavior as expected output:
three in test_implicit_server.py asserted the exclusive encoding, and two
request fixtures used the exclusive convention on the wire (passing only via the
same NumPy clipping that masked the bug).

Testing

pytest tests/ — 280 passed.

GetInfo is declared as a unary RPC in the proto, but the server
implemented it as a generator and the client indexed the response as if
it were a stream. gRPC could not serialize the generator, so every call
failed with "Failed to serialize response!".

The server now returns a DisciplineProperties message and the client
reads the fields directly. The server also populates the name and
version fields, which were previously left empty; disciplines carry
these via new _name / _version attributes.

Adds an end-to-end integration test that exercises GetInfo against a
real gRPC server, so the two sides cannot drift again. The existing unit
tests asserted against mocks shaped like the buggy implementation and
have been corrected.

Fixes #67
Array.end is inclusive per the standard, and the explicit server and both
clients encode and decode it that way. The implicit server instead wrote
the exclusive chunk bound from get_chunk_indices, so the client computed
a destination slice one element longer than the payload.

Any implicit variable spanning more than one chunk failed to decode with
"could not broadcast input array from shape (n,) into shape (n+1,)".
Single-chunk arrays survived by accident: the over-long slice was clipped
by NumPy to the array length, which happened to match the payload. Every
implicit variable in the examples and tests was a scalar, so nothing
exercised the multi-chunk path.

Adds an integration test with a 5-element implicit variable at
num_double=2 (3 chunks) covering solve_residuals, compute_residuals, and
residual_gradients. Existing implicit server unit tests asserted the
exclusive encoding and have been corrected to the inclusive convention.

Fixes #66
@chrislupp chrislupp self-assigned this Jul 27, 2026
@chrislupp chrislupp added the bug Something isn't working label Jul 27, 2026
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@chrislupp
chrislupp merged commit 510d3f8 into develop Jul 27, 2026
8 checks passed
@chrislupp
chrislupp deleted the bugfix/api_mismatches branch July 27, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant