Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aeec2f8

Browse files
Merge pull request #7 from dtm-labs/feat/addmoretests
test: add more tests
2 parents c4fab59 + 71bf9d9 commit aeec2f8

File tree

10 files changed

+280
-43
lines changed

10 files changed

+280
-43
lines changed

‎.github/workflows/build_and_ut.yml‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,25 @@ jobs:
5151
5252
- name: Run tests on net6.0
5353
run: |
54-
dotnet test --framework=net6.0 tests/Dtmgrpc.Tests/Dtmgrpc.Tests.csproj
54+
dotnet test --framework=net6.0 tests/Dtmgrpc.Tests/Dtmgrpc.Tests.csproj --collect:"XPlat Code Coverage"
55+
56+
- name: Prepare Codecov
57+
if: ${{ matrix.os == 'ubuntu-latest' }}
58+
run: |
59+
dotnet tool install -g dotnet-reportgenerator-globaltool
60+
61+
reportgenerator -reports:"${{ github.workspace }}/tests/Dtmgrpc.Tests/TestResults/**/coverage.cobertura.xml" \
62+
-targetdir:"${{ github.workspace }}/coverage" \
63+
-classfilters:-*dtmgpb.* \
64+
-reporttypes:Cobertura
65+
66+
ls ${{ github.workspace }}/coverage/
67+
- name: Upload coverage to Codecov
68+
if: ${{ matrix.os == 'ubuntu-latest' }}
69+
uses: codecov/codecov-action@v2
70+
with:
71+
token: ${{ secrets.CODECOV_TOKEN }}
72+
fail_ci_if_error: true
73+
files: ${{ github.workspace }}/coverage/Cobertura.xml
74+
name: codecov-umbrella
75+
verbose: true

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ English | [简体中文](./README-cn.md)
77

88
It has supported distributed transaction patterns of Saga pattern, TCC pattern and 2-phase message pattern.
99

10-
![Build_And_UnitTest](https://github.com/catcherwong/dtmgrpc-csharp/actions/workflows/build_and_ut.yml/badge.svg) ![Build_And_IntegrationTests](https://github.com/catcherwong/dtmgrpc-csharp/actions/workflows/build_and_it.yml/badge.svg)
10+
![Build_And_UnitTest](https://github.com/catcherwong/dtmgrpc-csharp/actions/workflows/build_and_ut.yml/badge.svg) ![Build_And_IntegrationTests](https://github.com/catcherwong/dtmgrpc-csharp/actions/workflows/build_and_it.yml/badge.svg)[![codecov](https://codecov.io/gh/dtm-labs/dtmgrpc-csharp/branch/main/graph/badge.svg?token=BMVU39PSH4)](https://codecov.io/gh/dtm-labs/dtmgrpc-csharp)
1111

1212
![](https://img.shields.io/nuget/v/Dtmgrpc.svg) ![](https://img.shields.io/nuget/vpre/Dtmgrpc.svg) ![](https://img.shields.io/nuget/dt/Dtmgrpc) ![](https://img.shields.io/github/license/catcherwong/dtmgrpc-csharp)
1313

‎tests/Dtmgrpc.Tests/BranchBarrierTests.cs‎

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -195,44 +195,5 @@ public void CreateBranchBarrier_FromContext_Should_ThrowException()
195195

196196
Assert.Throws<DtmException>(() => _factory.CreateBranchBarrier(context));
197197
}
198-
199-
private class CusServerCallContext : Grpc.Core.ServerCallContext
200-
{
201-
private Grpc.Core.Metadata _reqMetadata;
202-
203-
public CusServerCallContext(Grpc.Core.Metadata reqMetadata)
204-
{
205-
this._reqMetadata = reqMetadata;
206-
}
207-
208-
protected override string MethodCore => throw new NotImplementedException();
209-
210-
protected override string HostCore => throw new NotImplementedException();
211-
212-
protected override string PeerCore => throw new NotImplementedException();
213-
214-
protected override DateTime DeadlineCore => throw new NotImplementedException();
215-
216-
protected override Grpc.Core.Metadata RequestHeadersCore => _reqMetadata;
217-
218-
protected override CancellationToken CancellationTokenCore => throw new NotImplementedException();
219-
220-
protected override Grpc.Core.Metadata ResponseTrailersCore => throw new NotImplementedException();
221-
222-
protected override Grpc.Core.Status StatusCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
223-
protected override Grpc.Core.WriteOptions WriteOptionsCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
224-
225-
protected override Grpc.Core.AuthContext AuthContextCore => throw new NotImplementedException();
226-
227-
protected override Grpc.Core.ContextPropagationToken CreatePropagationTokenCore(Grpc.Core.ContextPropagationOptions options)
228-
{
229-
throw new NotImplementedException();
230-
}
231-
232-
protected override Task WriteResponseHeadersAsyncCore(Grpc.Core.Metadata responseHeaders)
233-
{
234-
return Task.CompletedTask;
235-
}
236-
}
237198
}
238199
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace Dtmgrpc.Tests
6+
{
7+
internal class CusServerCallContext : Grpc.Core.ServerCallContext
8+
{
9+
private Grpc.Core.Metadata _reqMetadata;
10+
11+
public CusServerCallContext(Grpc.Core.Metadata reqMetadata)
12+
{
13+
this._reqMetadata = reqMetadata;
14+
}
15+
16+
protected override string MethodCore => throw new NotImplementedException();
17+
18+
protected override string HostCore => throw new NotImplementedException();
19+
20+
protected override string PeerCore => throw new NotImplementedException();
21+
22+
protected override DateTime DeadlineCore => throw new NotImplementedException();
23+
24+
protected override Grpc.Core.Metadata RequestHeadersCore => _reqMetadata;
25+
26+
protected override CancellationToken CancellationTokenCore => throw new NotImplementedException();
27+
28+
protected override Grpc.Core.Metadata ResponseTrailersCore => throw new NotImplementedException();
29+
30+
protected override Grpc.Core.Status StatusCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
31+
protected override Grpc.Core.WriteOptions WriteOptionsCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
32+
33+
protected override Grpc.Core.AuthContext AuthContextCore => throw new NotImplementedException();
34+
35+
protected override Grpc.Core.ContextPropagationToken CreatePropagationTokenCore(Grpc.Core.ContextPropagationOptions options)
36+
{
37+
throw new NotImplementedException();
38+
}
39+
40+
protected override Task WriteResponseHeadersAsyncCore(Grpc.Core.Metadata responseHeaders)
41+
{
42+
return Task.CompletedTask;
43+
}
44+
}
45+
}

‎tests/Dtmgrpc.Tests/DbSpecialTests.cs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ public void Test_PgSQL_DbSpecial()
4646

4747
Assert.IsType<PostgresDBSpecial>(special);
4848
Assert.Equal("begin", special.GetXaSQL("start", "xa1"));
49+
Assert.Equal(string.Empty, special.GetXaSQL("aa", "bb"));
4950
Assert.Equal("insert into a(f) values(@f) on conflict ON CONSTRAINT c do nothing", special.GetInsertIgnoreTemplate("a(f) values(@f)", "c"));
51+
Assert.Equal("insert into a(f) values(@f)", special.GetPlaceHoldSQL("insert into a(f) values(@f)"));
5052
}
5153

5254
[Fact]
@@ -68,6 +70,7 @@ public void Test_MsSQL_DbSpecial()
6870

6971
Assert.IsType<SqlServerDBSpecial>(special);
7072
Assert.Equal("insert into a(f) values(@f)", special.GetInsertIgnoreTemplate("a(f) values(@f)", "c"));
73+
Assert.Equal("insert into a(f) values(@f)", special.GetPlaceHoldSQL("insert into a(f) values(@f)"));
7174
Assert.Throws<DtmException>(() => special.GetXaSQL("", ""));
7275
}
7376

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using Moq;
2+
using Xunit;
3+
4+
namespace Dtmgrpc.Tests
5+
{
6+
public class DtmTransFactoryTests
7+
{
8+
[Fact]
9+
public void NewMsg_Should_Succeed()
10+
{
11+
var tFactory = BuildFactory();
12+
13+
var gid = "TestMsgNormal";
14+
15+
var msg = tFactory.NewMsgGrpc(gid);
16+
17+
Assert.NotNull(msg);
18+
}
19+
20+
[Fact]
21+
public void NewSaga_Should_Succeed()
22+
{
23+
var tFactory = BuildFactory();
24+
25+
var gid = "TestSagaNormal";
26+
27+
var saga = tFactory.NewSagaGrpc(gid);
28+
29+
Assert.NotNull(saga);
30+
}
31+
32+
[Fact]
33+
public void NewTcc_Should_Succeed()
34+
{
35+
var tFactory = BuildFactory();
36+
37+
var gid = "TestTccNormal";
38+
39+
var saga = tFactory.NewTccGrpc(gid);
40+
41+
Assert.NotNull(saga);
42+
}
43+
44+
private DtmTransFactory BuildFactory()
45+
{
46+
var dtmClient = new Mock<IDtmgRPCClient>();
47+
var bbFactory = new Mock<IBranchBarrierFactory>();
48+
var option = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { });
49+
50+
return new DtmTransFactory(option, dtmClient.Object, bbFactory.Object);
51+
52+
}
53+
}
54+
}

‎tests/Dtmgrpc.Tests/MsgTests.cs‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,32 @@ public async void Submit_Should_Succeed()
5555
{
5656
{ "bh1", "123" },
5757
{ "bh2", "456" },
58-
});
58+
})
59+
.SetPassthroughHeaders(new List<string> { "bh1" });
5960

6061
await msg.Prepare(busi + "/query");
6162
await msg.Submit();
6263

6364
Assert.True(true);
6465
}
6566

67+
[Fact]
68+
public async void DoAndSubmit_Should_Throw_Exception_When_Transbase_InValid()
69+
{
70+
var dtmClient = new Mock<IDtmgRPCClient>();
71+
var bbFactory = new Mock<IBranchBarrierFactory>();
72+
73+
bbFactory.Setup(x => x.CreateBranchBarrier(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), null))
74+
.Returns(new BranchBarrier("", "", "", "", null, null));
75+
76+
var gid = string.Empty;
77+
var msg = new MsgGrpc(dtmClient.Object, bbFactory.Object, "", gid);
78+
79+
var req = new Empty();
80+
msg.Add(busi + "/TransOut", req);
81+
await Assert.ThrowsAsync<DtmException>(async () => await msg.DoAndSubmit(busi + "/query", x => Task.CompletedTask));
82+
}
83+
6684
[Fact]
6785
public async void DoAndSubmitDB_Should_Throw_Exception_When_Transbase_InValid()
6886
{

‎tests/Dtmgrpc.Tests/SagaTests.cs‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,25 @@ public async void Submit_Should_Succeed()
2626
.Add(string.Concat(busi, "/TransOut"), string.Concat(busi, "/TransOutRevert"), req)
2727
.Add(string.Concat(busi, "/TransIn"), string.Concat(busi, "/TransInRevert"), req)
2828
.Add(string.Concat(busi, "/TransIn"), string.Concat(busi, "/TransInRevert"), req)
29+
.AddBranchOrder(3, new List<int> { 1, 2 })
2930
.EnableWaitResult()
31+
.EnableConcurrent()
3032
.SetRetryInterval(10)
3133
.SetTimeoutToFail(100)
3234
.SetBranchHeaders(new Dictionary<string, string>
3335
{
3436
{ "bh1", "123" },
3537
{ "bh2", "456" },
36-
});
38+
})
39+
.SetPassthroughHeaders(new List<string> { "bh1" });
3740

3841
await saga.Submit();
3942

43+
var tb = saga.GetTransBase();
44+
Assert.NotNull(tb.CustomData);
45+
Assert.Equal(10, tb.RetryInterval);
46+
Assert.Equal(100, tb.TimeoutToFail);
47+
4048
Assert.True(true);
4149
}
4250

‎tests/Dtmgrpc.Tests/TccTests.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public async void Set_TransOptions_Should_Succeed()
8181
{ "bh1", "123" },
8282
{ "bh2", "456" },
8383
});
84+
tcc.SetPassthroughHeaders(new List<string> { "bh1" });
8485
}, async (tcc) =>
8586
{
8687
await tcc.CallBranch<Empty, Empty>(new Empty(), "localhost:9999/svc/TransOutTry", "localhost:9999/svc/TransOutConfirm", "localhost:9999/svc/TransOutCancel");

‎tests/Dtmgrpc.Tests/UtilsTests.cs‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
using DtmCommon;
2+
using Grpc.Core;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Xunit;
6+
7+
namespace Dtmgrpc.Tests
8+
{
9+
public class UtilsTests
10+
{
11+
private static DtmFailureException DtmFailure = new DtmFailureException();
12+
private static DtmOngingException DtmOnging = new DtmOngingException();
13+
14+
[Fact]
15+
public void DtmError2GrpcError_Should_Throw_Aborted_RpcException()
16+
{
17+
var ex = Assert.Throws<RpcException>(()=> DtmGImp.Utils.DtmError2GrpcError(DtmFailure));
18+
Assert.Equal(StatusCode.Aborted, ex.StatusCode);
19+
}
20+
21+
[Fact]
22+
public void DtmError2GrpcError_Should_Throw_FailedPrecondition_RpcException()
23+
{
24+
var ex = Assert.Throws<RpcException>(() => DtmGImp.Utils.DtmError2GrpcError(DtmOnging));
25+
Assert.Equal(StatusCode.FailedPrecondition, ex.StatusCode);
26+
}
27+
28+
[Fact]
29+
public void DtmError2GrpcError_Should_Throw_Unknown_RpcException()
30+
{
31+
var ex = Assert.Throws<RpcException>(() => DtmGImp.Utils.DtmError2GrpcError(new System.ArgumentNullException()));
32+
Assert.Equal(StatusCode.Unknown, ex.StatusCode);
33+
}
34+
35+
[Theory]
36+
[InlineData(StatusCode.Aborted, "ONGOING")]
37+
[InlineData(StatusCode.FailedPrecondition, "other")]
38+
public void GrpcError2DtmError_Should_Be_DtmOngingException(StatusCode code, string msg)
39+
{
40+
var rpcEx = new RpcException(new Status(code, msg), msg);
41+
var ex = DtmGImp.Utils.GrpcError2DtmError(rpcEx);
42+
Assert.IsType<DtmOngingException>(ex);
43+
}
44+
45+
[Fact]
46+
public void GrpcError2DtmError_Should_Be_DtmFailureException()
47+
{
48+
var rpcEx = new RpcException(new Status(StatusCode.Aborted, "Other"));
49+
var ex = DtmGImp.Utils.GrpcError2DtmError(rpcEx);
50+
Assert.IsType<DtmFailureException>(ex);
51+
}
52+
53+
[Fact]
54+
public void GrpcError2DtmError_Should_Be_RawException()
55+
{
56+
var rpcEx = new System.ArgumentNullException();
57+
var ex = DtmGImp.Utils.GrpcError2DtmError(rpcEx);
58+
Assert.IsType<System.ArgumentNullException>(ex);
59+
}
60+
61+
[Fact]
62+
public void String2DtmError_Should_Succeed()
63+
{
64+
var fEx = DtmGImp.Utils.String2DtmError(Constant.ResultFailure);
65+
Assert.IsType<DtmFailureException>(fEx);
66+
67+
var oEx = DtmGImp.Utils.String2DtmError(Constant.ResultOngoing);
68+
Assert.IsType<DtmOngingException>(oEx);
69+
70+
var nullEx = DtmGImp.Utils.String2DtmError(Constant.ResultSuccess);
71+
Assert.Null(nullEx);
72+
73+
nullEx = DtmGImp.Utils.String2DtmError(string.Empty);
74+
Assert.Null(nullEx);
75+
76+
nullEx = DtmGImp.Utils.String2DtmError("other");
77+
Assert.Null(nullEx);
78+
}
79+
80+
[Theory]
81+
[InlineData(null, "")]
82+
[InlineData("http://a.b.com/", "a.b.com")]
83+
[InlineData("https://a.b.com", "a.b.com")]
84+
public void GetWithoutPrefixgRPCUrl_Should_Succeed(string url, string exp)
85+
{
86+
var res = DtmGImp.Utils.GetWithoutPrefixgRPCUrl(url);
87+
Assert.Equal(exp, res);
88+
}
89+
90+
[Fact]
91+
public void TransInfo2Metadata_Should_Succeed()
92+
{
93+
var meta = DtmGImp.Utils.TransInfo2Metadata("1", "2", "3", "4", "5");
94+
95+
Assert.Equal("1", meta.Get(Constant.Md.Gid).Value);
96+
Assert.Equal("2", meta.Get(Constant.Md.TransType).Value);
97+
Assert.Equal("3", meta.Get(Constant.Md.BranchId).Value);
98+
Assert.Equal("4", meta.Get(Constant.Md.Op).Value);
99+
Assert.Equal("5", meta.Get(Constant.Md.Dtm).Value);
100+
}
101+
102+
[Fact]
103+
public void DtmGet_Should_Succeed()
104+
{
105+
var meta = new Metadata();
106+
meta.Add("a", "b");
107+
meta.Add("c", "d");
108+
var context = new CusServerCallContext(meta);
109+
110+
var str1 = DtmGImp.Utils.DtmGet(context, "a");
111+
Assert.Equal("b", str1);
112+
113+
var str2 = DtmGImp.Utils.DtmGet(context, "d");
114+
Assert.Null(str2);
115+
}
116+
117+
[Fact]
118+
public void DtmGet_When_Header_IsNull_Should_Succeed()
119+
{
120+
var context = new CusServerCallContext(null);
121+
122+
var str = DtmGImp.Utils.DtmGet(context, "a");
123+
Assert.Null(str);
124+
}
125+
}
126+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /