Repository navigation
Conversation
The second server, second_environment and the sync session setup move from test_syncsession.py into integration/helpers.py, with the setup in a new BasePushPullClientTestCase. PushPullClientTestCase extends it and keeps its tests and the activity timestamp checks they use. Other test modules can now reuse the harness without importing PushPullClientTestCase, which would collect and run its tests again. Refs #363 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pins what a full push and a full pull with ASYNC_OPERATIONS send and store, so the refactors of the sync layer can show they change neither. A spy on SessionWrapper.request records each request, then passes the call through to the real method. For each request it records the method, path, query params, body encoding, body keys, the values of the body fields that are stable between runs, the record count of each pushed chunk, and the is_retryable flag. Generated IDs are normalized to <id>. The tests compare the recording with fixed expected lists for every transfer stage. The tests also assert the final local transfer session, the Buffer, Store and app rows on both sides, and the byte counts the server stores. The spy fails a sync that sends more than 100 requests or runs longer than 120 seconds, so a stalled sync fails instead of hanging. Closes #363 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pins what a full push and a full pull send and store when the server lacks ASYNC_OPERATIONS, so the refactors of the LegacyNetwork* operations can show they change neither. The tests run against a live server that emulates a morango version before 0.6.0: the MORANGO_TEST_LEGACY_SERVER variable turns off both ASYNC_OPERATIONS and FSIC_V2_FORMAT on the server, and LiveServer now takes extra environment variables for that. The client keeps its full set of capabilities, as a current Kolibri does when it syncs with an older one. Reducing only the client capabilities, as #364 first proposed, fails today on the server for both push and pull (#416). The expected lists show that the client creates the transfer session and sends no stage updates for serializing, queuing, dequeuing, or deserializing. The legacy pull moves 11 records instead of 10: the client creates the transfer session before it serializes, so it sends an empty client_fsic, and the server queues the user from the initial pull again. Closes #364 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 tasks
bjester
marked this pull request as ready for review
November 6, 2026 18:34
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ASYNC_OPERATIONS) and the legacy flow used with servers before 0.6.0SessionWrapper.requestrecords each request and passes the call through to the real method. Per request, it records the method, path, query params, body encoding (json/gzip), body keys, the values of the stable body fields (filter,push,records_total,records_transferred,transfer_stage), the record count of each pushed chunk, andis_retryable. Generated IDs are normalized to<id>Buffer,Storeand app rows on both sides, and the byte counts the server storesMORANGO_TEST_LEGACY_SERVER, which turns offASYNC_OPERATIONSandFSIC_V2_FORMATinserver2_settings.py.LiveServerandBasePushPullClientTestCasetake extra server environment variables for thattest_syncsession.pyintointegration/helpers.pyasBasePushPullClientTestCase, so the new tests reuse it without re-runningPushPullClientTestCase's testsReviewer guidance
(method, path, body keys, transfer_stage)tuple. Mutation checks showed the narrower tuple let these through, and the expanded recording catches each: droppingis_retryable, sending buffer chunks as JSON instead of gzip, un-flipping the byte counts in the pull PATCH, and adding a query param to the buffer GETclient_fsic, and the legacy server queues the user from the initial pull again. This is today's behavior, pinned as-isreverse()or theapi_urlsconstants. The client sends them to peers on other morango versions, so a renamed route must fail these testschunk_sizeis set in the test class rather than inherited, because the expected request lists depend on it and the harness is not frozentest_network_characterization.pymust not change until M4 is completeIssues addressed
Closes #363
Closes #364
Related: #416
AI usage
Claude Code implemented the tests from the issues and the implementation plan. I had a separate Claude subagent review the async tests against the issue and spec. Its mutation checks showed regressions that the plan's narrower request tuple missed, so I had the recording strengthened, and directed extracting the shared harness into
integration/helpers.py. While implementing the legacy tests, Claude found that the approach in #364 fails against the current code, so we switched to emulating a legacy server and filed #416. Claude ran the integration suite and the mutation checks to verify the changes.🤖 Generated with Claude Code