diff --git a/.github/workflows/vale-lint-action.yml b/.github/workflows/vale-lint-action.yml index 12e3a841e..994fe8c4b 100644 --- a/.github/workflows/vale-lint-action.yml +++ b/.github/workflows/vale-lint-action.yml @@ -8,9 +8,19 @@ 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 @@ -18,8 +28,11 @@ jobs: 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: diff --git a/vale_styles/config/vocabularies/Base/accept.txt b/vale_styles/config/vocabularies/Base/accept.txt index 41e2ae1bc..9acf69b28 100644 --- a/vale_styles/config/vocabularies/Base/accept.txt +++ b/vale_styles/config/vocabularies/Base/accept.txt @@ -12,6 +12,7 @@ Cmd Cobertura config containerName +classpath custom_functions DBs declaratively @@ -36,6 +37,7 @@ Hoppscotch html HTTPProxy Idempotency +JaCoCo Jacoco JBehave JMeter @@ -71,6 +73,7 @@ Spotify status_code status_code_class status_code_in +subcommand substring templatize Testcase @@ -79,6 +82,7 @@ Testim testmode Testrun testsets +toolchain timeFreezing Traefik Twilio diff --git a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md index 5d4ca44c2..f06c8a185 100644 --- a/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-4.0.0/keploy-cloud/deduplication.md @@ -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 @@ -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'; -## 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 @@ -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 + + io.keploy + keploy-sdk + 2.0.0 + +``` + +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 ` 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 +``` diff --git a/versioned_docs/version-4.0.0/server/sdk-installation/java.md b/versioned_docs/version-4.0.0/server/sdk-installation/java.md index 2cef4465f..7a75d1ce0 100644 --- a/versioned_docs/version-4.0.0/server/sdk-installation/java.md +++ b/versioned_docs/version-4.0.0/server/sdk-installation/java.md @@ -1,142 +1,125 @@ --- id: java -title: Merge Test Coverage Data — Java +title: Java SDK for Dynamic Deduplication sidebar_label: Java -description: "Merge Keploy and Java unit test coverage using JaCoCo — combine integration and unit test reports for full visibility." +description: "Configure the Keploy Java SDK for Enterprise dynamic deduplication with in-process JaCoCo coverage." tags: - java - coverage + - deduplication keywords: - - MongoDB - - Jacoco - - Maven - - Springboot Framework - - Postgres - - SQL - Java - - API Test generator - - Auto Testcase generation - - Junit + - JaCoCo + - Maven + - Spring Boot + - dynamic deduplication --- import ProductTier from '@site/src/components/ProductTier'; - + -## 🛠️ Language Specific Requirements +The Java SDK is used for Enterprise dynamic deduplication during replay/test mode. It collects per-testcase Java coverage and sends it to Keploy Enterprise so duplicate testcases can be identified. -| Programming Language | Prerequisites | -| :------------------: | :------------- | -| java | [Jacoco 0.8.8] | +The Java SDK does not record API traffic or mock dependencies. Record your Keploy tests separately, commit the generated test fixtures when you use them in CI, and run Java dedup during `keploy test --dedup`. -**Note**: In case of java application, before running test subcommand, you need to clean the project by removing any previously generated file, and run install command. +## Requirements -```bash -mvn clean install -Dmaven.test.skip=true +- Java 8, 17, or 21 +- `io.keploy:keploy-sdk` +- JaCoCo Java agent attached to the application JVM +- Keploy Enterprise with dynamic deduplication enabled + +## Add the SDK + +Add the Keploy Java SDK dependency: + +```xml + + io.keploy + keploy-sdk + 2.0.0 + ``` -## Usage +## Start the Dedup Agent -### Update `pom.xml` file +For Spring Boot 2 or other `javax.servlet` applications, import the middleware: -You will need to add the following plugins in `pom.xml` file of your application. :- +```java +import io.keploy.servlet.KeployMiddleware; +import org.springframework.context.annotation.Import; -```xml - - - - - org.jacoco - jacoco-maven-plugin - 0.8.8 - - - - prepare-agent - - prepare-agent - - - - - merge-ut-e2e - test - - merge - - - - - ${project.build.directory} - - jacoco.exec - keploy-e2e.exec - - - - - ${project.build.directory}/ut-e2e-merged.exec - - - - - - post-unit-test - test - - report - - - ${project.build.directory}/jacoco.exec - - ${project.reporting.outputDirectory}/ut - - - - - combined-ut-e2e - test - - report - - - ${project.build.directory}/ut-e2e-merged.exec - - ${project.reporting.outputDirectory}/e2e-ut-aggregate - - - - - - - +@Import(KeployMiddleware.class) +public class Application { +} ``` -Once it has been done, run keploy test command: +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(); ``` -keploy test -c "your_application_command" + +## Run with the JaCoCo Java Agent + +The SDK reads coverage in-process via JaCoCo's runtime API (`org.jacoco.agent.rt.RT.getAgent()`), so attaching the JaCoCo agent is enough: no TCP server flags, no port choice. + +```bash +java -javaagent:/path/to/jacocoagent.jar -jar target/app.jar ``` -After successful execution of this command, A coverage report would be generated inside the test-run folder of keploy/reports. +If your compiled application classes are not under `target/classes` or `build/classes/java/main`, set `KEPLOY_JAVA_CLASS_DIRS`: +```bash +export KEPLOY_JAVA_CLASS_DIRS=/absolute/path/to/target/classes ``` -keploy -├── reports -│ └── test-run-0 -│ ├── coverage.yaml -│ └── test-set-0-report.yaml -└── test-set-0 - ├── mocks.yaml - └── tests - ├── test-1.yaml - └── test-2.yaml + +If the in-process API is unavailable in your environment, the SDK transparently falls back to JaCoCo's TCP server mode. To use the fallback explicitly, launch JaCoCo in `tcpserver` mode and configure `KEPLOY_JACOCO_HOST` / `KEPLOY_JACOCO_PORT` (defaults: `127.0.0.1:36320`): + +```bash +java -javaagent:/path/to/jacocoagent.jar=address=127.0.0.1,port=36320,output=tcpserver \ + -jar target/app.jar ``` -Now, To get the combined report as well as coverage report for your unit tests, Run +## Replay with Dedup + +Run Keploy in test mode with dynamic deduplication enabled: + +```bash +keploy test \ + -c "java -javaagent:/path/to/jacocoagent.jar -jar target/app.jar" \ + --dedup \ + --language java +``` + +If you are using the JaCoCo TCP fallback, also pass `--pass-through-ports ` so Keploy does not try to mock the coverage-control connection. + +After replay, run: + +```bash +keploy dedup +``` + +To apply the dynamic deduplication cleanup: ```bash -mvn test +keploy dedup --rm ``` -The html file for unit tests report would be generated in target/site/ut directory and, for combined report it would be generated in target/site/e2e-ut-aggregate directory. Open index.html to visualize the report. +## Docker and Restricted Docker + +Java dedup uses two Unix sockets shared between Keploy Enterprise and the Java process: + +- `/tmp/coverage_control.sock` +- `/tmp/coverage_data.sock` + +For Docker or Docker Compose runs, Keploy injects a shared `keploy-sockets-vol:/tmp` mount into the application container and the Keploy agent container so both processes use the same socket paths. Do not add a conflicting `/tmp` bind mount or `tmpfs`; keep `/tmp` writable even when the root filesystem is read-only. + +For restricted containers, the application can run as a non-root user with dropped capabilities and `no-new-privileges` as long as the injected `/tmp` volume is shared and writable. If the SDK falls back to JaCoCo TCP mode, the JaCoCo TCP port must also be reachable from the Java process. + +## CI Guidance + +CI should run replay/test mode against checked-in Keploy test fixtures. Do not record Java dedup fixtures in the pipeline unless you intentionally want to refresh them.