Skip to content

feat(keploytest): a test binary keploy's Go launcher started joins on the launcher's claim - #207

Merged
slayerjain merged 1 commit into
mainfrom
feat/keploytest-inherited-claim
Oct 13, 2026
Merged

slayerjain merged 1 commit into
mainfrom
feat/keploytest-inherited-claim

Conversation

@slayerjain

Copy link
Copy Markdown
Member

keploy's T2 release 1 (release1-cut §1.3, row 9s-L): keploy mock record and keploy mock replay run each go test binary through keploy's Go launcher, keploy-go-exec (-exec in GOFLAGS). The launcher freezes the binary's clock (a patched copy), refuses the go test keploy cannot judge (-p above 1, no -v/-json, -shuffle, -fuzz), sets -test.parallel, and claims keploy's run for the binary before it starts, so a dependency call that an init or TestMain makes lands in the binary's own key. That includes the init of a package Go initializes before keploytest's.

keploytest (#206) claims in its own init. This PR makes that claim a fallback, used only when no claim was inherited.

What changes

  • The inherited claim. The launcher sets KEPLOY_TEST_CLAIMED, a new variable, to its own pid, and exec keeps that pid. A binary whose pid it names claims nothing, refuses nothing, and makes its checks at the first test as before. keploytest also sets it after its own claim succeeds. A binary that execs itself again (same pid) therefore keeps its claim, while one refused the run claims again and is refused again.
  • KEPLOY_TEST_PID is set before the claim, as in feat(keploytest): join go test to keploy's Universal Mocker (release 1, one test process) #206. The processes a binary starts are members of its run (inert) whether its claim was taken or refused.
  • -test.parallel is set on both paths. The launcher passes its own value on the command line, which the flag parse applies afterwards. An exec'd image has only this one.
  • A frozen clock without the launcher is refused, and keploy's agent is told (clock_not_frozen, POST /agent/refusal), so keploy's verdict names it.
    • It applies when the claim answer carries a timeFile: keploy froze the run, and only the launcher can freeze a test binary. The tests would otherwise run on the real clock against recordings made on another.
    • The text names the fix: let go test start the binary (a go test -exec, or a GOFLAGS set by the test command itself, replaces keploy's), or start it in its package directory as keploy-go-exec <test binary> -test.v.
    • feat(keploytest): join go test to keploy's Universal Mocker (release 1, one test process) #206 refused the same case with "upgrade go-sdk", and did not tell the agent.

Without the launcher (switch off, and every user today)

There are only two differences from #206:

  • the clock refusal's text, and that the refusal is now told to the agent;
  • after a successful claim, an image that the binary execs in place does not claim again. With keploy's agent, the old re-claim from the same pid with no test open was accepted and changed nothing.

Tests

  • TestALauncherStartedBinaryJoinsOnItsClaim is end to end. sh sets both markers to its own pid and execs this package's test binary, as the launcher does. The fake agent's claim answer carries a timeFile, which would be refused if claimed. Checks: no claim is made; T and TP tests begin and end; -test.parallel=1048576.
  • TestABinaryThatExecsItselfAgainKeepsItsClaim: TestMain execs the binary in place. A claimed binary keeps one claim and its -test.parallel; a refused one claims twice and fails with the agent's words.
  • TestTheMarkersOfAClaimedAndOfARefusedBinary: KEPLOY_TEST_PID is set either way, and KEPLOY_TEST_CLAIMED only on a claim the agent took. A frozen-clock claim is refused and told to the agent with code clock_not_frozen.
  • TestAnInheritedClaimIsNotMadeAgain: no agent call, even under go test -p 2 with a frozen run.
  • Every new test fails when its fix is reverted (mutants). go test -race ./... passes, and go vet is clean on linux, windows, darwin and plan9.

The enterprise launcher sets both markers (keploy/enterprise 9s-L PR, which pins this change). Lane 2's Go suite (mock-local-loop-go-e2e) runs on it, including an init() that Go runs before keploytest's and a TestMain call, both recorded under their own package's key.

… the launcher's claim

keploy mock record and replay run each go test binary through keploy's Go
launcher (keploy-go-exec, -exec in GOFLAGS), which claims keploy's run for
the binary before it starts, so the calls an init or TestMain makes land in
the binary's key, and freezes its clock. keploytest's own claim, in its
init, becomes the fallback for a binary started without it.

- KEPLOY_TEST_CLAIMED names the pid keploy's agent took the claim from:
  the launcher sets it to its own pid, which exec keeps, and keploytest
  after its own claim. A binary whose pid it names claims nothing more,
  so an image that a claimed binary execs in place keeps the claim, and a
  refused binary's claims again and is refused again.
- KEPLOY_TEST_PID is set before the claim, as before: the processes a
  binary starts are its members whether its claim was taken or refused.
- -test.parallel is set on both paths.
- A claim answered with a frozen clock (timeFile), which only the launcher
  can apply, is refused as clock_not_frozen with the fix, and the refusal
  is told to keploy's agent, so keploy's verdict names it.

Signed-off-by: slayerjain <shubhamkjain@outlook.com>
@slayerjain
slayerjain marked this pull request as ready for review October 13, 2026 23:55
@slayerjain
slayerjain merged commit bed3c7d into main Oct 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant