Skip to content

Commit

Permalink
test(Dtmcli): improve unit test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
wooln committed Dec 16, 2024
1 parent 6ca3b79 commit 1089b34
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 19 deletions.
9 changes: 6 additions & 3 deletions src/Dtmcli/TransGlobal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class DtmTransactionForStatus
}
}

// convert from json(a prepared TCC global trans sample) to c# code
// convert from json to c# code, json sample: saga succeed http (dtm-labs/dtm/qs/main.go)
public class TransGlobal
{
[JsonPropertyName("branches")] public List<DtmBranch> Branches { get; set; }
Expand All @@ -42,9 +42,11 @@ public class DtmTransaction

[JsonPropertyName("status")] public string Status { get; set; }

[JsonPropertyName("query_prepared")] public string QueryPrepared { get; set; }
// [JsonPropertyName("query_prepared")] public string QueryPrepared { get; set; }

[JsonPropertyName("protocol")] public string Protocol { get; set; }

[JsonPropertyName("finish_time")] public DateTimeOffset FinishTime { get; set; }

[JsonPropertyName("options")] public string Options { get; set; }

Expand All @@ -53,7 +55,7 @@ public class DtmTransaction

[JsonPropertyName("next_cron_time")] public DateTimeOffset NextCronTime { get; set; }

[JsonPropertyName("wait_result")] public bool WaitResult { get; set; }
// [JsonPropertyName("wait_result")] public bool WaitResult { get; set; }

[JsonPropertyName("concurrent")] public bool Concurrent { get; set; }
}
Expand Down Expand Up @@ -82,5 +84,6 @@ public class DtmBranch
public class TransactionStep
{
[JsonPropertyName("action")] public string Action { get; set; }
[JsonPropertyName("Compensate")] public string Compensate { get; set; }
}
}
182 changes: 166 additions & 16 deletions tests/Dtmcli.Tests/DtmClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,35 +137,174 @@ public void TransBaseFromQuery_Should_Succeed()
Assert.Equal(dict["branch_id"], tb.BranchIDGen.BranchID);
}
#endif

[Fact]
public async Task Query_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
/*
{
"branches": [],
"transaction": {
"id": 7,
"gid": "mV9RGqZCV2mdn9YA6T2TPC",
"trans_type": "msg",
"status": "prepared",
"protocol": "http"
json sample: saga succeed http (dtm-labs/dtm/qs/main.go)
{
"branches": [
{
"id": 0,
"create_time": "2024-12-16T13:14:14.741109826+08:00",
"update_time": "2024-12-16T13:14:14.741109826+08:00",
"gid": "HZDVvoKbeCvABvXtVgPoyG",
"url": "http://localhost:8082/api/busi_start/TransOutCompensate",
"bin_data": "eyJhbW91bnQiOjMwfQ==",
"branch_id": "01",
"op": "compensate",
"status": "prepared"
},
{
"id": 0,
"create_time": "2024-12-16T13:14:14.741109826+08:00",
"update_time": "2024-12-16T13:14:14.746022823+08:00",
"gid": "HZDVvoKbeCvABvXtVgPoyG",
"url": "http://localhost:8082/api/busi_start/TransOut",
"bin_data": "eyJhbW91bnQiOjMwfQ==",
"branch_id": "01",
"op": "action",
"status": "succeed",
"finish_time": "2024-12-16T13:14:14.746022823+08:00"
},
{
"id": 0,
"create_time": "2024-12-16T13:14:14.741109826+08:00",
"update_time": "2024-12-16T13:14:14.741109826+08:00",
"gid": "HZDVvoKbeCvABvXtVgPoyG",
"url": "http://localhost:8082/api/busi_start/TransInCompensate",
"bin_data": "eyJhbW91bnQiOjMwfQ==",
"branch_id": "02",
"op": "compensate",
"status": "prepared"
},
{
"id": 0,
"create_time": "2024-12-16T13:14:14.741109826+08:00",
"update_time": "2024-12-16T13:14:14.748793116+08:00",
"gid": "HZDVvoKbeCvABvXtVgPoyG",
"url": "http://localhost:8082/api/busi_start/TransIn",
"bin_data": "eyJhbW91bnQiOjMwfQ==",
"branch_id": "02",
"op": "action",
"status": "succeed",
"finish_time": "2024-12-16T13:14:14.748793116+08:00"
}
}
],
"transaction": {
"id": 7,
"create_time": "2024-12-16T13:14:14.741109826+08:00",
"update_time": "2024-12-16T13:14:14.750753431+08:00",
"gid": "HZDVvoKbeCvABvXtVgPoyG",
"trans_type": "saga",
"steps": [
{
"action": "http://localhost:8082/api/busi_start/TransOut",
"compensate": "http://localhost:8082/api/busi_start/TransOutCompensate"
},
{
"action": "http://localhost:8082/api/busi_start/TransIn",
"compensate": "http://localhost:8082/api/busi_start/TransInCompensate"
}
],
"payloads": [
"{\"amount\":30}",
"{\"amount\":30}"
],
"status": "succeed",
"protocol": "http",
"finish_time": "2024-12-16T13:14:14.750753431+08:00",
"options": "{\"concurrent\":false}",
"next_cron_interval": 10,
"next_cron_time": "2024-12-16T13:14:24.741068145+08:00",
"concurrent": false
}
}
*/
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "{\n \"branches\": [],\n \"transaction\": {\n \"id\": 7,\n \"gid\": \"mV9RGqZCV2mdn9YA6T2TPC\",\n \"trans_type\": \"msg\",\n \"status\": \"prepared\",\n \"protocol\": \"http\"\n }\n} ");
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK,
"{\"branches\":[{\"id\":0,\"create_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"update_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"gid\":\"HZDVvoKbeCvABvXtVgPoyG\",\"url\":\"http://localhost:8082/api/busi_start/TransOutCompensate\",\"bin_data\":\"eyJhbW91bnQiOjMwfQ==\",\"branch_id\":\"01\",\"op\":\"compensate\",\"status\":\"prepared\"},{\"id\":0,\"create_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"update_time\":\"2024-12-16T13:14:14.746022823+08:00\",\"gid\":\"HZDVvoKbeCvABvXtVgPoyG\",\"url\":\"http://localhost:8082/api/busi_start/TransOut\",\"bin_data\":\"eyJhbW91bnQiOjMwfQ==\",\"branch_id\":\"01\",\"op\":\"action\",\"status\":\"succeed\",\"finish_time\":\"2024-12-16T13:14:14.746022823+08:00\"},{\"id\":0,\"create_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"update_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"gid\":\"HZDVvoKbeCvABvXtVgPoyG\",\"url\":\"http://localhost:8082/api/busi_start/TransInCompensate\",\"bin_data\":\"eyJhbW91bnQiOjMwfQ==\",\"branch_id\":\"02\",\"op\":\"compensate\",\"status\":\"prepared\"},{\"id\":0,\"create_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"update_time\":\"2024-12-16T13:14:14.748793116+08:00\",\"gid\":\"HZDVvoKbeCvABvXtVgPoyG\",\"url\":\"http://localhost:8082/api/busi_start/TransIn\",\"bin_data\":\"eyJhbW91bnQiOjMwfQ==\",\"branch_id\":\"02\",\"op\":\"action\",\"status\":\"succeed\",\"finish_time\":\"2024-12-16T13:14:14.748793116+08:00\"}],\"transaction\":{\"id\":7,\"create_time\":\"2024-12-16T13:14:14.741109826+08:00\",\"update_time\":\"2024-12-16T13:14:14.750753431+08:00\",\"gid\":\"HZDVvoKbeCvABvXtVgPoyG\",\"trans_type\":\"saga\",\"steps\":[{\"action\":\"http://localhost:8082/api/busi_start/TransOut\",\"compensate\":\"http://localhost:8082/api/busi_start/TransOutCompensate\"},{\"action\":\"http://localhost:8082/api/busi_start/TransIn\",\"compensate\":\"http://localhost:8082/api/busi_start/TransInCompensate\"}],\"payloads\":[\"{\\\"amount\\\":30}\",\"{\\\"amount\\\":30}\"],\"status\":\"succeed\",\"protocol\":\"http\",\"finish_time\":\"2024-12-16T13:14:14.750753431+08:00\",\"options\":\"{\\\"concurrent\\\":false}\",\"next_cron_interval\":10,\"next_cron_time\":\"2024-12-16T13:14:24.741068145+08:00\",\"concurrent\":false}}");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));
var client = new DtmClient(factory.Object, options);
var globalTrans = await client.Query(gid: "my-gid", new CancellationToken());
TransGlobal globalTrans = await client.Query(gid: "HZDVvoKbeCvABvXtVgPoyG", new CancellationToken());

// 生成globalTrans.Transaction对象的所有属性断言
Assert.Equal(7, globalTrans.Transaction.Id);
Assert.Equal("mV9RGqZCV2mdn9YA6T2TPC", globalTrans.Transaction.Gid);
Assert.Equal("msg", globalTrans.Transaction.TransType);
Assert.Equal("prepared", globalTrans.Transaction.Status);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Transaction.CreateTime);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.750753431+08:00"), globalTrans.Transaction.UpdateTime);
Assert.Equal("HZDVvoKbeCvABvXtVgPoyG", globalTrans.Transaction.Gid);
Assert.Equal("saga", globalTrans.Transaction.TransType);
Assert.Equal(2, globalTrans.Transaction.Steps.Count);
Assert.Equal("http://localhost:8082/api/busi_start/TransOut", globalTrans.Transaction.Steps[0].Action);
Assert.Equal("http://localhost:8082/api/busi_start/TransOutCompensate", globalTrans.Transaction.Steps[0].Compensate);
Assert.Equal("http://localhost:8082/api/busi_start/TransIn", globalTrans.Transaction.Steps[1].Action);
Assert.Equal("http://localhost:8082/api/busi_start/TransInCompensate", globalTrans.Transaction.Steps[1].Compensate);
Assert.Equal(2, globalTrans.Transaction.Payloads.Count);
Assert.Equal("{\"amount\":30}", globalTrans.Transaction.Payloads[0]);
Assert.Equal("{\"amount\":30}", globalTrans.Transaction.Payloads[1]);
Assert.Equal("succeed", globalTrans.Transaction.Status);
Assert.Equal("http", globalTrans.Transaction.Protocol);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.750753431+08:00"), globalTrans.Transaction.FinishTime);
Assert.Equal("{\"concurrent\":false}", globalTrans.Transaction.Options);
Assert.Equal(10, globalTrans.Transaction.NextCronInterval);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:24.741068145+08:00"), globalTrans.Transaction.NextCronTime);
Assert.False(globalTrans.Transaction.Concurrent);

Assert.Equal(4, globalTrans.Branches.Count);
// 1
Assert.Equal(0, globalTrans.Branches[0].Id);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Branches[0].CreateTime);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Branches[0].UpdateTime);
Assert.Equal("HZDVvoKbeCvABvXtVgPoyG", globalTrans.Branches[0].Gid);
Assert.Equal("http://localhost:8082/api/busi_start/TransOutCompensate", globalTrans.Branches[0].Url);
Assert.Equal("eyJhbW91bnQiOjMwfQ==", globalTrans.Branches[0].BinData);
Assert.Equal("01", globalTrans.Branches[0].BranchId);
Assert.Equal("compensate", globalTrans.Branches[0].Op);
Assert.Equal("prepared", globalTrans.Branches[0].Status);
// 2
Assert.Equal(0, globalTrans.Branches[0].Id);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Branches[1].CreateTime);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.746022823+08:00"), globalTrans.Branches[1].UpdateTime);
Assert.Equal("HZDVvoKbeCvABvXtVgPoyG", globalTrans.Branches[1].Gid);
Assert.Equal("http://localhost:8082/api/busi_start/TransOut", globalTrans.Branches[1].Url);
Assert.Equal("eyJhbW91bnQiOjMwfQ==", globalTrans.Branches[1].BinData);
Assert.Equal("01", globalTrans.Branches[1].BranchId);
Assert.Equal("action", globalTrans.Branches[1].Op);
Assert.Equal("succeed", globalTrans.Branches[1].Status);
// 3
Assert.Equal(0, globalTrans.Branches[2].Id);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Branches[2].CreateTime);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Branches[2].UpdateTime);
Assert.Equal("HZDVvoKbeCvABvXtVgPoyG", globalTrans.Branches[2].Gid);
Assert.Equal("http://localhost:8082/api/busi_start/TransInCompensate", globalTrans.Branches[2].Url);
Assert.Equal("eyJhbW91bnQiOjMwfQ==", globalTrans.Branches[2].BinData);
Assert.Equal("02", globalTrans.Branches[2].BranchId);
Assert.Equal("compensate", globalTrans.Branches[2].Op);
Assert.Equal("prepared", globalTrans.Branches[2].Status);
// 4
Assert.Equal(0, globalTrans.Branches[3].Id);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.741109826+08:00"), globalTrans.Branches[3].CreateTime);
Assert.Equal(DateTimeOffset.Parse("2024-12-16T13:14:14.748793116+08:00"), globalTrans.Branches[3].UpdateTime);
Assert.Equal("HZDVvoKbeCvABvXtVgPoyG", globalTrans.Branches[3].Gid);
Assert.Equal("http://localhost:8082/api/busi_start/TransIn", globalTrans.Branches[3].Url);
Assert.Equal("eyJhbW91bnQiOjMwfQ==", globalTrans.Branches[3].BinData);
Assert.Equal("02", globalTrans.Branches[3].BranchId);
Assert.Equal("action", globalTrans.Branches[3].Op);
Assert.Equal("succeed", globalTrans.Branches[3].Status);
}

[Fact]
public async Task Query_Gid_NullOrEmpty()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient());
var client = new DtmClient(factory.Object, options);
await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.Query(gid: null, new CancellationToken()));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.Query(gid: string.Empty, new CancellationToken()));
}
[Fact]
public async Task Query_Not_Exist_Gid()
{
Expand All @@ -180,7 +319,7 @@ public async Task Query_Not_Exist_Gid()
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "{\n \"branches\": [],\n \"transaction\": null\n}\n");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));
var client = new DtmClient(factory.Object, options);
var globalTrans = await client.Query(gid: "my-gid", new CancellationToken());
TransGlobal globalTrans = await client.Query(gid: "my-gid", new CancellationToken());
Assert.NotNull(globalTrans);
Assert.Null(globalTrans.Transaction);
}
Expand Down Expand Up @@ -224,6 +363,17 @@ public async Task QueryStatus_Should_Succeed()
string status = await client.QueryStatus(gid: "my-gid", new CancellationToken());
Assert.Equal("prepared", status);
}

[Fact]
public async Task QueryStatus_Gid_NullOrEmpty()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient());
var client = new DtmClient(factory.Object, options);
await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.QueryStatus(gid: null, new CancellationToken()));
await Assert.ThrowsAsync<ArgumentNullException>(async () => await client.QueryStatus(gid: string.Empty, new CancellationToken()));
}

[Fact]
public async Task QueryStatus_Not_Exist_Gid()
Expand Down

0 comments on commit 1089b34

Please sign in to comment.