From a5a16c4d8a47c5b2daea6329d7f695a5aefa4382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E4=BA=91=E9=87=91YunjinXu?= Date: Sun, 11 Jan 2026 21:17:51 +0800 Subject: [PATCH 1/3] MSG: Add intergration test for MSG(http/gPRC) delayed consum - implements by business effect time, return http status code 425(Early), will call again arrived next cron time. --- DtmClient.sln | 7 ++ tests/BusiGrpcService/BusiGrpcService.csproj | 1 + .../Controllers/BusiApiController.cs | 78 +++++++++++++++++++ tests/BusiGrpcService/Dtos/BusiRequest.cs | 24 ++++++ tests/BusiGrpcService/Program.cs | 23 ++++-- .../Properties/launchSettings.json | 5 +- .../Services/BusiApiService.cs | 10 +++ tests/BusiGrpcService/appsettings.json | 15 +++- tests/Dtmcli.IntegrationTests/BusiRequest.cs | 19 +++++ .../Dtmcli.IntegrationTests.csproj | 25 ++++++ tests/Dtmcli.IntegrationTests/ITTestHelper.cs | 67 ++++++++++++++++ tests/Dtmcli.IntegrationTests/MsgHttpTest.cs | 62 +++++++++++++++ tests/Dtmgrpc.IntegrationTests/MsgGrpcTest.cs | 33 +++++++- tests/protos/busi.proto | 2 + 14 files changed, 356 insertions(+), 15 deletions(-) create mode 100644 tests/BusiGrpcService/Controllers/BusiApiController.cs create mode 100644 tests/BusiGrpcService/Dtos/BusiRequest.cs create mode 100644 tests/Dtmcli.IntegrationTests/BusiRequest.cs create mode 100644 tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj create mode 100644 tests/Dtmcli.IntegrationTests/ITTestHelper.cs create mode 100644 tests/Dtmcli.IntegrationTests/MsgHttpTest.cs diff --git a/DtmClient.sln b/DtmClient.sln index a18b3bd..d9abb95 100644 --- a/DtmClient.sln +++ b/DtmClient.sln @@ -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 @@ -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 @@ -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} diff --git a/tests/BusiGrpcService/BusiGrpcService.csproj b/tests/BusiGrpcService/BusiGrpcService.csproj index b896af4..2935141 100644 --- a/tests/BusiGrpcService/BusiGrpcService.csproj +++ b/tests/BusiGrpcService/BusiGrpcService.csproj @@ -12,6 +12,7 @@ + diff --git a/tests/BusiGrpcService/Controllers/BusiApiController.cs b/tests/BusiGrpcService/Controllers/BusiApiController.cs new file mode 100644 index 0000000..cf95b6b --- /dev/null +++ b/tests/BusiGrpcService/Controllers/BusiApiController.cs @@ -0,0 +1,78 @@ +using System.Text.Json; +using BusiGrpcService.Dtos; +using Microsoft.AspNetCore.Mvc; + +namespace BusiGrpcService.Controllers +{ + [ApiController] + [Route("http/busi.Busi")] + public class BusiApiController : ControllerBase + { + private readonly ILogger _logger; + private readonly Dtmcli.IBranchBarrierFactory _barrierFactory; + private readonly Dtmgrpc.IBranchBarrierFactory _grpcBarrierFactory; + + public BusiApiController(ILogger logger, Dtmcli.IBranchBarrierFactory barrierFactory, Dtmgrpc.IBranchBarrierFactory grpcBarrierFactory) + { + _logger = logger; + _barrierFactory = barrierFactory; + _grpcBarrierFactory = grpcBarrierFactory; + } + + [HttpGet("Test")] + public async Task Test() + { + return this.Ok(nameof(this.Test)); + } + + [HttpPost("TransIn")] + public async Task 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 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}" }); + } + } +} \ No newline at end of file diff --git a/tests/BusiGrpcService/Dtos/BusiRequest.cs b/tests/BusiGrpcService/Dtos/BusiRequest.cs new file mode 100644 index 0000000..f0c29ef --- /dev/null +++ b/tests/BusiGrpcService/Dtos/BusiRequest.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace BusiGrpcService.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; + } +} \ No newline at end of file diff --git a/tests/BusiGrpcService/Program.cs b/tests/BusiGrpcService/Program.cs index be2cc0d..c7eeea2 100644 --- a/tests/BusiGrpcService/Program.cs +++ b/tests/BusiGrpcService/Program.cs @@ -1,25 +1,36 @@ +using BusiGrpcService; using BusiGrpcService.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.WebHost.ConfigureKestrel(options => +builder.Services.AddGrpc(options => { - // Setup a HTTP/2 endpoint without TLS. - options.ListenLocalhost(5005, o => o.Protocols = HttpProtocols.Http2); + // Configure gRPC to allow unencrypted HTTP/2 connections (for local development) + options.EnableDetailedErrors = true; }); - -builder.Services.AddGrpc(); 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(); +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(); +app.Run(); \ No newline at end of file diff --git a/tests/BusiGrpcService/Properties/launchSettings.json b/tests/BusiGrpcService/Properties/launchSettings.json index 5dd0f5f..be4c40f 100644 --- a/tests/BusiGrpcService/Properties/launchSettings.json +++ b/tests/BusiGrpcService/Properties/launchSettings.json @@ -1,13 +1,12 @@ -{ +{ "profiles": { "BusiGrpcService": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, - "applicationUrl": "http://localhost:5251;https://localhost:7251", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } -} +} \ No newline at end of file diff --git a/tests/BusiGrpcService/Services/BusiApiService.cs b/tests/BusiGrpcService/Services/BusiApiService.cs index a8f1370..0ac7068 100644 --- a/tests/BusiGrpcService/Services/BusiApiService.cs +++ b/tests/BusiGrpcService/Services/BusiApiService.cs @@ -27,6 +27,9 @@ public BusiApiService(ILogger logger, Dtmgrpc.IDtmgRPCClient cli public override async Task 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")) { @@ -49,6 +52,9 @@ public override async Task 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; @@ -87,6 +93,10 @@ public override async Task TransInRevert(BusiReq request, ServerCallConte public override async Task 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(); } diff --git a/tests/BusiGrpcService/appsettings.json b/tests/BusiGrpcService/appsettings.json index 95303fd..531dd56 100644 --- a/tests/BusiGrpcService/appsettings.json +++ b/tests/BusiGrpcService/appsettings.json @@ -7,9 +7,16 @@ } }, "AllowedHosts": "*", - "Kestrel": { - "EndpointDefaults": { - "Protocols": "Http2" + "Kestrel": { + "Endpoints": { + "myHttp": { + "Url": "http://localhost:5005", + "Protocols": "Http2" + }, + "myGRPC": { + "Url": "http://localhost:5006", + "Protocols": "Http1" + } } } -} +} \ No newline at end of file diff --git a/tests/Dtmcli.IntegrationTests/BusiRequest.cs b/tests/Dtmcli.IntegrationTests/BusiRequest.cs new file mode 100644 index 0000000..c5b8bd4 --- /dev/null +++ b/tests/Dtmcli.IntegrationTests/BusiRequest.cs @@ -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; +} \ No newline at end of file diff --git a/tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj b/tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj new file mode 100644 index 0000000..41a5ba0 --- /dev/null +++ b/tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + false + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + diff --git a/tests/Dtmcli.IntegrationTests/ITTestHelper.cs b/tests/Dtmcli.IntegrationTests/ITTestHelper.cs new file mode 100644 index 0000000..3d70854 --- /dev/null +++ b/tests/Dtmcli.IntegrationTests/ITTestHelper.cs @@ -0,0 +1,67 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Dtmcli.IntegrationTests; + +public class ITTestHelper +{ + public static string DTMHttpUrl = "http://localhost:36789"; + public static string BuisHttpUrl = "http://localhost:5006/http"; + private static System.Net.Http.HttpClient _client = new System.Net.Http.HttpClient(); + + public static async Task GetTranStatus(string gid) + { + var resp = await _client.GetAsync($"{DTMHttpUrl}/api/dtmsvr/query?gid={gid}").ConfigureAwait(false); + + if (resp.IsSuccessStatusCode) + { + var content = await resp.Content.ReadAsStringAsync(); + var res = System.Text.Json.JsonSerializer.Deserialize(content); + return res.Transaction.Status; + } + + return string.Empty; + } + + public class QueryResult + { + public class TransBranchStore + { + } + + public class TransGlobalStore + { + [System.Text.Json.Serialization.JsonPropertyName("status")] + public string Status { get; set; } + } + + + [System.Text.Json.Serialization.JsonPropertyName("branches")] + public List Branches { get; set; } + + [System.Text.Json.Serialization.JsonPropertyName("transaction")] + public TransGlobalStore Transaction { get; set; } + } + + public static BusiRequest GenBusiReq(bool outFailed, bool inFailed, int amount = 30) + { + return new BusiRequest + { + Amount = amount, + TransOutResult = outFailed ? "FAILURE" : "", + TransInResult = inFailed ? "FAILURE" : "" + }; + } + + public static ServiceProvider AddDtmHttp(int dtmTimout = 10000) + { + var services = new ServiceCollection(); + services.AddLogging(); + services.AddHttpClient(); + services.AddDtmcli(option => { option.DtmUrl = DTMHttpUrl; }); + var provider = services.BuildServiceProvider(); + return provider; + } +} \ No newline at end of file diff --git a/tests/Dtmcli.IntegrationTests/MsgHttpTest.cs b/tests/Dtmcli.IntegrationTests/MsgHttpTest.cs new file mode 100644 index 0000000..fc3e1c6 --- /dev/null +++ b/tests/Dtmcli.IntegrationTests/MsgHttpTest.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading.Tasks; +using Xunit; + +namespace Dtmcli.IntegrationTests; + +public class MsgHttpTest +{ + [Fact] + public async Task Submit_Should_Succeed() + { + var provider = ITTestHelper.AddDtmHttp(); + var transFactory = provider.GetRequiredService(); + + var gid = "msgTestGid" + Guid.NewGuid().ToString(); + var msg = transFactory.NewMsg(gid); + msg.EnableWaitResult(); + var req = ITTestHelper.GenBusiReq(false, false); + var busiUrl = ITTestHelper.BuisHttpUrl; + msg.Add(busiUrl + "/busi.Busi/TransOut", req) + .Add(busiUrl + "/busi.Busi/TransIn", req); + + await msg.Prepare(busiUrl + "/busi.Busi/QueryPrepared_404"); + await msg.Submit(); + + var status = await ITTestHelper.GetTranStatus(gid); + Assert.Equal("succeed", status); + } + + [Fact] + public async Task Submit_With_EffectTime_Should_Succeed_Later() + { + var provider = ITTestHelper.AddDtmHttp(); + var transFactory = provider.GetRequiredService(); + + var gid = "msgTestGid" + Guid.NewGuid().ToString(); + DateTime effectTime = DateTime.Now.AddSeconds(10); + var msg = transFactory.NewMsg(gid); + var req = ITTestHelper.GenBusiReq(false, false); + req.EffectTime = effectTime; + var busiUrl = ITTestHelper.BuisHttpUrl; + msg.Add(busiUrl + "/busi.Busi/TransOut", req) + .Add(busiUrl + "/busi.Busi/TransIn", req); + + await msg.Prepare(busiUrl + "/busi.Busi/QueryPrepared_404"); + await msg.Submit(); + + // Since the downstream execution is delayed by 10 seconds, it will be 'submitted' after 2 seconds and 'succeed' after 15 seconds + await Task.Delay(TimeSpan.FromSeconds(0)); + var status = await ITTestHelper.GetTranStatus(gid); + Assert.Equal("submitted", status); + + await Task.Delay(TimeSpan.FromSeconds(2)); + status = await ITTestHelper.GetTranStatus(gid); + Assert.Equal("submitted", status); + + await Task.Delay(TimeSpan.FromSeconds(13)); + status = await ITTestHelper.GetTranStatus(gid); + Assert.Equal("succeed", status); + } +} \ No newline at end of file diff --git a/tests/Dtmgrpc.IntegrationTests/MsgGrpcTest.cs b/tests/Dtmgrpc.IntegrationTests/MsgGrpcTest.cs index fed4cdb..38d0d0c 100644 --- a/tests/Dtmgrpc.IntegrationTests/MsgGrpcTest.cs +++ b/tests/Dtmgrpc.IntegrationTests/MsgGrpcTest.cs @@ -20,6 +20,7 @@ public async Task Submit_Should_Succeed() var gid = "msgTestGid" + Guid.NewGuid().ToString(); var msg = transFactory.NewMsgGrpc(gid); + msg.EnableWaitResult(); var req = ITTestHelper.GenBusiReq(false, false); var busiGrpc = ITTestHelper.BuisgRPCUrl; msg.Add(busiGrpc + "/busi.Busi/TransOut", req) @@ -27,8 +28,7 @@ public async Task Submit_Should_Succeed() await msg.Prepare(busiGrpc + "/busi.Busi/QueryPrepared"); await msg.Submit(); - - await Task.Delay(2000); + var status = await ITTestHelper.GetTranStatus(gid); Assert.Equal("succeed", status); } @@ -63,6 +63,35 @@ await branchBarrier.Call(conn, () => var status = await ITTestHelper.GetTranStatus(gid); Assert.Equal("succeed", status); } + + [Fact] + public async Task Submit_With_EffectTime_Should_Succeed_Later() + { + var provider = ITTestHelper.AddDtmGrpc(); + var transFactory = provider.GetRequiredService(); + + var gid = "msgTestGid" + Guid.NewGuid().ToString(); + DateTime effectTime = DateTime.Now.AddSeconds(10); + var msg = transFactory.NewMsgGrpc(gid); + var req = ITTestHelper.GenBusiReq(false, false); + req.EffectTime = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(effectTime.ToUniversalTime()); + var busiGrpc = ITTestHelper.BuisgRPCUrl; + msg.Add(busiGrpc + "/busi.Busi/TransOut", req) + .Add(busiGrpc + "/busi.Busi/TransIn", req); + + await msg.Prepare(busiGrpc + "/busi.Busi/QueryPrepared"); + await msg.Submit(); + + // Since the downstream execution is delayed by 10 seconds, it will be 'submitted' after 2 seconds and 'succeed' after 15 seconds + await Task.Delay(TimeSpan.FromSeconds(2)); + var status = await ITTestHelper.GetTranStatus(gid); + Assert.Equal("submitted", status); + + await Task.Delay(TimeSpan.FromSeconds(13)); + status = await ITTestHelper.GetTranStatus(gid); + Assert.Equal("succeed", status); + } + private static readonly int TransOutUID = 1; diff --git a/tests/protos/busi.proto b/tests/protos/busi.proto index 932ef1e..ee0b85a 100644 --- a/tests/protos/busi.proto +++ b/tests/protos/busi.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package busi; import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; option csharp_namespace = "busi"; option go_package = "./busi"; @@ -11,6 +12,7 @@ message BusiReq { int64 Amount = 1; string TransOutResult = 2; string TransInResult = 3; + google.protobuf.Timestamp EffectTime = 4; } message BusiReply { From c72e128957642d0ca8842e48f0bfd6142834a8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E4=BA=91=E9=87=91YunjinXu?= Date: Sun, 11 Jan 2026 21:33:02 +0800 Subject: [PATCH 2/3] test(github workflow): add integration tests for Dtmcli --- .github/workflows/build_and_it.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_it.yml b/.github/workflows/build_and_it.yml index 30895bf..149c3f7 100644 --- a/.github/workflows/build_and_it.yml +++ b/.github/workflows/build_and_it.yml @@ -58,7 +58,7 @@ jobs: run: | cd tests/BusiGrpcService 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 @@ -66,6 +66,14 @@ jobs: 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 From b8ba2d487d6543da9ea6dd7218e142f50b586f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E4=BA=91=E9=87=91YunjinXu?= Date: Sun, 11 Jan 2026 22:02:28 +0800 Subject: [PATCH 3/3] refactor(tests): rename BusiGrpcService to BusiIntegrationService --- .github/workflows/build_and_it.yml | 2 +- DtmClient.sln | 2 +- .../BusiIntegrationService.csproj} | 1 + .../Controllers/BusiApiController.cs | 4 ++-- .../Dtos/BusiRequest.cs | 2 +- tests/{BusiGrpcService => BusiIntegrationService}/Program.cs | 4 ++-- .../Properties/launchSettings.json | 4 ++-- .../Services/BusiApiService.cs | 2 +- .../appsettings.Development.json | 0 .../appsettings.json | 0 10 files changed, 11 insertions(+), 10 deletions(-) rename tests/{BusiGrpcService/BusiGrpcService.csproj => BusiIntegrationService/BusiIntegrationService.csproj} (93%) rename tests/{BusiGrpcService => BusiIntegrationService}/Controllers/BusiApiController.cs (97%) rename tests/{BusiGrpcService => BusiIntegrationService}/Dtos/BusiRequest.cs (94%) rename tests/{BusiGrpcService => BusiIntegrationService}/Program.cs (93%) rename tests/{BusiGrpcService => BusiIntegrationService}/Properties/launchSettings.json (85%) rename tests/{BusiGrpcService => BusiIntegrationService}/Services/BusiApiService.cs (99%) rename tests/{BusiGrpcService => BusiIntegrationService}/appsettings.Development.json (100%) rename tests/{BusiGrpcService => BusiIntegrationService}/appsettings.json (100%) diff --git a/.github/workflows/build_and_it.yml b/.github/workflows/build_and_it.yml index 149c3f7..e43a758 100644 --- a/.github/workflows/build_and_it.yml +++ b/.github/workflows/build_and_it.yml @@ -56,7 +56,7 @@ 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 (Dtmgrpc) env: diff --git a/DtmClient.sln b/DtmClient.sln index d9abb95..5b296e3 100644 --- a/DtmClient.sln +++ b/DtmClient.sln @@ -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 diff --git a/tests/BusiGrpcService/BusiGrpcService.csproj b/tests/BusiIntegrationService/BusiIntegrationService.csproj similarity index 93% rename from tests/BusiGrpcService/BusiGrpcService.csproj rename to tests/BusiIntegrationService/BusiIntegrationService.csproj index 2935141..61f2f91 100644 --- a/tests/BusiGrpcService/BusiGrpcService.csproj +++ b/tests/BusiIntegrationService/BusiIntegrationService.csproj @@ -4,6 +4,7 @@ net8.0 enable + BusiIntegrationService diff --git a/tests/BusiGrpcService/Controllers/BusiApiController.cs b/tests/BusiIntegrationService/Controllers/BusiApiController.cs similarity index 97% rename from tests/BusiGrpcService/Controllers/BusiApiController.cs rename to tests/BusiIntegrationService/Controllers/BusiApiController.cs index cf95b6b..94b28f1 100644 --- a/tests/BusiGrpcService/Controllers/BusiApiController.cs +++ b/tests/BusiIntegrationService/Controllers/BusiApiController.cs @@ -1,8 +1,8 @@ using System.Text.Json; -using BusiGrpcService.Dtos; +using BusiIntegrationService.Dtos; using Microsoft.AspNetCore.Mvc; -namespace BusiGrpcService.Controllers +namespace BusiIntegrationService.Controllers { [ApiController] [Route("http/busi.Busi")] diff --git a/tests/BusiGrpcService/Dtos/BusiRequest.cs b/tests/BusiIntegrationService/Dtos/BusiRequest.cs similarity index 94% rename from tests/BusiGrpcService/Dtos/BusiRequest.cs rename to tests/BusiIntegrationService/Dtos/BusiRequest.cs index f0c29ef..6ce0949 100644 --- a/tests/BusiGrpcService/Dtos/BusiRequest.cs +++ b/tests/BusiIntegrationService/Dtos/BusiRequest.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace BusiGrpcService.Dtos +namespace BusiIntegrationService.Dtos { public class BusiRequest { diff --git a/tests/BusiGrpcService/Program.cs b/tests/BusiIntegrationService/Program.cs similarity index 93% rename from tests/BusiGrpcService/Program.cs rename to tests/BusiIntegrationService/Program.cs index c7eeea2..1604a09 100644 --- a/tests/BusiGrpcService/Program.cs +++ b/tests/BusiIntegrationService/Program.cs @@ -1,5 +1,5 @@ -using BusiGrpcService; -using BusiGrpcService.Services; +using BusiIntegrationService; +using BusiIntegrationService.Services; using Dtmcli; using Dtmgrpc; using Microsoft.AspNetCore.Server.Kestrel.Core; diff --git a/tests/BusiGrpcService/Properties/launchSettings.json b/tests/BusiIntegrationService/Properties/launchSettings.json similarity index 85% rename from tests/BusiGrpcService/Properties/launchSettings.json rename to tests/BusiIntegrationService/Properties/launchSettings.json index be4c40f..0a17a79 100644 --- a/tests/BusiGrpcService/Properties/launchSettings.json +++ b/tests/BusiIntegrationService/Properties/launchSettings.json @@ -1,6 +1,6 @@ -{ +{ "profiles": { - "BusiGrpcService": { + "BusiIntegrationService": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, diff --git a/tests/BusiGrpcService/Services/BusiApiService.cs b/tests/BusiIntegrationService/Services/BusiApiService.cs similarity index 99% rename from tests/BusiGrpcService/Services/BusiApiService.cs rename to tests/BusiIntegrationService/Services/BusiApiService.cs index 0ac7068..7a56c19 100644 --- a/tests/BusiGrpcService/Services/BusiApiService.cs +++ b/tests/BusiIntegrationService/Services/BusiApiService.cs @@ -8,7 +8,7 @@ using DtmCommon; using DtmSERedisBarrier; -namespace BusiGrpcService.Services +namespace BusiIntegrationService.Services { public class BusiApiService : Busi.BusiBase { diff --git a/tests/BusiGrpcService/appsettings.Development.json b/tests/BusiIntegrationService/appsettings.Development.json similarity index 100% rename from tests/BusiGrpcService/appsettings.Development.json rename to tests/BusiIntegrationService/appsettings.Development.json diff --git a/tests/BusiGrpcService/appsettings.json b/tests/BusiIntegrationService/appsettings.json similarity index 100% rename from tests/BusiGrpcService/appsettings.json rename to tests/BusiIntegrationService/appsettings.json