Skip to content
Merged
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
55 changes: 55 additions & 0 deletions test/AzureServiceFabricTests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Running Azure Service Fabric Tests Locally

## Prerequisites

### 1. Install Service Fabric SDK

Follow the official guide to install the Service Fabric SDK and runtime:

https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-get-started

### 2. Start the Local Cluster (5-Node Configuration)

1. Look for the **Service Fabric Local Cluster Manager** tray icon in the Windows system tray.
2. Right-click the tray icon.
3. Select **Start Local Cluster**.
4. Choose the **5 Node** configuration.
5. Wait for the cluster to finish initializing — the tray icon will change to indicate it's running.

### 3. Build the Solution

```powershell
dotnet build DurableTask.sln -c Debug -p:Platform=x64
```

### 4. Package the Test Application

1. Open the solution in Visual Studio.
2. In Solution Explorer, right-click **TestApplication** (`test\TestFabricApplication\TestApplication\TestApplication.sfproj`).
3. Click **Package**.

This produces the Service Fabric application package needed by the integration tests.

### 5. Run the Tests

```powershell
# Unit tests
dotnet test test\DurableTask.AzureServiceFabric.Tests\DurableTask.AzureServiceFabric.Tests.csproj -c Debug -p:Platform=x64

# Integration tests (requires the local cluster and packaged application)
dotnet test test\DurableTask.AzureServiceFabric.Integration.Tests\DurableTask.AzureServiceFabric.Integration.Tests.csproj -c Debug -p:Platform=x64
```

## Troubleshooting

### Binding redirect / assembly load errors

The `net48` test projects require binding redirects for assemblies with revision-number mismatches. If you see `FileNotFoundException` or `ReflectionTypeLoadException` errors, verify that `App.config` exists in each test project with the appropriate `<bindingRedirect>` entries.

The binding redirect files are located at:
- `test/DurableTask.AzureServiceFabric.Tests/App.config` (unit tests)
- `test/DurableTask.AzureServiceFabric.Integration.Tests/App.config` (integration tests)

### Cluster not reachable

If tests fail to connect to the local cluster, verify the cluster is running by opening **Service Fabric Explorer** at http://localhost:19080.
22 changes: 21 additions & 1 deletion test/DurableTask.AzureServiceFabric.Integration.Tests/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,27 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
Comment thread
shankarsama marked this conversation as resolved.
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="6.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="6.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace DurableTask.AzureServiceFabric.Integration.Tests
using DurableTask.Test.Orchestrations.Performance;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Protected;
using TestApplication.Common.Orchestrations;

[TestClass]
Expand Down Expand Up @@ -591,38 +592,30 @@ public async Task ScheduledStartTest_NotSupported()
[TestMethod]
public async Task CreateTaskOrchestration_HandlesConflictResponse_When_HttpClientReturnsNullContent()
{
var httpClientMock = new Mock<HttpClient>();
var response = new HttpResponseMessage(System.Net.HttpStatusCode.Conflict) { Content = null };
SetupHttpClientMockForPut(httpClientMock, response);
var mockHandler = new Mock<HttpMessageHandler>();
mockHandler
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(response);

var httpClient = new HttpClient(mockHandler.Object)
{
BaseAddress = new Uri("http://localhost")
};

var taskHubClient = Utilities.CreateTaskHubClient((serviceClient) =>
{
serviceClient.HttpClient = httpClientMock.Object;
serviceClient.HttpClient = httpClient;
});

await Assert.ThrowsExceptionAsync<OrchestrationAlreadyExistsException>(async () =>
{
await taskHubClient.CreateOrchestrationInstanceAsync(typeof(TestOrchestration), new TestOrchestrationData());
});
}

private static void SetupHttpClientMockForPut(Mock<HttpClient> httpClientMock, HttpResponseMessage response)
{
httpClientMock
.Setup(x => x.PutAsync(It.IsAny<string>(), It.IsAny<HttpContent>()))
.ReturnsAsync(response);

httpClientMock
.Setup(x => x.PutAsync(It.IsAny<Uri>(), It.IsAny<HttpContent>()))
.ReturnsAsync(response);

httpClientMock
.Setup(x => x.PutAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(response);

httpClientMock
.Setup(x => x.PutAsync(It.IsAny<Uri>(), It.IsAny<HttpContent>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(response);
}
}
}
31 changes: 31 additions & 0 deletions test/DurableTask.AzureServiceFabric.Tests/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
Comment thread
shankarsama marked this conversation as resolved.
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="6.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="6.0.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Loading