Skip to content

Commit

Permalink
Merge pull request #41 from catcherwong/feat/moretest
Browse files Browse the repository at this point in the history
test: add more tests and add Codecov
  • Loading branch information
catcherwong authored May 19, 2022
2 parents 0529c92 + 60f8680 commit 63e08d5
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 8 deletions.
20 changes: 19 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,22 @@ jobs:
- name: Run tests on net6.0
run: |
dotnet test --framework=net6.0 src/Dtmcli.Tests/Dtmcli.Tests.csproj
dotnet test --framework=net6.0 src/Dtmcli.Tests/Dtmcli.Tests.csproj --collect:"XPlat Code Coverage"
- name: Prepare Codecov
run: |
mkdir ${{ github.workspace }}/coverage/
cp ${{ github.workspace }}/src/Dtmcli.Tests/TestResults/*/coverage.cobertura.xml ${{ github.workspace }}/coverage/
ls ${{ github.workspace }}/coverage/
- name: Upload coverage to Codecov
if: ${{ matrix.os == 'ubuntu-latest' }}
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
files: ${{ github.workspace }}/coverage/coverage.cobertura.xml
name: codecov-umbrella
verbose: true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.xap
*.user
/TestResults
TestResults/
*.suo
*.cache
*.docstates
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ English | [简体中文](./README-cn.md)

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

![Build_And_Test](https://github.com/dtm-labs/dtmcli-csharp/actions/workflows/build.yml/badge.svg)
![Build_And_Test](https://github.com/dtm-labs/dtmcli-csharp/actions/workflows/build.yml/badge.svg) [![codecov](https://codecov.io/gh/dtm-labs/dtmcli-csharp/branch/main/graph/badge.svg?token=Y2BOSQ5QKO)](https://codecov.io/gh/dtm-labs/dtmcli-csharp)

![](https://img.shields.io/nuget/v/Dtmcli.svg) ![](https://img.shields.io/nuget/vpre/Dtmcli.svg) ![](https://img.shields.io/nuget/dt/Dtmcli) ![](https://img.shields.io/github/license/dtm-labs/dtmcli-csharp)

Expand Down
160 changes: 160 additions & 0 deletions src/Dtmcli.Tests/DtmClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using Xunit;
using System.Net;
using Moq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;

namespace Dtmcli.Tests
{
public class DtmClientTests
{
[Fact]
public async void GenGid_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "{\"dtm_result\":\"SUCCESS\",\"gid\":\"123\"}");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

var res = await client.GenGid(new CancellationToken());

Assert.Equal("123", res);
}

[Fact]
public async void GenGid_Should_Throw_Failure_Exception()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.BadGateway, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

await Assert.ThrowsAsync<DtmCommon.DtmException>( async()=> await client.GenGid(new CancellationToken()));
}

[Fact]
public async void TransRegisterBranch_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

var tb = new DtmCommon.TransBase() { Gid = "123", TransType = "tcc" };

await client.TransRegisterBranch(tb, null, "OP", new CancellationToken());
}

[Fact]
public async void TransRegisterBranch_With_Added_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

var tb = new DtmCommon.TransBase() { Gid = "123", TransType = "tcc" };
var added = new System.Collections.Generic.Dictionary<string, string>() { { "a", "b" } };

await client.TransRegisterBranch(tb, added, "OP", new CancellationToken());
}

[Fact]
public async void TransRequestBranch_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

var tb = new DtmCommon.TransBase()
{
Gid = "123",
TransType = "tcc",
};

await client.TransRequestBranch(tb, HttpMethod.Post, new { }, "00", "try", "http://www.baidu.com?a=1", new CancellationToken());
}

[Fact]
public async void TransRequestBranch_With_BranchHeaders_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

var tb = new DtmCommon.TransBase()
{
Gid = "123",
TransType = "tcc",
BranchHeaders = new System.Collections.Generic.Dictionary<string, string> { { "a", "b" } }
};

await client.TransRequestBranch(tb, HttpMethod.Post, new { }, "00", "try", "http://www.baidu.com", new CancellationToken());
}

#if NET5_0_OR_GREATER
[Fact]
public void TransBaseFromQuery_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));

var client = new DtmClient(factory.Object, options);

var dict = new System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>()
{
{ "branch_id","11" },
{ "gid","1111" },
{ "op","try" },
{ "trans_type","tcc" },
};

var qs = new Microsoft.AspNetCore.Http.QueryCollection(dict);

var tb = client.TransBaseFromQuery(qs);

Assert.Equal(dict["op"], tb.Op);
Assert.Equal(dict["gid"], tb.Gid);
Assert.Equal(dict["trans_type"], tb.TransType);
Assert.Equal(dict["branch_id"], tb.BranchIDGen.BranchID);
}
#endif
}

internal class ClientMockHttpMessageHandler : DelegatingHandler
{
private readonly HttpStatusCode _code;
private readonly string _msg;
public ClientMockHttpMessageHandler(HttpStatusCode code, string msg)
{
this._code = code;
this._msg = msg;
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var content = new StringContent(_msg);
var resp = new HttpResponseMessage(_code);
resp.Content = content;

return Task.FromResult(resp);
}
}
}
38 changes: 38 additions & 0 deletions src/Dtmcli.Tests/DtmTransFactoryTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Moq;
using Xunit;

namespace Dtmcli.Tests
{
public class DtmTransFactoryTest
{
[Fact]
public void NewMsg_Should_Succeed()
{
var dtmClient = new Mock<IDtmClient>();
var bbFactory = new Mock<IBranchBarrierFactory>();

var tFactory = new DtmTransFactory(dtmClient.Object, bbFactory.Object);

var gid = "TestMsgNormal";

var msg = tFactory.NewMsg(gid);

Assert.NotNull(msg);
}

[Fact]
public void NewSaga_Should_Succeed()
{
var dtmClient = new Mock<IDtmClient>();
var bbFactory = new Mock<IBranchBarrierFactory>();

var tFactory = new DtmTransFactory(dtmClient.Object, bbFactory.Object);

var gid = "TestSagaNormal";

var saga = tFactory.NewSaga(gid);

Assert.NotNull(saga);
}
}
}
17 changes: 16 additions & 1 deletion src/Dtmcli.Tests/MsgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,28 @@ public async void Submit_Should_Succeed()
{
{ "bh1", "123" },
{ "bh2", "456" },
});
})
.SetPassthroughHeaders(new List<string> { "bh1" });

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

Assert.True(true);
}

[Fact]
public async void DoAndSubmit_Should_Throw_Exception_When_BB_InValid()
{
var dtmClient = new Mock<IDtmClient>();
var bbFactory = new Mock<IBranchBarrierFactory>();

bbFactory.Setup(x => x.CreateBranchBarrier(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), null))
.Returns(new BranchBarrier("", "", "", "", null, null));

var msg = new Msg(dtmClient.Object, bbFactory.Object, "123");
await Assert.ThrowsAnyAsync<DtmException>(async () => await msg.DoAndSubmit("", x => Task.CompletedTask));
}

[Fact]
public async void DoAndSubmitDB_Should_Throw_Exception_When_Transbase_InValid()
{
Expand Down Expand Up @@ -197,6 +211,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
Assert.Contains("bh2", transBase.BranchHeaders.Keys);
Assert.Equal(2, transBase.Payloads.Count);
Assert.Equal(2, transBase.Steps.Count);
Assert.Contains("bh1", transBase.PassthroughHeaders);

var content = new StringContent("{\"dtm_result\":\"SUCCESS\"}");

Expand Down
6 changes: 5 additions & 1 deletion src/Dtmcli.Tests/SagaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ public async void Submit_Should_Succeed()
{
{ "bh1", "123" },
{ "bh2", "456" },
});
})
.SetPassthroughHeaders(new List<string> { "bh1" });

await sage.Submit();

Assert.NotNull(sage.GetTransBase());
}

[Fact]
Expand Down Expand Up @@ -121,6 +124,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
Assert.Contains("bh2", transBase.BranchHeaders.Keys);
Assert.Equal(4, transBase.Payloads.Count);
Assert.Equal(4, transBase.Steps.Count);
Assert.Contains("bh1", transBase.PassthroughHeaders);

var content = new StringContent("{\"dtm_result\":\"SUCCESS\"}");

Expand Down
32 changes: 31 additions & 1 deletion src/Dtmcli.Tests/ServiceCollectionExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public void AddDtmcli_With_Action_Should_Succeed()
services.AddDtmcli(x =>
{
x.DtmUrl = dtmUrl;
x.DtmTimeout = 8000;
x.BranchTimeout = 8000;
});

var provider = services.BuildServiceProvider();
Expand All @@ -39,13 +41,15 @@ public void AddDtmcli_Without_Action_Should_Throw_Exception()
}

[Fact]
public void AddDtmcli_With_IConfiguration_Should_Succeed()
public async void AddDtmcli_With_IConfiguration_Should_Succeed()
{
var dtmUrl = "http://localhost:36789";

var dict = new Dictionary<string, string>
{
{ "dtm:DtmUrl", dtmUrl },
{ "dtm:DtmTimeout", "1000" },
{ "dtm:BranchTimeout", "8000" },
};

var config = new ConfigurationBuilder().AddInMemoryCollection(dict).Build();
Expand All @@ -61,6 +65,32 @@ public void AddDtmcli_With_IConfiguration_Should_Succeed()

var dtmClient = provider.GetRequiredService<IDtmClient>();
Assert.NotNull(dtmClient);

// for real test
await Assert.ThrowsAnyAsync<System.Exception>(async () => await dtmClient.GenGid(default));
await dtmClient.TransRequestBranch(new TransBase(), System.Net.Http.HttpMethod.Get, null, "", "", "https://www.baidu.com", default);
}

[Fact]
public void AddDtmcli_With_IConfiguration_And_Empty_Option_Should_Succeed()
{
var dtmUrl = "http://localhost:36789";

var dict = new Dictionary<string, string>
{
{ "dtmx:DtmUrl", dtmUrl },
};

var config = new ConfigurationBuilder().AddInMemoryCollection(dict).Build();

var services = new ServiceCollection();
services.AddDtmcli(config, "dtm");

var provider = services.BuildServiceProvider();

var dtmOptionsAccs = provider.GetService<IOptions<DtmOptions>>();
var dtmOptions = dtmOptionsAccs.Value;
Assert.NotEqual(dtmUrl, dtmOptions.DtmUrl);
}
}
}
Loading

0 comments on commit 63e08d5

Please sign in to comment.