M1I06: Connection wrapper - add ConnectionTest#59
Conversation
s2x
left a comment
There was a problem hiding this comment.
Thanks for the comprehensive test coverage! The tests are solid and well-structured. I found a few minor things worth addressing:
Medium
Flaky activity timestamp tests — usleep(1) at tests/Server/Socket/ConnectionTest.php lines 187 and 204. 1 microsecond is very short; microtime(true) has microsecond precision, and assertGreaterThan is strict (>). On a fast/loaded CI runner, timestamps may collide and the test fails spuriously. Consider using assertGreaterThanOrEqual or bumping sleep to usleep(10_000).
Low
-
testSetOptionSilentlyReturnsWhenClosed(line 247) — the only assertion (isClosed()) was already true before callingsetOption. The silent-return behavior is implicitly tested (PHPUnit catches uncaught exceptions), but consider adding an explicit assertion thatsetOptiondoesn't throw. -
createConnectedPair(line 31) —socket_connect()return value is not checked. If it fails, downstream tests will fail with confusing errors instead of a clear "connection failed" message. Worth adding$this->assertNotFalse(socket_connect(...)). -
testIsClosedInitiallyFalse(line 119) —$resourceis closed directly via\socket_close($resource)without calling$connection->close(). The Connection object retains a dangling socket reference. Not a crash risk but inconsistent cleanup pattern. -
Untested branches —
getPeerName(failed socket_getpeername) andsetOption(failed socket_set_option) throw paths are not covered. Not a blocker for this PR.
None of these are correctness bugs — the tests validate the right behaviors. The flaky sleep is the only one I'd suggest fixing before merge to avoid CI noise.
…n, consistent cleanup
s2x
left a comment
There was a problem hiding this comment.
Addressed feedback:
- Bumped
usleep(1)→usleep(10_000)in activity timestamp tests (lines 165, 185) - Added
$this->assertNotFalse()forsocket_connect()return value increateConnectedPair - Fixed cleanup in
testIsClosedInitiallyFalse— now uses$connection->close()instead of rawsocket_close
None of these change test behavior — the same 41 tests still pass with 146 assertions.
s2x
left a comment
There was a problem hiding this comment.
Verified the fixes in the second commit (209cfd6):
- ✅
usleep(1)→usleep(10_000)— flaky sleep fixed - ✅
socket_connect()return value checked withassertNotFalse— clear failure messages - ✅
testIsClosedInitiallyFalseuses$connection->close()— consistent cleanup
All 15 tests pass (52 assertions). Remaining low-priority items (setOption assertion, untested throw paths) are not blockers. LGTM.
🔴 Missing test coverage: two throw paths untestedThe 1.
|
| Method | Throw path | Covered? |
|---|---|---|
getPeerName() |
socket is closed → 'Connection is closed' |
✅ testGetPeerNameThrowsWhenClosed |
getPeerName() |
socket_getpeername() fails → 'Failed to get peer name' |
❌ missing |
setOption() |
socket is closed → early return (no throw) | ✅ testSetOptionSilentlyReturnsWhenClosed |
setOption() |
socket_set_option() fails → \RuntimeException |
❌ missing |
These two additional tests would bring ConnectionTest from 88% throw-path coverage (7 of 8 paths) to 100%.
s2x
left a comment
There was a problem hiding this comment.
Verified the third commit — all issues from the review are now addressed:
| # | Issue | Status |
|---|---|---|
| 1 | usleep(1) flaky |
✅ usleep(10_000) (commit 2) |
| 2 | socket_connect() unchecked |
✅ assertNotFalse() (commit 2) |
| 3 | raw socket_close leak |
✅ $connection->close() (commit 2) |
| 4 | weak assertion in testSetOptionSilentlyReturnsWhenClosed |
✅ explicit try/catch + assertNull($exception) (commit 3) — now uses SO_REUSEADDR (valid option) |
| 5 | untested throw paths (getPeerName / setOption) |
⬜ not added, but noted as non-blocker previously |
15 tests, 53 assertions, all green. The testSetOption improvement is clean: it explicitly verifies no exception is thrown by catching \Throwable and asserting null. LGTM for merge.
The two missing throw-path tests can be a follow-up PR if needed — they cover edge cases that are unlikely to regress.
s2x
left a comment
There was a problem hiding this comment.
All review items resolved. Final state:
| # | Issue | Fix |
|---|---|---|
| 1 | usleep(1) flaky |
usleep(10_000) |
| 2 | socket_connect() unchecked |
assertNotFalse() |
| 3 | raw socket_close leak |
$connection->close() |
| 4 | weak assertion in testSetOptionSilentlyReturnsWhenClosed |
try/catch + assertNull($exception) + SO_REUSEADDR |
| 5 | missing throw-path tests | testGetPeerNameThrowsOnFailedSocketCall (SOCK_DGRAM/UDP) + testSetOptionThrowsOnFailedSocketCall (SO_RCVBUF=-1) |
Tests: 17/17, 58 assertions, all green
PHPStan: level 8, no errors
Source: added @ suppression on socket_getpeername / socket_set_option to silence PHP warnings (exceptions are thrown instead)
✅ Ready to merge.
Summary
Adds
ConnectionTestwith comprehensive test coverage for theConnectionclass:Closes #6