diff --git a/src/main/java/io/jenkins/plugins/checks/status/FlowExecutionAnalyzer.java b/src/main/java/io/jenkins/plugins/checks/status/FlowExecutionAnalyzer.java index 2f4a5a2d..1f076597 100644 --- a/src/main/java/io/jenkins/plugins/checks/status/FlowExecutionAnalyzer.java +++ b/src/main/java/io/jenkins/plugins/checks/status/FlowExecutionAnalyzer.java @@ -36,6 +36,7 @@ class FlowExecutionAnalyzer { private static final Logger LOGGER = Logger.getLogger(FlowExecutionAnalyzer.class.getName()); private static final String TRUNCATED_MESSAGE = "\n\nOutput truncated."; + private static final String TRUNCATED_MESSAGE_BUILD_LOG = "Build log truncated.\n\n"; private static final int MAX_MESSAGE_SIZE_TO_CHECKS_API = 65_535; private final Run run; @@ -217,7 +218,7 @@ private static String getLog(final FlowNode flowNode, final int maxMessageSize) return new TruncatedString.Builder() .setChunkOnNewlines() .setTruncateStart() - .withTruncationText(TRUNCATED_MESSAGE) + .withTruncationText(TRUNCATED_MESSAGE_BUILD_LOG) .addText(log) .build() .build(maxMessageSize); diff --git a/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java b/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java index 3e64b049..dc137e5f 100644 --- a/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java +++ b/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java @@ -297,6 +297,54 @@ public void shouldPublishStageDetailsWithoutLogsIfRequested() { }); } + /** + * Test that log messages are properly truncated when they exceed the maximum size limit. + */ + @Test + public void shouldTruncateLogsWhenExceedingMaxSize() { + getProperties().setApplicable(true); + getProperties().setSkipped(false); + getProperties().setName("Test Status"); + getProperties().setSuppressLogs(false); + WorkflowJob job = createPipeline(); + + // Create a pipeline that generates a large log output + job.setDefinition(new CpsFlowDefinition("" + + "node {\n" + + " stage('Large Log Stage') {\n" + + " // Generate a large log by executing shell commands\n" + + " sh '''\n" + + " for i in {1..1000}; do\n" + + " echo \"Line $i: $(date) - This is a very long log line that will be repeated many times to test truncation. Adding some extra system information here.\"\n" + + " done\n" + + " exit 1\n" + + " '''\n" + + " error('Pipeline failed with large logs')\n" + + " }\n" + + "}", true)); + + buildWithResult(job, Result.FAILURE); + + List checksDetails = getFactory().getPublishedChecks(); + + // Get the final check details which should contain the truncated logs + ChecksDetails details = checksDetails.get(checksDetails.size() - 1); + assertThat(details.getStatus()).isEqualTo(ChecksStatus.COMPLETED); + assertThat(details.getConclusion()).isEqualTo(ChecksConclusion.FAILURE); + assertThat(details.getOutput()).isPresent().get().satisfies(output -> { + assertThat(output.getSummary()).isPresent().get().satisfies(summary -> { + // Verify the log section exists and is truncated + assertThat(summary).contains("
"); + assertThat(summary).contains("Build log"); + assertThat(summary).contains("Build log truncated."); + // Verify the truncation message appears at the start of the log section to show that truncation occurred at start + assertThat(summary).matches(Pattern.compile(".*Build log\\s+\\n```\\s*\\nBuild log truncated.\\n\\n.*", Pattern.DOTALL)); + // Verify the total size is within limits + assertThat(summary.length()).isLessThanOrEqualTo(65535); + }); + }); + } + /** * Validates that a simple successful pipeline works. */