ci: separate test workflow

This commit is contained in:
ReaJason
2025-08-21 18:14:18 +08:00
parent 4fb95374ad
commit 34e117c462
7 changed files with 220 additions and 320 deletions
+40
View File
@@ -0,0 +1,40 @@
name: Docker Build Test
on:
push:
branches:
- master
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'examples/**'
- 'web/**'
- '**.md'
- '**/*.png'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
docker-build-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build --build-arg ROUTE_ROOT_PATH=/memshell-party --build-arg CONTEXT_PATH=/memshell-party -t app .
docker images
- name: Run Docker container
run: |
docker run -d -e BOOT_OPTS=--server.servlet.context-path=/memshell-party -p 8080:8080 app
sleep 10
- name: Test with curl
run: |
if [[ $(curl -w "%{http_code}" -o /dev/null http://localhost:8080/memshell-party/version) -eq 200 ]]; then
echo "Test successful!"
else
echo "Test failed!"
exit 1
fi
@@ -0,0 +1,74 @@
name: Memshell IntegrationTest
on:
push:
branches:
- '**'
paths:
- '**/memshell/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
memshell-integration-test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
- middleware: "xxljob"
depend_tasks: ""
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
needs: [ unit-test ]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Prepare for Integration Test
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.memshell.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary
uses: mikepenz/action-junit-report@v5
if: success() || failure()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
@@ -0,0 +1,71 @@
name: Probe IntegrationTest
on:
push:
branches:
- '**'
paths:
- '**/probe/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Prepare for Integration Test
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.probe.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary
uses: mikepenz/action-junit-report@v5
if: success() || failure()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
-174
View File
@@ -1,174 +0,0 @@
name: Test
on:
push:
branches:
- '**'
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'examples/**'
- 'web/**'
- '**.md'
- '**/*.png'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
unit-test:
name: UniteTest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Generator Unit Test with Gradle
run: ./gradlew :generator:test
- name: Boot Unit Test with Gradle
run: ./gradlew :boot:test
docker-build-test:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build --build-arg ROUTE_ROOT_PATH=/memshell-party --build-arg CONTEXT_PATH=/memshell-party -t app .
docker images
- name: Run Docker container
run: |
docker run -d -e BOOT_OPTS=--server.servlet.context-path=/memshell-party -p 8080:8080 app
sleep 10
- name: Test with curl
run: |
if [[ $(curl -w "%{http_code}" -o /dev/null http://localhost:8080/memshell-party/version) -eq 200 ]]; then
echo "Test successful!"
else
echo "Test failed!"
exit 1
fi
memshell-integration-test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
- middleware: "xxljob"
depend_tasks: ""
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
needs: [ unit-test ]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Prepare for Integration Test
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.memshell.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary
run: cat integration-test/build/test-results/report.md >> $GITHUB_STEP_SUMMARY
detection-integration-test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
needs: [ unit-test ]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Prepare for Integration Test
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.probe.${{ matrix.cases.middleware }}.*' --info
+35
View File
@@ -0,0 +1,35 @@
name: Unit-Test
on:
push:
branches:
- '**'
paths:
- 'generator/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
unit-test:
name: UniteTest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Generator Unit Test with Gradle
run: ./gradlew :generator:test
- name: Boot Unit Test with Gradle
run: ./gradlew :boot:test
@@ -1,145 +0,0 @@
package com.reajason.javaweb.integration;
import lombok.Builder;
import lombok.Data;
import lombok.SneakyThrows;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.testcontainers.shaded.org.apache.commons.lang3.tuple.Pair;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* @author ReaJason
* @since 2024/12/1
*/
public class MarkdownTestExecutionListener implements TestExecutionListener {
private final Map<UniqueId, Instant> timeStamps = new ConcurrentHashMap<>();
private final Map<String, List<TestCase>> testCases = new ConcurrentHashMap<>();
private final Path markdownPath = Paths.get("build", "test-results", "report.md");
private Instant startTime;
@SneakyThrows
@Override
public void testPlanExecutionStarted(TestPlan testPlan) {
Files.deleteIfExists(markdownPath);
ArrayList<String> lines = new ArrayList<>();
lines.add("## Integration Test");
startTime = Instant.now();
lines.add("- Started: " + startTime);
Files.write(markdownPath, lines, StandardOpenOption.CREATE_NEW);
}
@Override
@SneakyThrows
public void testPlanExecutionFinished(TestPlan testPlan) {
List<String> lines = new ArrayList<>();
Instant endTime = Instant.now();
lines.add("- Finished: " + endTime);
Duration duration = Duration.between(startTime, endTime);
lines.add("- Total Duration: " + getDuration(duration));
Pair<Long, Long> countPair = parseCases();
lines.add(String.format("- Total Cases: %d/%d, %d failed", countPair.getLeft(), countPair.getRight(), countPair.getRight() - countPair.getLeft()));
lines.add("");
for (Map.Entry<String, List<TestCase>> entry : testCases.entrySet()) {
lines.add(String.format("### %s", entry.getKey()));
lines.add("|**Shell Type** | **Packer** | **Status**| **Duration(ms)** |");
lines.add("|---------------|------------|-----------|------------------|");
List<TestCase> value = entry.getValue().stream().sorted((tc1, tc2) -> {
if (tc1.getStatus() == tc2.getStatus()) {
return 0;
}
return tc1.getStatus() == TestExecutionResult.Status.FAILED ? -1 : 1;
}).collect(Collectors.toList());
for (TestCase testCase : value) {
String status = testCase.getStatus().equals(TestExecutionResult.Status.SUCCESSFUL) ? "" : "";
lines.add("|" + testCase.getShellType() + "|" + testCase.getPacker() + "|" + status + "|" + testCase.getDuration().toMillis() + "|");
}
}
Files.write(markdownPath, lines, StandardOpenOption.APPEND);
}
private String getDuration(Duration duration) {
long totalSeconds = duration.getSeconds();
long minutes = totalSeconds / 60;
long seconds = totalSeconds % 60;
if (totalSeconds < 60) {
return String.format("%d seconds", totalSeconds);
} else {
return String.format("%d minutes and %d seconds", minutes, seconds);
}
}
private Pair<Long, Long> parseCases() {
long totalCases = 0;
long successCases = 0;
for (List<TestCase> caseList : testCases.values()) {
totalCases += caseList.size();
for (TestCase testCase : caseList) {
if (testCase.getStatus().equals(TestExecutionResult.Status.SUCCESSFUL)) {
successCases++;
}
}
}
return Pair.of(successCases, totalCases);
}
@Override
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
if (!testIdentifier.isTest()) {
return;
}
Instant startTime = timeStamps.get(testIdentifier.getUniqueIdObject());
if (startTime == null) {
return;
}
String[] split = testIdentifier.getDisplayName().split("\\|");
if (split.length == 3) {
String imageName = split[0].trim();
String shellType = split[1].trim();
String packer = split[2].trim();
List<TestCase> cases = testCases.getOrDefault(imageName, new ArrayList<>());
cases.add(TestCase.builder()
.imageName(imageName)
.shellType(shellType)
.packer(packer)
.duration(Duration.between(startTime, Instant.now()))
.status(testExecutionResult.getStatus())
.build());
testCases.put(imageName, cases);
}
}
@Override
public void executionStarted(TestIdentifier testIdentifier) {
if (testIdentifier.isTest()) {
timeStamps.put(testIdentifier.getUniqueIdObject(), Instant.now());
}
}
@Data
@Builder
static class TestCase {
private String imageName;
private String shellType;
private String packer;
private Duration duration;
private TestExecutionResult.Status status;
}
}
@@ -1 +0,0 @@
com.reajason.javaweb.integration.MarkdownTestExecutionListener