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
15 changes: 15 additions & 0 deletions Magma.sln
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Magma.WinTun.TcpHost", "sam
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Magma.AF_XDP", "src\Magma.AF_XDP\Magma.AF_XDP.csproj", "{5922914B-D7E6-4A23-9A26-5589FD72727B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Magma.WinTun.Facts", "test\Magma.WinTun.Facts\Magma.WinTun.Facts.csproj", "{8B93DD2C-0C6B-4440-9126-2AF232478660}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -307,6 +309,18 @@ Global
{5922914B-D7E6-4A23-9A26-5589FD72727B}.Release|x64.Build.0 = Release|Any CPU
{5922914B-D7E6-4A23-9A26-5589FD72727B}.Release|x86.ActiveCfg = Release|Any CPU
{5922914B-D7E6-4A23-9A26-5589FD72727B}.Release|x86.Build.0 = Release|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Debug|x64.ActiveCfg = Debug|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Debug|x64.Build.0 = Debug|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Debug|x86.ActiveCfg = Debug|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Debug|x86.Build.0 = Debug|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Release|Any CPU.Build.0 = Release|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Release|x64.ActiveCfg = Release|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Release|x64.Build.0 = Release|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Release|x86.ActiveCfg = Release|Any CPU
{8B93DD2C-0C6B-4440-9126-2AF232478660}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -332,6 +346,7 @@ Global
{503140F9-24F6-41B5-89F2-BB0FB24CCB2E} = {34A1DC50-486C-4BB9-9929-1805CA0B0DD0}
{845A5A0B-E59B-46AF-BF95-4FC50D660967} = {23E375E0-8A4A-4D6A-8C96-9F2046CE9EB0}
{5922914B-D7E6-4A23-9A26-5589FD72727B} = {34A1DC50-486C-4BB9-9929-1805CA0B0DD0}
{8B93DD2C-0C6B-4440-9126-2AF232478660} = {B1BA53C8-CCCF-46D5-BA9F-6031811F2E19}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {99D656D2-FC86-462A-BB4C-610D644ADC62}
Expand Down
19 changes: 19 additions & 0 deletions test/Magma.WinTun.Facts/Magma.WinTun.Facts.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The test code does not contain any unsafe code blocks. The AllowUnsafeBlocks property can be removed. Other test projects in the codebase (e.g., Magma.Internet.Ip.Facts, Magma.Link.Facts) don't set this property unless the test code directly uses unsafe blocks.

Copilot uses AI. Check for mistakes.
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.6.6" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Magma.WinTun\Magma.WinTun.csproj" />
</ItemGroup>

</Project>
57 changes: 57 additions & 0 deletions test/Magma.WinTun.Facts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Magma.WinTun.Facts

Test suite for the WinTun module.

## Running Tests

### Unit Tests

Unit tests run on all platforms (Windows and Linux) and do not require the WinTun driver:

```bash
dotnet test test/Magma.WinTun.Facts
```

### Integration Tests

Integration tests require:
- Windows operating system
- WinTun driver installed
- A configured TAP adapter
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

While the implementation uses TAP-Windows compatibility (as noted in src/Magma.WinTun/README.md), referring to "A configured TAP adapter" might be confusing since the module is called WinTun and the distinction between TAP and TUN is important. Consider clarifying this as "A configured WinTun adapter (using TAP-compatible interface)" or similar to reduce confusion.

Copilot uses AI. Check for mistakes.

Integration tests are **skipped by default**. To enable them:

1. Set the environment variable:
```powershell
$env:WINTUN_INTEGRATION_TESTS="1"
```

2. (Optional) Specify a custom adapter name:
```powershell
$env:WINTUN_ADAPTER_NAME="YourAdapterName"
```

3. Run the tests:
```bash
dotnet test test/Magma.WinTun.Facts
```

Or run only integration tests:
```bash
dotnet test test/Magma.WinTun.Facts --filter Category=Integration
```

## Test Categories

- **Unit Tests**: Test public APIs without requiring the WinTun driver
- `WinIOFacts`: Constants and P/Invoke declarations
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The test class WinIOFacts mentioned in this documentation does not exist in the test project. Only WinTunMemoryPoolFacts, WinTunTransportReceiverFacts, and WinTunPortIntegrationFacts are implemented. Remove this reference or implement the missing test class.

Copilot uses AI. Check for mistakes.
- `WinTunTransportReceiverFacts`: Transport receiver interface
- `WinTunMemoryPoolFacts`: Memory pool lifecycle and management

- **Integration Tests** (Category="Integration"): Require WinTun driver
- `WinTunPortIntegrationFacts`: Adapter create/destroy lifecycle

## Platform Support

- **Linux**: Unit tests run and pass. Integration tests are skipped.
- **Windows**: All tests can run if WinTun driver is installed and integration tests are enabled.
115 changes: 115 additions & 0 deletions test/Magma.WinTun.Facts/WinTunMemoryPoolFacts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System;
using System.Buffers;
using System.Threading.Tasks;
using Magma.WinTun.Internal;
using Xunit;

namespace Magma.WinTun.Facts
{
public class WinTunMemoryPoolFacts
{
[Fact]
public void PoolCreatesBuffersOfCorrectSize()
{
var poolSize = 10;
var bufferSize = 2000;
var pool = new WinTunMemoryPool(poolSize, bufferSize);

var success = pool.TryGetMemory(out var memory);

Assert.True(success);
Assert.NotNull(memory);
Assert.Equal(bufferSize, memory.Memory.Length);

memory.Return();
}

[Fact]
public void PoolSupportsMultipleBuffers()
{
var poolSize = 5;
var bufferSize = 1500;
var pool = new WinTunMemoryPool(poolSize, bufferSize);

var buffers = new WinTunMemoryPool.WinTunOwnedMemory[poolSize];

for (var i = 0; i < poolSize; i++)
{
var success = pool.TryGetMemory(out buffers[i]);
Assert.True(success);
Assert.Equal(bufferSize, buffers[i].Memory.Length);
}

var exhausted = pool.TryGetMemory(out _);
Assert.False(exhausted);
Comment on lines +43 to +44
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The variable name exhausted is misleading because it holds the return value of TryGetMemory, which returns true on success and false when exhausted. Since you're asserting it's false, the variable actually indicates "not exhausted" (i.e., success). Consider renaming to success to match the semantic meaning of the return value, making the assertion Assert.False(success) clearer.

Copilot uses AI. Check for mistakes.

for (var i = 0; i < poolSize; i++)
{
buffers[i].Return();
}
}

[Fact]
public void ReturnedBufferCanBeReused()
{
var pool = new WinTunMemoryPool(2, 1000);

var success1 = pool.TryGetMemory(out var memory1);
Assert.True(success1);

memory1.Return();

var success2 = pool.TryGetMemory(out var memory2);
Assert.True(success2);

memory2.Return();
}

[Fact]
public void TryGetMemoryReturnsFalseWhenExhausted()
{
var pool = new WinTunMemoryPool(1, 1000);

var success1 = pool.TryGetMemory(out var memory1);
Assert.True(success1);

var success2 = pool.TryGetMemory(out var memory2);
Assert.False(success2);
Assert.Null(memory2);

memory1.Return();
}

[Fact]
public async Task GetMemoryAsyncWaitsWhenPoolIsEmpty()
{
var pool = new WinTunMemoryPool(1, 1000);

var memory1 = await pool.GetMemoryAsync();

var getTask = pool.GetMemoryAsync();
await Task.Delay(50);
Assert.False(getTask.IsCompleted);

memory1.Return();

var memory2 = await getTask;
Assert.NotNull(memory2);

memory2.Return();
}

[Fact]
public void MemoryOwnerGetSpanReturnsCorrectSpan()
{
var pool = new WinTunMemoryPool(1, 1500);
var success = pool.TryGetMemory(out var memory);

Assert.True(success);
var span = memory.GetSpan();
Assert.Equal(1500, span.Length);

memory.Return();
}
}
}
65 changes: 65 additions & 0 deletions test/Magma.WinTun.Facts/WinTunPortIntegrationFacts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Runtime.InteropServices;
using Magma.Network.Abstractions;
using Magma.WinTun.Internal;
using Xunit;

namespace Magma.WinTun.Facts
{
[Trait("Category", "Integration")]
public class WinTunPortIntegrationFacts
{
private static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
private static bool IntegrationTestsEnabled =>
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WINTUN_INTEGRATION_TESTS"));

[Fact(Skip = "Requires WinTun driver and adapter - set WINTUN_INTEGRATION_TESTS=1 to enable")]
public void CanCreateWinTunPort()
{
if (!IsWindows || !IntegrationTestsEnabled)
{
return;
}
Comment on lines +16 to +22
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The test has both a Skip attribute and runtime checks for the same conditions. This is redundant and means the test will never actually run even when WINTUN_INTEGRATION_TESTS is set. Either remove the Skip attribute to allow the test to run when the environment variable is set, or remove the runtime checks if the test should always be skipped. The former approach would be more useful.

Copilot uses AI. Check for mistakes.

var adapterName = Environment.GetEnvironmentVariable("WINTUN_ADAPTER_NAME") ?? "WinTun";

using (var port = new WinTunPort<TestPacketReceiver>(
adapterName,
transmitter => new TestPacketReceiver()))
{
Assert.NotNull(port);
}
}

[Fact(Skip = "Requires WinTun driver and adapter - set WINTUN_INTEGRATION_TESTS=1 to enable")]
public void WinTunPortDisposesCleanly()
{
if (!IsWindows || !IntegrationTestsEnabled)
{
return;
}
Comment on lines +34 to +40
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The test has both a Skip attribute and runtime checks for the same conditions. This is redundant and means the test will never actually run even when WINTUN_INTEGRATION_TESTS is set. Either remove the Skip attribute to allow the test to run when the environment variable is set, or remove the runtime checks if the test should always be skipped. The former approach would be more useful.

Copilot uses AI. Check for mistakes.

var adapterName = Environment.GetEnvironmentVariable("WINTUN_ADAPTER_NAME") ?? "WinTun";

var port = new WinTunPort<TestPacketReceiver>(
adapterName,
transmitter => new TestPacketReceiver());

port.Dispose();

port.Dispose();
}

private class TestPacketReceiver : IPacketReceiver
{
public void FlushPendingAcks()
{
}

public T TryConsume<T>(T input) where T : System.Buffers.IMemoryOwner<byte>
{
return default;
}
}
}
}
33 changes: 33 additions & 0 deletions test/Magma.WinTun.Facts/WinTunTransportReceiverFacts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Buffers;
using Magma.WinTun;
using Xunit;

namespace Magma.WinTun.Facts
{
public class WinTunTransportReceiverFacts
{
[Fact]
public void CanInstantiateWinTunTransportReceiver()
{
var receiver = new WinTunTransportReceiver();
Assert.NotNull(receiver);
}

[Fact]
public void FlushPendingAcksThrowsNotImplementedException()
{
var receiver = new WinTunTransportReceiver();
Assert.Throws<NotImplementedException>(() => receiver.FlushPendingAcks());
}

[Fact]
public void TryConsumeThrowsNotImplementedException()
{
var receiver = new WinTunTransportReceiver();
using var memory = MemoryPool<byte>.Shared.Rent(100);

Assert.Throws<NotImplementedException>(() => receiver.TryConsume(memory));
}
}
}
Loading