Skip to content

Commit 71d83a7

Browse files
committed
add container report
1 parent da5f817 commit 71d83a7

3 files changed

Lines changed: 94 additions & 11 deletions

File tree

.circleci/config.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ commands:
148148
if [ -f "$JACOCO_AGG" ]; then
149149
echo "=== Using aggregate JaCoCo report: $JACOCO_AGG ==="
150150
ls -lh "$JACOCO_AGG"
151-
./codecov upload-coverage $COMMON_ARGS --files "$JACOCO_AGG"
151+
./codecov upload-coverage $COMMON_ARGS --file "$JACOCO_AGG"
152152
else
153153
echo "=== No aggregate JaCoCo report found; skipping coverage upload ==="
154154
# Avoid uploading empty/partial reports (they can drag down overall coverage).
@@ -297,15 +297,19 @@ jobs:
297297
name: Auth ghcr
298298
command: echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$GITHUB_USER" --password-stdin
299299
- run:
300-
name: Build with Docker images (instrumented for coverage)
301-
command: mvn -U clean -T1C -B install -DonlyImages -Pinstrument -Ddocker.image.tag=local-${CIRCLE_SHA1}
300+
name: Build Docker images
301+
command: mvn -U clean -T1C -B install -DonlyImages -Ddocker.image.tag=local-${CIRCLE_SHA1}
302302
- run:
303303
name: Run container tests using TestContainers
304304
command: |
305305
mvn -B install -DonlyContainerE2E \
306306
-pl :sqrl-testing-container \
307+
-Dsqrl.container.coverage=true \
307308
-Ddocker.image.tag=local-${CIRCLE_SHA1} \
308309
-Dmcp.inspector.version=$MCP_TAG
310+
- run:
311+
name: Generate aggregate JaCoCo report
312+
command: mvn -B -pl :sqrl-coverage -am -DskipTests -DskipITs verify
309313
- save-test-results
310314

311315
deploy:

sqrl-testing/sqrl-coverage/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<dataFileIncludes>
7171
<dataFileInclude>**/target/jacoco.exec</dataFileInclude>
7272
<dataFileInclude>**/target/jacoco-it.exec</dataFileInclude>
73+
<dataFileInclude>**/target/jacoco/jacoco-container.exec</dataFileInclude>
7374
</dataFileIncludes>
7475
</configuration>
7576
</execution>

sqrl-testing/sqrl-testing-container/src/test/java/com/datasqrl/container/testing/SqrlContainerTestBase.java

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ protected void commonTearDown() {
7171
protected static final String SQRL_CMD_IMAGE = "datasqrl/cmd";
7272
protected static final String SQRL_SERVER_IMAGE = "datasqrl/sqrl-server";
7373
protected static final String BUILD_DIR = "/build";
74+
protected static final String JACOCO_OUT_DIR = "/jacoco";
75+
protected static final String JACOCO_AGENT_PATH = "/jacoco-agent.jar";
7476
protected static final int HTTP_SERVER_PORT = 8888;
7577

7678
protected static Network sharedNetwork;
@@ -115,6 +117,8 @@ protected GenericContainer<?> createCmdContainer(Path workingDir, boolean debug)
115117
.withFileSystemBind(workingDir.toString(), BUILD_DIR, BindMode.READ_WRITE)
116118
.withEnv("TZ", "America/Los_Angeles");
117119

120+
container = configureJacocoCoverage(container, "cmd");
121+
118122
if (debug) {
119123
container = container.withEnv("SQRL_DEBUG", "1");
120124
}
@@ -127,14 +131,19 @@ protected GenericContainer<?> createServerContainer(Path workingDir) {
127131
var deployPlanPath = workingDir.resolve("build/deploy/plan");
128132
assertThat(deployPlanPath).exists().isDirectory();
129133

130-
return new GenericContainer<>(DockerImageName.parse(SQRL_SERVER_IMAGE + ":" + getImageTag()))
131-
.withNetwork(sharedNetwork)
132-
.withExposedPorts(HTTP_SERVER_PORT)
133-
.withFileSystemBind(deployPlanPath.toString(), "/opt/sqrl/config", BindMode.READ_ONLY)
134-
.withEnv("SQRL_DEBUG", "1")
135-
.waitingFor(
136-
Wait.forLogMessage(".*HTTP server listening on port 8888.*", 1)
137-
.withStartupTimeout(Duration.ofSeconds(30)));
134+
var container =
135+
new GenericContainer<>(DockerImageName.parse(SQRL_SERVER_IMAGE + ":" + getImageTag()))
136+
.withNetwork(sharedNetwork)
137+
.withExposedPorts(HTTP_SERVER_PORT)
138+
.withFileSystemBind(deployPlanPath.toString(), "/opt/sqrl/config", BindMode.READ_ONLY)
139+
.withEnv("SQRL_DEBUG", "1")
140+
.waitingFor(
141+
Wait.forLogMessage(".*HTTP server listening on port 8888.*", 1)
142+
.withStartupTimeout(Duration.ofSeconds(30)));
143+
144+
container = configureJacocoCoverage(container, "server");
145+
146+
return container;
138147
}
139148

140149
protected void compileSqrlProject(Path workingDir) {
@@ -290,6 +299,75 @@ private String getImageTag() {
290299
return System.getProperty("docker.image.tag", "local");
291300
}
292301

302+
@SneakyThrows
303+
private GenericContainer<?> configureJacocoCoverage(GenericContainer<?> container, String component) {
304+
if (!Boolean.parseBoolean(System.getProperty("sqrl.container.coverage", "false"))) {
305+
return container;
306+
}
307+
308+
var jacocoAgentJar = findJacocoAgentJar();
309+
if (jacocoAgentJar == null) {
310+
log.warn("Container coverage enabled but JaCoCo agent jar not found in ~/.m2; skipping");
311+
return container;
312+
}
313+
314+
var jacocoOutDir = Paths.get("target", "jacoco").toAbsolutePath();
315+
var hostDestFile = jacocoOutDir.resolve("jacoco-container.exec");
316+
Files.createDirectories(jacocoOutDir);
317+
318+
var containerDestFile = JACOCO_OUT_DIR + "/jacoco-container.exec";
319+
var agentArg =
320+
"-javaagent:"
321+
+ JACOCO_AGENT_PATH
322+
+ "=destfile="
323+
+ containerDestFile
324+
+ ",append=true,excludes=org/**";
325+
326+
var toolOptions = agentArg;
327+
328+
log.info(
329+
"Enabling container JaCoCo for {}: agent={} destfile={}",
330+
component,
331+
jacocoAgentJar,
332+
hostDestFile);
333+
334+
return container
335+
.withFileSystemBind(jacocoOutDir.toString(), JACOCO_OUT_DIR, BindMode.READ_WRITE)
336+
.withFileSystemBind(jacocoAgentJar.toString(), JACOCO_AGENT_PATH, BindMode.READ_ONLY)
337+
.withEnv("JAVA_TOOL_OPTIONS", toolOptions);
338+
}
339+
340+
@Nullable
341+
private Path findJacocoAgentJar() {
342+
var m2 = Paths.get(System.getProperty("user.home"), ".m2", "repository");
343+
var jacocoDir = m2.resolve(Paths.get("org", "jacoco", "org.jacoco.agent"));
344+
if (!Files.exists(jacocoDir)) {
345+
return null;
346+
}
347+
348+
try (var stream = Files.list(jacocoDir)) {
349+
var versions =
350+
stream
351+
.filter(Files::isDirectory)
352+
.map(p -> p.getFileName().toString())
353+
.sorted()
354+
.toList();
355+
for (int i = versions.size() - 1; i >= 0; i--) {
356+
var version = versions.get(i);
357+
var candidate =
358+
jacocoDir.resolve(
359+
Paths.get(version, "org.jacoco.agent-" + version + "-runtime.jar"));
360+
if (Files.exists(candidate)) {
361+
return candidate;
362+
}
363+
}
364+
return null;
365+
} catch (Exception e) {
366+
log.warn("Failed to locate JaCoCo agent jar under {}", jacocoDir, e);
367+
return null;
368+
}
369+
}
370+
293371
protected String getDockerRunCommand(GenericContainer<?> container, Path workingDir) {
294372
var sb = new StringBuilder();
295373
sb.append("docker run -it --rm");

0 commit comments

Comments
 (0)