You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 8f92303
Browse filesBrowse the repository at this point in the historyBrowse files
fix(dedup): bind the control socket before the app starts (#189)
* fix(dedup): bind the control socket before the app starts
The agent bound /tmp/coverage_control.sock on its background thread, and
nothing ordered that bind before the app's first answer to a health check.
Keploy fires tests as soon as the app answers, so when the bind came late
the first tests' START and END reached no one and their coverage was lost:
a run reported 153 of 200 tests covered. The END that met the socket just
after it came up logged "Ignoring mismatched END command".
start() now binds on the calling thread, which is premain for -javaagent,
before the app's main runs, and hands the bound socket to the accept
thread. A bind failure still leaves the app running without dedup: start()
logs it and returns false, and nothing escapes premain.
An END with no START for that test publishes nothing, yet was answered
ACK, so Keploy took it as delivered and waited for a record that never
came. The unix control socket now answers IGNORED. A Keploy that does not
know the reply reads any answer as taken, as it did before.
* test(dedup): check the control socket is up when main runs, in CI
The smoke harness waited for the control socket file before its first
command. That wait is the race Keploy loses: it fires tests as soon as the
app answers, with no such wait, so the smoke could not see a late bind.
START is now main's first act and nothing waits for the socket, so an agent
that binds it after premain fails the smoke with the jar that ships. The
smoke fails this way on JDK 8, 17 and 21 with the bind put back on the
accept thread.
The verify job built with -DskipTests, so the module's unit tests ran in no
pipeline. It now runs them on each JDK.
* fix(dedup): name a test whose END was ignored on the TCP transport
On the TCP transport an END with no START for it was answered with a bare
ACK and no COV, so the collector could not tell the test had gone unmeasured.
Only the app's own log said so, in a pod the collector never reads. The unix
socket already answers IGNORED for the same END.
The SDK now sends "IGNORED <id>" ahead of the ACK. The ACK stays because it
is what ends the collector's wait: a collector that does not know the frame
skips it and goes on as before, where IGNORED in place of ACK would have cost
it a full ACK timeout on each such test.
* test(dedup): check the app runs when the native library cannot load
The agent binds its control socket in premain, so junixsocket's native
library now loads there, before the app's main. Whatever that throws,
premain must not stop the app: start() catches Throwable and runs the
app without dedup. Nothing tested that guard; narrowed to IOException,
it passed the unit tests and the smoke while a JVM that cannot load the
library aborted before main.
The smoke now runs an app with junixsocket's override properties
pointing at a library that does not exist, and checks that main ran and
that the agent said the control socket is unavailable, so the case
cannot pass with the library loaded.
* test(dedup): assert the IGNORED reply word that Keploy reads
Keploy's agent reads an answer starting "IGNORED", and k8s-proxy's
collector a frame starting "IGNORED ", as a command the SDK did not
take. The rows compared the reply with the SDK's own constant, so a
change to the word passed them while both readers would take every
ignored END as taken. They now compare it with the literal.
Signed-off-by: slayerjain <shubhamkjain@outlook.com>
Coverage is collected at per-testcase granularity, not process granularity.
27
27
28
+
The agent binds `/tmp/coverage_control.sock` before the application's `main` runs, so the socket is listening before the application can answer a health check. It answers `ACK` to each command it took, and `IGNORED` to an `END` that no `START` for that testcase came before: nothing is published for it, and Enterprise keeps that testcase out of the comparison. On the TCP transport used in Kubernetes the same `END` is answered with `IGNORED <testcase>` and then `ACK`.
0 commit comments