quarkus-verification

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Quarkus Verification Loop

Quarkus项目验证循环

Run before PRs, after major changes, and pre-deploy.
在PR提交前、重大变更后以及预部署阶段运行。

When to Activate

激活时机

  • Before opening a pull request for a Quarkus service
  • After major refactoring or dependency upgrades
  • Pre-deployment verification for staging or production
  • Running full build → lint → test → security scan → native compilation pipeline
  • Validating test coverage meets thresholds (80%+)
  • Testing native image compatibility
  • 为Quarkus服务提交拉取请求(PR)之前
  • 重大重构或依赖升级之后
  • 预发布环境或生产环境的部署前验证
  • 运行完整的构建→代码检查→测试→安全扫描→原生编译流水线
  • 验证测试覆盖率达到阈值(80%以上)
  • 测试原生镜像兼容性

Phase 1: Build

阶段1:构建

bash
undefined
bash
undefined

Maven

Maven

mvn clean verify -DskipTests
mvn clean verify -DskipTests

Gradle

Gradle

./gradlew clean assemble -x test

If build fails, stop and fix compilation errors.
./gradlew clean assemble -x test

如果构建失败,立即停止并修复编译错误。

Phase 2: Static Analysis

阶段2:静态分析

Checkstyle, PMD, SpotBugs (Maven)

Checkstyle, PMD, SpotBugs (Maven)

bash
mvn checkstyle:check pmd:check spotbugs:check
bash
mvn checkstyle:check pmd:check spotbugs:check

SonarQube (if configured)

SonarQube (if configured)

bash
mvn sonar:sonar \
  -Dsonar.projectKey=my-quarkus-project \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=${SONAR_TOKEN}
bash
mvn sonar:sonar \
  -Dsonar.projectKey=my-quarkus-project \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=${SONAR_TOKEN}

Common Issues to Address

需要解决的常见问题

  • Unused imports or variables
  • Complex methods (high cyclomatic complexity)
  • Potential null pointer dereferences
  • Security issues flagged by SpotBugs
  • 未使用的导入或变量
  • 复杂方法(高圈复杂度)
  • 潜在的空指针引用
  • SpotBugs标记的安全问题

Phase 3: Tests + Coverage

阶段3:测试与覆盖率

bash
undefined
bash
undefined

Run all tests

运行所有测试

mvn clean test
mvn clean test

Generate coverage report

生成覆盖率报告

mvn jacoco:report
mvn jacoco:report

Enforce coverage threshold (80%)

强制执行覆盖率阈值(80%)

mvn jacoco:check
mvn jacoco:check

Or with Gradle

或使用Gradle

./gradlew test jacocoTestReport jacocoTestCoverageVerification
undefined
./gradlew test jacocoTestReport jacocoTestCoverageVerification
undefined

Test Categories

测试分类

Unit Tests

单元测试

Test service logic with mocked dependencies:
java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
  @Mock UserRepository userRepository;
  @InjectMocks UserService userService;

  @Test
  void createUser_validInput_returnsUser() {
    var dto = new CreateUserDto("Alice", "alice@example.com");

    // Panache persist() is void — use doNothing + verify
    doNothing().when(userRepository).persist(any(User.class));

    User result = userService.create(dto);

    assertThat(result.name).isEqualTo("Alice");
    verify(userRepository).persist(any(User.class));
  }
}
使用模拟依赖测试服务逻辑:
java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
  @Mock UserRepository userRepository;
  @InjectMocks UserService userService;

  @Test
  void createUser_validInput_returnsUser() {
    var dto = new CreateUserDto("Alice", "alice@example.com");

    // Panache persist() is void — use doNothing + verify
    doNothing().when(userRepository).persist(any(User.class));

    User result = userService.create(dto);

    assertThat(result.name).isEqualTo("Alice");
    verify(userRepository).persist(any(User.class));
  }
}

Integration Tests

集成测试

Test with real database (Testcontainers):
java
@QuarkusTest
@QuarkusTestResource(PostgresTestResource.class)
class UserRepositoryIntegrationTest {

  @Inject
  UserRepository userRepository;

  @Test
  @Transactional
  void findByEmail_existingUser_returnsUser() {
    User user = new User();
    user.name = "Alice";
    user.email = "alice@example.com";
    userRepository.persist(user);

    Optional<User> found = userRepository.findByEmail("alice@example.com");

    assertThat(found).isPresent();
    assertThat(found.get().name).isEqualTo("Alice");
  }
}
使用真实数据库(Testcontainers)进行测试:
java
@QuarkusTest
@QuarkusTestResource(PostgresTestResource.class)
class UserRepositoryIntegrationTest {

  @Inject
  UserRepository userRepository;

  @Test
  @Transactional
  void findByEmail_existingUser_returnsUser() {
    User user = new User();
    user.name = "Alice";
    user.email = "alice@example.com";
    userRepository.persist(user);

    Optional<User> found = userRepository.findByEmail("alice@example.com");

    assertThat(found).isPresent();
    assertThat(found.get().name).isEqualTo("Alice");
  }
}

API Tests

API测试

Test REST endpoints with REST Assured:
java
@QuarkusTest
class UserResourceTest {

  @Test
  void createUser_validInput_returns201() {
    given()
        .contentType(ContentType.JSON)
        .body("""
            {"name": "Alice", "email": "alice@example.com"}
            """)
        .when().post("/api/users")
        .then()
        .statusCode(201)
        .body("name", equalTo("Alice"));
  }

  @Test
  void createUser_invalidEmail_returns400() {
    given()
        .contentType(ContentType.JSON)
        .body("""
            {"name": "Alice", "email": "invalid"}
            """)
        .when().post("/api/users")
        .then()
        .statusCode(400);
  }
}
使用REST Assured测试REST端点:
java
@QuarkusTest
class UserResourceTest {

  @Test
  void createUser_validInput_returns201() {
    given()
        .contentType(ContentType.JSON)
        .body("""
            {"name": "Alice", "email": "alice@example.com"}
            """)
        .when().post("/api/users")
        .then()
        .statusCode(201)
        .body("name", equalTo("Alice"));
  }

  @Test
  void createUser_invalidEmail_returns400() {
    given()
        .contentType(ContentType.JSON)
        .body("""
            {"name": "Alice", "email": "invalid"}
            """)
        .when().post("/api/users")
        .then()
        .statusCode(400);
  }
}

Coverage Report

覆盖率报告

Check
target/site/jacoco/index.html
for detailed coverage:
  • Overall line coverage (target: 80%+)
  • Branch coverage (target: 70%+)
  • Identify uncovered critical paths
查看
target/site/jacoco/index.html
获取详细覆盖率信息:
  • 整体行覆盖率(目标:80%以上)
  • 分支覆盖率(目标:70%以上)
  • 识别未覆盖的关键路径

Phase 4: Security Scanning

阶段4:安全扫描

Dependency Vulnerabilities (Maven)

Dependency Vulnerabilities (Maven)

bash
mvn org.owasp:dependency-check-maven:check
Review
target/dependency-check-report.html
for CVEs.
bash
mvn org.owasp:dependency-check-maven:check
查看
target/dependency-check-report.html
了解CVE漏洞信息。

Quarkus Security Audit

Quarkus Security Audit

bash
undefined
bash
undefined

Check vulnerable extensions

检查易受攻击的扩展

mvn quarkus:audit
mvn quarkus:audit

List all extensions

列出所有扩展

mvn quarkus:list-extensions
undefined
mvn quarkus:list-extensions
undefined

OWASP ZAP (API Security Testing)

OWASP ZAP (API Security Testing)

bash
docker run -t owasp/zap2docker-stable zap-api-scan.py \
  -t http://localhost:8080/q/openapi \
  -f openapi
bash
docker run -t owasp/zap2docker-stable zap-api-scan.py \
  -t http://localhost:8080/q/openapi \
  -f openapi

Common Security Checks

常见安全检查

  • All secrets in environment variables (not in code)
  • Input validation on all endpoints
  • Authentication/authorization configured
  • CORS properly configured
  • Security headers set
  • Passwords hashed with BCrypt
  • SQL injection protection (parameterized queries)
  • Rate limiting on public endpoints
  • 所有密钥存储在环境变量中(而非代码里)
  • 所有端点都配置了输入验证
  • 已配置身份验证/授权
  • CORS配置正确
  • 设置了安全头
  • 使用BCrypt哈希密码
  • 防止SQL注入(参数化查询)
  • 公共端点配置了速率限制

Phase 5: Native Compilation

阶段5:原生编译

Test GraalVM native image compatibility:
bash
undefined
测试GraalVM原生镜像兼容性:
bash
undefined

Build native executable

构建原生可执行文件

mvn package -Dnative
mvn package -Dnative

Or with container

或使用容器构建

mvn package -Dnative -Dquarkus.native.container-build=true
mvn package -Dnative -Dquarkus.native.container-build=true

Test native executable

测试原生可执行文件

./target/*-runner
./target/*-runner

Run basic smoke tests

运行基础冒烟测试

Native Image Troubleshooting

原生镜像问题排查

Common issues:
  • Reflection: Add reflection config for dynamic classes
  • Resources: Include resources with
    quarkus.native.resources.includes
  • JNI: Register JNI classes if using native libraries
Example reflection config:
java
@RegisterForReflection(targets = {MyDynamicClass.class})
public class ReflectionConfiguration {}
常见问题:
  • 反射:为动态类添加反射配置
  • 资源:使用
    quarkus.native.resources.includes
    包含资源
  • JNI:如果使用原生库,注册JNI类
示例反射配置:
java
@RegisterForReflection(targets = {MyDynamicClass.class})
public class ReflectionConfiguration {}

Phase 6: Performance Testing

阶段6:性能测试

Load Testing with K6

Load Testing with K6

javascript
// load-test.js
import http from 'k6/http';
import { check } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 50 },
    { duration: '1m', target: 100 },
    { duration: '30s', target: 0 },
  ],
};

export default function () {
  const res = http.get('http://localhost:8080/api/markets');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });
}
Run:
bash
k6 run load-test.js
javascript
// load-test.js
import http from 'k6/http';
import { check } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 50 },
    { duration: '1m', target: 100 },
    { duration: '30s', target: 0 },
  ],
};

export default function () {
  const res = http.get('http://localhost:8080/api/markets');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });
}
运行:
bash
k6 run load-test.js

Metrics to Monitor

需要监控的指标

  • Response time (p50, p95, p99)
  • Throughput (requests/sec)
  • Error rate
  • Memory usage
  • CPU usage
  • 响应时间(p50、p95、p99)
  • 吞吐量(请求/秒)
  • 错误率
  • 内存使用情况
  • CPU使用率

Phase 7: Health Checks

阶段7:健康检查

bash
undefined
bash
undefined

Liveness

存活检查

Readiness

就绪检查

All health checks

所有健康检查

Metrics (if enabled)

指标(若已启用)


Expected responses:
```json
{
  "status": "UP",
  "checks": [
    {
      "name": "Database connection",
      "status": "UP"
    }
  ]
}

预期响应:
```json
{
  "status": "UP",
  "checks": [
    {
      "name": "Database connection",
      "status": "UP"
    }
  ]
}

Phase 8: Container Image Build

阶段8:容器镜像构建

bash
undefined
bash
undefined

Build container image

构建容器镜像

mvn package -Dquarkus.container-image.build=true
mvn package -Dquarkus.container-image.build=true

Or with specific registry

或指定镜像仓库

mvn package
-Dquarkus.container-image.build=true
-Dquarkus.container-image.registry=docker.io
-Dquarkus.container-image.group=myorg
-Dquarkus.container-image.tag=1.0.0
mvn package
-Dquarkus.container-image.build=true
-Dquarkus.container-image.registry=docker.io
-Dquarkus.container-image.group=myorg
-Dquarkus.container-image.tag=1.0.0

Test container

测试容器

docker run -p 8080:8080 myorg/my-quarkus-app:1.0.0
undefined
docker run -p 8080:8080 myorg/my-quarkus-app:1.0.0
undefined

Container Security Scan

容器安全扫描

bash
undefined
bash
undefined

Trivy

Trivy

trivy image myorg/my-quarkus-app:1.0.0
trivy image myorg/my-quarkus-app:1.0.0

Grype

Grype

grype myorg/my-quarkus-app:1.0.0
undefined
grype myorg/my-quarkus-app:1.0.0
undefined

Phase 9: Configuration Validation

阶段9:配置验证

bash
undefined
bash
undefined

Check all configuration properties

检查所有配置属性

mvn quarkus:info
mvn quarkus:info

List all config sources

列出所有配置源

Environment-Specific Checks

环境专属检查

  • Database URLs configured per environment
  • Secrets externalized (Vault, env vars)
  • Logging levels appropriate
  • CORS origins set correctly
  • Rate limiting configured
  • Monitoring/tracing enabled
  • 每个环境都配置了对应的数据库URL
  • 密钥已外部化(Vault、环境变量)
  • 日志级别设置合理
  • CORS源设置正确
  • 已配置速率限制
  • 已启用监控/追踪

Phase 10: Documentation Review

阶段10:文档审查

  • OpenAPI/Swagger docs up to date (
    /q/swagger-ui
    )
  • README has setup instructions
  • API changes documented
  • Migration guide for breaking changes
  • Configuration properties documented
Generate OpenAPI spec:
bash
curl http://localhost:8080/q/openapi -o openapi.json
  • OpenAPI/Swagger文档是最新的(
    /q/swagger-ui
  • README包含搭建说明
  • API变更已记录
  • 破坏性变更有迁移指南
  • 配置属性已文档化
生成OpenAPI规范:
bash
curl http://localhost:8080/q/openapi -o openapi.json

Verification Checklist

验证检查清单

Code Quality

代码质量

  • Build passes without warnings
  • Static analysis clean (no high/medium issues)
  • Code follows team conventions
  • No commented-out code or TODOs in PR
  • 构建通过且无警告
  • 静态分析无高/中风险问题
  • 代码符合团队规范
  • PR中无注释掉的代码或TODO项

Testing

测试

  • All tests pass
  • Code coverage ≥ 80%
  • Integration tests with real database
  • Security tests pass
  • Performance within acceptable limits
  • 所有测试通过
  • 代码覆盖率≥80%
  • 使用真实数据库的集成测试已完成
  • 安全测试通过
  • 性能在可接受范围内

Security

安全

  • No dependency vulnerabilities
  • Authentication/authorization tested
  • Input validation complete
  • Secrets not in source code
  • Security headers configured
  • 无依赖漏洞
  • 身份验证/授权已测试
  • 输入验证完整
  • 密钥未在源代码中
  • 已配置安全头

Deployment

部署

  • Native compilation successful
  • Container image builds
  • Health checks respond correctly
  • Configuration valid for target environment
  • 原生编译成功
  • 容器镜像构建完成
  • 健康检查响应正确
  • 目标环境的配置有效

Native Image

原生镜像

  • Native executable builds
  • Native tests pass
  • Startup time < 100ms
  • Memory footprint acceptable
  • 原生可执行文件构建成功
  • 原生测试通过
  • 启动时间<100ms
  • 内存占用符合预期

Automated Verification Script

自动化验证脚本

bash
#!/bin/bash
set -e

echo "=== Phase 1: Build ==="
mvn clean verify -DskipTests

echo "=== Phase 2: Static Analysis ==="
mvn checkstyle:check pmd:check spotbugs:check

echo "=== Phase 3: Tests + Coverage ==="
mvn test jacoco:report jacoco:check

echo "=== Phase 4: Security Scan ==="
mvn org.owasp:dependency-check-maven:check

echo "=== Phase 5: Native Compilation ==="
mvn package -Dnative -Dquarkus.native.container-build=true

echo "=== All Phases Complete ==="
echo "Review reports:"
echo "  - Coverage: target/site/jacoco/index.html"
echo "  - Security: target/dependency-check-report.html"
echo "  - Native: target/*-runner"
bash
#!/bin/bash
set -e

echo "=== Phase 1: Build ==="
mvn clean verify -DskipTests

echo "=== Phase 2: Static Analysis ==="
mvn checkstyle:check pmd:check spotbugs:check

echo "=== Phase 3: Tests + Coverage ==="
mvn test jacoco:report jacoco:check

echo "=== Phase 4: Security Scan ==="
mvn org.owasp:dependency-check-maven:check

echo "=== Phase 5: Native Compilation ==="
mvn package -Dnative -Dquarkus.native.container-build=true

echo "=== All Phases Complete ==="
echo "Review reports:"
echo "  - Coverage: target/site/jacoco/index.html"
echo "  - Security: target/dependency-check-report.html"
echo "  - Native: target/*-runner"

CI/CD Integration

CI/CD集成

GitHub Actions Example

GitHub Actions Example

yaml
name: Verification

on: [push, pull_request]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up JDK 21
        uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'temurin'
      
      - name: Cache Maven packages
        uses: actions/cache@v3
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
      
      - name: Build
        run: mvn clean verify -DskipTests
      
      - name: Test with Coverage
        run: mvn test jacoco:report jacoco:check
      
      - name: Security Scan
        run: mvn org.owasp:dependency-check-maven:check
      
      - name: Upload Coverage
        uses: codecov/codecov-action@v3
        with:
          files: target/site/jacoco/jacoco.xml
yaml
name: Verification

on: [push, pull_request]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up JDK 21
        uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'temurin'
      
      - name: Cache Maven packages
        uses: actions/cache@v3
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
      
      - name: Build
        run: mvn clean verify -DskipTests
      
      - name: Test with Coverage
        run: mvn test jacoco:report jacoco:check
      
      - name: Security Scan
        run: mvn org.owasp:dependency-check-maven:check
      
      - name: Upload Coverage
        uses: codecov/codecov-action@v3
        with:
          files: target/site/jacoco/jacoco.xml

Best Practices

最佳实践

  • Run verification loop before every PR
  • Automate in CI/CD pipeline
  • Fix issues immediately; don't accumulate debt
  • Keep coverage above 80%
  • Update dependencies regularly
  • Test native compilation periodically
  • Monitor performance trends
  • Document breaking changes
  • Review security scan results
  • Validate configuration for each environment
  • 每个PR提交前运行验证循环
  • 在CI/CD流水线中自动化验证流程
  • 立即修复问题,不要积累技术债务
  • 保持覆盖率在80%以上
  • 定期更新依赖
  • 定期测试原生编译
  • 监控性能趋势
  • 记录破坏性变更
  • 审查安全扫描结果
  • 验证每个环境的配置