Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
10d2c25
docs: document Java dynamic dedup
officialasishkumar Apr 23, 2026
2270f56
ci: scope Vale lint to changed docs
officialasishkumar Apr 23, 2026
37e96d4
docs: mention JaCoCo pass-through for Java dedup
officialasishkumar Apr 23, 2026
a0d8a21
docs: document Java dedup Docker hardening
officialasishkumar Apr 23, 2026
b89b674
docs: clarify Java dedup Docker socket volume
officialasishkumar Apr 23, 2026
e6feee6
docs: clarify Java dedup Docker bind mount
officialasishkumar Apr 23, 2026
5cdd500
docs: document Java dedup-only SDK
officialasishkumar Apr 24, 2026
0fb64ae
docs: fix Java dedup wording
officialasishkumar Apr 24, 2026
4d01541
docs: avoid Vale Servlet warning
officialasishkumar Apr 24, 2026
3579d9d
docs(java-dedup): drop JaCoCo TCP server requirement
officialasishkumar Apr 25, 2026
78b3fec
docs(java): pin keploy-sdk dependency version to 2.0.0
officialasishkumar Apr 26, 2026
95f52bc
docs(java-dedup): scope Java dynamic dedup changes to v4 only
officialasishkumar Apr 26, 2026
d07ff8d
docs(dedup): improve v4 dedup page navigation and reorder Golang first
officialasishkumar Apr 26, 2026
385b564
docs(dedup): match existing dedup page heading pattern
officialasishkumar Apr 26, 2026
82631ce
docs(dedup): expose step headings in v4 dedup TOC
officialasishkumar Apr 26, 2026
ce3d82a
fix: align java dedup docs with runtime behavior
officialasishkumar Apr 27, 2026
900b4ab
docs: rename dedup page to dynamic deduplication
officialasishkumar Apr 27, 2026
88662c0
docs: refine Java dynamic dedup guide
officialasishkumar Apr 27, 2026
1353de9
Merge remote-tracking branch 'origin/main' into codex/java-dynamic-de…
officialasishkumar Apr 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .github/workflows/vale-lint-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,31 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
with:
fetch-depth: 0

- name: Collect changed docs
id: changed-docs
shell: bash
run: |
files=$(git diff --name-only --diff-filter=ACMRT "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}" -- 'versioned_docs/**/*.md' | paste -sd, -)
echo "files=${files}" >> "$GITHUB_OUTPUT"

# Set up Vale Action — only lint changed lines to avoid flagging pre-existing issues.
- uses: errata-ai/vale-action@v2.1.1
if: steps.changed-docs.outputs.files != ''
with:
# Only check lines added/modified in the PR diff.
filter_mode: diff_context
# Set the reporter to display the output
reporter: github-pr-check
# Fails the action if there are errors
fail_on_error: true
# Lint docs across all versioned directories
files: 'versioned_docs'
# Lint only changed versioned docs. The action fails on all Vale output
# before reviewdog filters annotations, so a broad directory here makes
# pre-existing docs issues fail unrelated PRs.
files: ${{ steps.changed-docs.outputs.files }}
separator: ','
# Specify the Vale version
version: 3.0.3
env:
Expand Down
4 changes: 4 additions & 0 deletions vale_styles/config/vocabularies/Base/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Cmd
Cobertura
config
containerName
classpath
custom_functions
DBs
declaratively
Expand All @@ -36,6 +37,7 @@ Hoppscotch
html
HTTPProxy
Idempotency
JaCoCo
Jacoco
JBehave
JMeter
Expand Down Expand Up @@ -71,6 +73,7 @@ Spotify
status_code
status_code_class
status_code_in
subcommand
substring
templatize
Testcase
Expand All @@ -79,6 +82,7 @@ Testim
testmode
Testrun
testsets
toolchain
timeFreezing
Traefik
Twilio
Expand Down
132 changes: 126 additions & 6 deletions versioned_docs/version-4.0.0/keploy-cloud/deduplication.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
id: deduplication
title: Remove Duplicates Tests
sidebar_label: Remove Duplicate Tests
description: "Remove duplicate test cases with Keploy Enterprise deduplication — save time and resources by eliminating redundant tests."
title: Dynamic Deduplication
sidebar_label: Dynamic Deduplication
description: "Use Keploy Enterprise dynamic deduplication to identify redundant test cases and save time and resources."
tags:
- explanation
- feature guide
Expand All @@ -14,21 +14,23 @@ keywords:
- duplicate tests
- golang
- testcases
toc_min_heading_level: 2
toc_max_heading_level: 4
---

import ProductTier from '@site/src/components/ProductTier';

<ProductTier tiers="Enterprise" offerings="Self-Hosted, Dedicated" />

## Why Deduplication? ❄️
## Why Dynamic Deduplication? ❄️

When developing or maintaining a software, it is common for test suites to grow in size. This often results in redundancy, as many test cases cover the same functions or scenarios. This is where Test Deduplication comes into play.

It simplifies the testing process by removing redundant test cases, which saves time and resources while keeping the testcases which adds value to the overall coverage of the application.
It simplifies the testing process by identifying redundant test cases, which saves time and resources while keeping the testcases that add value to the overall coverage of the application.

## Usage 🛠️

To detect duplicate tests, simply run the below command, like so:
To collect coverage for dynamic deduplication, run:

```bash
keploy test -c "docker compose up" --containerName containerName --dedup
Expand Down Expand Up @@ -114,3 +116,121 @@ In order to remove all the duplicate test cases, run the following command:
```bash
keploy dedup --rm
```

### For Java Applications

#### 1. Pre-requisite

Add the Keploy Java SDK to your application:

```xml
<dependency>
<groupId>io.keploy</groupId>
<artifactId>keploy-sdk</artifactId>
<version>2.0.0</version>
</dependency>
```

For Spring Boot 2 or other `javax.servlet` applications, register the Keploy middleware in your main class:

```java
import io.keploy.servlet.KeployMiddleware;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import(KeployMiddleware.class)
public class App {
}
```

For Spring Boot 3, Jakarta EE applications, other frameworks, or custom launchers, start the agent during application startup:

```java
import io.keploy.dedup.KeployDedupAgent;

KeployDedupAgent.start();
```

Java dynamic deduplication uses JaCoCo runtime coverage. The SDK reads coverage in-process via JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent()`), so attaching the JaCoCo Java agent is enough: no TCP server flags, no `--pass-through-ports`.

```bash
java -javaagent:/path/to/org.jacoco.agent-runtime.jar -jar target/app.jar
```

If the in-process API is unavailable for some reason (for example, an isolated class loader), the SDK transparently falls back to JaCoCo's TCP server mode. To force the fallback, launch JaCoCo in `tcpserver` mode and tell Keploy to leave that port alone:

```bash
java -javaagent:/path/to/org.jacoco.agent-runtime.jar=address=127.0.0.1,port=36320,output=tcpserver \
-jar target/app.jar
```

The default JaCoCo endpoint for the fallback is `127.0.0.1:36320`. You can override it with `KEPLOY_JACOCO_HOST` and `KEPLOY_JACOCO_PORT`, or with the JVM properties `keploy.jacoco.host` and `keploy.jacoco.port`. When using the fallback, add the JaCoCo port to `--pass-through-ports` so coverage-control traffic is not mocked.

#### 2. Build Configuration

Build the application before running Keploy so the Java class files are available for coverage analysis:

```bash
mvn clean package -DskipTests
```

By default, the SDK scans `target/classes`, `build/classes/java/main`, and runtime classpath jars. For custom layouts or restricted Docker images, set `KEPLOY_JAVA_CLASS_DIRS` to the class directories or jars that should be analyzed.

#### 3. Dockerfile Configuration (Important for Docker Users)

When you use Docker or Docker Compose, make sure the final runtime image contains:

- the runnable application jar,
- the JaCoCo runtime agent jar,
- the compiled classes or the fat jar that contains the application classes.

For example:

```dockerfile
COPY target/app.jar /app/app.jar
COPY target/classes /app/target/classes
COPY jacocoagent.jar /app/jacocoagent.jar
```

Then run the app with the JaCoCo agent attached:

```bash
java -javaagent:/app/jacocoagent.jar -jar /app/app.jar
```

Keploy and the Java SDK exchange per-test coverage signals over `/tmp/coverage_control.sock` and `/tmp/coverage_data.sock`. For Docker and Docker Compose, Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container so both processes see the same socket paths.

For hardened Docker runs, the Java dedup sample is validated with a non-root runtime user, a read-only root filesystem, dropped Linux capabilities, `no-new-privileges`, and Keploy's shared `/tmp` named volume for the Keploy control/data sockets and JaCoCo output. Do not add a conflicting `/tmp` bind mount or `tmpfs`; Keploy requires the injected shared `/tmp` volume to reach the Java SDK control socket.

#### 4. Run Deduplication

For Docker, run:

```bash
keploy test -c "docker compose up" --container-name containerName --dedup --language java
```

For Native, run:

```bash
keploy test -c "java -javaagent:/path/to/org.jacoco.agent-runtime.jar -jar target/app.jar" --dedup --language java
```

If the SDK falls back to the JaCoCo TCP server, also pass `--pass-through-ports <jacoco-port>` so Keploy does not try to mock the coverage-control connection.

This will generate a `dedupData.yaml` file.

After this, run:

```bash
keploy dedup
```

This command will create a `duplicates.yaml` file containing the test cases that dynamic deduplication marked as redundant.

To apply the dynamic deduplication cleanup to the local Keploy test set, run:

```bash
keploy dedup --rm
```
Loading
Loading