Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c6f4448
commit 6e210ed
Showing
7 changed files
with
182 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Collections.Concurrent; | ||
using MyDriver; | ||
using System.Threading; | ||
using log4net; | ||
|
||
namespace MyClient | ||
{ | ||
internal interface IMyReceiver | ||
{ | ||
void Process(); | ||
|
||
BlockingCollection<MyData> DataProduced { get; } | ||
|
||
CancellationToken CancellationToken { get; } | ||
} | ||
|
||
internal class MyReceiver : IMyReceiver | ||
{ | ||
private static ILog Logger = LogManager.GetLogger(typeof(MyReceiver)); | ||
|
||
private IMyConnector _connector; | ||
private CancellationTokenSource _cts; | ||
|
||
public MyReceiver(IMyConnector connector) | ||
{ | ||
this._connector = connector; | ||
this._cts = new CancellationTokenSource(); | ||
this.DataProduced = new BlockingCollection<MyData>(); | ||
} | ||
|
||
public void Process() | ||
{ | ||
var client = this._connector.Client; | ||
if (client == null) | ||
{ | ||
Logger.Info("Connector isn't prepared, stop processing."); | ||
return; | ||
} | ||
|
||
while (true) | ||
{ | ||
MyData data; | ||
|
||
try | ||
{ | ||
data = client.Receive(); | ||
} | ||
catch (MyDriverException ex) | ||
{ | ||
Logger.Error("Exception occurred when receiving, close the client and stop processing.", ex); | ||
|
||
this._connector.CloseClient(); | ||
this._cts.Cancel(); | ||
return; | ||
} | ||
|
||
if (data == null) | ||
{ | ||
Logger.Info("The client is closed by others, stop processing."); | ||
this._cts.Cancel(); | ||
return; | ||
} | ||
|
||
this.DataProduced.Add(data); | ||
} | ||
} | ||
|
||
public BlockingCollection<MyData> DataProduced { get; private set; } | ||
|
||
public CancellationToken CancellationToken { get { return this._cts.Token; } } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace MyClient.Tests | ||
{ | ||
public class DummyException : Exception { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
csharp/Practice01-End/tests/MyClient.Tests/MyReceiverTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using MyClient.Driver; | ||
using Moq; | ||
using Xunit; | ||
using MyDriver; | ||
|
||
namespace MyClient.Tests | ||
{ | ||
public class MyReceiverTest | ||
{ | ||
internal Mock<IMyDriverClient> _clientMock; | ||
internal Mock<IMyConnector> _connectorMock; | ||
internal MyReceiver _receiver; | ||
|
||
public MyReceiverTest() | ||
{ | ||
this._clientMock = new Mock<IMyDriverClient>(MockBehavior.Strict); | ||
|
||
this._connectorMock = new Mock<IMyConnector>(MockBehavior.Strict); | ||
this._connectorMock.Setup(c => c.Client).Returns(this._clientMock.Object); | ||
|
||
this._receiver = new MyReceiver(this._connectorMock.Object); | ||
} | ||
|
||
public class Process : MyReceiverTest | ||
{ | ||
[Fact] | ||
public void DataReceived_PutIntoCollection() | ||
{ | ||
var dataList = Enumerable.Range(0, 10).Select(i => new MyData(0, i.ToString())).ToList(); | ||
|
||
var setup = this._clientMock.SetupSequence(c => c.Receive()); | ||
foreach (var data in dataList) | ||
{ | ||
setup = setup.Returns(data); | ||
} | ||
|
||
setup.Throws(new DummyException()); | ||
|
||
Assert.Throws(typeof(DummyException), () => this._receiver.Process()); | ||
|
||
Assert.False(this._receiver.CancellationToken.IsCancellationRequested); | ||
|
||
var producedList = this._receiver.DataProduced.ToList(); | ||
Assert.Equal(dataList.Count, producedList.Count); | ||
for (var i = 0; i < dataList.Count; i++) | ||
{ | ||
Assert.Same(dataList[i], producedList[i]); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void ErrorOccurred_TokenCanceled_CloseClient() | ||
{ | ||
this._connectorMock.Setup(c => c.CloseClient()); | ||
|
||
this._clientMock.SetupSequence(c => c.Receive()).Returns(new MyData(0, "")).Throws(new MyDriverException("Test")); | ||
|
||
this._receiver.Process(); | ||
|
||
Assert.True(this._receiver.CancellationToken.IsCancellationRequested); | ||
|
||
Assert.Equal(1, this._receiver.DataProduced.Count); | ||
Assert.False(this._receiver.DataProduced.IsAddingCompleted); | ||
|
||
this._connectorMock.Verify(c => c.CloseClient(), Times.Once()); | ||
} | ||
|
||
[Fact] | ||
public void NullReceived_TokenCanceled() | ||
{ | ||
this._clientMock.SetupSequence(c => c.Receive()).Returns(new MyData(0, "")).Returns(null); | ||
|
||
this._receiver.Process(); | ||
|
||
Assert.True(this._receiver.CancellationToken.IsCancellationRequested); | ||
|
||
Assert.Equal(1, this._receiver.DataProduced.Count); | ||
Assert.False(this._receiver.DataProduced.IsAddingCompleted); | ||
} | ||
} | ||
} | ||
} |