diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2222a4d..1ecfb1f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -43,33 +43,32 @@ jobs:
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- - name: Compile project
- run: mvn clean compile test-compile
-
- name: Run unit tests
- run: mvn test -Dtest=RedlockConfigurationTest
-
+ run: mvn test
+
- name: Run integration tests with Testcontainers
- run: mvn test -Dtest=RedlockIntegrationTest
+ run: mvn verify -Dmaven.test.skip.exec=false
env:
# Ensure Docker is available for Testcontainers
TESTCONTAINERS_RYUK_DISABLED: false
-
- - name: Run all tests (including performance tests on nightly)
+
+ - name: Run performance tests (on nightly schedule only)
if: github.event_name == 'schedule'
- run: mvn test -Dtest=RedlockPerformanceTest
+ run: mvn test -Dgroups=performance
env:
TESTCONTAINERS_RYUK_DISABLED: false
-
+
- name: Generate test report
uses: dorny/test-reporter@v1
if: (success() || failure()) && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
with:
name: Maven Tests (ubuntu-latest, Java ${{ matrix.java }})
- path: target/surefire-reports/*.xml
+ path: |
+ target/surefire-reports/*.xml
+ target/failsafe-reports/*.xml
reporter: java-junit
fail-on-error: true
-
+
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
@@ -77,6 +76,7 @@ jobs:
name: test-results-ubuntu-latest-java${{ matrix.java }}
path: |
target/surefire-reports/
+ target/failsafe-reports/
target/site/jacoco/
retention-days: 30
@@ -104,7 +104,7 @@ jobs:
restore-keys: ${{ runner.os }}-m2
- name: Run tests with coverage
- run: mvn clean test jacoco:report
+ run: mvn clean verify jacoco:report
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index f0c4658..7b2455f 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -36,53 +36,20 @@ jobs:
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- - name: Clean and compile
- run: mvn clean compile test-compile
-
- - name: Run all unit tests
- run: mvn test -Dtest=RedlockConfigurationTest
-
- - name: Run all integration tests
- run: mvn test -Dtest=RedlockIntegrationTest
+ - name: Run unit tests
+ run: mvn test
+
+ - name: Run integration tests
+ run: mvn verify -Dmaven.test.skip.exec=false
env:
TESTCONTAINERS_RYUK_DISABLED: false
-
+
- name: Run performance tests
if: github.event.inputs.run_performance_tests == 'true' || github.event_name == 'schedule'
- run: |
- # Enable performance tests by removing @Disabled annotation temporarily
- sed -i 's/@Disabled("Performance tests - enable manually when needed")/\/\/@Disabled("Performance tests - enable manually when needed")/g' src/test/java/org/codarama/redlock4j/performance/RedlockPerformanceTest.java
- mvn test -Dtest=RedlockPerformanceTest
+ run: mvn test -Dgroups=performance
env:
TESTCONTAINERS_RYUK_DISABLED: false
- - name: Run stress tests
- run: |
- echo "## Stress Test Results" >> $GITHUB_STEP_SUMMARY
- echo "Running extended stress tests..." >> $GITHUB_STEP_SUMMARY
-
- # Create a simple stress test
- cat > stress-test.java << 'EOF'
- import org.codarama.redlock4j.*;
- import java.util.concurrent.*;
- import java.util.concurrent.locks.Lock;
-
- public class StressTest {
- public static void main(String[] args) throws Exception {
- RedlockConfiguration config = RedlockConfiguration.builder()
- .addRedisNode("localhost", 6379)
- .addRedisNode("localhost", 6380)
- .addRedisNode("localhost", 6381)
- .defaultLockTimeout(5, TimeUnit.SECONDS)
- .build();
-
- System.out.println("Stress test completed successfully");
- }
- }
- EOF
-
- echo "Stress test configuration validated" >> $GITHUB_STEP_SUMMARY
-
- name: Generate comprehensive test report
run: |
echo "## Nightly Test Summary" >> $GITHUB_STEP_SUMMARY
@@ -91,10 +58,10 @@ jobs:
echo "- **Java Version:** $(java -version 2>&1 | head -n 1)" >> $GITHUB_STEP_SUMMARY
# Count test results
- if [ -d "target/surefire-reports" ]; then
- TOTAL_TESTS=$(find target/surefire-reports -name "*.xml" -exec grep -h "tests=" {} \; | sed 's/.*tests="\([0-9]*\)".*/\1/' | awk '{sum+=$1} END {print sum}')
- FAILED_TESTS=$(find target/surefire-reports -name "*.xml" -exec grep -h "failures=" {} \; | sed 's/.*failures="\([0-9]*\)".*/\1/' | awk '{sum+=$1} END {print sum}')
- ERROR_TESTS=$(find target/surefire-reports -name "*.xml" -exec grep -h "errors=" {} \; | sed 's/.*errors="\([0-9]*\)".*/\1/' | awk '{sum+=$1} END {print sum}')
+ if [ -d "target/surefire-reports" ] || [ -d "target/failsafe-reports" ]; then
+ TOTAL_TESTS=$(find target/surefire-reports target/failsafe-reports -name "*.xml" 2>/dev/null -exec grep -h "tests=" {} \; | sed 's/.*tests="\([0-9]*\)".*/\1/' | awk '{sum+=$1} END {print sum}')
+ FAILED_TESTS=$(find target/surefire-reports target/failsafe-reports -name "*.xml" 2>/dev/null -exec grep -h "failures=" {} \; | sed 's/.*failures="\([0-9]*\)".*/\1/' | awk '{sum+=$1} END {print sum}')
+ ERROR_TESTS=$(find target/surefire-reports target/failsafe-reports -name "*.xml" 2>/dev/null -exec grep -h "errors=" {} \; | sed 's/.*errors="\([0-9]*\)".*/\1/' | awk '{sum+=$1} END {print sum}')
echo "- **Total Tests:** ${TOTAL_TESTS:-0}" >> $GITHUB_STEP_SUMMARY
echo "- **Failed Tests:** ${FAILED_TESTS:-0}" >> $GITHUB_STEP_SUMMARY
@@ -114,6 +81,7 @@ jobs:
name: nightly-test-results-${{ github.run_number }}
path: |
target/surefire-reports/
+ target/failsafe-reports/
target/site/
retention-days: 7
@@ -149,7 +117,7 @@ jobs:
sed -i 's/redis:7-alpine/redis:${{ matrix.redis-version }}/g' src/test/java/org/codarama/redlock4j/performance/RedlockPerformanceTest.java
- name: Run integration tests with Redis ${{ matrix.redis-version }}
- run: mvn test -Dtest=RedlockIntegrationTest
+ run: mvn verify -Dmaven.test.skip.exec=false
env:
TESTCONTAINERS_RYUK_DISABLED: false
@@ -160,70 +128,4 @@ jobs:
echo "Tests passed with Redis ${{ matrix.redis-version }}" >> $GITHUB_STEP_SUMMARY
else
echo "Tests failed with Redis ${{ matrix.redis-version }}" >> $GITHUB_STEP_SUMMARY
- fi
-
- notification:
- name: Send Notifications
- runs-on: ubuntu-latest
- needs: [comprehensive-test, multi-redis-version-test]
- if: always()
-
- steps:
- - name: Determine overall status
- id: status
- run: |
- if [[ "${{ needs.comprehensive-test.result }}" == "success" && "${{ needs.multi-redis-version-test.result }}" == "success" ]]; then
- echo "status=success" >> $GITHUB_OUTPUT
- echo "message=All nightly tests passed successfully" >> $GITHUB_OUTPUT
- else
- echo "status=failure" >> $GITHUB_OUTPUT
- echo "message=Some nightly tests failed" >> $GITHUB_OUTPUT
- fi
-
- - name: Create issue on failure
- if: steps.status.outputs.status == 'failure'
- uses: actions/github-script@v7
- with:
- script: |
- const title = `Nightly Tests Failed - ${new Date().toISOString().split('T')[0]}`;
- const body = `
- ## Nightly Test Failure Report
-
- **Date:** ${new Date().toISOString()}
- **Workflow:** ${{ github.workflow }}
- **Run ID:** ${{ github.run_id }}
- **Commit:** ${{ github.sha }}
-
- ### Failed Jobs:
- - Comprehensive Test: ${{ needs.comprehensive-test.result }}
- - Multi Redis Version Test: ${{ needs.multi-redis-version-test.result }}
-
- ### Action Required:
- Please investigate the test failures and fix any issues.
-
- **Workflow URL:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- `;
-
- // Check if issue already exists
- const issues = await github.rest.issues.listForRepo({
- owner: context.repo.owner,
- repo: context.repo.repo,
- labels: ['nightly-test-failure'],
- state: 'open'
- });
-
- if (issues.data.length === 0) {
- await github.rest.issues.create({
- owner: context.repo.owner,
- repo: context.repo.repo,
- title: title,
- body: body,
- labels: ['nightly-test-failure', 'bug']
- });
- }
-
- - name: Summary
- run: |
- echo "## Nightly Test Summary" >> $GITHUB_STEP_SUMMARY
- echo "${{ steps.status.outputs.message }}" >> $GITHUB_STEP_SUMMARY
- echo "**Workflow completed at:** $(date)" >> $GITHUB_STEP_SUMMARY
+ fi
\ No newline at end of file
diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml
index d5a9ad0..ada9a5a 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -11,127 +11,6 @@ permissions:
pull-requests: write
jobs:
- validate-pr:
- name: Validate Pull Request
- runs-on: ubuntu-latest
- if: github.event.pull_request.draft == false
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Fetch full history for better analysis
-
- - name: Set up JDK 11
- uses: actions/setup-java@v4
- with:
- java-version: 11
- distribution: 'temurin'
-
- - name: Cache Maven dependencies
- uses: actions/cache@v4
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
-
- - name: Validate Maven POM
- run: mvn validate
-
- - name: Compile project
- run: mvn clean compile test-compile
-
- - name: Run unit tests
- run: mvn test -Dtest=RedlockConfigurationTest
-
- - name: Run integration tests
- run: mvn test -Dtest=RedlockIntegrationTest
- env:
- TESTCONTAINERS_RYUK_DISABLED: false
-
- - name: Generate test coverage
- run: mvn jacoco:report
-
- - name: Check code coverage
- run: |
- COVERAGE=$(mvn jacoco:report | grep -o 'Total.*[0-9]*%' | tail -1 | grep -o '[0-9]*%' || echo "0%")
- echo "Code coverage: $COVERAGE"
- echo "## PR Validation Results" >> $GITHUB_STEP_SUMMARY
- echo "- **Code Coverage:** $COVERAGE" >> $GITHUB_STEP_SUMMARY
- echo "- **Build Status:** Passed" >> $GITHUB_STEP_SUMMARY
-
- - name: Comment PR with results
- uses: actions/github-script@v7
- if: always() && github.event.pull_request.head.repo.full_name == github.repository
- with:
- script: |
- const fs = require('fs');
-
- // Read test results
- let testResults = "Tests completed";
- try {
- const summaryFile = process.env.GITHUB_STEP_SUMMARY;
- if (fs.existsSync(summaryFile)) {
- testResults = fs.readFileSync(summaryFile, 'utf8');
- }
- } catch (error) {
- console.log('Could not read test results:', error);
- }
-
- const jobStatus = '${{ job.status }}';
- const statusText = jobStatus === 'success' ? 'Passed' : 'Failed';
- const nextSteps = jobStatus === 'success'
- ? 'All checks passed! This PR is ready for review.'
- : 'Some checks failed. Please review the workflow logs and fix any issues.';
-
- const comment = `
- ## PR Validation Results
-
- **Commit:** \`${{ github.event.pull_request.head.sha }}\`
- **Status:** ${statusText}
-
- ### Test Results
- - Maven POM validation
- - Project compilation
- - Unit tests
- - Integration tests with Testcontainers
- - Code coverage analysis
-
- ### Next Steps
- ${nextSteps}
-
- **Workflow:** [${{ github.workflow }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
- `;
-
- // Find existing comment
- const comments = await github.rest.issues.listComments({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.issue.number,
- });
-
- const existingComment = comments.data.find(comment =>
- comment.body.includes('PR Validation Results')
- );
-
- if (existingComment) {
- // Update existing comment
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: existingComment.id,
- body: comment
- });
- } else {
- // Create new comment
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.issue.number,
- body: comment
- });
- }
-
security-scan:
name: Security Scan
runs-on: ubuntu-latest
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index dc726df..38484fe 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -52,11 +52,11 @@ jobs:
- name: Run tests before release
run: |
echo "Running tests before release..."
- mvn --no-transfer-progress --batch-mode clean test -Dtest=RedlockConfigurationTest
+ mvn --no-transfer-progress --batch-mode clean test
echo "Unit tests passed"
# Run integration tests
- mvn --no-transfer-progress --batch-mode test -Dtest=RedlockIntegrationTest
+ mvn --no-transfer-progress --batch-mode verify -Dmaven.test.skip.exec=false
echo "Integration tests passed"
- name: Install GPG key
@@ -75,6 +75,7 @@ jobs:
deploy -P sonatype-oss-release
- name: Create release summary
+ continue-on-error: true
run: |
echo "## Release Published Successfully" >> $GITHUB_STEP_SUMMARY
echo "- **Version:** ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
@@ -98,19 +99,21 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Note:** It may take up to 2 hours for the artifact to be available in Maven Central." >> $GITHUB_STEP_SUMMARY
- - name: Comment on release
+ - name: Update release notes
if: github.event_name == 'release'
+ continue-on-error: true
uses: actions/github-script@v7
with:
script: |
const version = '${{ steps.version.outputs.version }}';
- const comment = `
- ## Successfully Published to Maven Central!
-
- **Version:** \`${version}\`
-
+ const mavenInfo = `
+
+ ---
+
+ ## Published to Maven Central
+
### Usage
-
+
**Maven:**
\`\`\`xml
@@ -119,31 +122,21 @@ jobs:
${version}
\`\`\`
-
+
**Gradle:**
\`\`\`gradle
implementation 'org.codarama:redlock4j:${version}'
\`\`\`
-
+
**Note:** It may take up to 2 hours for the artifact to be available in Maven Central.
-
+
๐ **Maven Central:** https://central.sonatype.com/artifact/org.codarama/redlock4j/${version}
`;
-
- await github.rest.repos.createRelease({
+
+ // Update the existing release with Maven Central info
+ await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
- tag_name: context.payload.release.tag_name,
- name: context.payload.release.name,
- body: context.payload.release.body + '\n\n' + comment,
- draft: false,
- prerelease: context.payload.release.prerelease
- }).catch(() => {
- // If release already exists, just add a comment
- return github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.payload.release.number,
- body: comment
- });
+ release_id: context.payload.release.id,
+ body: (context.payload.release.body || '') + mavenInfo
});
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index a5e6632..8a71171 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,4 +41,5 @@ build/
.DS_Store
### MkDocs ###
-site/
\ No newline at end of file
+site/
+/.venv/
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d98005e..3d45e76 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -13,21 +13,31 @@ Thank you for your interest in contributing to Redlock4j! This document provides
## ๐งช Testing
+### Test Organization
+Tests are organized using JUnit 5 `@Tag` annotations and Maven lifecycle phases:
+
+- **Unit tests** (`@Tag("unit")`) - Run during `test` phase via maven-surefire-plugin
+- **Integration tests** (`@Tag("integration")`) - Run during `integration-test` phase via maven-failsafe-plugin
+- **Performance tests** (`@Tag("performance")`) - Run on-demand or during nightly builds
+
### Local Testing
Before submitting a PR, run the tests locally:
```bash
-# Run all tests
+# Run unit tests only (fast, no Docker required)
mvn test
-# Run only unit tests
-mvn test -Dtest=RedlockConfigurationTest
+# Run unit + integration tests (requires Docker for Testcontainers)
+mvn verify
+
+# Run only integration tests (skip unit tests)
+mvn failsafe:integration-test failsafe:verify
-# Run only integration tests (requires Docker)
-mvn test -Dtest=RedlockIntegrationTest
+# Run performance tests
+mvn test -Dgroups=performance
# Run with coverage
-mvn test jacoco:report
+mvn verify jacoco:report
# Security scan
mvn org.owasp:dependency-check-maven:check
diff --git a/pom.xml b/pom.xml
index 8b26911..bb41e36 100644
--- a/pom.xml
+++ b/pom.xml
@@ -141,17 +141,40 @@
+
org.apache.maven.plugins
maven-surefire-plugin
3.2.2
+ unit
**/*Test.java
-
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.2.2
+
+ integration
+
+ **/*Test.java
+
+
+
+
+
+ integration-test
+ verify
+
+
+
+
+
org.jacoco
@@ -333,5 +356,28 @@
+
+
+
+ java17plus
+
+ [17,)
+
+
+
+
+ org.mockito
+ mockito-core
+ 5.14.2
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 5.14.2
+ test
+
+
+
diff --git a/src/test/java/org/codarama/redlock4j/FairLockTest.java b/src/test/java/org/codarama/redlock4j/FairLockTest.java
index 2f30274..54dd7ec 100644
--- a/src/test/java/org/codarama/redlock4j/FairLockTest.java
+++ b/src/test/java/org/codarama/redlock4j/FairLockTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -26,6 +27,7 @@
/**
* Unit tests for FairLock using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class FairLockTest {
diff --git a/src/test/java/org/codarama/redlock4j/LockExtensionTest.java b/src/test/java/org/codarama/redlock4j/LockExtensionTest.java
index 8354c69..c5a7f97 100644
--- a/src/test/java/org/codarama/redlock4j/LockExtensionTest.java
+++ b/src/test/java/org/codarama/redlock4j/LockExtensionTest.java
@@ -7,8 +7,9 @@
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -24,6 +25,7 @@
/**
* Unit tests for lock extension functionality.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class LockExtensionTest {
diff --git a/src/test/java/org/codarama/redlock4j/LockResultTest.java b/src/test/java/org/codarama/redlock4j/LockResultTest.java
index 9ecdbd0..9095b9d 100644
--- a/src/test/java/org/codarama/redlock4j/LockResultTest.java
+++ b/src/test/java/org/codarama/redlock4j/LockResultTest.java
@@ -4,6 +4,7 @@
*/
package org.codarama.redlock4j;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -11,6 +12,7 @@
/**
* Unit tests for LockResult value object.
*/
+@Tag("unit")
public class LockResultTest {
@Test
diff --git a/src/test/java/org/codarama/redlock4j/MultiLockTest.java b/src/test/java/org/codarama/redlock4j/MultiLockTest.java
index 49a4052..43ad46c 100644
--- a/src/test/java/org/codarama/redlock4j/MultiLockTest.java
+++ b/src/test/java/org/codarama/redlock4j/MultiLockTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -25,6 +26,7 @@
/**
* Unit tests for MultiLock using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class MultiLockTest {
diff --git a/src/test/java/org/codarama/redlock4j/RedlockCountDownLatchTest.java b/src/test/java/org/codarama/redlock4j/RedlockCountDownLatchTest.java
index 4f73721..da2683c 100644
--- a/src/test/java/org/codarama/redlock4j/RedlockCountDownLatchTest.java
+++ b/src/test/java/org/codarama/redlock4j/RedlockCountDownLatchTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -25,6 +26,7 @@
/**
* Unit tests for RedlockCountDownLatch using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class RedlockCountDownLatchTest {
@@ -77,9 +79,10 @@ void shouldAllowZeroCount() throws RedisDriverException {
@Test
void shouldReturnCountFromQuorum() throws RedisDriverException, InterruptedException {
- when(mockDriver1.get(anyString())).thenReturn("5");
- when(mockDriver2.get(anyString())).thenReturn("5");
- when(mockDriver3.get(anyString())).thenReturn("5");
+ // Use lenient stubs since quorum logic may not call all drivers
+ lenient().when(mockDriver1.get(anyString())).thenReturn("5");
+ lenient().when(mockDriver2.get(anyString())).thenReturn("5");
+ lenient().when(mockDriver3.get(anyString())).thenReturn("5");
RedlockCountDownLatch latch = new RedlockCountDownLatch("test", 5, drivers, testConfig);
long count = latch.getCount();
diff --git a/src/test/java/org/codarama/redlock4j/RedlockExceptionTest.java b/src/test/java/org/codarama/redlock4j/RedlockExceptionTest.java
index cabaf2d..ae3f94c 100644
--- a/src/test/java/org/codarama/redlock4j/RedlockExceptionTest.java
+++ b/src/test/java/org/codarama/redlock4j/RedlockExceptionTest.java
@@ -4,6 +4,7 @@
*/
package org.codarama.redlock4j;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -11,6 +12,7 @@
/**
* Unit tests for RedlockException.
*/
+@Tag("unit")
public class RedlockExceptionTest {
@Test
diff --git a/src/test/java/org/codarama/redlock4j/RedlockManagerTest.java b/src/test/java/org/codarama/redlock4j/RedlockManagerTest.java
index 9cbe5ce..9fc9b17 100644
--- a/src/test/java/org/codarama/redlock4j/RedlockManagerTest.java
+++ b/src/test/java/org/codarama/redlock4j/RedlockManagerTest.java
@@ -5,8 +5,9 @@
package org.codarama.redlock4j;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import java.time.Duration;
@@ -15,6 +16,7 @@
/**
* Unit tests for RedlockManager. These tests focus on the manager's public interface and configuration handling.
*/
+@Tag("unit")
public class RedlockManagerTest {
private RedlockConfiguration testConfig;
diff --git a/src/test/java/org/codarama/redlock4j/RedlockReadWriteLockTest.java b/src/test/java/org/codarama/redlock4j/RedlockReadWriteLockTest.java
index 4dabda6..9d3fac9 100644
--- a/src/test/java/org/codarama/redlock4j/RedlockReadWriteLockTest.java
+++ b/src/test/java/org/codarama/redlock4j/RedlockReadWriteLockTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -26,6 +27,7 @@
/**
* Unit tests for RedlockReadWriteLock using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class RedlockReadWriteLockTest {
diff --git a/src/test/java/org/codarama/redlock4j/RedlockSemaphoreTest.java b/src/test/java/org/codarama/redlock4j/RedlockSemaphoreTest.java
index 95076fa..34173f1 100644
--- a/src/test/java/org/codarama/redlock4j/RedlockSemaphoreTest.java
+++ b/src/test/java/org/codarama/redlock4j/RedlockSemaphoreTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -25,6 +26,7 @@
/**
* Unit tests for RedlockSemaphore using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class RedlockSemaphoreTest {
diff --git a/src/test/java/org/codarama/redlock4j/RedlockTest.java b/src/test/java/org/codarama/redlock4j/RedlockTest.java
index ae3050f..201a0e5 100644
--- a/src/test/java/org/codarama/redlock4j/RedlockTest.java
+++ b/src/test/java/org/codarama/redlock4j/RedlockTest.java
@@ -7,8 +7,9 @@
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -25,6 +26,7 @@
/**
* Unit tests for Redlock using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class RedlockTest {
diff --git a/src/test/java/org/codarama/redlock4j/ReentrantAsyncRedlockTest.java b/src/test/java/org/codarama/redlock4j/ReentrantAsyncRedlockTest.java
index 87e1d00..8b6eb5e 100644
--- a/src/test/java/org/codarama/redlock4j/ReentrantAsyncRedlockTest.java
+++ b/src/test/java/org/codarama/redlock4j/ReentrantAsyncRedlockTest.java
@@ -8,9 +8,10 @@
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -31,6 +32,7 @@
/**
* Unit tests for reentrant functionality of AsyncRedlockImpl using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class ReentrantAsyncRedlockTest {
diff --git a/src/test/java/org/codarama/redlock4j/ReentrantRedlockTest.java b/src/test/java/org/codarama/redlock4j/ReentrantRedlockTest.java
index 03539d8..e8770c1 100644
--- a/src/test/java/org/codarama/redlock4j/ReentrantRedlockTest.java
+++ b/src/test/java/org/codarama/redlock4j/ReentrantRedlockTest.java
@@ -7,8 +7,9 @@
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -29,6 +30,7 @@
/**
* Unit tests for reentrant functionality of Redlock using Mockito mocks.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class ReentrantRedlockTest {
diff --git a/src/test/java/org/codarama/redlock4j/async/AsyncLockExtensionTest.java b/src/test/java/org/codarama/redlock4j/async/AsyncLockExtensionTest.java
index 23d2e8a..f3a5b5a 100644
--- a/src/test/java/org/codarama/redlock4j/async/AsyncLockExtensionTest.java
+++ b/src/test/java/org/codarama/redlock4j/async/AsyncLockExtensionTest.java
@@ -7,9 +7,10 @@
import io.reactivex.rxjava3.observers.TestObserver;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.codarama.redlock4j.driver.RedisDriver;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -26,6 +27,7 @@
/**
* Unit tests for async lock extension functionality.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class AsyncLockExtensionTest {
diff --git a/src/test/java/org/codarama/redlock4j/async/AsyncRedlockImplTest.java b/src/test/java/org/codarama/redlock4j/async/AsyncRedlockImplTest.java
index 0b3f324..c0e7dff 100644
--- a/src/test/java/org/codarama/redlock4j/async/AsyncRedlockImplTest.java
+++ b/src/test/java/org/codarama/redlock4j/async/AsyncRedlockImplTest.java
@@ -7,8 +7,9 @@
import io.reactivex.rxjava3.observers.TestObserver;
import org.codarama.redlock4j.RedlockManager;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -22,6 +23,7 @@
/**
* Tests for asynchronous CompletionStage and RxJava reactive APIs.
*/
+@Tag("integration")
@Testcontainers
public class AsyncRedlockImplTest {
diff --git a/src/test/java/org/codarama/redlock4j/async/RxRedlockTest.java b/src/test/java/org/codarama/redlock4j/async/RxRedlockTest.java
index bc79264..b7f22bf 100644
--- a/src/test/java/org/codarama/redlock4j/async/RxRedlockTest.java
+++ b/src/test/java/org/codarama/redlock4j/async/RxRedlockTest.java
@@ -9,6 +9,7 @@
import org.codarama.redlock4j.driver.RedisDriver;
import org.codarama.redlock4j.driver.RedisDriverException;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -28,6 +29,7 @@
/**
* Unit tests for RxRedlock reactive API.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class RxRedlockTest {
diff --git a/src/test/java/org/codarama/redlock4j/configuration/RedlockConfigurationTest.java b/src/test/java/org/codarama/redlock4j/configuration/RedlockConfigurationTest.java
index 3d01212..fbb1c34 100644
--- a/src/test/java/org/codarama/redlock4j/configuration/RedlockConfigurationTest.java
+++ b/src/test/java/org/codarama/redlock4j/configuration/RedlockConfigurationTest.java
@@ -4,6 +4,7 @@
*/
package org.codarama.redlock4j.configuration;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Duration;
@@ -11,6 +12,7 @@
/**
* Unit tests for RedlockConfiguration.
*/
+@Tag("unit")
public class RedlockConfigurationTest {
@Test
diff --git a/src/test/java/org/codarama/redlock4j/driver/JedisRedisDriverTest.java b/src/test/java/org/codarama/redlock4j/driver/JedisRedisDriverTest.java
index b13764f..042e349 100644
--- a/src/test/java/org/codarama/redlock4j/driver/JedisRedisDriverTest.java
+++ b/src/test/java/org/codarama/redlock4j/driver/JedisRedisDriverTest.java
@@ -5,14 +5,16 @@
package org.codarama.redlock4j.driver;
import org.codarama.redlock4j.configuration.RedisNodeConfiguration;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/**
* Unit tests for JedisRedisDriver. These tests focus on the driver's public interface and configuration handling.
*/
+@Tag("unit")
public class JedisRedisDriverTest {
private RedisNodeConfiguration testConfig;
diff --git a/src/test/java/org/codarama/redlock4j/driver/LettuceRedisDriverTest.java b/src/test/java/org/codarama/redlock4j/driver/LettuceRedisDriverTest.java
index bd86b9b..156ec20 100644
--- a/src/test/java/org/codarama/redlock4j/driver/LettuceRedisDriverTest.java
+++ b/src/test/java/org/codarama/redlock4j/driver/LettuceRedisDriverTest.java
@@ -9,8 +9,9 @@
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import org.codarama.redlock4j.configuration.RedisNodeConfiguration;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -22,6 +23,7 @@
/**
* Unit tests for LettuceRedisDriver using Mockito mocks. These tests do not require a working Redis server.
*/
+@Tag("unit")
@ExtendWith(MockitoExtension.class)
public class LettuceRedisDriverTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/AdvancedLockingIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/AdvancedLockingIntegrationTest.java
index cb6fdff..f62395b 100644
--- a/src/test/java/org/codarama/redlock4j/integration/AdvancedLockingIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/AdvancedLockingIntegrationTest.java
@@ -7,6 +7,7 @@
import org.codarama.redlock4j.*;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
@@ -25,6 +26,7 @@
/**
* Integration tests for advanced locking primitives.
*/
+@Tag("integration")
@Testcontainers
public class AdvancedLockingIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/AsyncRedlockIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/AsyncRedlockIntegrationTest.java
index 403d488..998e6ff 100644
--- a/src/test/java/org/codarama/redlock4j/integration/AsyncRedlockIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/AsyncRedlockIntegrationTest.java
@@ -10,8 +10,9 @@
import org.codarama.redlock4j.async.AsyncRedlockImpl;
import org.codarama.redlock4j.async.RxRedlock;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -25,6 +26,7 @@
/**
* Simple tests to verify async and reactive APIs work correctly.
*/
+@Tag("integration")
@Testcontainers
public class AsyncRedlockIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/FairLockIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/FairLockIntegrationTest.java
index 2c2f85b..58a4167 100644
--- a/src/test/java/org/codarama/redlock4j/integration/FairLockIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/FairLockIntegrationTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.RedlockManager;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
@@ -27,6 +28,7 @@
/**
* Integration tests for {@link FairLock}.
*/
+@Tag("integration")
@Testcontainers
public class FairLockIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/MultiLockIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/MultiLockIntegrationTest.java
index 9bcf03e..58369ab 100644
--- a/src/test/java/org/codarama/redlock4j/integration/MultiLockIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/MultiLockIntegrationTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.RedlockManager;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
@@ -28,6 +29,7 @@
/**
* Integration tests for {@link MultiLock}.
*/
+@Tag("integration")
@Testcontainers
public class MultiLockIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/RedlockCountDownLatchIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/RedlockCountDownLatchIntegrationTest.java
index 108344d..af74ca9 100644
--- a/src/test/java/org/codarama/redlock4j/integration/RedlockCountDownLatchIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/RedlockCountDownLatchIntegrationTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.RedlockManager;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
@@ -28,6 +29,7 @@
* Comprehensive integration tests for {@link RedlockCountDownLatch}. Verifies the distributed countdown latch honors
* its contract.
*/
+@Tag("integration")
@Testcontainers
public class RedlockCountDownLatchIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/RedlockIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/RedlockIntegrationTest.java
index 7215f52..db193ff 100644
--- a/src/test/java/org/codarama/redlock4j/integration/RedlockIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/RedlockIntegrationTest.java
@@ -9,6 +9,7 @@
import org.codarama.redlock4j.RedlockManager;
import org.codarama.redlock4j.configuration.RedisNodeConfiguration;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterAll;
@@ -26,6 +27,7 @@
* Integration tests for Redlock functionality using Testcontainers. These tests automatically spin up Redis containers
* for testing.
*/
+@Tag("integration")
@Testcontainers
public class RedlockIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/RedlockReadWriteLockIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/RedlockReadWriteLockIntegrationTest.java
index ca7e4dc..16ad897 100644
--- a/src/test/java/org/codarama/redlock4j/integration/RedlockReadWriteLockIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/RedlockReadWriteLockIntegrationTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.RedlockReadWriteLock;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
@@ -28,6 +29,7 @@
/**
* Integration tests for {@link RedlockReadWriteLock}.
*/
+@Tag("integration")
@Testcontainers
public class RedlockReadWriteLockIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/integration/RedlockSemaphoreIntegrationTest.java b/src/test/java/org/codarama/redlock4j/integration/RedlockSemaphoreIntegrationTest.java
index 3e37a4a..b13f307 100644
--- a/src/test/java/org/codarama/redlock4j/integration/RedlockSemaphoreIntegrationTest.java
+++ b/src/test/java/org/codarama/redlock4j/integration/RedlockSemaphoreIntegrationTest.java
@@ -8,6 +8,7 @@
import org.codarama.redlock4j.RedlockSemaphore;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
@@ -26,6 +27,7 @@
/**
* Integration tests for {@link RedlockSemaphore}.
*/
+@Tag("integration")
@Testcontainers
public class RedlockSemaphoreIntegrationTest {
diff --git a/src/test/java/org/codarama/redlock4j/performance/RedlockPerformanceTest.java b/src/test/java/org/codarama/redlock4j/performance/RedlockPerformanceTest.java
index ef6aa62..ac09d3b 100644
--- a/src/test/java/org/codarama/redlock4j/performance/RedlockPerformanceTest.java
+++ b/src/test/java/org/codarama/redlock4j/performance/RedlockPerformanceTest.java
@@ -7,9 +7,9 @@
import org.codarama.redlock4j.Redlock;
import org.codarama.redlock4j.RedlockManager;
import org.codarama.redlock4j.configuration.RedlockConfiguration;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -27,7 +27,7 @@
* Performance tests for Redlock functionality using Testcontainers. These tests are disabled by default as they are for
* performance analysis.
*/
-@Disabled("Performance tests - enable manually when needed")
+@Tag("performance")
@Testcontainers
public class RedlockPerformanceTest {