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
30 changes: 29 additions & 1 deletion .github/workflows/pr_validation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ permissions:
contents: read

jobs:
aot-compat:
permissions: write-all
name: AOT-publish-${{matrix.os}}-${{ matrix.version }}
runs-on: ${{matrix.os}}

strategy:
matrix:
os: [ubuntu-latest, windows-latest]
version: [ net8.0 ]

steps:
- name: "Checkout"
uses: actions/[email protected]
with:
lfs: true
fetch-depth: 0

- name: "Install .NET SDK"
uses: actions/[email protected]
with:
dotnet-version: |
8.0.x
global-json-file: "./global.json"

- name: publish AOT testApp, assert static analysis warning count, and run the app
shell: pwsh
run: .\build\test-aot-compatibility.ps1 ${{ matrix.version }}

test:
timeout-minutes: 20 # Increase this timeout value as needed
# Permissions this GitHub Action needs for other things in GitHub
Expand Down Expand Up @@ -107,4 +135,4 @@ jobs:
if: always() && runner.os == 'Linux'
uses: EnricoMi/[email protected]
with:
trx_files: "${{ github.workspace }}/**/*.trx"
trx_files: "${{ github.workspace }}/**/*.trx"
5 changes: 5 additions & 0 deletions TurboMqtt.sln
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TurboMqtt.Container.Tests", "tests\TurboMqtt.Container.Tests\TurboMqtt.Container.Tests.csproj", "{CEE1640B-1C76-4683-BA14-C970B19E17E2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestContainers.TurboMqtt", "tests\TestContainers.TurboMqtt\TestContainers.TurboMqtt.csproj", "{CC7C2D64-7C40-4676-A32A-0F2ECDE99BDF}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TurboMqtt.AotCompatibility.TestApp", "tests\TurboMqtt.AotCompatibility.TestApp\TurboMqtt.AotCompatibility.TestApp.csproj", "{B2FBA3C2-00D7-4ACA-982C-BA9BF9E3F6FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -65,6 +66,10 @@ Global
{CC7C2D64-7C40-4676-A32A-0F2ECDE99BDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC7C2D64-7C40-4676-A32A-0F2ECDE99BDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC7C2D64-7C40-4676-A32A-0F2ECDE99BDF}.Release|Any CPU.Build.0 = Release|Any CPU
{B2FBA3C2-00D7-4ACA-982C-BA9BF9E3F6FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2FBA3C2-00D7-4ACA-982C-BA9BF9E3F6FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2FBA3C2-00D7-4ACA-982C-BA9BF9E3F6FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2FBA3C2-00D7-4ACA-982C-BA9BF9E3F6FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AF733B60-8A45-42FC-8E80-B4EE432EE0AD} = {294A1BA9-C55D-4F08-8EEF-BC6B467892CB}
Expand Down
57 changes: 57 additions & 0 deletions build/test-aot-compatibility.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
param([string]$targetNetFramework = "net8.0")

$rootDirectory = Split-Path $PSScriptRoot -Parent
$publishOutput = dotnet publish $rootDirectory/tests/TurboMqtt.AotCompatibility.TestApp/TurboMqtt.AotCompatibility.TestApp.csproj -nodeReuse:false /p:UseSharedCompilation=false /p:ExposeExperimentalFeatures=true

$actualWarningCount = 0

foreach ($line in $($publishOutput -split "`r`n"))
{
if ($line -like "*analysis warning IL*")
{
Write-Host $line

$actualWarningCount += 1
}
}

# Determine the OS-specific folder
$osPlatform = [System.Runtime.InteropServices.RuntimeInformation]::OSDescription
if ($osPlatform -match "Windows") {
$osFolder = "win-x64"
} else {
$osFolder = "linux-x64"
# Default to linux
}

$testAppPath = Join-Path -Path $rootDirectory/tests/TurboMqtt.AotCompatibility.TestApp/bin/Release/$targetNetFramework -ChildPath $osFolder

if (-Not (Test-Path $testAppPath)) {
Write-Error "Test App path does not exist: $testAppPath"
Exit 1
}

pushd $testAppPath

Write-Host "Executing test App..."
./TurboMqtt.AotCompatibility.TestApp
Write-Host "Finished executing test App"

if ($LastExitCode -ne 0)
{
Write-Host "There was an error while executing AotCompatibility Test App. LastExitCode is:", $LastExitCode
}

popd

Write-Host "Actual warning count is:", $actualWarningCount
$expectedWarningCount = 0

$testPassed = 0
if ($actualWarningCount -ne $expectedWarningCount)
{
$testPassed = 1
Write-Host "Actual warning count:", $actualWarningCount, "is not as expected. Expected warning count is:", $expectedWarningCount
}

Exit $testPassed
68 changes: 68 additions & 0 deletions tests/TurboMqtt.AotCompatibility.TestApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Akka.Actor;
using TurboMqtt;
using TurboMqtt.Client;

var actorSystem = ActorSystem.Create("AotTestSystem");
var clientFactory = new MqttClientFactory(actorSystem);

var inMemoryClient =
await clientFactory.CreateInMemoryClient(new MqttClientConnectOptions("test-client",
TurboMqtt.Protocol.MqttProtocolVersion.V3_1_1));

var connectResult = await inMemoryClient.ConnectAsync(CancellationToken.None);

if (!connectResult.IsSuccess)
{
Console.WriteLine("Failed to connect to broker: " + connectResult.Reason);
return;
}

Console.WriteLine("Connected to broker.");

// go with QoS 2 because it exercises the most stuff
var subscribeResult = await inMemoryClient.SubscribeAsync("test-topic", QualityOfService.ExactlyOnce, CancellationToken.None);

if (!subscribeResult.IsSuccess)
{
Console.WriteLine("Failed to subscribe to topic: " + subscribeResult.Reason);
return;
}

Console.WriteLine("Subscribed to topic.");

const int MsgCount = 10;

// publish 10 messages with QoS 2
for (var i = 0; i < MsgCount; i++)
{
var publishResult = await inMemoryClient.PublishAsync(new MqttMessage("test-topic", "test-payload")
{
QoS = QualityOfService.ExactlyOnce
}, CancellationToken.None);

if (!publishResult.IsSuccess)
{
Console.WriteLine("Failed to publish message: " + publishResult.Reason);
return;
}

Console.WriteLine("Published message.");
}

Console.WriteLine("Published all messages.");

// receive all of the messages we just published
using var quickCts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var receivedMessages = inMemoryClient.ReceivedMessages;
var recvMsgCount = 0;
while(recvMsgCount < MsgCount && await receivedMessages.WaitToReadAsync(quickCts.Token))
{
while(receivedMessages.TryRead(out var msg))
{
Console.WriteLine("Received message: " + msg.Payload);
recvMsgCount++;
}
}

Console.WriteLine("Received all messages.");
await inMemoryClient.DisconnectAsync(CancellationToken.None);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<SelfContained>true</SelfContained>
<IsPackable>false</IsPackable>
</PropertyGroup>

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

</Project>
Loading