Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- supported frameworks -->
<PropertyGroup>
<TargetFrameworks>net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<RootNamespace>Sisk.Cadente.CoreEngine</RootNamespace>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>
Expand Down
3 changes: 2 additions & 1 deletion cadente/Sisk.Cadente/Sisk.Cadente.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

<!-- supported frameworks -->
<PropertyGroup>
<TargetFrameworks>net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<RootNamespace>Sisk.Cadente</RootNamespace>
<LangVersion>preview</LangVersion>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>

Expand Down
120 changes: 120 additions & 0 deletions tests/Sisk.Core/Tests/LargePayloadTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Net.Http;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using System.Text; is unused in this file. With TreatWarningsAsErrors=true in the test project, this will fail the build (CS8019). Remove it or use it.

Suggested change
using System.Net.Http;

Copilot uses AI. Check for mistakes.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sisk.Cadente;
using Sisk.Cadente.CoreEngine;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using Sisk.Cadente; appears unused here (types are coming from Sisk.Cadente.CoreEngine). With warnings-as-errors, this will break the build; remove the directive or reference a type from that namespace if intended.

Suggested change
using Sisk.Cadente.CoreEngine;

Copilot uses AI. Check for mistakes.
using Sisk.Core.Http;
using Sisk.Core.Http.Hosting;
using Sisk.Core.Routing;

namespace tests;
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file uses namespace tests; while the other test classes in this project consistently use namespace tests.Tests; (e.g., Tests/HttpRequestTests.cs, Tests/EngineRareTests.cs). Align the namespace to keep discovery/organization consistent.

Suggested change
namespace tests;
namespace tests.Tests;

Copilot uses AI. Check for mistakes.

[TestClass]
public class LargePayloadTests
{
private HttpServerHostContext? _server;
private int _port;

Comment on lines +15 to +20
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test project runs with [assembly: Parallelize(Scope = MethodLevel, Workers = 4)]. These payload sizes (especially 500MB and 1.5GB) can easily cause CI timeouts/OOM when multiple tests execute concurrently. Mark this class/methods as [DoNotParallelize] and/or gate the largest cases behind an env var / explicit category so they don't run in the default suite.

Copilot uses AI. Check for mistakes.
private static int GetRandomPort()
{
using var listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Loopback, 0);
listener.Start();
return ((System.Net.IPEndPoint)listener.LocalEndpoint).Port;
Comment on lines +23 to +25
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This duplicates ListeningPort.GetRandomPort() (and the host builder already chooses a random port when none is specified). Consider reusing the existing helper or letting HttpServer.CreateBuilder().Build() pick the port, to avoid duplicated logic.

Suggested change
using var listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Loopback, 0);
listener.Start();
return ((System.Net.IPEndPoint)listener.LocalEndpoint).Port;
return ListeningPort.GetRandomPort();

Copilot uses AI. Check for mistakes.
}

private async Task<string> CalculateHashAsync(Stream stream)
{
byte[] hashBytes = await SHA1.HashDataAsync(stream);
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses SHA1.HashDataAsync(...). If .NET analyzers are enabled (common in SDK-style projects), SHA1 can trigger security analyzer warnings (e.g., CA5350) which become errors due to TreatWarningsAsErrors=true. Prefer SHA256 (or another non-deprecated hash) for test integrity checks.

Suggested change
byte[] hashBytes = await SHA1.HashDataAsync(stream);
byte[] hashBytes = await SHA256.HashDataAsync(stream);

Copilot uses AI. Check for mistakes.
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
}

[TestInitialize]
public void Setup()
{
_port = GetRandomPort();
}

[TestCleanup]
public void Cleanup()
{
_server?.Dispose();
}

private async Task RunPayloadTest(long size)
{
var router = new Router();
router.SetRoute(RouteMethod.Post, "/payload", async (HttpRequest req) =>
{
using var stream = req.GetRequestStream();
string hash = await CalculateHashAsync(stream);
return new HttpResponse(200) { Content = new StringContent(hash) };
});

var engine = new CadenteHttpServerEngine(host => {
// Configure large timeouts for the test
host.TimeoutManager.BodyDrainTimeout = TimeSpan.FromMinutes(10);
host.TimeoutManager.ClientReadTimeout = TimeSpan.FromMinutes(10);
host.TimeoutManager.ClientWriteTimeout = TimeSpan.FromMinutes(10);
});

_server = HttpServer.CreateBuilder()
.UseListeningPort((ushort)_port)
.UseRouter(router)
.UseEngine(engine)
.UseConfiguration(config =>
{
config.AccessLogsStream = null;
config.ErrorsLogsStream = LogStream.ConsoleOutput;
})
.Build();

_server.Start(verbose: false, preventHault: false);

using var client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(10);

int seed = 12345;
using var payloadStream = new RandomStream(size, seed);
using var content = new StreamContent(payloadStream);
content.Headers.ContentLength = size;

// Calculate expected hash
using var calculationStream = new RandomStream(size, seed);
string expectedHash = await CalculateHashAsync(calculationStream);

var response = await client.PostAsync($"http://localhost:{_port}/payload", content);
response.EnsureSuccessStatusCode();

string serverHash = await response.Content.ReadAsStringAsync();
Assert.AreEqual(expectedHash, serverHash, $"Hash mismatch for payload size {size}");
}

[TestMethod]
public async Task TestPayload_10MB()
{
await RunPayloadTest(10 * 1024 * 1024);
}

[TestMethod]
public async Task TestPayload_100MB()
{
await RunPayloadTest(100 * 1024 * 1024);
}

[TestMethod]
public async Task TestPayload_500MB()
{
await RunPayloadTest(500 * 1024 * 1024);
}
Comment on lines +95 to +111
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 10MB/100MB/500MB tests have no MSTest [Timeout], so a hung upload/read can stall the whole run (and parallel workers). Consider adding timeouts (or a shared timeout policy) for each method, not just the 1.5GB case.

Copilot uses AI. Check for mistakes.

[TestMethod]
[Timeout(600000)] // 10 minutes
public async Task TestPayload_1_5GB()
{
long size = (long)(1.5 * 1024 * 1024 * 1024);
await RunPayloadTest(size);
}
}
49 changes: 49 additions & 0 deletions tests/Sisk.Core/Tests/RandomStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.IO;

namespace tests;

public class RandomStream : Stream
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is in namespace tests; but appears to be a helper used by tests. If it's meant to be internal-only test infrastructure, consider making it internal sealed to reduce surface area and align with the rest of the test assembly style.

Suggested change
public class RandomStream : Stream
internal sealed class RandomStream : Stream

Copilot uses AI. Check for mistakes.
{
private readonly long _length;
private long _position;
private readonly Random _random;

public RandomStream(long length, int seed)
{
_length = length;
_random = new Random(seed);
}

public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => _length;
public override long Position
{
get => _position;
set => throw new NotSupportedException();
}

public override void Flush() { }

public override int Read(byte[] buffer, int offset, int count)
{
return Read(buffer.AsSpan(offset, count));
}

public override int Read(Span<byte> buffer)
{
long remaining = _length - _position;
if (remaining <= 0) return 0;

int toRead = (int)Math.Min(buffer.Length, remaining);
_random.NextBytes(buffer.Slice(0, toRead));
_position += toRead;
return toRead;
}

public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}
3 changes: 2 additions & 1 deletion tests/Sisk.Core/tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -15,6 +15,7 @@

<ItemGroup>
<ProjectReference Include="..\..\cadente\Sisk.Cadente.CoreEngine\Sisk.Cadente.CoreEngine.csproj" />
<ProjectReference Include="..\..\cadente\Sisk.Cadente\Sisk.Cadente.csproj" />
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added project reference to Sisk.Cadente.csproj looks redundant: tests already references Sisk.Cadente.CoreEngine, which itself references Sisk.Cadente transitively. If nothing in the test project uses Sisk.Cadente directly, consider removing this reference to keep dependencies minimal.

Suggested change
<ProjectReference Include="..\..\cadente\Sisk.Cadente\Sisk.Cadente.csproj" />

Copilot uses AI. Check for mistakes.
<ProjectReference Include="..\..\src\Sisk.Core.csproj" />
</ItemGroup>

Expand Down
Loading