Skip to content

Commit d7d3db8

Browse files
authored
fix(dedup): answer every command on the control socket, say proto=2 (#190)
* fix(dedup): answer every command on the control socket, say proto=2 The unix control socket answered ACK even when a START's counter reset failed or an END's coverage was never sent, and closed with no answer on a blank line or a command it could not parse. Keploy read each of those as taken. A command that threw (a JaCoCo port out of range) ended the accept loop, so every later test's command was refused. Every command the SDK reads now gets one line before the close: "ACK proto=2" when it was taken, "IGNORED proto=2" when not. A START whose reset failed is ignored and so is its END; an END whose coverage could not be collected or sent is ignored and still ends the test. A command that throws is ignored and the server goes on. Only a connection closed with nothing sent gets no answer. proto=2 says this SDK answers every command it reads, so Keploy can read a close with no answer as a command not taken: on macOS a connection closed with its command unread gives the reader a plain close, not an error. Agents that read only an IGNORED prefix, or no answer at all, read "ACK proto=2" as ACK. The TCP transport is unchanged. The data socket path is a field, as the control socket's is, so the rows can bind their own. The smoke test now requires the exact answer. * fix(dedup): close the control socket on its own thread; IGNORED on TCP stop() closed the unix control socket from the caller's thread and returned at once, with the accept thread still running. junixsocket's accept holds the socket's raw fd number, and when it finds the socket file gone it closes that number. With start() right after stop(), that number could already be the new server's socket, which was then closed with its file still there: every later command was refused. The old thread also deleted the socket file by path once it ended, so a start() on the same path, as the default /tmp/coverage_control.sock always is, lost its file, and every later command found no socket. Once junixsocket had closed the socket under it, the accept loop went on: it spun a core, logged without end, and isStarted() still said true. Now only the accept thread closes its socket. stop() wakes that accept with a connection of its own and waits up to 5 s for the thread to end, so a command in flight is answered first; a start() after it waits for that thread too. A socket closed under the server (its file deleted, or bound again by another process) is said once and ends the server. On the TCP transport, a START whose counter reset failed was answered ACK, and its END sent the lines of the tests before it as this test's. It is now answered "IGNORED <id>" and then ACK, as an END not taken is, and its END is ignored too. A START whose reset threw (a JaCoCo port out of range) ended the TCP thread, so no later command was answered; it is now ignored and the connection goes on. * fix(dedup): leave another server's socket file; IGNORED on a failed dump junixsocket's delete on close deletes the socket file by path. When another server had bound the control socket's path since (the file deleted and bound again), stop() deleted that server's file. The SDK now turns it off and deletes the file once its socket is closed, only while the file is still the one it bound (the same device and inode). On the TCP transport, an END whose JaCoCo dump failed sent an empty COV, the frame of a test that ran no line of the app, so the collector could not tell the two apart. It is now answered "IGNORED <id>" and then ACK, as on the unix socket, and it ends the test. stop() waits for the worker's thread through one interface for both transports. When its wait is over with the thread still running, it closes the socket, says so at WARNING and returns, where it waited a second time before: a start() waits for that thread in turn. bind() closes the socket it opened when it fails, so close() is only ever called on a listening socket: it wakes the accept, and closes the socket from the caller's thread only when the wake-up cannot connect. The tests shorten the waits. New rows: stop() during a command leaves the socket open to its own thread; stop() after another server took the path ends the thread and leaves that server's file; stop() after the socket file was deleted ends at once; start() while the stopped worker still runs a command refuses, and binds once that worker has ended; a TCP END whose dump failed. The deleted-file row now also checks that it is said once. Signed-off-by: slayerjain <shubhamkjain@outlook.com>
1 parent 8f92303 commit d7d3db8

5 files changed

Lines changed: 909 additions & 99 deletions

File tree

0 commit comments

Comments
 (0)