diff --git a/.github/workflows/validate-build.yml b/.github/workflows/validate-build.yml
index 497ceac7..0cc79a16 100644
--- a/.github/workflows/validate-build.yml
+++ b/.github/workflows/validate-build.yml
@@ -28,6 +28,16 @@ jobs:
with:
dotnet-version: '6.0.x'
+ - name: Setup .NET 8.0
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: '8.0.x'
+
+ - name: Setup .NET 10.0
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: '10.0.x'
+
- name: Setup .NET from global.json
uses: actions/setup-dotnet@v3
with:
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index f7dbaae0..b1dbbb64 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -38,7 +38,7 @@
"type": "func",
"dependsOn": "build (AzureFunctionsApp)",
"options": {
- "cwd": "${workspaceFolder}/out/samples/bin/Debug/AzureFunctionsApp/net6.0"
+ "cwd": "${workspaceFolder}/out/samples/bin/Debug/AzureFunctionsApp/net8.0"
},
"command": "host start",
"isBackground": true,
diff --git a/Directory.Packages.props b/Directory.Packages.props
index a3e580b8..b3945014 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -9,23 +9,22 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -41,20 +40,20 @@
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
@@ -63,27 +62,28 @@
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
+
-
-
-
+
+
+
+
-
-
+
+
diff --git a/global.json b/global.json
index 4ac08fda..4b560e68 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.100",
+ "version": "10.0.100",
"rollForward": "latestFeature"
},
"msbuild-sdks": {
diff --git a/samples/AzureFunctionsApp/AzureFunctionsApp.csproj b/samples/AzureFunctionsApp/AzureFunctionsApp.csproj
index 1e56f9fd..8531f38a 100644
--- a/samples/AzureFunctionsApp/AzureFunctionsApp.csproj
+++ b/samples/AzureFunctionsApp/AzureFunctionsApp.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0
v4
Exe
enable
diff --git a/samples/AzureFunctionsUnitTests/AzureFunctionsApp.Tests.csproj b/samples/AzureFunctionsUnitTests/AzureFunctionsApp.Tests.csproj
index faa8299a..e1e548ad 100644
--- a/samples/AzureFunctionsUnitTests/AzureFunctionsApp.Tests.csproj
+++ b/samples/AzureFunctionsUnitTests/AzureFunctionsApp.Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net6.0;net8.0
enable
enable
diff --git a/samples/ConsoleApp/ConsoleApp.csproj b/samples/ConsoleApp/ConsoleApp.csproj
index 36bad25c..5de1fbdf 100644
--- a/samples/ConsoleApp/ConsoleApp.csproj
+++ b/samples/ConsoleApp/ConsoleApp.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net6.0;net8.0;net10.0
enable
diff --git a/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj b/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj
index 36bad25c..5de1fbdf 100644
--- a/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj
+++ b/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net6.0;net8.0;net10.0
enable
diff --git a/samples/LargePayloadConsoleApp/LargePayloadConsoleApp.csproj b/samples/LargePayloadConsoleApp/LargePayloadConsoleApp.csproj
index b0f2914c..c7ac5d2e 100644
--- a/samples/LargePayloadConsoleApp/LargePayloadConsoleApp.csproj
+++ b/samples/LargePayloadConsoleApp/LargePayloadConsoleApp.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net8.0;net10.0
enable
diff --git a/samples/ScheduleConsoleApp/ScheduleConsoleApp.csproj b/samples/ScheduleConsoleApp/ScheduleConsoleApp.csproj
index 7efdf0fc..5c356d93 100644
--- a/samples/ScheduleConsoleApp/ScheduleConsoleApp.csproj
+++ b/samples/ScheduleConsoleApp/ScheduleConsoleApp.csproj
@@ -2,7 +2,7 @@
Exe
- net8.0
+ net8.0;net10.0
enable
diff --git a/samples/ScheduleWebApp/ScheduleWebApp.csproj b/samples/ScheduleWebApp/ScheduleWebApp.csproj
index 8206fa42..a505e3df 100644
--- a/samples/ScheduleWebApp/ScheduleWebApp.csproj
+++ b/samples/ScheduleWebApp/ScheduleWebApp.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
enable
enable
true
diff --git a/samples/WebAPI/WebAPI.csproj b/samples/WebAPI/WebAPI.csproj
index 2ee98470..84680817 100644
--- a/samples/WebAPI/WebAPI.csproj
+++ b/samples/WebAPI/WebAPI.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
enable
enable
true
diff --git a/src/Client/AzureManaged/Client.AzureManaged.csproj b/src/Client/AzureManaged/Client.AzureManaged.csproj
index 087f60f8..78fa3ad5 100644
--- a/src/Client/AzureManaged/Client.AzureManaged.csproj
+++ b/src/Client/AzureManaged/Client.AzureManaged.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
Azure Managed extensions for the Durable Task Framework client.
true
diff --git a/src/Client/Grpc/Client.Grpc.csproj b/src/Client/Grpc/Client.Grpc.csproj
index fe13b9df..a266287d 100644
--- a/src/Client/Grpc/Client.Grpc.csproj
+++ b/src/Client/Grpc/Client.Grpc.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;net6.0
+ netstandard2.0;net6.0;net8.0;net10.0
The gRPC client for the Durable Task Framework.
true
diff --git a/src/Extensions/AzureBlobPayloads/AzureBlobPayloads.csproj b/src/Extensions/AzureBlobPayloads/AzureBlobPayloads.csproj
index 58e039a5..0a524ed6 100644
--- a/src/Extensions/AzureBlobPayloads/AzureBlobPayloads.csproj
+++ b/src/Extensions/AzureBlobPayloads/AzureBlobPayloads.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;net6.0
+ netstandard2.0;net6.0;net8.0;net10.0
Azure Blob Storage externalized payload support for Durable Task.
Microsoft.DurableTask.Extensions.AzureBlobPayloads
Microsoft.DurableTask
diff --git a/src/Generators/DurableTaskSourceGenerator.cs b/src/Generators/DurableTaskSourceGenerator.cs
index 4ad0eb2d..32821c93 100644
--- a/src/Generators/DurableTaskSourceGenerator.cs
+++ b/src/Generators/DurableTaskSourceGenerator.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
+using System.Collections.Immutable;
using System.Diagnostics;
using System.Text;
using Microsoft.CodeAnalysis;
@@ -15,7 +16,7 @@ namespace Microsoft.DurableTask.Generators
/// Generator for DurableTask.
///
[Generator]
- public class DurableTaskSourceGenerator : ISourceGenerator
+ public class DurableTaskSourceGenerator : IIncrementalGenerator
{
/* Example input:
*
@@ -39,32 +40,150 @@ public class DurableTaskSourceGenerator : ISourceGenerator
*/
///
- public void Initialize(GeneratorInitializationContext context)
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- context.RegisterForSyntaxNotifications(() => new DurableTaskSyntaxReceiver());
+ // Create providers for DurableTask attributes
+ IncrementalValuesProvider durableTaskAttributes = context.SyntaxProvider
+ .CreateSyntaxProvider(
+ predicate: static (node, _) => node is AttributeSyntax,
+ transform: static (ctx, _) => GetDurableTaskTypeInfo(ctx))
+ .Where(static info => info != null)!;
+
+ // Create providers for Durable Functions
+ IncrementalValuesProvider durableFunctions = context.SyntaxProvider
+ .CreateSyntaxProvider(
+ predicate: static (node, _) => node is MethodDeclarationSyntax,
+ transform: static (ctx, _) => GetDurableFunction(ctx))
+ .Where(static func => func != null)!;
+
+ // Collect all results and check if Durable Functions is referenced
+ IncrementalValueProvider<(Compilation, ImmutableArray, ImmutableArray)> compilationAndTasks =
+ durableTaskAttributes.Collect()
+ .Combine(durableFunctions.Collect())
+ .Combine(context.CompilationProvider)
+ .Select((x, _) => (x.Right, x.Left.Left, x.Left.Right));
+
+ // Generate the source
+ context.RegisterSourceOutput(compilationAndTasks, static (spc, source) => Execute(spc, source.Item1, source.Item2, source.Item3));
}
- ///
- public void Execute(GeneratorExecutionContext context)
+ static DurableTaskTypeInfo? GetDurableTaskTypeInfo(GeneratorSyntaxContext context)
+ {
+ AttributeSyntax attribute = (AttributeSyntax)context.Node;
+
+ ITypeSymbol? attributeType = context.SemanticModel.GetTypeInfo(attribute.Name).Type;
+ if (attributeType?.ToString() != "Microsoft.DurableTask.DurableTaskAttribute")
+ {
+ return null;
+ }
+
+ if (attribute.Parent is not AttributeListSyntax list || list.Parent is not ClassDeclarationSyntax classDeclaration)
+ {
+ return null;
+ }
+
+ // Verify that the attribute is being used on a non-abstract class
+ if (classDeclaration.Modifiers.Any(SyntaxKind.AbstractKeyword))
+ {
+ return null;
+ }
+
+ if (context.SemanticModel.GetDeclaredSymbol(classDeclaration) is not ITypeSymbol classType)
+ {
+ return null;
+ }
+
+ string className = classType.ToDisplayString();
+ INamedTypeSymbol? taskType = null;
+ bool isActivity = false;
+
+ INamedTypeSymbol? baseType = classType.BaseType;
+ while (baseType != null)
+ {
+ if (baseType.ContainingAssembly.Name == "Microsoft.DurableTask.Abstractions")
+ {
+ if (baseType.Name == "TaskActivity")
+ {
+ taskType = baseType;
+ isActivity = true;
+ break;
+ }
+ else if (baseType.Name == "TaskOrchestrator")
+ {
+ taskType = baseType;
+ isActivity = false;
+ break;
+ }
+ }
+
+ baseType = baseType.BaseType;
+ }
+
+ if (taskType == null || taskType.TypeParameters.Length <= 1)
+ {
+ return null;
+ }
+
+ ITypeSymbol inputType = taskType.TypeArguments.First();
+ ITypeSymbol outputType = taskType.TypeArguments.Last();
+
+ string taskName = classType.Name;
+ if (attribute.ArgumentList?.Arguments.Count > 0)
+ {
+ ExpressionSyntax expression = attribute.ArgumentList.Arguments[0].Expression;
+ taskName = context.SemanticModel.GetConstantValue(expression).ToString();
+ }
+
+ return new DurableTaskTypeInfo(className, taskName, inputType, outputType, isActivity);
+ }
+
+ static DurableFunction? GetDurableFunction(GeneratorSyntaxContext context)
+ {
+ MethodDeclarationSyntax method = (MethodDeclarationSyntax)context.Node;
+
+ if (DurableFunction.TryParse(context.SemanticModel, method, out DurableFunction? function))
+ {
+ return function;
+ }
+
+ return null;
+ }
+
+ static void Execute(
+ SourceProductionContext context,
+ Compilation compilation,
+ ImmutableArray allTasks,
+ ImmutableArray allFunctions)
{
+ if (allTasks.IsDefaultOrEmpty && allFunctions.IsDefaultOrEmpty)
+ {
+ return;
+ }
+
// This generator also supports Durable Functions for .NET isolated, but we only generate Functions-specific
// code if we find the Durable Functions extension listed in the set of referenced assembly names.
- bool isDurableFunctions = context.Compilation.ReferencedAssemblyNames.Any(
+ bool isDurableFunctions = compilation.ReferencedAssemblyNames.Any(
assembly => assembly.Name.Equals("Microsoft.Azure.Functions.Worker.Extensions.DurableTask", StringComparison.OrdinalIgnoreCase));
- // Enumerate all the activities in the project
- // the generator infrastructure will create a receiver and populate it
- // we can retrieve the populated instance via the context
- if (context.SyntaxContextReceiver is not DurableTaskSyntaxReceiver receiver)
+ // Separate tasks into orchestrators and activities
+ List orchestrators = new();
+ List activities = new();
+
+ foreach (DurableTaskTypeInfo task in allTasks)
{
- // Unexpected receiver came back?
- return;
+ if (task.IsActivity)
+ {
+ activities.Add(task);
+ }
+ else
+ {
+ orchestrators.Add(task);
+ }
}
- int found = receiver.Activities.Count + receiver.Orchestrators.Count + receiver.DurableFunctions.Count;
+ int found = activities.Count + orchestrators.Count + allFunctions.Length;
if (found == 0)
{
- // Didn't find anything
return;
}
@@ -92,14 +211,14 @@ public static class GeneratedDurableTaskExtensions
if (isDurableFunctions)
{
// Generate a singleton orchestrator object instance that can be reused for all invocations.
- foreach (DurableTaskTypeInfo orchestrator in receiver.Orchestrators)
+ foreach (DurableTaskTypeInfo orchestrator in orchestrators)
{
sourceBuilder.AppendLine($@"
static readonly ITaskOrchestrator singleton{orchestrator.TaskName} = new {orchestrator.TypeName}();");
}
}
- foreach (DurableTaskTypeInfo orchestrator in receiver.Orchestrators)
+ foreach (DurableTaskTypeInfo orchestrator in orchestrators)
{
if (isDurableFunctions)
{
@@ -111,7 +230,7 @@ public static class GeneratedDurableTaskExtensions
AddSubOrchestratorCallMethod(sourceBuilder, orchestrator);
}
- foreach (DurableTaskTypeInfo activity in receiver.Activities)
+ foreach (DurableTaskTypeInfo activity in activities)
{
AddActivityCallMethod(sourceBuilder, activity);
@@ -123,7 +242,7 @@ public static class GeneratedDurableTaskExtensions
}
// Activity function triggers are supported for code-gen (but not orchestration triggers)
- IEnumerable activityTriggers = receiver.DurableFunctions.Where(
+ IEnumerable activityTriggers = allFunctions.Where(
df => df.Kind == DurableFunctionKind.Activity);
foreach (DurableFunction function in activityTriggers)
{
@@ -132,7 +251,7 @@ public static class GeneratedDurableTaskExtensions
if (isDurableFunctions)
{
- if (receiver.Activities.Count > 0)
+ if (activities.Count > 0)
{
// Functions-specific helper class, which is only needed when
// using the class-based syntax.
@@ -144,8 +263,8 @@ public static class GeneratedDurableTaskExtensions
// ASP.NET Core-specific service registration methods
AddRegistrationMethodForAllTasks(
sourceBuilder,
- receiver.Orchestrators,
- receiver.Activities);
+ orchestrators,
+ activities);
}
sourceBuilder.AppendLine(" }").AppendLine("}");
@@ -273,124 +392,14 @@ internal static DurableTaskRegistry AddAllGeneratedTasks(this DurableTaskRegistr
}}");
}
- class DurableTaskSyntaxReceiver : ISyntaxContextReceiver
- {
- readonly List orchestrators = new();
- readonly List activities = new();
- readonly List durableFunctions = new();
-
- public IReadOnlyList Orchestrators => this.orchestrators;
- public IReadOnlyList Activities => this.activities;
- public IReadOnlyList DurableFunctions => this.durableFunctions;
-
- public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
- {
- // Check for Azure Functions syntax
- if (context.Node is MethodDeclarationSyntax method &&
- DurableFunction.TryParse(context.SemanticModel, method, out DurableFunction? function) &&
- function != null)
- {
- Debug.WriteLine($"Adding {function.Kind} function '{function.Name}'");
- this.durableFunctions.Add(function);
- return;
- }
-
- // Check for class-based syntax
- if (context.Node is not AttributeSyntax attribute)
- {
- return;
- }
-
- ITypeSymbol? attributeType = context.SemanticModel.GetTypeInfo(attribute.Name).Type;
- if (attributeType?.ToString() != "Microsoft.DurableTask.DurableTaskAttribute")
- {
- return;
- }
-
- if (attribute.Parent is not AttributeListSyntax list || list.Parent is not ClassDeclarationSyntax classDeclaration)
- {
- // TODO: Issue a warning that the [DurableTask] attribute was found in a place it wasn't expected.
- return;
- }
-
- // Verify that the attribute is being used on a non-abstract class
- if (classDeclaration.Modifiers.Any(SyntaxKind.AbstractKeyword))
- {
- // TODO: Issue a warning that you can't use [DurableTask] on abstract classes
- return;
- }
-
- if (context.SemanticModel.GetDeclaredSymbol(classDeclaration) is not ITypeSymbol classType)
- {
- // Invalid type declaration?
- return;
- }
-
- string className = classType.ToDisplayString();
-
- List? taskList = null;
- INamedTypeSymbol? taskType = null;
-
- INamedTypeSymbol? baseType = classType.BaseType;
- while (baseType != null)
- {
- if (baseType.ContainingAssembly.Name == "Microsoft.DurableTask.Abstractions")
- {
- if (baseType.Name == "TaskActivity")
- {
- taskList = this.activities;
- taskType = baseType;
- break;
- }
- else if (baseType.Name == "TaskOrchestrator")
- {
- taskList = this.orchestrators;
- taskType = baseType;
- break;
- }
- }
-
- baseType = baseType.BaseType;
- }
-
- if (taskList == null || taskType == null)
- {
- // TODO: Issue a warning that [DurableTask] can only be used with activity and orchestration-derived classes
- return;
- }
-
- if (taskType.TypeParameters.Length <= 1)
- {
- // We expect that the base class will always have at least two type parameters
- return;
- }
-
- ITypeSymbol inputType = taskType.TypeArguments.First();
- ITypeSymbol outputType = taskType.TypeArguments.Last();
-
- // By default, the task name is the class name.
- string taskName = classType.Name; // TODO: What if the class has generic type parameters?
- if (attribute.ArgumentList?.Arguments.Count > 0)
- {
- ExpressionSyntax expression = attribute.ArgumentList.Arguments[0].Expression;
- taskName = context.SemanticModel.GetConstantValue(expression).ToString();
- }
-
- taskList.Add(new DurableTaskTypeInfo(
- className,
- taskName,
- inputType,
- outputType));
- }
- }
-
class DurableTaskTypeInfo
{
public DurableTaskTypeInfo(
string taskType,
string taskName,
ITypeSymbol? inputType,
- ITypeSymbol? outputType)
+ ITypeSymbol? outputType,
+ bool isActivity)
{
this.TypeName = taskType;
this.TaskName = taskName;
@@ -402,6 +411,7 @@ public DurableTaskTypeInfo(
}
this.OutputType = GetRenderedTypeExpression(outputType);
+ this.IsActivity = isActivity;
}
public string TypeName { get; }
@@ -409,6 +419,7 @@ public DurableTaskTypeInfo(
public string InputType { get; }
public string InputParameter { get; }
public string OutputType { get; }
+ public bool IsActivity { get; }
static string GetRenderedTypeExpression(ITypeSymbol? symbol)
{
diff --git a/src/Grpc/Grpc.csproj b/src/Grpc/Grpc.csproj
index 4839af20..e433e01e 100644
--- a/src/Grpc/Grpc.csproj
+++ b/src/Grpc/Grpc.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;net6.0
+ netstandard2.0;net6.0;net8.0;net10.0
The gRPC Protobuf .NET services for Durable Task Framework.
@@ -13,7 +13,7 @@
-
+
diff --git a/src/InProcessTestHost/InProcessTestHost.csproj b/src/InProcessTestHost/InProcessTestHost.csproj
index 8839ef0f..45c263e7 100644
--- a/src/InProcessTestHost/InProcessTestHost.csproj
+++ b/src/InProcessTestHost/InProcessTestHost.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
Microsoft.DurableTask.Testing
Microsoft.DurableTask.InProcessTestHost
Microsoft.DurableTask.InProcessTestHost
diff --git a/src/ScheduledTasks/ScheduledTasks.csproj b/src/ScheduledTasks/ScheduledTasks.csproj
index 7283fb12..5971a560 100644
--- a/src/ScheduledTasks/ScheduledTasks.csproj
+++ b/src/ScheduledTasks/ScheduledTasks.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
Durable Task Scheduled Tasks Client
true
preview.1
diff --git a/src/Worker/AzureManaged/Worker.AzureManaged.csproj b/src/Worker/AzureManaged/Worker.AzureManaged.csproj
index 890da014..0eea5a5d 100644
--- a/src/Worker/AzureManaged/Worker.AzureManaged.csproj
+++ b/src/Worker/AzureManaged/Worker.AzureManaged.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
Azure Managed extensions for the Durable Task Framework worker.
true
diff --git a/src/Worker/Grpc/Worker.Grpc.csproj b/src/Worker/Grpc/Worker.Grpc.csproj
index 991fef8f..52ea3954 100644
--- a/src/Worker/Grpc/Worker.Grpc.csproj
+++ b/src/Worker/Grpc/Worker.Grpc.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;net6.0
+ netstandard2.0;net6.0;net8.0;net10.0
The gRPC worker for the Durable Task Framework.
true
diff --git a/test/Abstractions.Tests/Abstractions.Tests.csproj b/test/Abstractions.Tests/Abstractions.Tests.csproj
index e4cf7da9..1e10da3c 100644
--- a/test/Abstractions.Tests/Abstractions.Tests.csproj
+++ b/test/Abstractions.Tests/Abstractions.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/Abstractions.Tests/PageableTests.cs b/test/Abstractions.Tests/PageableTests.cs
index 8fb03645..9b20d201 100644
--- a/test/Abstractions.Tests/PageableTests.cs
+++ b/test/Abstractions.Tests/PageableTests.cs
@@ -23,7 +23,7 @@ public async Task Create_Func_Enumerable()
List expected = CreateSource(15);
AsyncPageable pageable = CreatePageable(expected, counter);
- List actual = await pageable.ToListAsync();
+ List actual = await pageable.ToListAsync(CancellationToken.None);
actual.Should().BeEquivalentTo(expected);
counter.Callbacks.Should().Be(5); // 15 / 3 = 5.
}
@@ -41,7 +41,7 @@ public async Task Create_Func_AsPages(int? start, int? pageSize)
AsyncPageable pageable = CreatePageable(source, counter);
List expected = source.Skip(start ?? 0).ToList();
- List> pages = await pageable.AsPages(start?.ToString(), pageSize).ToListAsync();
+ List> pages = await pageable.AsPages(start?.ToString(), pageSize).ToListAsync(CancellationToken.None);
pages.Should().HaveCount((int)Math.Ceiling((15.0 - (start ?? 0)) / (pageSize ?? 3)));
pages.SelectMany(x => x.Values).Should().BeEquivalentTo(expected);
counter.Callbacks.Should().Be(pages.Count);
diff --git a/test/Analyzers.Tests/Analyzers.Tests.csproj b/test/Analyzers.Tests/Analyzers.Tests.csproj
index a43fbdd0..e93d9c6d 100644
--- a/test/Analyzers.Tests/Analyzers.Tests.csproj
+++ b/test/Analyzers.Tests/Analyzers.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/Benchmarks/Benchmarks.csproj b/test/Benchmarks/Benchmarks.csproj
index 58504ddf..b7657682 100644
--- a/test/Benchmarks/Benchmarks.csproj
+++ b/test/Benchmarks/Benchmarks.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
Exe
Benchmarks
@@ -11,7 +11,6 @@
-
diff --git a/test/Client/AzureManaged.Tests/Client.AzureManaged.Tests.csproj b/test/Client/AzureManaged.Tests/Client.AzureManaged.Tests.csproj
index 4d43922f..77928b51 100644
--- a/test/Client/AzureManaged.Tests/Client.AzureManaged.Tests.csproj
+++ b/test/Client/AzureManaged.Tests/Client.AzureManaged.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
diff --git a/test/Client/Core.Tests/Client.Tests.csproj b/test/Client/Core.Tests/Client.Tests.csproj
index 29966adc..a8790ba5 100644
--- a/test/Client/Core.Tests/Client.Tests.csproj
+++ b/test/Client/Core.Tests/Client.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/Client/Grpc.Tests/Client.Grpc.Tests.csproj b/test/Client/Grpc.Tests/Client.Grpc.Tests.csproj
index 6d3dba79..41c0667a 100644
--- a/test/Client/Grpc.Tests/Client.Grpc.Tests.csproj
+++ b/test/Client/Grpc.Tests/Client.Grpc.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0;net48
+ net6.0;net8.0;net10.0;net48
diff --git a/test/Client/OrchestrationServiceClientShim.Tests/Client.OrchestrationServiceClientShim.Tests.csproj b/test/Client/OrchestrationServiceClientShim.Tests/Client.OrchestrationServiceClientShim.Tests.csproj
index f24130cb..c0899d09 100644
--- a/test/Client/OrchestrationServiceClientShim.Tests/Client.OrchestrationServiceClientShim.Tests.csproj
+++ b/test/Client/OrchestrationServiceClientShim.Tests/Client.OrchestrationServiceClientShim.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableEntityClientTests.cs b/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableEntityClientTests.cs
index a4c32f77..55c6e0a2 100644
--- a/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableEntityClientTests.cs
+++ b/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableEntityClientTests.cs
@@ -120,7 +120,7 @@ public async Task GetAllEntitiesAsync_NoFilter_ReturnsExpectedResult()
}
ShimDurableEntityClient client = this.CreateEntityClient();
- List actualEntities = await client.GetAllEntitiesAsync().ToListAsync();
+ List actualEntities = await client.GetAllEntitiesAsync().ToListAsync(CancellationToken.None);
using AssertionScope scope = new();
actualEntities.Should().HaveCount(entities.Count);
@@ -164,7 +164,7 @@ public async Task GetAllEntitiesAsync_WithFilter_ReturnsExpectedResult()
}
ShimDurableEntityClient client = this.CreateEntityClient();
- List actualEntities = await client.GetAllEntitiesAsync(query).ToListAsync();
+ List actualEntities = await client.GetAllEntitiesAsync(query).ToListAsync(CancellationToken.None);
using AssertionScope scope = new();
actualEntities.Should().HaveCount(entities.Count);
@@ -207,7 +207,7 @@ public async Task GetAllEntitiesAsyncOfT_NoFilter_ReturnsExpectedResult()
}
ShimDurableEntityClient client = this.CreateEntityClient();
- List> actualEntities = await client.GetAllEntitiesAsync().ToListAsync();
+ List> actualEntities = await client.GetAllEntitiesAsync().ToListAsync(CancellationToken.None);
using AssertionScope scope = new();
actualEntities.Should().HaveCount(entities.Count);
@@ -251,7 +251,7 @@ public async Task GetAllEntitiesAsyncOfT_WithFilter_ReturnsExpectedResult()
}
ShimDurableEntityClient client = this.CreateEntityClient();
- List> actualEntities = await client.GetAllEntitiesAsync(query).ToListAsync();
+ List> actualEntities = await client.GetAllEntitiesAsync(query).ToListAsync(CancellationToken.None);
using AssertionScope scope = new();
actualEntities.Should().HaveCount(entities.Count);
@@ -274,7 +274,7 @@ public async Task GetEntityAsync_Success(bool includeState)
entity.Should().NotBeNull();
VerifyEntity(entity!, expected);
entity!.IncludesState.Should().Be(includeState);
-
+
if (includeState)
{
entity!.State.Value.Should().Be("\"state\"");
@@ -294,7 +294,7 @@ public async Task GetEntityAsyncOfT_Success(bool includeState)
entity.Should().NotBeNull();
VerifyEntity(entity!, expected);
entity!.IncludesState.Should().Be(includeState);
-
+
if (includeState)
{
entity!.State.Should().Be("state");
diff --git a/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableTaskClientTests.cs b/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableTaskClientTests.cs
index 588f59ac..0d14b396 100644
--- a/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableTaskClientTests.cs
+++ b/test/Client/OrchestrationServiceClientShim.Tests/ShimDurableTaskClientTests.cs
@@ -151,7 +151,7 @@ public async Task GetInstances_Results(bool getInputs)
};
// act
- List result = await this.client.GetAllInstancesAsync(query).ToListAsync();
+ List result = await this.client.GetAllInstancesAsync(query).ToListAsync(CancellationToken.None);
// assert
this.orchestrationClient.VerifyAll();
@@ -373,7 +373,7 @@ public async Task RestartAsync_EndToEnd(bool restartWithNewInstanceId)
// Verify the captured message details
capturedMessage.Should().NotBeNull();
capturedMessage!.Event.Should().BeOfType();
-
+
var startedEvent = (ExecutionStartedEvent)capturedMessage.Event;
startedEvent.Name.Should().Be(orchestratorName);
startedEvent.Input.Should().Be(serializedInput);
diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets
index 911567b5..8ee08d1d 100644
--- a/test/Directory.Build.targets
+++ b/test/Directory.Build.targets
@@ -12,7 +12,7 @@
-
+
diff --git a/test/Generators.Tests/Generators.Tests.csproj b/test/Generators.Tests/Generators.Tests.csproj
index f805fecb..55aba3ea 100644
--- a/test/Generators.Tests/Generators.Tests.csproj
+++ b/test/Generators.Tests/Generators.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
diff --git a/test/Generators.Tests/Utils/CSharpSourceGeneratorVerifier.cs b/test/Generators.Tests/Utils/CSharpSourceGeneratorVerifier.cs
index 98233b8d..331ebd14 100644
--- a/test/Generators.Tests/Utils/CSharpSourceGeneratorVerifier.cs
+++ b/test/Generators.Tests/Utils/CSharpSourceGeneratorVerifier.cs
@@ -10,17 +10,17 @@
namespace Microsoft.DurableTask.Generators.Tests.Utils;
// Mostly copy/pasted from the Microsoft Source Generators testing documentation
-public static class CSharpSourceGeneratorVerifier where TSourceGenerator : ISourceGenerator, new()
+public static class CSharpSourceGeneratorVerifier where TSourceGenerator : IIncrementalGenerator, new()
{
public class Test : CSharpSourceGeneratorTest
{
public Test()
{
- // See https://www.nuget.org/packages/Microsoft.NETCore.App.Ref/6.0.0
+ // See https://www.nuget.org/packages/Microsoft.NETCore.App.Ref/8.0.22
this.ReferenceAssemblies = new ReferenceAssemblies(
- targetFramework: "net6.0",
- referenceAssemblyPackage: new PackageIdentity("Microsoft.NETCore.App.Ref", "6.0.0"),
- referenceAssemblyPath: Path.Combine("ref", "net6.0"));
+ targetFramework: "net8.0",
+ referenceAssemblyPackage: new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.22"),
+ referenceAssemblyPath: Path.Combine("ref", "net8.0"));
}
public LanguageVersion LanguageVersion { get; set; } = LanguageVersion.CSharp9;
diff --git a/test/Generators.Tests/Utils/TestHelpers.cs b/test/Generators.Tests/Utils/TestHelpers.cs
index 651d27b4..8b53462d 100644
--- a/test/Generators.Tests/Utils/TestHelpers.cs
+++ b/test/Generators.Tests/Utils/TestHelpers.cs
@@ -15,7 +15,7 @@ public static Task RunTestAsync(
string expectedFileName,
string inputSource,
string expectedOutputSource,
- bool isDurableFunctions) where TSourceGenerator : ISourceGenerator, new()
+ bool isDurableFunctions) where TSourceGenerator : IIncrementalGenerator, new()
{
CSharpSourceGeneratorVerifier.Test test = new()
{
@@ -43,7 +43,7 @@ public static Task RunTestAsync(
// Assembly functionsWorkerCore = typeof(FunctionContext).Assembly;
// test.TestState.AdditionalReferences.Add(functionsWorkerCore);
-
+
// Assembly durableExtension = typeof(OrchestrationTriggerAttribute).Assembly;
// test.TestState.AdditionalReferences.Add(durableExtension);
@@ -134,7 +134,7 @@ static bool IsValueType(string typeExpression)
Type? runtimeType = Type.GetType(typeExpression, throwOnError: false);
return runtimeType != null && runtimeType.IsValueType;
}
- };
+ }
if (inputType.StartsWith("(") || inputType.EndsWith('?') || IsValueType(inputType))
{
diff --git a/test/Grpc.IntegrationTests/Grpc.IntegrationTests.csproj b/test/Grpc.IntegrationTests/Grpc.IntegrationTests.csproj
index 88ab0633..08ec22e1 100644
--- a/test/Grpc.IntegrationTests/Grpc.IntegrationTests.csproj
+++ b/test/Grpc.IntegrationTests/Grpc.IntegrationTests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/Grpc.IntegrationTests/GrpcDurableTaskClientIntegrationTests.cs b/test/Grpc.IntegrationTests/GrpcDurableTaskClientIntegrationTests.cs
index 63f92ef3..2d5df336 100644
--- a/test/Grpc.IntegrationTests/GrpcDurableTaskClientIntegrationTests.cs
+++ b/test/Grpc.IntegrationTests/GrpcDurableTaskClientIntegrationTests.cs
@@ -104,14 +104,14 @@ await ForEachOrchestrationAsync(
AsyncPageable pageable = server.Client.GetAllInstancesAsync(query);
await ForEachOrchestrationAsync(x => server.Client.WaitForInstanceStartAsync(x, default));
- List metadata = await pageable.ToListAsync();
+ List metadata = await pageable.ToListAsync(CancellationToken.None);
metadata.Should().HaveCount(2)
.And.AllSatisfy(m => AssertMetadata(m, OrchestrationRuntimeStatus.Running))
.And.NotContain(x => string.Equals(x.InstanceId, notIncluded, StringComparison.OrdinalIgnoreCase));
await ForEachOrchestrationAsync(x => server.Client.RaiseEventAsync(x, "event", default));
await ForEachOrchestrationAsync(x => server.Client.WaitForInstanceCompletionAsync(x, default));
- metadata = await pageable.ToListAsync();
+ metadata = await pageable.ToListAsync(CancellationToken.None);
metadata.Should().HaveCount(2)
.And.AllSatisfy(m => AssertMetadata(m, OrchestrationRuntimeStatus.Completed))
.And.NotContain(x => string.Equals(x.InstanceId, notIncluded, StringComparison.OrdinalIgnoreCase));
@@ -130,12 +130,12 @@ await server.Client.ScheduleNewOrchestrationInstanceAsync(
}
AsyncPageable pageable = server.Client.GetAllInstancesAsync(query);
- List> pages = await pageable.AsPages(pageSizeHint: 5).ToListAsync();
+ List> pages = await pageable.AsPages(pageSizeHint: 5).ToListAsync(CancellationToken.None);
pages.Should().HaveCount(5);
pages.ForEach(p => p.Values.Should().HaveCount(p.ContinuationToken is null ? 1 : 5));
List> resumedPages = await pageable.AsPages(
- pages[1].ContinuationToken, pageSizeHint: 4).ToListAsync();
+ pages[1].ContinuationToken, pageSizeHint: 4).ToListAsync(CancellationToken.None);
resumedPages.Should().HaveCount(3);
List left = resumedPages.SelectMany(p => p.Values).ToList();
@@ -145,7 +145,7 @@ await server.Client.ScheduleNewOrchestrationInstanceAsync(
cfg => cfg.Including(x => x.InstanceId).Including(x => x.CreatedAt)
.Using());
- Page page = await pageable.AsPages(pageSizeHint: 10).FirstAsync();
+ Page page = await pageable.AsPages(pageSizeHint: 10).FirstAsync(CancellationToken.None);
page.Values.Should().HaveCount(10);
page.ContinuationToken.Should().NotBeNull();
}
@@ -240,7 +240,7 @@ public async Task RestartAsync_EndToEnd(bool restartWithNewInstanceId)
await server.Client.WaitForInstanceStartAsync(originalInstanceId, default);
await server.Client.RaiseEventAsync(originalInstanceId, "event", default);
await server.Client.WaitForInstanceCompletionAsync(originalInstanceId, cts.Token);
-
+
// Verify the original orchestration completed
OrchestrationMetadata? originalMetadata = await server.Client.GetInstanceAsync(originalInstanceId, true);
originalMetadata.Should().NotBeNull();
@@ -261,7 +261,7 @@ public async Task RestartAsync_EndToEnd(bool restartWithNewInstanceId)
// Complete the restarted orchestration
await server.Client.RaiseEventAsync(restartedInstanceId, "event");
-
+
using var completionCts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
await server.Client.WaitForInstanceCompletionAsync(restartedInstanceId, completionCts.Token);
diff --git a/test/Grpc.IntegrationTests/OrchestrationPatterns.cs b/test/Grpc.IntegrationTests/OrchestrationPatterns.cs
index 500a1952..45fbd490 100644
--- a/test/Grpc.IntegrationTests/OrchestrationPatterns.cs
+++ b/test/Grpc.IntegrationTests/OrchestrationPatterns.cs
@@ -329,7 +329,7 @@ public async Task ActivityFanOut()
Assert.Equal(OrchestrationRuntimeStatus.Completed, metadata.RuntimeStatus);
string[] expected = new[] { "9", "8", "7", "6", "5", "4", "3", "2", "1", "0" };
- Assert.Equal(expected, metadata.ReadOutputAs());
+ Assert.Equal((IEnumerable)expected, metadata.ReadOutputAs());
}
[Theory]
diff --git a/test/Grpc.IntegrationTests/PageableIntegrationTests.cs b/test/Grpc.IntegrationTests/PageableIntegrationTests.cs
index 6d8d0727..c05010cf 100644
--- a/test/Grpc.IntegrationTests/PageableIntegrationTests.cs
+++ b/test/Grpc.IntegrationTests/PageableIntegrationTests.cs
@@ -41,7 +41,7 @@ public async Task PageableActivity_Enumerates()
{
int pageSize = input?.PageSize ?? 3;
Page CreatePage(string? next)
- => new (Enumerable.Range(0, pageSize).Select(x => $"item_{x}").ToList(), next);
+ => new(Enumerable.Range(0, pageSize).Select(x => $"item_{x}").ToList(), next);
Page? page = input?.Continuation switch
{
null => CreatePage("1"),
@@ -61,7 +61,7 @@ static async Task PageableOrchestrationAsync(TaskOrchestrationContext conte
nameof(PageableActivityAsync), new PageRequest(continuation))!;
});
- return await pageable.CountAsync();
+ return await pageable.CountAsync(CancellationToken.None);
}
record PageRequest(string? Continuation, int? PageSize = null);
diff --git a/test/InProcessTestHost.Tests/InProcessTestHost.Tests.csproj b/test/InProcessTestHost.Tests/InProcessTestHost.Tests.csproj
index 479d88a1..e2dbbe5e 100644
--- a/test/InProcessTestHost.Tests/InProcessTestHost.Tests.csproj
+++ b/test/InProcessTestHost.Tests/InProcessTestHost.Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net6.0;net8.0;net10.0
enable
enable
diff --git a/test/ScheduledTasks.Tests/ScheduledTasks.Tests.csproj b/test/ScheduledTasks.Tests/ScheduledTasks.Tests.csproj
index 33726a62..3f788c51 100644
--- a/test/ScheduledTasks.Tests/ScheduledTasks.Tests.csproj
+++ b/test/ScheduledTasks.Tests/ScheduledTasks.Tests.csproj
@@ -2,7 +2,7 @@
- net6.0
+ net8.0;net10.0
enable
enable
false
@@ -10,7 +10,6 @@
-
diff --git a/test/Shared/AzureManaged.Tests/Shared.AzureManaged.Tests.csproj b/test/Shared/AzureManaged.Tests/Shared.AzureManaged.Tests.csproj
index f9822995..efd29a70 100644
--- a/test/Shared/AzureManaged.Tests/Shared.AzureManaged.Tests.csproj
+++ b/test/Shared/AzureManaged.Tests/Shared.AzureManaged.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/TestHelpers/TestHelpers.csproj b/test/TestHelpers/TestHelpers.csproj
index 55514082..f522d518 100644
--- a/test/TestHelpers/TestHelpers.csproj
+++ b/test/TestHelpers/TestHelpers.csproj
@@ -1,7 +1,7 @@
- net6.0;netstandard2.0
+ net6.0;net8.0;net10.0;netstandard2.0
diff --git a/test/Worker/AzureManaged.Tests/Worker.AzureManaged.Tests.csproj b/test/Worker/AzureManaged.Tests/Worker.AzureManaged.Tests.csproj
index 4a5a7cc1..fc933611 100644
--- a/test/Worker/AzureManaged.Tests/Worker.AzureManaged.Tests.csproj
+++ b/test/Worker/AzureManaged.Tests/Worker.AzureManaged.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0;net10.0
diff --git a/test/Worker/Core.Tests/Worker.Tests.csproj b/test/Worker/Core.Tests/Worker.Tests.csproj
index 736986d4..b0fcd6bc 100644
--- a/test/Worker/Core.Tests/Worker.Tests.csproj
+++ b/test/Worker/Core.Tests/Worker.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net6.0;net8.0;net10.0
diff --git a/test/Worker/Grpc.Tests/Worker.Grpc.Tests.csproj b/test/Worker/Grpc.Tests/Worker.Grpc.Tests.csproj
index b3c7f9c1..32d83f45 100644
--- a/test/Worker/Grpc.Tests/Worker.Grpc.Tests.csproj
+++ b/test/Worker/Grpc.Tests/Worker.Grpc.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0;net48
+ net8.0;net10.0;net48
@@ -12,7 +12,7 @@
-
+