Skip to content
5 changes: 2 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>

<ItemGroup>
<PackageVersion Include="coverlet.collector" Version="10.0.0" />
<PackageVersion Include="CSharpier.MsBuild" Version="1.2.6" />
Expand All @@ -12,9 +11,9 @@
<PackageVersion Include="Microsoft.Testing.Platform" Version="2.2.2" />
<PackageVersion Include="MSTest" Version="4.2.2" />
<PackageVersion Include="PolyShim" Version="2.11.0" />
<PackageVersion Include="PowerKit" Version="1.1.1" />
<PackageVersion Include="PowerKit" Version="1.2.0" />
<PackageVersion Include="RazorBlade" Version="1.0.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>
</Project>
</Project>
62 changes: 62 additions & 0 deletions GitHubActionsTestLogger.Tests/MtpSummarySpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,4 +387,66 @@ public async Task I_can_try_to_use_the_logger_to_produce_a_summary_when_the_outp
testOutput.WriteLine("Summary output:");
testOutput.WriteLine(summaryOutput);
}

[Fact]
public async Task I_can_try_to_use_the_logger_to_produce_a_summary_when_the_output_file_is_nearly_full_and_content_contains_non_ascii_characters_and_get_a_truncated_summary_within_the_size_limit()
{
// Arrange
using var testResultsDir = TempDirectory.Create();
using var summaryFile = TempFile.Create();

const int prefillSize = 1024 * 1024 - 250;
File.WriteAllZeroes(summaryFile.Path, prefillSize);

using var commandWriter = new StringWriter();

// Use a file-backed StreamWriter so that the file path is exposed internally
await using var summaryFileStream = File.Open(
summaryFile.Path,
FileMode.Append,
FileAccess.Write,
FileShare.ReadWrite
);

await using var summaryWriter = new StreamWriter(summaryFileStream);

var builder = await TestApplication.CreateBuilderAsync([
"--results-directory",
testResultsDir.Path,
"--report-github",
"--report-github-summary-include-passed",
]);

// Use non-ASCII characters in test names (each Chinese character is 3 bytes in UTF-8,
// so truncating by char count instead of byte count would exceed the size limit)
builder.RegisterFakeTests(
new TestNodeBuilder()
.SetDisplayName(new string('一', 100))
.SetOutcome(TestOutcome.Failed)
.Build(),
new TestNodeBuilder()
.SetDisplayName(new string('二', 100))
.SetOutcome(TestOutcome.Failed)
.Build()
);

builder.AddGitHubActionsReporting(commandWriter, summaryWriter);

// Act
var app = await builder.BuildAsync();
await app.RunAsync();

await summaryWriter.FlushAsync();

// Assert
var commandOutput = commandWriter.ToString();
var summaryFileSize = new FileInfo(summaryFile.Path).Length;

commandOutput.Should().ContainAll("::warning", "truncated");
summaryFileSize.Should().BeLessThanOrEqualTo(1024 * 1024);

testOutput.WriteLine($"Summary file size: {summaryFileSize}");
testOutput.WriteLine("Command output:");
testOutput.WriteLine(commandOutput);
}
}
61 changes: 61 additions & 0 deletions GitHubActionsTestLogger.Tests/VsTestSummarySpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -432,4 +432,65 @@ public async Task I_can_try_to_use_the_logger_to_produce_a_summary_when_the_outp
testOutput.WriteLine("Summary output:");
testOutput.WriteLine(summaryOutput);
}

[Fact]
public async Task I_can_try_to_use_the_logger_to_produce_a_summary_when_the_output_file_is_nearly_full_and_content_contains_non_ascii_characters_and_get_a_truncated_summary_within_the_size_limit()
{
// Arrange
using var summaryFile = TempFile.Create();

const int prefillSize = 1024 * 1024 - 250;
File.WriteAllZeroes(summaryFile.Path, prefillSize);

using var commandWriter = new StringWriter();

var events = new FakeTestLoggerEvents();
var logger = new VsTestLogger();

// Use a file-backed StreamWriter so that the file path is exposed internally
using var summaryFileStream = File.Open(
summaryFile.Path,
FileMode.Append,
FileAccess.Write,
FileShare.ReadWrite
);

using var summaryWriter = new StreamWriter(summaryFileStream);

logger.Initialize(
events,
new Dictionary<string, string?> { ["summary-include-passed"] = "true" },
commandWriter,
summaryWriter
);

// Act
// Use non-ASCII characters in test names (each Chinese character is 3 bytes in UTF-8,
// so truncating by char count instead of byte count would exceed the size limit)
events.SimulateTestRun(
new TestResultBuilder()
.SetDisplayName(new string('一', 100))
.SetFullyQualifiedName("TestProject.SomeTests.Test1")
.SetOutcome(TestOutcome.Failed)
.Build(),
new TestResultBuilder()
.SetDisplayName(new string('二', 100))
.SetFullyQualifiedName("TestProject.SomeTests.Test2")
.SetOutcome(TestOutcome.Failed)
.Build()
);

await summaryWriter.FlushAsync();

// Assert
var commandOutput = commandWriter.ToString();
var summaryFileSize = new FileInfo(summaryFile.Path).Length;

commandOutput.Should().ContainAll("::warning", "truncated");
summaryFileSize.Should().BeLessThanOrEqualTo(1024 * 1024);

testOutput.WriteLine($"Summary file size: {summaryFileSize}");
testOutput.WriteLine("Command output:");
testOutput.WriteLine(commandOutput);
}
}
5 changes: 3 additions & 2 deletions GitHubActionsTestLogger/GitHub/GitHubWorkflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ private string TruncateSummary(string content)
&& requiredSize <= availableSize
? content
// There is enough space to fit some of the content
: availableSize > 0 && requiredSize > availableSize ? content[..availableSize]
: availableSize > 0 && requiredSize > availableSize
? content.TruncateBytes(availableSize, Encoding.UTF8)
Comment thread
Tyrrrz marked this conversation as resolved.
Outdated
// There is no space at all
: string.Empty;
Comment thread
Tyrrrz marked this conversation as resolved.
}
Expand Down Expand Up @@ -155,7 +156,7 @@ If you have multiple summary providers in the same step (e.g. running multiple t
await summaryWriter.WriteLineAsync();
await summaryWriter.WriteLineAsync();

await summaryWriter.WriteLineAsync(content);
await summaryWriter.WriteLineAsync(truncated);
await summaryWriter.FlushAsync();
Comment thread
Tyrrrz marked this conversation as resolved.
Outdated
}
}
Expand Down