Skip to content

Commit

Permalink
Merge pull request #1 from CommunityHiQ/UnitTest
Browse files Browse the repository at this point in the history
Unit test updated
  • Loading branch information
OssiGalkin authored Jan 22, 2021
2 parents 916b969 + 0efb447 commit 5c5d6dd
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 46 deletions.
46 changes: 39 additions & 7 deletions Frends.Community.TCP.Tests/Frends.Community.TCP.Tests.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,66 @@
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using System;
using System.Threading;

namespace Frends.Community.TCP.Tests
{
[Ignore("Test locally with listener")]
// [Ignore("Test locally")]

[TestFixture]
class TestClass
{

[OneTimeSetUp]
public void StartListener()
{

Thread listenerThread = new Thread(new ThreadStart(TestListener.Listener));

listenerThread.Start();

}

[Test]
public void TestSendMessage()
public void TestSendAndReceive()
{
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;

var input = new Parameters
{
Command = new string[] { "COMMAND1", "COMMAND2" },
Commands = new Command[] { new Command { CommandString = "COMMAND1", ResponseStart = "<C", ResponseEnd = ">" },
new Command{CommandString = "COMMAND2", ResponseStart = "<", ResponseEnd = "" },
new Command{CommandString = "COMMAND3", ResponseStart = "<", ResponseEnd = ">" }},
IpAddress = "127.0.0.1",
Port = 13000
};

var options = new Options
{
Timeout = 15
Timeout = 60000,

};

var input2 = new Parameters
{
Commands = new Command[] { new Command { CommandString = "COMMAND1" }, new Command { CommandString = "" },
new Command {CommandString = "SEND_EMPTY_RESP" }, new Command {CommandString ="STOP" } },
IpAddress = "127.0.0.1",
Port = 13000
};

var res1 = TCPTasks.ASCIIRequest(input, options).Result.Responses;
JArray expected = JArray.Parse(@"['COMMAND1Response','COMMAND2Response']");
Assert.AreEqual(expected, res1);
var options2 = new Options
{

};

var res1 = TCPTasks.ASCIIRequest(input, options, token).Result.Responses;
JArray expected = JArray.Parse(@"['<COMMAND1Response_ResponseContinues>','<COMMAND2Response','<COMMAND3Response_ResponseContinues>' ]");
Assert.AreEqual(expected.ToString(), res1.ToString());
Assert.That(async () => await TCPTasks.ASCIIRequest(input2, options2, token), Throws.Exception);

}

}
}
91 changes: 91 additions & 0 deletions Frends.Community.TCP.Tests/TestListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Frends.Community.TCP.Tests
{
class TestListener
{
public static void Listener()
{
TcpListener server = null;
try
{
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
server = new TcpListener(localAddr, port);
server.Start();


Byte[] bytes = new Byte[256];
String data = null;

while (true)
{
TcpClient client = server.AcceptTcpClient();
client.NoDelay = true;

data = null;

NetworkStream stream = client.GetStream();

//msgStart should be ignored by the task. Only responses to commands should be returned.
byte[] msgStart = System.Text.Encoding.ASCII.GetBytes("Message on listener launch");
stream.Write(msgStart, 0, msgStart.Length);

int i;

while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{

data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

data = data.ToUpper();

if (data.Equals("STOP"))
break;
else if (data.Equals("SEND_EMPTY_RESP"))
{
byte[] msgEmpty = System.Text.Encoding.ASCII.GetBytes("");
stream.Write(msgEmpty, 0, msgEmpty.Length);
}

else
{
byte[] msg1 = System.Text.Encoding.ASCII.GetBytes("...<" + data + "Response");
byte[] msg2 = System.Text.Encoding.ASCII.GetBytes("_ResponseContinues>...");
byte[] msg3 = System.Text.Encoding.ASCII.GetBytes("_this should be discarded only for command1 response");

stream.Write(msg1, 0, msg1.Length);
Thread.Sleep(1000);
stream.Write(msg2, 0, msg2.Length);
Thread.Sleep(1000);
stream.Write(msg3, 0, msg3.Length);

}


}

client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
server.Stop();
}

}


}
}
3 changes: 3 additions & 0 deletions Frends.Community.TCP.sln
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{35C305C0-8108-4A98-BB1D-AFE5C926239E} = {78F7F22E-6E20-4BCE-8362-0C558568B729}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55BC6629-85C9-48D8-8CA2-B0046AF1AF4B}
EndGlobalSection
Expand Down
14 changes: 10 additions & 4 deletions Frends.Community.TCP/Definition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Frends.Community.TCP
public class Parameters
{
[DisplayFormat(DataFormatString = "Text")]
public string[] Command { get; set; }
public Command[] Commands { get; set; }

[DisplayFormat(DataFormatString = "Text")]
public string IpAddress { get; set; }
Expand All @@ -19,15 +19,21 @@ public class Parameters
public int Port { get; set; }
}

public class Command
{
public string CommandString { get; set; }
public string ResponseStart { get; set; }
public string ResponseEnd { get; set; }

}

public class Options
{
/// <summary>
/// Read timeout
/// Task timeout (ms). Operation will timeout in case of empty response.
/// </summary>
[DefaultValue(15)]
[DefaultValue(10000)]
public int Timeout { get; set; }

}

public class Result
Expand Down
109 changes: 75 additions & 34 deletions Frends.Community.TCP/Frends.Community.TCP.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
Expand All @@ -14,60 +15,100 @@ namespace Frends.Community.TCP
public static class TCPTasks
{
/// <summary>
/// Documentation: https://github.com/CommunityHiQ/Frends.Community.TCPClient
/// Documentation: https://github.com/CommunityHiQ/Frends.Community.TCP
/// </summary>
public static async Task<Result> ASCIIRequest(Parameters input, Options options)
public static async Task<Result> ASCIIRequest(Parameters input, Options options, CancellationToken cancellationToken)
{
var output = new Result();
output.Responses = new JArray();

try
var output = new Result
{
using (TcpClient client = new TcpClient())
{
IPAddress ip = IPAddress.Parse(input.IpAddress);
await client.ConnectAsync(ip, input.Port);
Responses = new JArray()
};

using (NetworkStream stream = client.GetStream())
using (var writer = new StreamWriter(stream))
using (var reader = new StreamReader(stream))
{
if (options.Timeout.Equals(null))
options.Timeout = 60000;

stream.ReadTimeout = options.Timeout;

// Translate the passed message into ASCII and store it as a Byte array.
using (TcpClient client = new TcpClient())
{
IPAddress ip = IPAddress.Parse(input.IpAddress);
await client.ConnectAsync(ip, input.Port);

foreach (var cmd in input.Command)
{
Byte[] data = System.Text.Encoding.ASCII.GetBytes(cmd);
using (NetworkStream stream = client.GetStream())

await stream.WriteAsync(data, 0, data.Length);
{

data = new Byte[256];
foreach (var cmd in input.Commands)
{
Byte[] dataIn = System.Text.Encoding.ASCII.GetBytes(cmd.CommandString);

await stream.WriteAsync(dataIn, 0, dataIn.Length, cancellationToken);

Int32 bytes = await stream.ReadAsync(data, 0, data.Length);
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
output.Responses.Add(responseData);
Thread.Sleep(1000);

int timeout = options.Timeout;
Task<string> task = Read(stream, cancellationToken, cmd.ResponseStart, cmd.ResponseEnd);

if (task.Wait(timeout, cancellationToken))
{
await task;
output.Responses.Add(task.Result);
}
else

// Close everything.
stream.Close();
client.Close();
throw new TimeoutException();
}

// Close everything.
stream.Close();
client.Close();
}
}
catch (ArgumentNullException e)
{
throw e;
}
catch (SocketException e)
{
throw e;
}


return output;
}

private static async Task<string> Read(NetworkStream stream, CancellationToken cancellationToken, string start = "", string end = "")
{
string result = "";

while (true)
{

Byte[] dataOut = new Byte[8192];
Int32 bytes = await stream.ReadAsync(dataOut, 0, dataOut.Length, cancellationToken);
string responseData = System.Text.Encoding.ASCII.GetString(dataOut, 0, bytes);

result += responseData;

if (result != "")
{

if (start == "" && end == "")
return result;

if (end == "" && result.Contains(start))
return result.Substring(result.IndexOf(start));

if (start == "" && result.Contains(end))
return result.Substring(0, (result.IndexOf(end) + end.Length));

if (result.Contains(start))
{
var startIndex = result.IndexOf(start);

if (result.IndexOf(end, startIndex) > -1)
{
var length = result.IndexOf(end, startIndex) - startIndex + end.Length;
return result.Substring(startIndex, length);
}

}

}

}
}
}
}
2 changes: 1 addition & 1 deletion Frends.Community.TCP/Frends.Community.TCP.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<IncludeSource>true</IncludeSource>
<PackageTags>Frends</PackageTags>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Version>0.0.1</Version>
<Version>0.0.10</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ NOTE: Be sure to merge the latest from "upstream" before making a pull request!
| Version | Changes |
| ------- | ------- |
| 0.0.1 | Demo version |
| 0.0.2 | Flush incoming stream before new command |

0 comments on commit 5c5d6dd

Please sign in to comment.