diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 0dfbccc4e..3804712a3 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"nuke.globaltool": {
- "version": "6.0.3",
+ "version": "10.1.0",
"commands": [
"nuke"
]
diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index b96a92417..90081562c 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -1,23 +1,56 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
- "$ref": "#/definitions/build",
- "title": "Build Schema",
"definitions": {
- "build": {
- "type": "object",
+ "Host": {
+ "type": "string",
+ "enum": [
+ "AppVeyor",
+ "AzurePipelines",
+ "Bamboo",
+ "Bitbucket",
+ "Bitrise",
+ "GitHubActions",
+ "GitLab",
+ "Jenkins",
+ "Rider",
+ "SpaceAutomation",
+ "TeamCity",
+ "Terminal",
+ "TravisCI",
+ "VisualStudio",
+ "VSCode"
+ ]
+ },
+ "ExecutableTarget": {
+ "type": "string",
+ "enum": [
+ "Clean",
+ "Compile",
+ "CompileDotNet",
+ "CompileNetFramework",
+ "CopyToLocalPackages",
+ "Default",
+ "Pack",
+ "PackTestPortForwarder",
+ "Restore",
+ "TestLinux",
+ "TestWindows",
+ "TestWindowsDotNet",
+ "TestWindowsNetFramework"
+ ]
+ },
+ "Verbosity": {
+ "type": "string",
+ "description": "",
+ "enum": [
+ "Verbose",
+ "Normal",
+ "Minimal",
+ "Quiet"
+ ]
+ },
+ "NukeBuild": {
"properties": {
- "AutoDetectBranch": {
- "type": "boolean",
- "description": "Whether to auto-detect the branch name - this is okay for a local build, but should not be used under CI"
- },
- "Configuration": {
- "type": "string",
- "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)",
- "enum": [
- "Debug",
- "Release"
- ]
- },
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
@@ -27,34 +60,13 @@
"description": "Shows the help text for this build assembly"
},
"Host": {
- "type": "string",
"description": "Host for execution. Default is 'automatic'",
- "enum": [
- "AppVeyor",
- "AzurePipelines",
- "Bamboo",
- "Bitbucket",
- "Bitrise",
- "GitHubActions",
- "GitLab",
- "Jenkins",
- "Rider",
- "SpaceAutomation",
- "TeamCity",
- "Terminal",
- "TravisCI",
- "VisualStudio",
- "VSCode"
- ]
+ "$ref": "#/definitions/Host"
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
- "OCTOVERSION_CurrentBranch": {
- "type": "string",
- "description": "Branch name for OctoVersion to use to calculate the version number. Can be set via the environment variable OCTOVERSION_CurrentBranch"
- },
"Partition": {
"type": "string",
"description": "Partition to use on CI"
@@ -74,73 +86,65 @@
"type": "string",
"description": "Root directory during build execution"
},
- "RunDotMemoryTests": {
- "type": "boolean",
- "description": "True if dot memory tests should be run, otherwise false. Default to True for Windows and False for Linux"
- },
"Skip": {
"type": "array",
"description": "List of targets to be skipped. Empty list skips all dependencies",
"items": {
- "type": "string",
- "enum": [
- "Clean",
- "Compile",
- "CompileNet48",
- "CompileNet80",
- "CopyToLocalPackages",
- "Default",
- "Pack",
- "PackTestPortForwarder",
- "Restore",
- "TestLinux",
- "TestWindows",
- "TestWindowsNet48",
- "TestWindowsNet80"
- ]
+ "$ref": "#/definitions/ExecutableTarget"
}
},
- "Solution": {
- "type": "string",
- "description": "Path to a solution file that is automatically loaded"
- },
"Target": {
"type": "array",
"description": "List of targets to be invoked. Default is '{default_target}'",
"items": {
- "type": "string",
- "enum": [
- "Clean",
- "Compile",
- "CompileNet48",
- "CompileNet80",
- "CopyToLocalPackages",
- "Default",
- "Pack",
- "PackTestPortForwarder",
- "Restore",
- "TestLinux",
- "TestWindows",
- "TestWindowsNet48",
- "TestWindowsNet80"
- ]
+ "$ref": "#/definitions/ExecutableTarget"
}
},
- "TestFilter": {
- "type": "string",
- "description": "The test Filter passed to dotnet test e.g. TestCategory=Async"
- },
"Verbosity": {
- "type": "string",
"description": "Logging verbosity during build execution. Default is 'Normal'",
+ "$ref": "#/definitions/Verbosity"
+ }
+ }
+ }
+ },
+ "allOf": [
+ {
+ "properties": {
+ "AutoDetectBranch": {
+ "type": "boolean",
+ "description": "Whether to auto-detect the branch name - this is okay for a local build, but should not be used under CI"
+ },
+ "Configuration": {
+ "type": "string",
+ "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)",
"enum": [
- "Minimal",
- "Normal",
- "Quiet",
- "Verbose"
+ "Debug",
+ "Release"
]
+ },
+ "OCTOVERSION_CurrentBranch": {
+ "type": "string",
+ "description": "Branch name for OctoVersion to use to calculate the version number. Can be set via the environment variable OCTOVERSION_CurrentBranch"
+ },
+ "RunDotMemoryTests": {
+ "type": [
+ "boolean",
+ "null"
+ ],
+ "description": "True if dot memory tests should be run, otherwise false. Default to True for Windows and False for Linux"
+ },
+ "Solution": {
+ "type": "string",
+ "description": "Path to a solution file that is automatically loaded"
+ },
+ "TestFilter": {
+ "type": "string",
+ "description": "The test Filter passed to dotnet test e.g. TestCategory=Async"
}
}
+ },
+ {
+ "$ref": "#/definitions/NukeBuild"
}
- }
+ ]
}
diff --git a/build/Build.cs b/build/Build.cs
index 98bdb3599..dd0c3464f 100644
--- a/build/Build.cs
+++ b/build/Build.cs
@@ -10,7 +10,6 @@
using Nuke.Common.Tools.OctoVersion;
using Nuke.Common.Utilities;
using Nuke.Common.Utilities.Collections;
-using static Nuke.Common.IO.FileSystemTasks;
using static Nuke.Common.Tools.DotMemoryUnit.DotMemoryUnitTasks;
using static Nuke.Common.Tools.DotNet.DotNetTasks;
@@ -35,7 +34,7 @@ class Build : NukeBuild
[Parameter("Branch name for OctoVersion to use to calculate the version number. Can be set via the environment variable OCTOVERSION_CurrentBranch.", Name = "OCTOVERSION_CurrentBranch")]
readonly string BranchName;
- [OctoVersion(UpdateBuildNumber = true, BranchMember = nameof(BranchName), AutoDetectBranchMember = nameof(AutoDetectBranch), Framework = "net8.0")]
+ [OctoVersion(UpdateBuildNumber = true, BranchMember = nameof(BranchName), AutoDetectBranchMember = nameof(AutoDetectBranch), Framework = "net10.0")]
readonly OctoVersionInfo OctoVersionInfo;
[Parameter("The test Filter passed to dotnet test e.g. TestCategory=Async")]
@@ -79,9 +78,9 @@ class Build : NukeBuild
Target Compile => _ => CompileDefinition(_, null);
- Target CompileNet48 => _ => CompileDefinition(_, "net48");
+ Target CompileNetFramework => _ => CompileDefinition(_, "net48");
- Target CompileNet80 => _ => CompileDefinition(_, "net8.0");
+ Target CompileDotNet => _ => CompileDefinition(_, "net10.0");
ITargetDefinition CompileDefinition(ITargetDefinition targetDefinition, [CanBeNull] string framework)
{
@@ -106,10 +105,10 @@ ITargetDefinition CompileDefinition(ITargetDefinition targetDefinition, [CanBeNu
Target TestLinux => _ => TestDefinition(_, Compile, null, runDotMemoryTests: false);
[PublicAPI]
- Target TestWindowsNet48 => _ => TestDefinition(_, CompileNet48, "net48", runDotMemoryTests: true);
+ Target TestWindowsNetFramework => _ => TestDefinition(_, CompileNetFramework, "net48", runDotMemoryTests: true);
[PublicAPI]
- Target TestWindowsNet80 => _ => TestDefinition(_, CompileNet80, "net8.0", runDotMemoryTests: false);
+ Target TestWindowsDotNet => _ => TestDefinition(_, CompileDotNet, "net10.0", runDotMemoryTests: false);
ITargetDefinition TestDefinition(ITargetDefinition targetDefinition, Target dependsOn, [CanBeNull] string framework, bool runDotMemoryTests)
{
@@ -166,7 +165,7 @@ ITargetDefinition TestDefinition(ITargetDefinition targetDefinition, Target depe
{
LocalPackagesDirectory.CreateDirectory();
ArtifactsDirectory.GlobFiles("*.nupkg")
- .ForEach(package => CopyFileToDirectory(package, LocalPackagesDirectory, FileExistsPolicy.Overwrite));
+ .ForEach(package => package.CopyToDirectory(LocalPackagesDirectory, ExistsPolicy.FileOverwrite));
});
[PublicAPI]
diff --git a/build/_build.csproj b/build/_build.csproj
index 7679e4a44..5af72320d 100644
--- a/build/_build.csproj
+++ b/build/_build.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net10.0
CS0649;CS0169
..
@@ -11,8 +11,10 @@
-
-
+
+
+
+
diff --git a/global.json b/global.json
index 6a14d5d34..99bfe4cad 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.303",
+ "version": "10.0.401",
"rollForward": "latestFeature"
}
}
diff --git a/source/Halibut.TestProxy/Halibut.TestProxy.csproj b/source/Halibut.TestProxy/Halibut.TestProxy.csproj
index 1440b763c..442a2a8e6 100644
--- a/source/Halibut.TestProxy/Halibut.TestProxy.csproj
+++ b/source/Halibut.TestProxy/Halibut.TestProxy.csproj
@@ -8,16 +8,16 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
-
-
-
+
+
+
diff --git a/source/Halibut.TestUtils.CompatBinary.Base/Halibut.TestUtils.CompatBinary.Base.csproj b/source/Halibut.TestUtils.CompatBinary.Base/Halibut.TestUtils.CompatBinary.Base.csproj
index bc01e10da..f9e4221aa 100644
--- a/source/Halibut.TestUtils.CompatBinary.Base/Halibut.TestUtils.CompatBinary.Base.csproj
+++ b/source/Halibut.TestUtils.CompatBinary.Base/Halibut.TestUtils.CompatBinary.Base.csproj
@@ -8,10 +8,10 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
diff --git a/source/Halibut.TestUtils.CompatBinary.Base/SettingsHelper.cs b/source/Halibut.TestUtils.CompatBinary.Base/SettingsHelper.cs
index eb453ddb1..5deec8ffb 100644
--- a/source/Halibut.TestUtils.CompatBinary.Base/SettingsHelper.cs
+++ b/source/Halibut.TestUtils.CompatBinary.Base/SettingsHelper.cs
@@ -76,7 +76,9 @@ public static X509Certificate2 GetClientCertificate()
{
var octopusCertPath = GetSetting("octopuscertpath");
//Console.WriteLine($"Using octopus cert path: {octopusCertPath}");
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
var clientCert = new X509Certificate2(octopusCertPath);
+#pragma warning restore SYSLIB0057
//Console.WriteLine("Octopus/Client cert details " + clientCert);
return clientCert;
@@ -94,7 +96,9 @@ public static X509Certificate2 GetServiceCertificate()
{
var tentacleCertPath = GetSetting("tentaclecertpath");
//Console.WriteLine($"Using tentacle cert path: {tentacleCertPath}");
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
var serviceCert = new X509Certificate2(tentacleCertPath);
+#pragma warning restore SYSLIB0057
//Console.WriteLine("Tentacle/service cert details " + serviceCert);
return serviceCert;
diff --git a/source/Halibut.TestUtils.CompatBinary.v4_4_8/Halibut.TestUtils.CompatBinary.v4_4_8.csproj b/source/Halibut.TestUtils.CompatBinary.v4_4_8/Halibut.TestUtils.CompatBinary.v4_4_8.csproj
index c6dedf19e..fb8020cb2 100644
--- a/source/Halibut.TestUtils.CompatBinary.v4_4_8/Halibut.TestUtils.CompatBinary.v4_4_8.csproj
+++ b/source/Halibut.TestUtils.CompatBinary.v4_4_8/Halibut.TestUtils.CompatBinary.v4_4_8.csproj
@@ -9,10 +9,10 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
diff --git a/source/Halibut.TestUtils.CompatBinary.v5_0_236/Halibut.TestUtils.CompatBinary.v5_0_236.csproj b/source/Halibut.TestUtils.CompatBinary.v5_0_236/Halibut.TestUtils.CompatBinary.v5_0_236.csproj
index ab4610de5..f56052e66 100644
--- a/source/Halibut.TestUtils.CompatBinary.v5_0_236/Halibut.TestUtils.CompatBinary.v5_0_236.csproj
+++ b/source/Halibut.TestUtils.CompatBinary.v5_0_236/Halibut.TestUtils.CompatBinary.v5_0_236.csproj
@@ -9,10 +9,10 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
diff --git a/source/Halibut.TestUtils.CompatBinary.v6_0_658/Halibut.TestUtils.CompatBinary.v6_0_658.csproj b/source/Halibut.TestUtils.CompatBinary.v6_0_658/Halibut.TestUtils.CompatBinary.v6_0_658.csproj
index 347d8068a..d8027b54f 100644
--- a/source/Halibut.TestUtils.CompatBinary.v6_0_658/Halibut.TestUtils.CompatBinary.v6_0_658.csproj
+++ b/source/Halibut.TestUtils.CompatBinary.v6_0_658/Halibut.TestUtils.CompatBinary.v6_0_658.csproj
@@ -9,14 +9,15 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
+
diff --git a/source/Halibut.TestUtils.Contracts/Halibut.TestUtils.Contracts.csproj b/source/Halibut.TestUtils.Contracts/Halibut.TestUtils.Contracts.csproj
index e42348846..e2cb6ba10 100644
--- a/source/Halibut.TestUtils.Contracts/Halibut.TestUtils.Contracts.csproj
+++ b/source/Halibut.TestUtils.Contracts/Halibut.TestUtils.Contracts.csproj
@@ -8,17 +8,17 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
all
-
+
diff --git a/source/Halibut.Tests.DotMemory/Certificates.cs b/source/Halibut.Tests.DotMemory/Certificates.cs
index bc22c4439..7db89fb20 100644
--- a/source/Halibut.Tests.DotMemory/Certificates.cs
+++ b/source/Halibut.Tests.DotMemory/Certificates.cs
@@ -26,17 +26,25 @@ static Certificates()
//jump through hoops to find certs because the nunit test runner is messing with directories
var directory = Path.Combine(Path.GetDirectoryName(new Uri(typeof(Certificates).Assembly.Location).LocalPath)!, "Certificates");
TentacleListeningPfxPath = Path.Combine(directory, "TentacleListening.pfx");
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
TentacleListening = new X509Certificate2(TentacleListeningPfxPath);
+#pragma warning restore SYSLIB0057
TentacleListeningPublicThumbprint = TentacleListening.Thumbprint;
OctopusPfxPath = Path.Combine(directory, "Octopus.pfx");
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
Octopus = new X509Certificate2(OctopusPfxPath);
+#pragma warning restore SYSLIB0057
OctopusPublicThumbprint = Octopus.Thumbprint;
TentaclePollingPfxPath = Path.Combine(directory, "TentaclePolling.pfx");
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
TentaclePolling = new X509Certificate2(TentaclePollingPfxPath);
+#pragma warning restore SYSLIB0057
TentaclePollingPublicThumbprint = TentaclePolling.Thumbprint;
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
Ssl = new X509Certificate2(Path.Combine(directory, "Ssl.pfx"), "password");
+#pragma warning restore SYSLIB0057
SslThumbprint = Ssl.Thumbprint;
}
}
diff --git a/source/Halibut.Tests.DotMemory/Halibut.Tests.DotMemory.csproj b/source/Halibut.Tests.DotMemory/Halibut.Tests.DotMemory.csproj
index 3b556a710..f50f0a78c 100644
--- a/source/Halibut.Tests.DotMemory/Halibut.Tests.DotMemory.csproj
+++ b/source/Halibut.Tests.DotMemory/Halibut.Tests.DotMemory.csproj
@@ -10,10 +10,10 @@
enable
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
@@ -29,19 +29,19 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
+
diff --git a/source/Halibut.Tests/ExceptionContractFixture.cs b/source/Halibut.Tests/ExceptionContractFixture.cs
index eb1ae5bc0..a59f8d9c4 100644
--- a/source/Halibut.Tests/ExceptionContractFixture.cs
+++ b/source/Halibut.Tests/ExceptionContractFixture.cs
@@ -151,7 +151,9 @@ public async Task WhenTheListeningRequestFailsToBeSent_AsTheServiceRejectsTheCon
.And.Message.Should().ContainAny(
$"An error occurred when sending a request to '{clientAndService.ServiceUri}', before the request could begin: Unable to read data from the transport connection",
$"An error occurred when sending a request to '{clientAndService.ServiceUri}', before the request could begin: Unable to write data to the transport connection",
+ // .NET Framework's SslStream message has a leading space; modern .NET's does not
$"An error occurred when sending a request to '{clientAndService.ServiceUri}', before the request could begin: Received an unexpected EOF or 0 bytes from the transport stream",
+ $"An error occurred when sending a request to '{clientAndService.ServiceUri}', before the request could begin: Received an unexpected EOF or 0 bytes from the transport stream",
$"An error occurred when sending a request to '{clientAndService.ServiceUri}', before the request could begin: Transport endpoint is not connected");
}
diff --git a/source/Halibut.Tests/FriendlyHtmlPageTests.cs b/source/Halibut.Tests/FriendlyHtmlPageTests.cs
index 9bb4ffadc..7ede856a9 100644
--- a/source/Halibut.Tests/FriendlyHtmlPageTests.cs
+++ b/source/Halibut.Tests/FriendlyHtmlPageTests.cs
@@ -121,11 +121,15 @@ static async Task>> GetHeadersIgnoringCertific
using (var client = new HttpClient(httpClientHandler))
{
var headers = new List>();
+#pragma warning disable SYSLIB0014
var existingServerCertificateValidationCallback = ServicePointManager.ServerCertificateValidationCallback;
+#pragma warning restore SYSLIB0014
try
{
// We need to ignore server certificate validation errors - the server certificate is self-signed
+#pragma warning disable SYSLIB0014
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
+#pragma warning restore SYSLIB0014
var response = await client.GetAsync(uri);
foreach (var key in response.Headers)
{
@@ -135,7 +139,9 @@ static async Task>> GetHeadersIgnoringCertific
finally
{
// And restore it back to default behaviour
+#pragma warning disable SYSLIB0014
ServicePointManager.ServerCertificateValidationCallback = existingServerCertificateValidationCallback;
+#pragma warning restore SYSLIB0014
}
return headers;
diff --git a/source/Halibut.Tests/Halibut.Tests.csproj b/source/Halibut.Tests/Halibut.Tests.csproj
index 602280ad8..526854c7d 100644
--- a/source/Halibut.Tests/Halibut.Tests.csproj
+++ b/source/Halibut.Tests/Halibut.Tests.csproj
@@ -7,15 +7,15 @@
true
false
9.0
- VSTHRD002,VSTHRD003;VSTHRD103
+ VSTHRD002,VSTHRD003;VSTHRD103;CA2022
enable
true
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
@@ -34,30 +34,30 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
$(DefineConstants);SUPPORTS_WEB_SOCKET_CLIENT;DOES_NOT_SUPPORT_CANCELLATION_ON_SOCKETS
-
+
$(DefineConstants);HAS_TCP_KEEP_ALIVE_SOCKET_OPTIONS
diff --git a/source/Halibut.Tests/Queue/Redis/Utils/RedisContainerBuilder.cs b/source/Halibut.Tests/Queue/Redis/Utils/RedisContainerBuilder.cs
index 510a64df7..07b6f0155 100644
--- a/source/Halibut.Tests/Queue/Redis/Utils/RedisContainerBuilder.cs
+++ b/source/Halibut.Tests/Queue/Redis/Utils/RedisContainerBuilder.cs
@@ -86,8 +86,7 @@ public RedisContainer Build()
// permissions, so Redis (running as 1001) would fail to start if the checkout is not readable by other users.
var redisConfigArguments = RedisConfigFileToArguments(Path.Combine(redisConfigPath, "redis.conf"));
- var container = new ContainerBuilder()
- .WithImage(_image)
+ var container = new ContainerBuilder(_image)
.WithPortBinding(hostPort, 6379)
// Start redis-server directly, the official image's entrypoint loads the Redis 8 modules (JSON, search etc.) which Octopus Cloud's image does not.
.WithEntrypoint("redis-server")
@@ -98,7 +97,7 @@ public RedisContainer Build()
.WithCreateParameterModifier(parameters =>
{
parameters.User = "1001:1001";
- parameters.HostConfig.ReadonlyRootfs = true;
+ parameters.HostConfig!.ReadonlyRootfs = true;
parameters.HostConfig.CapDrop = new List { "ALL" };
parameters.HostConfig.SecurityOpt = new List { "no-new-privileges" };
})
diff --git a/source/Halibut.Tests/Support/AsyncEnumerableCompat.cs b/source/Halibut.Tests/Support/AsyncEnumerableCompat.cs
new file mode 100644
index 000000000..9b5ed6f46
--- /dev/null
+++ b/source/Halibut.Tests/Support/AsyncEnumerableCompat.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Halibut.Tests.Support
+{
+ // On net10.0 the framework's System.Linq.AsyncEnumerable and the System.Linq.Async package
+ // (pulled in by System.Interactive.Async on net48) both define ToAsyncEnumerable and SelectAwait-style
+ // operators, which makes calls ambiguous or unavailable. These helpers give both targets one implementation.
+ public static class AsyncEnumerableCompat
+ {
+ public static async IAsyncEnumerable ToAsyncEnumerableCompat(this IEnumerable source)
+ {
+ foreach (var item in source)
+ {
+ yield return item;
+ }
+ }
+
+ public static async IAsyncEnumerable SelectAwaitCompat(this IAsyncEnumerable source, Func> selector)
+ {
+ await foreach (var item in source)
+ {
+ yield return await selector(item);
+ }
+ }
+ }
+}
diff --git a/source/Halibut.Tests/Support/Certificates.cs b/source/Halibut.Tests/Support/Certificates.cs
index bd0a31f1a..d1c13d164 100644
--- a/source/Halibut.Tests/Support/Certificates.cs
+++ b/source/Halibut.Tests/Support/Certificates.cs
@@ -31,23 +31,33 @@ static Certificates()
//jump through hoops to find certs because the nunit test runner is messing with directories
var directory = Path.Combine(Path.GetDirectoryName(new Uri(typeof(Certificates).Assembly.Location).LocalPath)!, "Certificates");
TentacleListeningPfxPath = Path.Combine(directory, "TentacleListening.pfx");
+#pragma warning disable SYSLIB0057
TentacleListening = new X509Certificate2(TentacleListeningPfxPath);
+#pragma warning restore SYSLIB0057
TentacleListeningPublicThumbprint = TentacleListening.Thumbprint;
OctopusPfxPath = Path.Combine(directory, "Octopus.pfx");
+#pragma warning disable SYSLIB0057
Octopus = new X509Certificate2(OctopusPfxPath);
+#pragma warning restore SYSLIB0057
OctopusPublicThumbprint = Octopus.Thumbprint;
TentaclePollingPfxPath = Path.Combine(directory, "TentaclePolling.pfx");
+#pragma warning disable SYSLIB0057
TentaclePolling = new X509Certificate2(TentaclePollingPfxPath);
+#pragma warning restore SYSLIB0057
TentaclePollingPublicThumbprint = TentaclePolling.Thumbprint;
WrongPfxPath = Path.Combine(directory, "WrongCert.pfx");
+#pragma warning disable SYSLIB0057
Wrong = new X509Certificate2(WrongPfxPath);
+#pragma warning restore SYSLIB0057
WrongPublicThumbprint = Wrong.Thumbprint;
sslPfxPath = Path.Combine(directory, "Ssl.pfx");
+#pragma warning disable SYSLIB0057
Ssl = new X509Certificate2(sslPfxPath, "password");
+#pragma warning restore SYSLIB0057
SslThumbprint = Ssl.Thumbprint;
}
}
diff --git a/source/Halibut.Tests/Support/Streams/SynIoRecording/SyncIoRecordingWebSocketStream.cs b/source/Halibut.Tests/Support/Streams/SynIoRecording/SyncIoRecordingWebSocketStream.cs
index 4bb1c57f5..e0ad329d9 100644
--- a/source/Halibut.Tests/Support/Streams/SynIoRecording/SyncIoRecordingWebSocketStream.cs
+++ b/source/Halibut.Tests/Support/Streams/SynIoRecording/SyncIoRecordingWebSocketStream.cs
@@ -5,7 +5,7 @@
namespace Halibut.Tests.Support.Streams.SynIoRecording
{
- public class SyncIoRecordingWebSocketStream : WebSocketStream, IRecordSyncIo
+ public class SyncIoRecordingWebSocketStream : Halibut.Transport.Protocol.WebSocketStream, IRecordSyncIo
{
readonly List syncCalls = new();
diff --git a/source/Halibut.Tests/Support/TempDisposableCertAndThumbprint.cs b/source/Halibut.Tests/Support/TempDisposableCertAndThumbprint.cs
index 2c952fec0..cf2469482 100644
--- a/source/Halibut.Tests/Support/TempDisposableCertAndThumbprint.cs
+++ b/source/Halibut.Tests/Support/TempDisposableCertAndThumbprint.cs
@@ -49,7 +49,9 @@ public static ICertAndThumbprint CreateSelfSigned(DisposableCollection disposedB
var bytes = certificate.Export(X509ContentType.Pfx);
var filePath = Path.Combine(tempDir.DirectoryPath, $"{name}.pfx");
File.WriteAllBytes(filePath, bytes);
+#pragma warning disable SYSLIB0057
var disposableCert = new TempDisposableCertAndThumbprint(tempDir, filePath, new X509Certificate2(bytes));
+#pragma warning restore SYSLIB0057
disposedBy.Add(disposableCert);
return disposableCert;
}
diff --git a/source/Halibut.Tests/TestServices/AsyncComplexObjectService.cs b/source/Halibut.Tests/TestServices/AsyncComplexObjectService.cs
index c37262a37..b50faa4b0 100644
--- a/source/Halibut.Tests/TestServices/AsyncComplexObjectService.cs
+++ b/source/Halibut.Tests/TestServices/AsyncComplexObjectService.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Halibut.Tests.Support;
using Halibut.Tests.Util;
using Halibut.TestUtils.Contracts;
@@ -28,13 +29,13 @@ public async Task ProcessAsync(ComplexObjectMulti
{
ChildPayload1 = await ReadIntoNewDataStream(request.Child1!.ChildPayload1, cancellationToken),
ChildPayload2 = await ReadIntoNewDataStream(request.Child1!.ChildPayload2, cancellationToken),
- ListOfStreams = await request.Child1.ListOfStreams!.ToAsyncEnumerable().SelectAwait(async ds => await ReadIntoNewDataStream(ds, cancellationToken)).ToListAsync(cancellationToken),
+ ListOfStreams = await request.Child1.ListOfStreams!.ToAsyncEnumerableCompat().SelectAwaitCompat(async ds => await ReadIntoNewDataStream(ds, cancellationToken)).ToListAsync(cancellationToken),
DictionaryPayload = request.Child1.DictionaryPayload!.ToDictionary(pair => pair.Key, pair => pair.Value),
},
Child2 = new ComplexChild2
{
EnumPayload = request.Child2!.EnumPayload,
- ComplexPayloadSet = await request.Child2.ComplexPayloadSet!.ToAsyncEnumerable().SelectAwait(async x => new ComplexPair(x.EnumValue, await ReadIntoNewDataStream(x.Payload, cancellationToken))).ToHashSetAsync(cancellationToken)
+ ComplexPayloadSet = await request.Child2.ComplexPayloadSet!.ToAsyncEnumerableCompat().SelectAwaitCompat(async x => new ComplexPair(x.EnumValue, await ReadIntoNewDataStream(x.Payload, cancellationToken))).ToHashSetAsync(cancellationToken: cancellationToken)
}
};
}
diff --git a/source/Halibut.Tests/Transport/Protocol/MessageSerializerFixture.cs b/source/Halibut.Tests/Transport/Protocol/MessageSerializerFixture.cs
index c36acdd85..3ac48bedb 100644
--- a/source/Halibut.Tests/Transport/Protocol/MessageSerializerFixture.cs
+++ b/source/Halibut.Tests/Transport/Protocol/MessageSerializerFixture.cs
@@ -16,6 +16,13 @@ namespace Halibut.Tests.Transport.Protocol
{
public class MessageSerializerFixture : BaseTest
{
+#if NETFRAMEWORK
+ const long ExpectedCompressedBytes = 55;
+#else
+ // .NET 9+ uses zlib-ng for DeflateStream, which produces slightly different output.
+ const long ExpectedCompressedBytes = 57;
+#endif
+
[Test]
[TestCaseSource(typeof(MessageSerializerTestCaseSource))]
public async Task SendReceiveMessageShouldRoundTrip(MessageSerializerTestCase testCase)
@@ -52,8 +59,8 @@ public async Task WriteMessage_ObservesThatMessageIsWritten(MessageSerializerTes
}
var writtenMessage = messageSerializerObserver.MessagesWritten.Should().ContainSingle().Subject;
- writtenMessage.CompressedBytesWritten.Should().Be(55);
- var expectedCompressedBytesWrittenIntoMemory = testCase.AsyncMemoryLimit > 55 ? 55 : 0;
+ writtenMessage.CompressedBytesWritten.Should().Be(ExpectedCompressedBytes);
+ var expectedCompressedBytesWrittenIntoMemory = testCase.AsyncMemoryLimit > ExpectedCompressedBytes ? ExpectedCompressedBytes : 0;
writtenMessage.CompressedBytesWrittenIntoMemory.Should().Be(expectedCompressedBytesWrittenIntoMemory);
messageSerializerObserver.MessagesRead.Should().BeEmpty();
}
@@ -83,7 +90,7 @@ public async Task ReadMessage_ObservesThatMessageIsRead(MessageSerializerTestCas
}
var readMessage = messageSerializerObserver.MessagesRead.Should().ContainSingle().Subject;
- readMessage.CompressedBytesRead.Should().Be(55);
+ readMessage.CompressedBytesRead.Should().Be(ExpectedCompressedBytes);
readMessage.DecompressedBytesRead.Should().Be(120);
var expectedDecompressedBytesReadIntoMemory = Math.Min(testCase.AsyncMemoryLimit, 120);
readMessage.DecompressedBytesReadIntoMemory.Should().Be(expectedDecompressedBytesReadIntoMemory);
@@ -210,7 +217,7 @@ public async Task ReadMessage_Rewindable_ObservesThatMessageIsRead(MessageSerial
}
var readMessage = messageSerializerObserver.MessagesRead.Should().ContainSingle().Subject;
- readMessage.CompressedBytesRead.Should().Be(55);
+ readMessage.CompressedBytesRead.Should().Be(ExpectedCompressedBytes);
readMessage.DecompressedBytesRead.Should().Be(120);
var expectedDecompressedBytesReadIntoMemory = Math.Min(testCase.AsyncMemoryLimit, 120);
readMessage.DecompressedBytesReadIntoMemory.Should().Be(expectedDecompressedBytesReadIntoMemory);
@@ -272,7 +279,7 @@ public async Task ReadMessage_Rewindable_ShouldNotObserveTrailingDataWhenReading
}
var readMessage = messageSerializerObserver.MessagesRead.Should().ContainSingle().Subject;
- readMessage.CompressedBytesRead.Should().Be(55);
+ readMessage.CompressedBytesRead.Should().Be(ExpectedCompressedBytes);
readMessage.DecompressedBytesRead.Should().Be(120);
var expectedDecompressedBytesReadIntoMemory = Math.Min(testCase.AsyncMemoryLimit, 120);
readMessage.DecompressedBytesReadIntoMemory.Should().Be(expectedDecompressedBytesReadIntoMemory);
diff --git a/source/Halibut.Tests/UsageFixture.cs b/source/Halibut.Tests/UsageFixture.cs
index 4de3035a9..0be41209d 100644
--- a/source/Halibut.Tests/UsageFixture.cs
+++ b/source/Halibut.Tests/UsageFixture.cs
@@ -5,6 +5,7 @@
using System.Threading.Tasks;
using FluentAssertions;
using Halibut.Exceptions;
+using Halibut.Tests.Support;
using Halibut.Tests.Support.TestAttributes;
using Halibut.Tests.Support.TestCases;
using Halibut.Tests.TestServices.Async;
@@ -256,8 +257,8 @@ public async Task OctopusCanSendAndReceiveComplexObjects_WithMultipleComplexChil
response.Child1.ChildPayload2.Should().NotBeSameAs(request.Child1.ChildPayload2);
(await response.Child1.ChildPayload2!.ReadAsString(CancellationToken)).Should().Be(childPayload2);
response.Child1.ListOfStreams.Should().NotBeSameAs(request.Child1.ListOfStreams);
- (await response.Child1.ListOfStreams!.ToAsyncEnumerable()
- .SelectAwait(async x => await x.ReadAsString(CancellationToken))
+ (await response.Child1.ListOfStreams!.ToAsyncEnumerableCompat()
+ .SelectAwaitCompat(async x => await x.ReadAsString(CancellationToken))
.ToListAsync(CancellationToken))
.Should().BeEquivalentTo(list);
response.Child1.DictionaryPayload.Should().NotBeSameAs(request.Child1.DictionaryPayload);
@@ -266,8 +267,8 @@ public async Task OctopusCanSendAndReceiveComplexObjects_WithMultipleComplexChil
response.Child2.Should().NotBeSameAs(request.Child2);
response.Child2!.EnumPayload.Should().Be(enumValue);
response.Child2.ComplexPayloadSet.Should().NotBeSameAs(request.Child2.ComplexPayloadSet);
- (await response.Child2.ComplexPayloadSet!.ToAsyncEnumerable()
- .SelectAwait(async x => new ComplexPair(x.EnumValue, await x.Payload.ReadAsString(CancellationToken)))
+ (await response.Child2.ComplexPayloadSet!.ToAsyncEnumerableCompat()
+ .SelectAwaitCompat(async x => new ComplexPair(x.EnumValue, await x.Payload.ReadAsString(CancellationToken)))
.ToArrayAsync())
.ToHashSet()
.Should()
diff --git a/source/Halibut/Halibut.csproj b/source/Halibut/Halibut.csproj
index 383684887..46b608079 100644
--- a/source/Halibut/Halibut.csproj
+++ b/source/Halibut/Halibut.csproj
@@ -19,10 +19,10 @@
enable
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
True
@@ -32,18 +32,17 @@
-
+
-
+
-
+
-
@@ -51,7 +50,7 @@
-
+
$(DefineConstants);LIBLOG_PORTABLE;HAS_TCP_KEEP_ALIVE_SOCKET_OPTIONS
diff --git a/source/Halibut/Transport/ClientCertificateValidator.cs b/source/Halibut/Transport/ClientCertificateValidator.cs
index ea37d453a..b5929268f 100644
--- a/source/Halibut/Transport/ClientCertificateValidator.cs
+++ b/source/Halibut/Transport/ClientCertificateValidator.cs
@@ -15,7 +15,9 @@ public ClientCertificateValidator(ServiceEndPoint endPoint)
public bool Validate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslpolicyerrors)
{
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
var providedCert = new X509Certificate2(certificate!.Export(X509ContentType.Cert), (string)null!); // Copy the cert so that we can reference it later
+#pragma warning restore SYSLIB0057
var providedThumbprint = providedCert.Thumbprint;
if (providedThumbprint == endPoint.RemoteThumbprint)
diff --git a/source/Halibut/Transport/DiscoveryClient.cs b/source/Halibut/Transport/DiscoveryClient.cs
index c92280702..cedaa5edb 100644
--- a/source/Halibut/Transport/DiscoveryClient.cs
+++ b/source/Halibut/Transport/DiscoveryClient.cs
@@ -61,7 +61,9 @@ await ssl.AuthenticateAsClientEnforcingTimeout(
throw new Exception("The server did not provide an SSL certificate");
#pragma warning disable PC001 // API not supported on all platforms - X509Certificate2 not supported on macOS
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
return new ServiceEndPoint(serviceEndpoint.BaseUri, new X509Certificate2(ssl.RemoteCertificate.Export(X509ContentType.Cert), (string)null!).Thumbprint, halibutTimeoutsAndLimits);
+#pragma warning restore SYSLIB0057
#pragma warning restore PC001 // API not supported on all platforms - X509Certificate2 not supported on macOS
}
}
diff --git a/source/Halibut/Transport/SecureListener.cs b/source/Halibut/Transport/SecureListener.cs
index a32c0ad64..40db01b3d 100644
--- a/source/Halibut/Transport/SecureListener.cs
+++ b/source/Halibut/Transport/SecureListener.cs
@@ -457,7 +457,9 @@ async Task SendFriendlyHtmlPage(Stream stream)
return null;
}
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
var thumbprint = new X509Certificate2(stream.RemoteCertificate.Export(X509ContentType.Cert), (string)null!).Thumbprint;
+#pragma warning restore SYSLIB0057
return thumbprint;
}
diff --git a/source/Halibut/Transport/SecureWebSocketListener.cs b/source/Halibut/Transport/SecureWebSocketListener.cs
index 1807a469f..ec562fb26 100644
--- a/source/Halibut/Transport/SecureWebSocketListener.cs
+++ b/source/Halibut/Transport/SecureWebSocketListener.cs
@@ -233,7 +233,9 @@ async Task Authorize(HttpListenerContext context, string clientName)
return false;
}
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
var thumbprint = new X509Certificate2(certificate.Export(X509ContentType.Cert), (string)null!).Thumbprint;
+#pragma warning restore SYSLIB0057
var isAuthorized = verifyClientThumbprint(thumbprint);
if (!isAuthorized)
diff --git a/source/Halibut/Transport/ServerCertificateInterceptor.cs b/source/Halibut/Transport/ServerCertificateInterceptor.cs
index 33b6b55b8..30b169a22 100644
--- a/source/Halibut/Transport/ServerCertificateInterceptor.cs
+++ b/source/Halibut/Transport/ServerCertificateInterceptor.cs
@@ -38,7 +38,9 @@ static void Initialize()
{
if (certificates.ContainsKey(clientId))
{
+#pragma warning disable SYSLIB0057 // obsolete ctor; kept for identical behaviour on net48 and net10
var providedCert = new X509Certificate2(certificate.Export(X509ContentType.Cert), (string)null!); // Copy the cert so that we can reference it later
+#pragma warning restore SYSLIB0057
certificates[clientId] = providedCert;
return true;
}
diff --git a/source/Halibut/Transport/Streams/StreamFactory.cs b/source/Halibut/Transport/Streams/StreamFactory.cs
index 1f941bc48..87f7719e4 100644
--- a/source/Halibut/Transport/Streams/StreamFactory.cs
+++ b/source/Halibut/Transport/Streams/StreamFactory.cs
@@ -15,7 +15,7 @@ public Stream CreateStream(TcpClient client)
public Stream CreateStream(WebSocket webSocket)
{
- var webSocketStream = new WebSocketStream(webSocket);
+ var webSocketStream = new Halibut.Transport.Protocol.WebSocketStream(webSocket);
var networkStream = new NetworkTimeoutStream(webSocketStream);
// When synchronous serialization is performed, it will call the synchronous versions of Read/Write.
diff --git a/source/Octopus.TestPortForwarder/Octopus.TestPortForwarder.csproj b/source/Octopus.TestPortForwarder/Octopus.TestPortForwarder.csproj
index 1dff29309..f302e3471 100644
--- a/source/Octopus.TestPortForwarder/Octopus.TestPortForwarder.csproj
+++ b/source/Octopus.TestPortForwarder/Octopus.TestPortForwarder.csproj
@@ -8,13 +8,13 @@
- net48;net8.0
+ net48;net10.0
- net8.0
+ net10.0
-
+