refactor: extract duplicated mock-loading logic from RunTestSet in replay.go (~2,168-line function) · Issue #4560 · keploy/keploy · GitHub
Skip to content

refactor: extract duplicated mock-loading logic from RunTestSet in replay.go (~2,168-line function) #4560

Description

@Prateek-og

Description

pkg/service/replay/replay.go is currently the largest file in the codebase at 4,621 lines / 188 KB, containing 75 functions. The most critical hotspot is RunTestSet() — a single function spanning 2,168 lines (lines 1001–3169).

Within RunTestSet, the Docker Compose branch (lines ~1184–1401) and the non-Docker Compose branch (lines ~1403–1570) contain nearly identical blocks of ~150 lines performing the same mock-loading pipeline:

  1. Call determineMockingStrategy()
  2. Build mocksThatHaveMappings / mocksWeNeed maps
  3. Call GetMocks() with time-range filtering
  4. Call addKinds() on filtered + unfiltered mocks
  5. Extract telemetry domains from mocks
  6. Call MockMutator.AfterGetMocks() + rebalanceReusableMocks()
  7. Call StoreMocks() on the instrumentation
  8. Build OutgoingOptions struct and call MockOutgoing()
  9. Call SendMockFilterParamsToAgent()
  10. Handle FallBackOnMiss deprecation notice

This duplication means that every bug fix or feature change to mock loading must be applied in two places, and the two branches have already begun to drift subtly (e.g., InitSortCounter only in the non-compose branch, MakeAgentReadyForDockerCompose only in the compose branch).

Evidence of Duplication

The Docker Compose branch (starting ~line 1297) and the non-Docker-Compose branch (starting ~line 1405) both execute this identical sequence:

go useMappingBased, expectedTestMockMappings = r.determineMockingStrategy(ctx, testSetID, isMappingEnabled) mocksThatHaveMappings := make(map[string]bool) mocksWeNeed := make(map[string]bool) if isMappingEnabled && len(expectedTestMockMappings) > 0 { for _, mocks := range expectedTestMockMappings { for _, m := range mocks { mocksThatHaveMappings[m.Name] = true } } // ... selectedTests filtering ... } filteredMocks, unfilteredMocks, err := r.GetMocks(ctx, testSetID, ...) addKinds(filteredMocks); addKinds(unfilteredMocks) // ... telemetry extraction ... err = r.instrumentation.StoreMocks(ctx, filteredMocks, unfilteredMocks) err = r.instrumentation.MockOutgoing(runTestSetCtx, models.OutgoingOptions{...}) err = r.SendMockFilterParamsToAgent(ctx, ...)

Broader Context — File Size

The top 5 largest .go files in the codebase:

File Lines Size
pkg/service/replay/replay.go 4,621 188 KB
pkg/agent/proxy/proxy.go 4,159 183 KB
pkg/util.go 4,050 141 KB
pkg/models/postgres_v3_cell.go 3,181 115 KB
pkg/agent/proxy/integrations/mysql/replayer/match.go 2,776 112 KB

This issue focuses on replay.go as the most impactful starting point because RunTestSet is the central function in the test-replay critical path and its duplication is the most dangerous kind — it's not just dead code, it's actively maintained logic that can (and has started to) drift.

Proposed Refactoring

  1. Extract prepareMocksForTestSet() — A new method on *Replayer that encapsulates steps 1–10 above. Both branches call it with their branch-specific parameters (e.g., compose-only calls like MakeAgentReadyForDockerCompose happen outside this function).

  2. Extract setupAppLifecycleMonitor() — The app-launch + error-channel goroutine pair (lines 1186–1223 and 1516–1570) is also duplicated; it can be unified with a boolean flag for compose-specific behavior.

  3. Consider splitting RunTestSet further into phases: setup -> mock-loading -> test-loop -> reporting -> pruning. Each phase is already implicitly separated by comments but lives in one monolithic function.

Impact

  • Reduced maintenance burden: Bug fixes to mock loading apply once, not twice
  • Drift prevention: Eliminates a class of bugs where one branch gets a fix and the other doesn't
  • Reviewability: A 2,168-line function is extremely hard to review in PRs
  • Testability: Extracted functions can be unit-tested independently (the project already does this for buildExpectedMockInfos, buildActualMockInfos, etc.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions