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
12 changes: 10 additions & 2 deletions .github/workflows/build_and_it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,24 @@ jobs:
curl "127.0.0.1:36789/api/dtmsvr/newGid"
- name: Setup Busi Service
run: |
cd tests/BusiGrpcService
cd tests/BusiIntegrationService
nohup dotnet run > /home/runner/work/client-csharp/client-csharp/logs/app.log 2>&1 &
- name: Run Integration Tests
- name: Run Integration Tests (Dtmgrpc)
env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_NOLOGO: 1
DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home
run: |
dotnet build tests/Dtmgrpc.IntegrationTests/Dtmgrpc.IntegrationTests.csproj
dotnet test --framework=net8.0 tests/Dtmgrpc.IntegrationTests/Dtmgrpc.IntegrationTests.csproj
- name: Run Integration Tests (Dtmcli)
env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_NOLOGO: 1
DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home
run: |
dotnet build tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj
dotnet test --framework=net8.0 tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj
- name: Upload logs
if: always()
uses: actions/upload-artifact@v4
Expand Down
9 changes: 8 additions & 1 deletion DtmClient.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AFCF4E29-660
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED5B84F1-876F-4617-A4F4-5C160319310C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusiGrpcService", "tests\BusiGrpcService\BusiGrpcService.csproj", "{FFF41358-6974-4E87-840D-C61E1B6BEDC3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusiIntegrationService", "tests\BusiIntegrationService\BusiIntegrationService.csproj", "{FFF41358-6974-4E87-840D-C61E1B6BEDC3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dtmgrpc.IntegrationTests", "tests\Dtmgrpc.IntegrationTests\Dtmgrpc.IntegrationTests.csproj", "{AFDB3DCD-55CE-402F-A1B0-FCD4737FE314}"
EndProject
Expand All @@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dtmgrpc.StrongName", "src\s
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dtmworkflow.StrongName", "src\strong-name\Dtmworkflow.StrongName\Dtmworkflow.StrongName.csproj", "{96634D84-A11E-448C-8033-CC643F96558A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dtmcli.IntegrationTests", "tests\Dtmcli.IntegrationTests\Dtmcli.IntegrationTests.csproj", "{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -125,6 +127,10 @@ Global
{96634D84-A11E-448C-8033-CC643F96558A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96634D84-A11E-448C-8033-CC643F96558A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96634D84-A11E-448C-8033-CC643F96558A}.Release|Any CPU.Build.0 = Release|Any CPU
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -149,6 +155,7 @@ Global
{3196931A-26B1-4C48-BA66-003356153C34} = {A8DF688D-43CE-4227-B5FD-F65760DE7967}
{60051A80-A987-43B7-A5D1-284B8FD330D4} = {A8DF688D-43CE-4227-B5FD-F65760DE7967}
{96634D84-A11E-448C-8033-CC643F96558A} = {A8DF688D-43CE-4227-B5FD-F65760DE7967}
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F} = {ED5B84F1-876F-4617-A4F4-5C160319310C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A872C3EE-D0B6-4943-8C7D-9ADD28AC029A}
Expand Down
25 changes: 0 additions & 25 deletions tests/BusiGrpcService/Program.cs

This file was deleted.

15 changes: 0 additions & 15 deletions tests/BusiGrpcService/appsettings.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>BusiIntegrationService</RootNamespace>
</PropertyGroup>

<ItemGroup>
Expand All @@ -12,6 +13,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Dtmcli\Dtmcli.csproj" />
<ProjectReference Include="..\..\src\Dtmgrpc\Dtmgrpc.csproj" />
<ProjectReference Include="..\..\src\DtmSERedisBarrier\DtmSERedisBarrier.csproj" />
</ItemGroup>
Expand Down
78 changes: 78 additions & 0 deletions tests/BusiIntegrationService/Controllers/BusiApiController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System.Text.Json;
using BusiIntegrationService.Dtos;
using Microsoft.AspNetCore.Mvc;

namespace BusiIntegrationService.Controllers
{
[ApiController]
[Route("http/busi.Busi")]
public class BusiApiController : ControllerBase
{
private readonly ILogger<BusiApiController> _logger;
private readonly Dtmcli.IBranchBarrierFactory _barrierFactory;
private readonly Dtmgrpc.IBranchBarrierFactory _grpcBarrierFactory;

public BusiApiController(ILogger<BusiApiController> logger, Dtmcli.IBranchBarrierFactory barrierFactory, Dtmgrpc.IBranchBarrierFactory grpcBarrierFactory)
{
_logger = logger;
_barrierFactory = barrierFactory;
_grpcBarrierFactory = grpcBarrierFactory;
}

[HttpGet("Test")]
public async Task<IActionResult> Test()
{
return this.Ok(nameof(this.Test));
}

[HttpPost("TransIn")]
public async Task<IActionResult> TransIn([FromBody] BusiRequest request)
{
_logger.LogInformation("TransIn req={req}", JsonSerializer.Serialize(request));

if (DateTime.Now < request.EffectTime)
return this.StatusCode(425, new { error = "Early" });

if (string.IsNullOrWhiteSpace(request.TransInResult) || request.TransInResult.Equals("SUCCESS"))
{
await Task.CompletedTask;
return Ok();
}
else if (request.TransInResult.Equals("FAILURE"))
{
return StatusCode(422, new { error = "FAILURE" }); // 422 Unprocessable Entity for business failure
}
else if (request.TransInResult.Equals("ONGOING"))
{
return StatusCode(425, new { error = "ONGOING" }); // 425 Too Early for ongoing state
}

return StatusCode(500, new { error = $"unknown result {request.TransInResult}" });
}

[HttpPost("TransOut")]
public async Task<IActionResult> TransOut([FromBody] BusiRequest request)
{
_logger.LogInformation("TransOut req={req}", JsonSerializer.Serialize(request));

if (DateTime.Now < request.EffectTime)
return this.StatusCode(425, new { error = "Early" });

if (string.IsNullOrWhiteSpace(request.TransOutResult) || request.TransOutResult.Equals("SUCCESS"))
{
await Task.CompletedTask;
return Ok();
}
else if (request.TransOutResult.Equals("FAILURE"))
{
return StatusCode(422, new { error = "FAILURE" }); // 422 Unprocessable Entity for business failure
}
else if (request.TransOutResult.Equals("ONGOING"))
{
return StatusCode(425, new { error = "ONGOING" }); // 425 Too Early for ongoing state
}

return StatusCode(500, new { error = $"unknown result {request.TransOutResult}" });
}
}
}
24 changes: 24 additions & 0 deletions tests/BusiIntegrationService/Dtos/BusiRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Text.Json.Serialization;

namespace BusiIntegrationService.Dtos
{
public class BusiRequest
{
[JsonPropertyName("amount")]
public long Amount { get; set; }

[JsonPropertyName("transOutResult")]
public string TransOutResult { get; set; } = string.Empty;

[JsonPropertyName("transInResult")]
public string TransInResult { get; set; } = string.Empty;

[JsonPropertyName("effectTime")] public DateTime EffectTime { get; set; }
}

public class BusiReply
{
[JsonPropertyName("message")]
public string Message { get; set; } = string.Empty;
}
}
36 changes: 36 additions & 0 deletions tests/BusiIntegrationService/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using BusiIntegrationService;
using BusiIntegrationService.Services;
using Dtmcli;
using Dtmgrpc;
using Microsoft.AspNetCore.Server.Kestrel.Core;

// Enable HTTP/2 support for unencrypted HTTP connections (required for gRPC over HTTP)
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc(options =>
{
// Configure gRPC to allow unencrypted HTTP/2 connections (for local development)
options.EnableDetailedErrors = true;
});
builder.Services.AddDtmGrpc(x =>
{
x.DtmGrpcUrl = "http://localhost:36790";
});
builder.Services.AddDtmcli(option =>
{
option.DtmUrl = "http://localhost:36789";
});

// Add controllers for HTTP API
builder.Services.AddControllers();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.MapGrpcService<BusiApiService>();
app.MapControllers(); // Map the HTTP API controllers
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

app.Run();
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"profiles": {
"BusiGrpcService": {
"BusiIntegrationService": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5251;https://localhost:7251",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using DtmCommon;
using DtmSERedisBarrier;

namespace BusiGrpcService.Services
namespace BusiIntegrationService.Services
{
public class BusiApiService : Busi.BusiBase
{
Expand All @@ -27,6 +27,9 @@ public BusiApiService(ILogger<BusiApiService> logger, Dtmgrpc.IDtmgRPCClient cli
public override async Task<Empty> TransIn(BusiReq request, ServerCallContext context)
{
_logger.LogInformation("TransIn req={req}", JsonSerializer.Serialize(request));

if (request.EffectTime != null && DateTime.UtcNow < request.EffectTime.ToDateTime())
throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, "ONGOING"));

if (string.IsNullOrWhiteSpace(request.TransInResult) || request.TransInResult.Equals("SUCCESS"))
{
Expand All @@ -49,6 +52,9 @@ public override async Task<Empty> TransInTcc(BusiReq request, ServerCallContext
{
_logger.LogInformation("TransIn req={req}", JsonSerializer.Serialize(request));

if (request.EffectTime != null && request.EffectTime.ToDateTime() < DateTime.Now)
throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, "ONGOING"));

if (string.IsNullOrWhiteSpace(request.TransInResult) || request.TransInResult.Equals("SUCCESS"))
{
await Task.CompletedTask;
Expand Down Expand Up @@ -87,6 +93,10 @@ public override async Task<Empty> TransInRevert(BusiReq request, ServerCallConte
public override async Task<Empty> TransOut(BusiReq request, ServerCallContext context)
{
_logger.LogInformation("TransOut req={req}", JsonSerializer.Serialize(request));

if (request.EffectTime != null && DateTime.UtcNow < request.EffectTime.ToDateTime())
throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, "ONGOING"));

await Task.CompletedTask;
return new Empty();
}
Expand Down
22 changes: 22 additions & 0 deletions tests/BusiIntegrationService/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Dtm": "Debug"
}
},
"AllowedHosts": "*",
"Kestrel": {
"Endpoints": {
"myHttp": {
"Url": "http://localhost:5005",
"Protocols": "Http2"
},
"myGRPC": {
"Url": "http://localhost:5006",
"Protocols": "Http1"
}
}
}
}
19 changes: 19 additions & 0 deletions tests/Dtmcli.IntegrationTests/BusiRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Text.Json.Serialization;

namespace Dtmcli.IntegrationTests;

public class BusiRequest
{
[JsonPropertyName("amount")] public long Amount { get; set; }

[JsonPropertyName("transOutResult")] public string TransOutResult { get; set; } = string.Empty;

[JsonPropertyName("transInResult")] public string TransInResult { get; set; } = string.Empty;
[JsonPropertyName("effectTime")] public DateTime EffectTime { get; set; }
}

public class BusiReply
{
[JsonPropertyName("message")] public string Message { get; set; } = string.Empty;
}
25 changes: 25 additions & 0 deletions tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(MicrosoftExtensionsDependencyInjectionPackageVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualstudioPackageVersion)">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorPackageVersion)">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Dtmcli\Dtmcli.csproj" />
</ItemGroup>
</Project>
Loading
Loading