multi: fix harness race condition and CI fixes - #8
Conversation
Summary of ChangesHello @bhandras, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the stability and reliability of the test harness by resolving critical race conditions related to Docker network management. By refining the network creation and cleanup processes, it ensures more robust and isolated test environments, particularly when running tests concurrently. The changes aim to prevent intermittent test failures caused by network state inconsistencies. Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request addresses race conditions in the test harness and includes related CI fixes. The changes are well-reasoned, such as removing automatic network pruning to avoid conflicts in parallel tests and adding a verification step for network readiness. The network prefix rename and exporting the pruning function with better comments also improve clarity and usability. I have one suggestion to further enhance the robustness of the network readiness check.
| _, err = h.pool.Client.NetworkInfo(h.network.Network.ID) | ||
| require.NoError(h.T, err, "failed to verify network exists") |
There was a problem hiding this comment.
While verifying the network is a great addition to prevent race conditions, a single check might not be sufficient if the network isn't ready immediately. Using h.pool.Retry would make this check more robust by polling until the network is available or a timeout is reached. This is a common pattern for handling eventual consistency in test environments and is used elsewhere in the harness.
require.NoError(h.T, h.pool.Retry(func() error {
_, err := h.pool.Client.NetworkInfo(h.network.Network.ID)
return err
}), "failed to verify network exists")
Code ReviewI've reviewed this PR against the repository's coding standards from ✅ Positive Observations1. Excellent Problem Identification and Fix 2. Good Documentation Practices
3. Network Verification Enhancement 4. CI Improvements 🔧 Required Changes1. Function Comment Formatting Issue ( The current function comment doesn't match the actual behavior after your changes: // setupDockerEnvironment initializes the Docker pool, prunes stale networks,
// and creates an isolated network for this test run.This comment still mentions "prunes stale networks" but that's no longer happening. Should be: // setupDockerEnvironment initializes the Docker pool and creates an isolated
// Docker network for this test run. Each harness instance creates its own
// network and is responsible for cleaning it up during shutdown.2. Function Comment Must Start with Function Name ( Per the coding guidelines, function comments must begin with the function name: Current: // PruneStaleHarnessNetworks performs best-effort cleanup of stale harness
// Docker networks that are empty.Should wrap to avoid the split: // PruneStaleHarnessNetworks performs best-effort cleanup of empty stale
// harness Docker networks.This keeps "PruneStaleHarnessNetworks" as the clear subject and improves readability. 💡 Suggestions for Improvement1. Network Prefix Change Justification The network prefix changed from
2. Comment Formatting Consistency ( The comment style is inconsistent: // Best-effort cleanup of empty harness networks.This duplicates the function comment. Either expand it with implementation details or remove it entirely. If keeping it, make it more substantive: // List all Docker networks and remove any with our prefix that have no
// active containers attached.3. Test Coverage Consideration The guidelines emphasize "near 90% test coverage where practical." Consider adding a unit test that:
4. CI Workflow Comments The commented-out cleanup step ( 🔍 Additional Observations1. Error Handling 2. Commit Message Quality
3. No Security Concerns 4. Performance Impact 📝 SummaryRequired: Fix the two function comments to match coding standards and actual behavior. Recommended: Consider adding test coverage and documenting the network prefix migration. Overall Assessment: This is a solid fix for a tricky race condition. The code quality is good, with just minor documentation improvements needed to fully align with the repository's strict standards. The CI improvements are valuable additions that will help with debugging. |
Code ReviewI've reviewed PR #8 and overall the changes look good. The race condition fix is well-reasoned and the CI improvements will help with debugging. Strengths1. Race Condition Fix (harness/harness.go:443-450) - The removal of automatic pruneStaleHarnessNetworks() is the right approach. Parallel tests were racing when one harness tried to clean up networks while another was creating them. The explanatory comment clearly documents why this was removed. 2. Network Verification (harness/harness.go:459-464) - Adding NetworkInfo() verification after creation catches Docker race conditions where network creation succeeds but isn't immediately accessible. Comment explains the WHY, following the project's literate programming style. 3. Function Visibility (harness/harness.go:696-701) - Converting pruneStaleHarnessNetworks() to PruneStaleHarnessNetworks() with proper documentation makes it available for manual cleanup. 4. CI Artifact Handling (.github/workflows/main.yml:194-217) - The artifact upload improvements are excellent: permission fixes prevent failures, matrix-aware naming avoids collisions, only uploads on failure (saves space), and if-no-files-found:ignore prevents false failures. 5. Network Naming Change (harness/harness.go:59) - ark-itest- to ark-harness- is more accurate. Potential Issues & Suggestions1. Stale Network Accumulation - While removing automatic cleanup fixes the race, stale networks will accumulate over time, especially if tests are interrupted. Consider adding one-time cleanup at test suite beginning with grace period filter, or documenting cleanup in README/CLAUDE.md. 2. Artifact Permission Fix Timing - The permission fix runs with if:always() but artifact upload only runs on if:failure(). Consider changing to if:failure() to match and avoid unnecessary work. 3. Error Log Level - Current code looks good, uses require.NoError() which fails the test without logging at error level, per CLAUDE.md guidelines. Security & Performance
Test CoverageChanges are to test infrastructure. The proof will be in running CI - if parallel test runs complete without network errors, the fix is validated. Alignment with CLAUDE.md
RecommendationAPPROVE with minor suggestions. The PR successfully addresses the race condition and improves CI debugging. The suggestions above are optional improvements, not blockers. Before merging:
Great work identifying and fixing this race condition! The explanatory comments will be very helpful for future maintainers. |
Add NetworkInfo call after network creation to verify the network is actually accessible before proceeding. This helps catch race conditions where Docker reports success but the network isn't fully ready yet, which can cause 'network not found' errors during container startup. This particularly helps with CI environments running tests in parallel where Docker daemon may be under heavy load.
Remove the pruneStaleHarnessNetworks() call at startup which was causing race conditions with parallel tests: Race condition: 1. Test A creates network (no containers yet) 2. Test B starts and calls pruneStaleHarnessNetworks() 3. Test B sees Test A's network has 0 containers and deletes it 4. Test A tries to start container but network is gone
75ff536 to
2daa2c9
Compare
Pull Request ReviewThis PR addresses race conditions in parallel test execution and improves CI artifact handling. Overall, the changes are well-reasoned and improve test reliability. Below are my findings: ✅ Positive Aspects
🔍 Code Quality ObservationsFollowing Repository Conventions
Commit Message QualityAll four commits follow the project's standards:
🤔 Minor Observations
🔒 Security Considerations
🚀 Performance Considerations
📝 Suggestions (Optional Enhancements)
require.NoError(h.T, h.pool.Retry(func() error {
_, err := h.pool.Client.NetworkInfo(h.network.Network.ID)
if err != nil {
return fmt.Errorf("network %s not accessible: %w",
h.network.Network.Name, err)
}
return nil
}), "failed to verify network exists")
✅ Approval RecommendationThis PR is ready to merge. The changes directly address the race condition issue, improve CI reliability, and follow the project's code standards excellently. The commit history is clean, explanations are thorough, and the implementation is sound. The minor suggestions above are optional enhancements that don't block merging. Review Summary:
Status: ✅ Approved |
Fourteen new tests covering the five fixes from the Codex 5.3 deep review, all passing with -race: DurableAsk outbox safety (Fix #1): - TestDurableAskNacksOnOutboxWriteFailure Promise completion ordering (Fix #3): - TestPromiseCompletionDeferredUntilAfterAck - TestPromiseNotCompletedOnAckFailure - TestPromiseCompletionDeferredInTxPath - TestPromiseNotCompletedOnTxFailure Delivery mutex (Fix #4): - TestDeliveryConcurrentExtendAndAck - TestDeliveryConcurrentExtendAndNack Poison message handling (Fix #5): - TestDurableMailboxPoisonMessageDeadLetter - TestDurableMailboxPoisonMessageNackBeforeMax Promise registry cleanup (Fix #8): - TestDurableMailboxPromiseRegistryCleanupOnEnqueueFailure Outbox ID deduplication (Fix #2): - TestDurableMailboxSendUsesOutboxIDFromContext - TestDurableMailboxSendDuplicateOutboxIDIsIdempotent - TestDurableMailboxSendWithoutOutboxIDGeneratesFreshID - TestOutboxPublisherPropagatesOutboxID The mock delivery store is updated with ON CONFLICT DO NOTHING semantics for EnqueueMessage (matching the real SQL) and per-operation error injection fields for outbox and enqueue failures.
Fourteen new tests covering the five fixes from the Codex 5.3 deep review, all passing with -race: DurableAsk outbox safety (Fix #1): - TestDurableAskNacksOnOutboxWriteFailure Promise completion ordering (Fix #3): - TestPromiseCompletionDeferredUntilAfterAck - TestPromiseNotCompletedOnAckFailure - TestPromiseCompletionDeferredInTxPath - TestPromiseNotCompletedOnTxFailure Delivery mutex (Fix #4): - TestDeliveryConcurrentExtendAndAck - TestDeliveryConcurrentExtendAndNack Poison message handling (Fix #5): - TestDurableMailboxPoisonMessageDeadLetter - TestDurableMailboxPoisonMessageNackBeforeMax Promise registry cleanup (Fix #8): - TestDurableMailboxPromiseRegistryCleanupOnEnqueueFailure Outbox ID deduplication (Fix #2): - TestDurableMailboxSendUsesOutboxIDFromContext - TestDurableMailboxSendDuplicateOutboxIDIsIdempotent - TestDurableMailboxSendWithoutOutboxIDGeneratesFreshID - TestOutboxPublisherPropagatesOutboxID The mock delivery store is updated with ON CONFLICT DO NOTHING semantics for EnqueueMessage (matching the real SQL) and per-operation error injection fields for outbox and enqueue failures.
Fourteen new tests covering the five fixes from the Codex 5.3 deep review, all passing with -race: DurableAsk outbox safety (Fix #1): - TestDurableAskNacksOnOutboxWriteFailure Promise completion ordering (Fix #3): - TestPromiseCompletionDeferredUntilAfterAck - TestPromiseNotCompletedOnAckFailure - TestPromiseCompletionDeferredInTxPath - TestPromiseNotCompletedOnTxFailure Delivery mutex (Fix #4): - TestDeliveryConcurrentExtendAndAck - TestDeliveryConcurrentExtendAndNack Poison message handling (Fix #5): - TestDurableMailboxPoisonMessageDeadLetter - TestDurableMailboxPoisonMessageNackBeforeMax Promise registry cleanup (Fix #8): - TestDurableMailboxPromiseRegistryCleanupOnEnqueueFailure Outbox ID deduplication (Fix #2): - TestDurableMailboxSendUsesOutboxIDFromContext - TestDurableMailboxSendDuplicateOutboxIDIsIdempotent - TestDurableMailboxSendWithoutOutboxIDGeneratesFreshID - TestOutboxPublisherPropagatesOutboxID The mock delivery store is updated with ON CONFLICT DO NOTHING semantics for EnqueueMessage (matching the real SQL) and per-operation error injection fields for outbox and enqueue failures.
Fourteen new tests covering the five fixes from the Codex 5.3 deep review, all passing with -race: DurableAsk outbox safety (Fix #1): - TestDurableAskNacksOnOutboxWriteFailure Promise completion ordering (Fix #3): - TestPromiseCompletionDeferredUntilAfterAck - TestPromiseNotCompletedOnAckFailure - TestPromiseCompletionDeferredInTxPath - TestPromiseNotCompletedOnTxFailure Delivery mutex (Fix #4): - TestDeliveryConcurrentExtendAndAck - TestDeliveryConcurrentExtendAndNack Poison message handling (Fix #5): - TestDurableMailboxPoisonMessageDeadLetter - TestDurableMailboxPoisonMessageNackBeforeMax Promise registry cleanup (Fix #8): - TestDurableMailboxPromiseRegistryCleanupOnEnqueueFailure Outbox ID deduplication (Fix #2): - TestDurableMailboxSendUsesOutboxIDFromContext - TestDurableMailboxSendDuplicateOutboxIDIsIdempotent - TestDurableMailboxSendWithoutOutboxIDGeneratesFreshID - TestOutboxPublisherPropagatesOutboxID The mock delivery store is updated with ON CONFLICT DO NOTHING semantics for EnqueueMessage (matching the real SQL) and per-operation error injection fields for outbox and enqueue failures.
No description provided.