using Bogus;
using Mil.Navy.Nrl.Norm.Buffers;
using Mil.Navy.Nrl.Norm.Enums;
using System.Net;
using System.Text;
namespace Mil.Navy.Nrl.Norm.IntegrationTests
{
public class NormSessionTests : IDisposable
{
private readonly NormInstance _normInstance;
private NormSession _normSession;
private bool _isInstanceDestroyed;
private bool _isSessionDestroyed;
private bool _isSenderStarted;
private bool _isSenderStopped;
private bool _isReceiverStarted;
private bool _isReceiverStopped;
private string _testPath;
private NormSession CreateSession()
{
var faker = new Faker();
var sessionAddress = "224.1.2.3";
var sessionPort = faker.Internet.Port();
var localNodeId = NormNode.NORM_NODE_ANY;
return _normInstance.CreateSession(sessionAddress, sessionPort, localNodeId);
}
private void CreateTestDirectory()
{
if (!Directory.Exists(_testPath))
{
Directory.CreateDirectory(_testPath);
}
}
private void DeleteTestDirectory()
{
if (Directory.Exists(_testPath))
{
Directory.Delete(_testPath, true);
}
}
public NormSessionTests()
{
_normInstance = new NormInstance();
_normSession = CreateSession();
_isInstanceDestroyed = false;
_isSessionDestroyed = false;
_isSenderStarted = false;
_isSenderStopped = false;
var currentDirectory = Directory.GetCurrentDirectory();
_testPath = Path.Combine(currentDirectory, Guid.NewGuid().ToString());
CreateTestDirectory();
}
private void StartSender()
{
if (!_isSenderStarted)
{
_normSession.StartSender(1024 * 1024, 1400, 64, 16);
_isSenderStarted = true;
}
}
private void StopSender()
{
if (_isSenderStarted && !_isSenderStopped)
{
_normSession.StopSender();
_isSenderStopped = true;
}
}
private void StartReceiver()
{
if (!_isReceiverStarted)
{
_normSession.StartReceiver(10 * 10);
_isReceiverStarted = true;
}
}
private void StopReceiver()
{
if (_isReceiverStarted && !_isReceiverStopped)
{
_normSession.StopReceiver();
_isReceiverStopped = true;
}
}
private void DestroySession()
{
if (!_isSessionDestroyed)
{
StopSender();
_normSession.DestroySession();
_isSessionDestroyed = true;
}
}
private void DestroyInstance()
{
if (!_isInstanceDestroyed)
{
DestroySession();
_normInstance.DestroyInstance();
_isInstanceDestroyed = true;
}
}
public void Dispose()
{
DestroyInstance();
DeleteTestDirectory();
}
[Fact]
public void CreatesSession()
{
Assert.NotNull(_normSession);
}
[Fact]
public void DestroysSession()
{
DestroySession();
}
[SkippableFact(typeof(IOException))]
public void StartsSender()
{
StartSender();
}
[SkippableFact(typeof(IOException))]
public void StopsSender()
{
StartSender();
StopSender();
}
[SkippableFact(typeof(IOException))]
public void StartsReceiver()
{
StartReceiver();
}
[SkippableFact(typeof(IOException))]
public void StopsReceiver()
{
StartReceiver();
StopReceiver();
}
private static string GenerateTextContent()
{
var faker = new Faker();
return faker.Lorem.Paragraph();
}
private static string GenerateInfoContent()
{
var faker = new Faker();
return faker.Lorem.Sentence();
}
private IEnumerable<NormEvent> GetEvents(TimeSpan delayTime)
{
var normEvents = new List<NormEvent>();
while (_normInstance.HasNextEvent(delayTime))
{
var normEvent = _normInstance.GetNextEvent(false);
if (normEvent != null)
{
normEvents.Add(normEvent);
}
}
return normEvents;
}
private IEnumerable<NormEvent> GetEvents()
{
return GetEvents(TimeSpan.FromMilliseconds(30));
}
private void WaitForEvents(TimeSpan delayTime)
{
GetEvents(delayTime);
}
private void WaitForEvents()
{
GetEvents();
}
private void AssertNormEvents(IEnumerable<NormEvent> normEvents)
{
foreach (var normEvent in normEvents)
{
var normNode = normEvent.Node;
if (normNode != null)
{
var actualId = normNode.Id;
Assert.NotEqual(NormNode.NORM_NODE_NONE, actualId);
var expectedIpAddresses = Dns.GetHostAddresses(Dns.GetHostName())
.Where(i => i.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !IPAddress.IsLoopback(i));
var actualAddress = normNode.Address;
Assert.NotNull(actualAddress);
Assert.Contains(actualAddress.Address, expectedIpAddresses);
Assert.NotEqual(default, actualAddress.Port);
var actualGrtt = normNode.Grtt;
Assert.NotEqual(-1, actualGrtt);
var expectedEventString = $"NormEvent [type={normEvent.Type}]";
var actualEventString = normEvent.ToString();
Assert.Equal(expectedEventString, actualEventString);
}
}
}
public static IEnumerable<object?[]> GenerateInfo()
{
var info = new List<object?[]>();
var infoContent = GenerateInfoContent();
var expectedInfoContent = infoContent;
var infoOffset = 0;
var infoLength = infoContent.Length;
info.Add(new object?[] { infoContent, expectedInfoContent, infoOffset, infoLength });
var faker = new Faker();
infoLength = faker.Random.Int(infoContent.Length / 2, infoContent.Length - 1);
expectedInfoContent = infoContent.Substring(infoOffset, infoLength);
info.Add(new object?[] { infoContent, expectedInfoContent, infoOffset, infoLength });
infoOffset = faker.Random.Int(1, (infoContent.Length - 1) / 2);
infoLength = infoContent.Length - infoOffset;
expectedInfoContent = infoContent.Substring(infoOffset, infoLength);
info.Add(new object?[] { infoContent, expectedInfoContent, infoOffset, infoLength });
infoOffset = faker.Random.Int(1, (infoContent.Length - 1) / 2);
infoLength = faker.Random.Int(1, infoContent.Length - infoOffset);
expectedInfoContent = infoContent.Substring(infoOffset, infoLength);
info.Add(new object?[] { infoContent, expectedInfoContent, infoOffset, infoLength });
info.Add(new object?[] { null, null, null, null });
info.Add(new object?[] { null, "", 0, 0 });
return info;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateInfo))]
public void EnqueuesFile(string? infoContent = null, string? expectedInfoContent = null, int? infoOffset = null, int? infoLength = null)
{
StartSender();
var fileContent = GenerateTextContent();
var fileName = Guid.NewGuid().ToString();
var filePath = Path.Combine(_testPath, fileName);
File.WriteAllText(filePath, fileContent);
byte[]? info = null;
if (infoContent != null) {
info = Encoding.ASCII.GetBytes(infoContent);
}
else if (expectedInfoContent == null)
{
expectedInfoContent = filePath;
}
var expectedInfo = Array.Empty<byte>();
if (expectedInfoContent != null)
{
expectedInfo = Encoding.ASCII.GetBytes(expectedInfoContent);
}
try
{
var normFile = infoOffset != null && infoLength != null ?
_normSession.FileEnqueue(filePath, info, infoOffset.Value, infoLength.Value) :
_normSession.FileEnqueue(filePath);
Assert.NotNull(normFile);
var expectedEventTypes = new List<NormEventType> { NormEventType.NORM_TX_OBJECT_SENT, NormEventType.NORM_TX_QUEUE_EMPTY };
var actualEvents = GetEvents();
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equal(expectedEventTypes, actualEventTypes);
var expectedFileName = filePath;
var actualFileName = normFile.Name;
Assert.Equal(expectedFileName, actualFileName);
var actualInfo = normFile.Info;
Assert.Equal(expectedInfo, actualInfo);
if (actualInfo != null)
{
var actualInfoContent = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedInfoContent, actualInfoContent);
}
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
public static IEnumerable<object[]> GenerateOutOfRangeInfo()
{
var info = new List<object[]>();
var faker = new Faker();
var infoContent = GenerateInfoContent();
var infoOffset = faker.Random.Int(-infoContent.Length, -1);
var infoLength = infoContent.Length;
info.Add(new object[] { infoContent, infoOffset, infoLength });
infoOffset = faker.Random.Int(infoContent.Length, infoContent.Length * 2);
infoLength = infoContent.Length;
info.Add(new object[] { infoContent, infoOffset, infoLength });
infoOffset = 0;
infoLength = faker.Random.Int(infoContent.Length + 1, infoContent.Length * 2);
info.Add(new object[] { infoContent, infoOffset, infoLength });
infoLength = -1;
info.Add(new object[] { infoContent, infoOffset, infoLength });
infoLength = 0;
info.Add(new object[] { infoContent, infoOffset, infoLength });
infoOffset = infoContent.Length - 1;
infoLength = infoContent.Length;
info.Add(new object[] { infoContent, infoOffset, infoLength });
return info;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateOutOfRangeInfo))]
public void EnqueuesFileThrowsExceptionWhenOutOfRange(string? infoContent = null, int? infoOffset = null, int? infoLength = null)
{
StartSender();
var fileContent = GenerateTextContent();
var fileName = Guid.NewGuid().ToString();
var filePath = Path.Combine(_testPath, fileName);
File.WriteAllText(filePath, fileContent);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
try
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
infoOffset != null && infoLength != null ?
_normSession.FileEnqueue(filePath, info, infoOffset.Value, infoLength.Value) :
_normSession.FileEnqueue(filePath));
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateInfo))]
public void ReceivesFile(string? infoContent = null, string? expectedInfoContent = null, int? infoOffset = null, int? infoLength = null)
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var fileName = Guid.NewGuid().ToString();
var fileContent = GenerateTextContent();
var filePath = Path.Combine(_testPath, fileName);
File.WriteAllText(filePath, fileContent);
byte[]? info = null;
if (infoContent != null) {
info = Encoding.ASCII.GetBytes(infoContent);
}
else if (expectedInfoContent == null)
{
expectedInfoContent = filePath;
}
var expectedInfo = Array.Empty<byte>();
if (expectedInfoContent != null)
{
expectedInfo = Encoding.ASCII.GetBytes(expectedInfoContent);
}
try
{
var normFile = infoOffset != null && infoLength != null ?
_normSession.FileEnqueue(filePath, info, infoOffset.Value, infoLength.Value) :
_normSession.FileEnqueue(filePath);
var normEvents = GetEvents();
AssertNormEvents(normEvents);
var expectedNormEventType = NormEventType.NORM_RX_OBJECT_COMPLETED;
Assert.Contains(expectedNormEventType, normEvents.Select(e => e.Type));
var normObjectEvent = normEvents.First(e => e.Type == expectedNormEventType);
var receivedNormFile = Assert.IsType<NormFile>(normObjectEvent.Object);
var expectedFileName = receivedNormFile.Name;
var expectedFileCount = 1;
var actualFiles = Directory.GetFiles(cachePath);
var actualFileCount = actualFiles.Length;
Assert.Equal(expectedFileCount, actualFileCount);
var actualFileName = actualFiles.First();
Assert.Equal(expectedFileName, actualFileName);
var actualContent = File.ReadAllText(actualFileName);
Assert.Equal(fileContent, actualContent);
var actualInfo = receivedNormFile.Info;
Assert.Equal(expectedInfo, actualInfo);
if (actualInfo != null)
{
var actualInfoContent = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedInfoContent, actualInfoContent);
}
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void ReceivesFileWithRename()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var fileName = Guid.NewGuid().ToString();
var fileContent = GenerateTextContent();
var filePath = Path.Combine(_testPath, fileName);
File.WriteAllText(filePath, fileContent);
try
{
var fileNameBytes = Encoding.ASCII.GetBytes(fileName);
var normFile = _normSession.FileEnqueue(filePath, fileNameBytes, 0, fileNameBytes.Length);
var normEvents = GetEvents();
AssertNormEvents(normEvents);
var expectedNormEventType = NormEventType.NORM_RX_OBJECT_COMPLETED;
Assert.Contains(expectedNormEventType, normEvents.Select(e => e.Type));
var normObjectEvent = normEvents.First(e => e.Type == expectedNormEventType);
var receivedNormFile = Assert.IsType<NormFile>(normObjectEvent.Object);
var actualInfo = receivedNormFile.Info;
Assert.NotNull(actualInfo);
var expectedFileName = fileName;
var actualFileName = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedFileName, actualFileName);
var expectedFilePath = Path.Combine(cachePath, actualFileName);
receivedNormFile.Rename(expectedFilePath);
var expectedFileCount = 1;
var actualFiles = Directory.GetFiles(cachePath);
var actualFileCount = actualFiles.Length;
Assert.Equal(expectedFileCount, actualFileCount);
var actualFilePath = actualFiles.First();
Assert.Equal(expectedFilePath, actualFilePath);
var actualContent = File.ReadAllText(actualFilePath);
Assert.Equal(fileContent, actualContent);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
public static IEnumerable<object[]> GenerateData()
{
var data = new List<object[]>();
var dataContent = GenerateTextContent();
var expectedDataContent = dataContent;
var dataOffset = 0;
var dataLength = dataContent.Length;
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength });
var infoContent = GenerateInfoContent();
var expectedInfoContent = infoContent;
var infoOffset = 0;
var infoLength = infoContent.Length;
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength, infoContent, expectedInfoContent, infoOffset, infoLength });
var faker = new Faker();
infoLength = faker.Random.Int(infoContent.Length / 2, infoContent.Length - 1);
expectedInfoContent = infoContent.Substring(infoOffset, infoLength);
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength, infoContent, expectedInfoContent, infoOffset, infoLength });
infoOffset = faker.Random.Int(1, (infoContent.Length - 1) / 2);
infoLength = infoContent.Length - infoOffset;
expectedInfoContent = infoContent.Substring(infoOffset, infoLength);
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength, infoContent, expectedInfoContent, infoOffset, infoLength });
infoOffset = faker.Random.Int(1, (infoContent.Length - 1) / 2);
infoLength = faker.Random.Int(1, infoContent.Length - infoOffset);
expectedInfoContent = infoContent.Substring(infoOffset, infoLength);
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength, infoContent, expectedInfoContent, infoOffset, infoLength });
dataLength = faker.Random.Int(dataContent.Length / 2, dataContent.Length - 1);
expectedDataContent = dataContent.Substring(dataOffset, dataLength);
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength });
dataOffset = faker.Random.Int(1, (dataContent.Length - 1) / 2);
dataLength = dataContent.Length - dataOffset;
expectedDataContent = dataContent.Substring(dataOffset, dataLength);
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength });
dataOffset = faker.Random.Int(1, (dataContent.Length - 1) / 2);
dataLength = faker.Random.Int(1, dataContent.Length - dataOffset);
expectedDataContent = dataContent.Substring(dataOffset, dataLength);
data.Add(new object[] { dataContent, expectedDataContent, dataOffset, dataLength });
return data;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateData))]
public void EnqueuesData(string dataContent, string expectedDataContent, int dataOffset, int dataLength, string? infoContent = null, string expectedInfoContent = "", int? infoOffset = null, int? infoLength = null)
{
StartSender();
var data = Encoding.ASCII.GetBytes(dataContent);
using var dataBuffer = ByteBuffer.AllocateDirect(data.Length);
dataBuffer.WriteArray(0, data, 0, data.Length);
var expectedData = Encoding.ASCII.GetBytes(expectedDataContent);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
var expectedInfo = Encoding.ASCII.GetBytes(expectedInfoContent);
try
{
var normData = infoOffset != null && infoLength != null ?
_normSession.DataEnqueue(dataBuffer, dataOffset, dataLength, info, infoOffset.Value, infoLength.Value) :
_normSession.DataEnqueue(dataBuffer, dataOffset, dataLength);
var expectedEventTypes = new List<NormEventType> { NormEventType.NORM_TX_OBJECT_SENT, NormEventType.NORM_TX_QUEUE_EMPTY };
var actualEventTypes = GetEvents().Select(e => e.Type).ToList();
Assert.Equal(expectedEventTypes, actualEventTypes);
var actualData = normData.GetData();
Assert.Equal(expectedData, actualData);
var actualDataContent = Encoding.ASCII.GetString(actualData);
Assert.Equal(expectedDataContent, actualDataContent);
var actualInfo = normData.Info;
Assert.Equal(expectedInfo, actualInfo);
if (actualInfo != null)
{
var actualInfoContent = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedInfoContent, actualInfoContent);
}
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
public static IEnumerable<object[]> GenerateOutOfRangeData()
{
var data = new List<object[]>();
var dataContent = GenerateTextContent();
var faker = new Faker();
var dataOffset = faker.Random.Int(-dataContent.Length, -1);
var dataLength = dataContent.Length;
data.Add(new object[] { dataContent, dataOffset, dataLength });
dataOffset = faker.Random.Int(dataContent.Length, dataContent.Length * 2);
dataLength = dataContent.Length;
data.Add(new object[] { dataContent, dataOffset, dataLength });
dataOffset = 0;
dataLength = faker.Random.Int(dataContent.Length + 1, dataContent.Length * 2);
data.Add(new object[] { dataContent, dataOffset, dataLength });
dataLength = -1;
data.Add(new object[] { dataContent, dataOffset, dataLength });
dataLength = 0;
data.Add(new object[] { dataContent, dataOffset, dataLength });
dataOffset = dataContent.Length - 1;
dataLength = dataContent.Length;
data.Add(new object[] { dataContent, dataOffset, dataLength });
dataOffset = 0;
dataLength = dataContent.Length;
var infoContent = GenerateInfoContent();
var infoOffset = faker.Random.Int(-infoContent.Length, -1);
var infoLength = infoContent.Length;
data.Add(new object[] { dataContent, dataOffset, dataLength, infoContent, infoOffset, infoLength });
infoOffset = faker.Random.Int(infoContent.Length, infoContent.Length * 2);
infoLength = infoContent.Length;
data.Add(new object[] { dataContent, dataOffset, dataLength, infoContent, infoOffset, infoLength });
infoOffset = 0;
infoLength = faker.Random.Int(infoContent.Length + 1, infoContent.Length * 2);
data.Add(new object[] { dataContent, dataOffset, dataLength, infoContent, infoOffset, infoLength });
infoLength = -1;
data.Add(new object[] { dataContent, dataOffset, dataLength, infoContent, infoOffset, infoLength });
infoLength = 0;
data.Add(new object[] { dataContent, dataOffset, dataLength, infoContent, infoOffset, infoLength });
infoOffset = infoContent.Length - 1;
infoLength = infoContent.Length;
data.Add(new object[] { dataContent, dataOffset, dataLength, infoContent, infoOffset, infoLength });
return data;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateOutOfRangeData))]
public void EnqueuesDataThrowsExceptionWhenOutOfRange(string dataContent, int dataOffset, int dataLength, string? infoContent = null, int? infoOffset = null, int? infoLength = null)
{
StartSender();
var data = Encoding.ASCII.GetBytes(dataContent);
using var dataBuffer = ByteBuffer.AllocateDirect(data.Length);
dataBuffer.WriteArray(0, data, 0, data.Length);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
try
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
infoOffset != null && infoLength != null ?
_normSession.DataEnqueue(dataBuffer, dataOffset, dataLength, info, infoOffset.Value, infoLength.Value) :
_normSession.DataEnqueue(dataBuffer, dataOffset, dataLength));
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateData))]
public void ReceivesData(string content, string expectedDataContent, int dataOffset, int dataLength, string? infoContent = null, string expectedInfoContent = "", int? infoOffset = null, int? infoLength = null)
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var data = Encoding.ASCII.GetBytes(content);
using var dataBuffer = ByteBuffer.AllocateDirect(data.Length);
dataBuffer.WriteArray(0, data, 0, data.Length);
var expectedData = Encoding.ASCII.GetBytes(expectedDataContent);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
var expectedInfo = Encoding.ASCII.GetBytes(expectedInfoContent);
try
{
var normData = infoOffset != null && infoLength != null ?
_normSession.DataEnqueue(dataBuffer, dataOffset, dataLength, info, infoOffset.Value, infoLength.Value) :
_normSession.DataEnqueue(dataBuffer, dataOffset, dataLength);
var expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_REMOTE_SENDER_NEW,
NormEventType.NORM_REMOTE_SENDER_ACTIVE,
NormEventType.NORM_TX_OBJECT_SENT,
NormEventType.NORM_TX_QUEUE_EMPTY,
NormEventType.NORM_RX_OBJECT_NEW,
NormEventType.NORM_RX_OBJECT_UPDATED,
NormEventType.NORM_RX_OBJECT_COMPLETED
};
var actualEvents = GetEvents();
AssertNormEvents(actualEvents);
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
var actualEvent = actualEvents.FirstOrDefault(e => e.Type == NormEventType.NORM_RX_OBJECT_COMPLETED);
var actualNormData = Assert.IsType<NormData>(actualEvent?.Object);
var actualData = actualNormData.GetData();
Assert.Equal(expectedData, actualData);
var actualDataContent = Encoding.ASCII.GetString(actualData);
Assert.Equal(expectedDataContent, actualDataContent);
var actualInfo = actualNormData.Info;
Assert.Equal(expectedInfo, actualInfo);
if (actualInfo != null)
{
var actualInfoContent = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedInfoContent, actualInfoContent);
}
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateData))]
public void SendsStream(string content, string expectedContent, int offset, int length, string? infoContent = null, string expectedInfoContent = "", int? infoOffset = null, int? infoLength = null)
{
StartSender();
var buffer = Encoding.ASCII.GetBytes(content);
var expectedBuffer = Encoding.ASCII.GetBytes(expectedContent);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
var expectedInfo = Encoding.ASCII.GetBytes(expectedInfoContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = infoOffset != null && infoLength != null ?
_normSession.StreamOpen(repairWindowSize, info, infoOffset.Value, infoLength.Value) :
_normSession.StreamOpen(repairWindowSize);
var expectedBytesWritten = expectedBuffer.Length;
var actualBytesWritten = normStream.Write(buffer, offset, length);
WaitForEvents();
normStream.MarkEom();
normStream.Flush();
Assert.Equal(expectedBytesWritten, actualBytesWritten);
var actualInfo = normStream.Info;
Assert.Equal(expectedInfo, actualInfo);
if (actualInfo != null)
{
var actualInfoContent = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedInfoContent, actualInfoContent);
}
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateOutOfRangeData))]
public void SendsStreamThrowsExceptionWhenOutOfRange(string content, int offset, int length, string? infoContent = null, int? infoOffset = null, int? infoLength = null)
{
StartSender();
var buffer = Encoding.ASCII.GetBytes(content);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
if (infoOffset != null && infoLength != null) {
Assert.Throws<ArgumentOutOfRangeException>(() =>
_normSession.StreamOpen(repairWindowSize, info, infoOffset.Value, infoLength.Value));
}
else
{
normStream = _normSession.StreamOpen(repairWindowSize);
Assert.Throws<ArgumentOutOfRangeException>(() =>
normStream.Write(buffer, offset, length));
}
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateData))]
public void ReceivesStream(string content, string expectedContent, int offset, int length, string? infoContent = null, string expectedInfoContent = "", int? infoOffset = null, int? infoLength = null)
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var buffer = Encoding.ASCII.GetBytes(content);
var expectedBuffer = Encoding.ASCII.GetBytes(expectedContent);
var info = infoContent != null ? Encoding.ASCII.GetBytes(infoContent) : null;
var expectedInfo = Encoding.ASCII.GetBytes(expectedInfoContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = infoOffset != null && infoLength != null ?
_normSession.StreamOpen(repairWindowSize, info, infoOffset.Value, infoLength.Value) :
_normSession.StreamOpen(repairWindowSize);
var expectedBytesWritten = expectedBuffer.Length;
normStream.Write(buffer, offset, length);
normStream.MarkEom();
normStream.Flush();
var normEvents = GetEvents();
AssertNormEvents(normEvents);
var expectedNormEventType = NormEventType.NORM_RX_OBJECT_UPDATED;
Assert.Contains(expectedNormEventType, normEvents.Select(e => e.Type));
var normObjectEvent = normEvents.First(e => e.Type == expectedNormEventType);
var receivedNormStream = Assert.IsType<NormStream>(normObjectEvent.Object);
var numRead = 0;
var receiveBuffer = new byte[65536];
while ((numRead = receivedNormStream.Read(receiveBuffer, 0, length)) > 0)
{
if (numRead != -1)
{
var receivedData = receiveBuffer.Take(numRead).ToArray();
var receivedContent = Encoding.ASCII.GetString(receivedData);
Assert.Equal(expectedContent, receivedContent);
}
}
var actualInfo = receivedNormStream.Info;
Assert.Equal(expectedInfo, actualInfo);
if (actualInfo != null)
{
var actualInfoContent = Encoding.ASCII.GetString(actualInfo);
Assert.Equal(expectedInfoContent, actualInfoContent);
}
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void ReceivesStreamWithOffset()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
var offset = 0;
var length = data.Length;
normStream.Write(data, offset, length);
normStream.MarkEom();
normStream.Flush();
var normEvents = GetEvents();
AssertNormEvents(normEvents);
var expectedNormEventType = NormEventType.NORM_RX_OBJECT_UPDATED;
var normObjectEvent = normEvents.First(e => e.Type == expectedNormEventType);
var receivedNormStream = Assert.IsType<NormStream>(normObjectEvent.Object);
var receiveBuffer = new byte[65536];
var receiveOffset = 0;
var receiveBufferLength = 10;
var totalNumRead = 0;
var numRead = 0;
while ((numRead = receivedNormStream.Read(receiveBuffer, receiveOffset, receiveBufferLength)) > 0)
{
if (numRead != -1)
{
totalNumRead += numRead;
receiveOffset += numRead;
}
}
var receivedData = receiveBuffer.Take(totalNumRead).ToArray();
var receivedContent = Encoding.ASCII.GetString(receivedData);
Assert.Equal(fileContent, receivedContent);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
StopReceiver();
}
}
public static IEnumerable<object[]> GenerateOutOfRangeReceiveStream()
{
var data = new List<object[]>();
var faker = new Faker();
var initialLength = faker.Random.Int(256, 1024);
var dataOffset = faker.Random.Int(-initialLength, -1);
var dataLength = initialLength;
data.Add(new object[] { initialLength, dataOffset, dataLength });
dataOffset = faker.Random.Int(initialLength, initialLength * 2);
dataLength = initialLength;
data.Add(new object[] { initialLength, dataOffset, dataLength });
dataOffset = 0;
dataLength = faker.Random.Int(initialLength + 1, initialLength * 2);
data.Add(new object[] { initialLength, dataOffset, dataLength });
dataLength = -1;
data.Add(new object[] { initialLength, dataOffset, dataLength });
dataLength = 0;
data.Add(new object[] { initialLength, dataOffset, dataLength });
dataOffset = initialLength - 1;
dataLength = initialLength;
data.Add(new object[] { initialLength, dataOffset, dataLength });
return data;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateOutOfRangeReceiveStream))]
public void ReceivesStreamThrowsExceptionWhenOutOfRange(int initialReceiveBufferLength, int receiveBufferOffset, int receiveBufferLength)
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
var offset = 0;
var length = data.Length;
normStream.Write(data, offset, length);
normStream.MarkEom();
normStream.Flush();
var normEvents = GetEvents();
AssertNormEvents(normEvents);
var expectedNormEventType = NormEventType.NORM_RX_OBJECT_UPDATED;
var normObjectEvent = normEvents.First(e => e.Type == expectedNormEventType);
var receivedNormStream = Assert.IsType<NormStream>(normObjectEvent.Object);
var receiveBuffer = new byte[initialReceiveBufferLength];
Assert.Throws<ArgumentOutOfRangeException>(() =>
receivedNormStream.Read(receiveBuffer, receiveBufferOffset, receiveBufferLength));
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
StopReceiver();
}
}
[Fact]
public void SetsTxPort()
{
_normSession.SetTxPort(6003);
}
[Fact]
public void SetsRxPortReuseTrue()
{
_normSession.SetRxPortReuse(true);
}
[Fact]
public void SetsRxPortReuseFalse()
{
_normSession.SetRxPortReuse(false);
}
[Fact]
public void SetsEcnSupport()
{
_normSession.SetEcnSupport(true, true);
}
[Fact]
public void SetsMulticastInterface()
{
_normSession.SetMulticastInterface("interface_name");
}
[Fact]
public void SetsSSM()
{
var sourceAddress = "224.1.2.3";
_normSession.SetSSM(sourceAddress);
}
[Fact]
public void SetsSSMThrowsIOException()
{
var sourceAddress = "999.999.999.999";
Assert.Throws<IOException>(() => _normSession.SetSSM(sourceAddress));
}
[Fact]
public void SetsTTL()
{
var ttl = (byte)200;
_normSession.SetTTL(ttl);
}
[Fact]
public void SetsTOS()
{
var tos = (byte)200;
_normSession.SetTOS(tos);
}
[Fact]
public void SetsMessageTrace()
{
var flag = true;
_normSession.SetMessageTrace(flag);
}
[Fact]
public void SetsTxLoss()
{
var txLoss = .50;
_normSession.SetTxLoss(txLoss);
}
[Fact]
public void SetsRxLoss()
{
var rxLoss = .50;
_normSession.SetRxLoss(rxLoss);
}
[Fact]
public void SetsReportInterval()
{
var expectedReportInterval = .50;
_normSession.ReportInterval = expectedReportInterval;
var actualReportInterval = _normSession.ReportInterval;
Assert.Equal(expectedReportInterval, actualReportInterval);
}
[Fact]
public void SetsTxOnly()
{
var txOnly = true;
_normSession.SetTxOnly(txOnly);
}
[Fact]
public void SetsFlowControl()
{
var flowControlFactor = .50;
_normSession.SetFlowControl(flowControlFactor);
}
[Fact]
public void SetsTxSocketBuffer()
{
StartSender();
var bufferSize = 100;
_normSession.SetTxSocketBuffer(bufferSize);
}
[Fact]
public void SetsCongestionControl()
{
var enable = true;
_normSession.SetCongestionControl(enable);
}
[Fact]
public void SetsTxRateBounds()
{
var rateMin = 1.0;
var rateMax = 100.0;
_normSession.SetTxRateBounds(rateMin, rateMax);
}
[Fact]
public void SetsTxCacheBounds()
{
var sizeMax = 100;
var countMin = 1;
var countMax = 99;
_normSession.SetTxCacheBounds(sizeMax, countMin, countMax);
}
[Fact]
public void SetsAutoParity()
{
short autoParity = 123;
_normSession.SetAutoParity(autoParity);
}
[Fact]
public void SetsTxRate()
{
double txRate = 20.0;
_normSession.TxRate = txRate;
}
[Fact]
public void GetsTxRate()
{
double expectedTxRate = 10.0;
_normSession.TxRate = expectedTxRate;
var actualTxRate = _normSession.TxRate;
Assert.Equal(expectedTxRate, actualTxRate);
}
[Fact]
public void SetsGrttEstimate()
{
double grttEstimate = 10.0;
_normSession.GrttEstimate = grttEstimate;
}
[Fact]
public void GetsGrttEstimate()
{
double expetedGrttEstimate = 10.0;
_normSession.GrttEstimate = expetedGrttEstimate;
var actualGrttEstimate = _normSession.GrttEstimate;
Assert.InRange<double>(actualGrttEstimate, expetedGrttEstimate - 1.0, expetedGrttEstimate + 1.0);
}
[Fact]
public void SetsGrttMax()
{
double grttMax = 20.0;
_normSession.SetGrttMax(grttMax);
}
[Fact]
public void SetsGrttProbingMode_NORM_PROBE_NONE()
{
var probingMode = NormProbingMode.NORM_PROBE_NONE;
_normSession.SetGrttProbingMode(probingMode);
}
[Fact]
public void SetsGrttProbingMode_NORM_PROBE_PASSIVE()
{
var probingMode = NormProbingMode.NORM_PROBE_PASSIVE;
_normSession.SetGrttProbingMode(probingMode);
}
[Fact]
public void SetsGrttProbingMode_NORM_PROBE_ACTIVE()
{
var probingMode = NormProbingMode.NORM_PROBE_ACTIVE;
_normSession.SetGrttProbingMode(probingMode);
}
[Fact]
public void SetsGrttProbingInterval()
{
var intervalMin = 1.0;
var intervalMax = 10.0;
_normSession.SetGrttProbingInterval(intervalMin, intervalMax);
}
[Fact]
public void SetsBackoffFactor()
{
var backoffFactor = 10.0;
_normSession.SetBackoffFactor(backoffFactor);
}
[Fact]
public void SetsGroupSize()
{
var groupSize = 100;
_normSession.SetGroupSize(groupSize);
}
[Fact]
public void SetsTxRobustFactor()
{
var txRobustFactor = 2;
_normSession.SetTxRobustFactor(txRobustFactor);
}
[SkippableFact(typeof(IOException))]
public void RequeuesObject()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
var expectedEventTypes = new List<NormEventType> { NormEventType.NORM_TX_OBJECT_SENT, NormEventType.NORM_TX_QUEUE_EMPTY };
var actualEventTypes = GetEvents().Select(e => e.Type).ToList();
Assert.Equal(expectedEventTypes, actualEventTypes);
_normSession.RequeueObject(normData);
actualEventTypes = GetEvents().Select(e => e.Type).ToList();
Assert.Equal(expectedEventTypes, actualEventTypes);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void SetsWatermark()
{
_normSession.AddAckingNode(_normSession.LocalNodeId);
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
_normSession.SetWatermark(normData);
var expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_REMOTE_SENDER_NEW,
NormEventType.NORM_REMOTE_SENDER_ACTIVE,
NormEventType.NORM_TX_OBJECT_SENT,
NormEventType.NORM_TX_QUEUE_EMPTY,
NormEventType.NORM_RX_OBJECT_NEW,
NormEventType.NORM_RX_OBJECT_UPDATED,
NormEventType.NORM_RX_OBJECT_COMPLETED,
NormEventType.NORM_TX_WATERMARK_COMPLETED
};
var actualEvents = GetEvents(TimeSpan.FromSeconds(1));
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void CancelsWatermark()
{
_normSession.AddAckingNode(_normSession.LocalNodeId);
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
_normSession.SetWatermark(normData);
_normSession.CancelWatermark();
var expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_REMOTE_SENDER_NEW,
NormEventType.NORM_REMOTE_SENDER_ACTIVE,
NormEventType.NORM_TX_OBJECT_SENT,
NormEventType.NORM_TX_QUEUE_EMPTY,
NormEventType.NORM_RX_OBJECT_NEW,
NormEventType.NORM_RX_OBJECT_UPDATED,
NormEventType.NORM_RX_OBJECT_COMPLETED
};
var actualEvents = GetEvents(TimeSpan.FromSeconds(1));
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void ResetsWatermark()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
_normSession.SetWatermark(normData);
var expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_REMOTE_SENDER_NEW,
NormEventType.NORM_REMOTE_SENDER_ACTIVE,
NormEventType.NORM_TX_OBJECT_SENT,
NormEventType.NORM_TX_QUEUE_EMPTY,
NormEventType.NORM_RX_OBJECT_NEW,
NormEventType.NORM_RX_OBJECT_UPDATED,
NormEventType.NORM_RX_OBJECT_COMPLETED
};
var actualEvents = GetEvents(TimeSpan.FromSeconds(1));
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
_normSession.AddAckingNode(_normSession.LocalNodeId);
_normSession.ResetWatermark();
expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_TX_WATERMARK_COMPLETED
};
actualEvents = GetEvents(TimeSpan.FromSeconds(1));
actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[Fact]
public void AddsAckingNode()
{
_normSession.AddAckingNode(_normSession.LocalNodeId);
}
[Fact]
public void RemovesAckingNode()
{
_normSession.AddAckingNode(_normSession.LocalNodeId);
_normSession.RemoveAckingNode(_normSession.LocalNodeId);
}
[SkippableFact(typeof(IOException))]
public void GetsAckingStatus()
{
_normSession.AddAckingNode(_normSession.LocalNodeId);
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
_normSession.SetWatermark(normData);
WaitForEvents(TimeSpan.FromSeconds(1));
var expectedAckingStatus = NormAckingStatus.NORM_ACK_SUCCESS;
var actualAckingStatus = _normSession.GetAckingStatus(_normSession.LocalNodeId);
Assert.Equal(expectedAckingStatus, actualAckingStatus);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void SendsCommand()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var expectedEventTypes = new List<NormEventType> { NormEventType.NORM_TX_CMD_SENT };
var actualEventTypes = GetEvents().Select(e => e.Type).ToList();
Assert.Equal(expectedEventTypes, actualEventTypes);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
public static IEnumerable<object[]> GenerateOutOfRangeCommand()
{
var command = new List<object[]>();
var faker = new Faker();
var content = GenerateInfoContent();
var offset = faker.Random.Int(-content.Length, -1);
var length = content.Length;
command.Add(new object[] { content, offset, length });
offset = faker.Random.Int(content.Length, content.Length * 2);
length = content.Length;
command.Add(new object[] { content, offset, length });
offset = 0;
length = faker.Random.Int(content.Length + 1, content.Length * 2);
command.Add(new object[] { content, offset, length });
length = -1;
command.Add(new object[] { content, offset, length });
length = 0;
command.Add(new object[] { content, offset, length });
offset = content.Length - 1;
length = content.Length;
command.Add(new object[] { content, offset, length });
return command;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateOutOfRangeCommand))]
public void SendsCommandThrowsExceptionWhenOutOfRange(string content, int offset, int length)
{
StartSender();
var command = Encoding.ASCII.GetBytes(content);
try
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
_normSession.SendCommand(command, offset, length, false));
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void ReceivesCommand()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var content = GenerateInfoContent();
var expectedContent = content;
var offset = 0;
var length = content.Length;
var command = Encoding.ASCII.GetBytes(content);
var expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(command, 0, command.Length, false);
var expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_TX_CMD_SENT,
NormEventType.NORM_REMOTE_SENDER_NEW,
NormEventType.NORM_REMOTE_SENDER_ACTIVE,
NormEventType.NORM_RX_CMD_NEW
};
var actualEvents = GetEvents();
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
var actualEvent = actualEvents.First(e => e.Type == NormEventType.NORM_RX_CMD_NEW);
var actualCommand = new byte[command.Length];
var actualLength = actualEvent?.Node?.GetCommand(actualCommand, offset, length);
Assert.Equal(length, actualLength);
Assert.Equal(expectedCommand, actualCommand);
var actualContent = Encoding.ASCII.GetString(actualCommand);
Assert.Equal(expectedContent, actualContent);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
private void ReceivesCommandThrowsException<TExceptionType>(string content, int offset, int length) where TExceptionType : Exception
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var command = Encoding.ASCII.GetBytes(content);
try
{
_normSession.SendCommand(command, 0, command.Length, false);
var expectedEventTypes = new List<NormEventType>
{
NormEventType.NORM_TX_CMD_SENT,
NormEventType.NORM_REMOTE_SENDER_NEW,
NormEventType.NORM_REMOTE_SENDER_ACTIVE,
NormEventType.NORM_RX_CMD_NEW
};
var actualEvents = GetEvents();
var actualEventTypes = actualEvents.Select(e => e.Type).ToList();
Assert.Equivalent(expectedEventTypes, actualEventTypes);
var actualEvent = actualEvents.First(e => e.Type == NormEventType.NORM_RX_CMD_NEW);
var actualCommand = new byte[command.Length];
Assert.Throws<TExceptionType>(() =>
actualEvent?.Node?.GetCommand(actualCommand, offset, length));
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
public static IEnumerable<object[]> GenerateShortLengthCommand()
{
var command = new List<object[]>();
var content = GenerateInfoContent();
var faker = new Faker();
var offset = 0;
var length = faker.Random.Int(content.Length / 2, content.Length - 1);
command.Add(new object[] { content, offset, length });
offset = faker.Random.Int(1, (content.Length - 1) / 2);
length = content.Length - offset;
command.Add(new object[] { content, offset, length });
offset = faker.Random.Int(1, (content.Length - 1) / 2);
length = faker.Random.Int(1, content.Length - offset);
command.Add(new object[] { content, offset, length });
return command;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateShortLengthCommand))]
public void ReceivesCommandThrowsExceptionWhenLengthLessThanCommand(string content, int offset, int length)
{
ReceivesCommandThrowsException<IOException>(content, offset, length);
}
public static IEnumerable<object[]> GenerateOutOfRangeReceiveCommand()
{
var command = new List<object[]>();
var content = GenerateTextContent();
var faker = new Faker();
var offset = faker.Random.Int(-content.Length, -1);
var length = content.Length;
command.Add(new object[] { content, offset, length });
offset = faker.Random.Int(content.Length, content.Length * 2);
length = content.Length;
command.Add(new object[] { content, offset, length });
offset = 0;
length = faker.Random.Int(content.Length + 1, content.Length * 2);
command.Add(new object[] { content, offset, length });
length = -1;
command.Add(new object[] { content, offset, length });
length = 0;
command.Add(new object[] { content, offset, length });
offset = content.Length - 1;
length = content.Length;
command.Add(new object[] { content, offset, length });
return command;
}
[SkippableTheory(typeof(IOException))]
[MemberData(nameof(GenerateOutOfRangeReceiveCommand))]
public void ReceivesCommandThrowsExceptionWhenOutOfRange(string content, int offset, int length)
{
ReceivesCommandThrowsException<ArgumentOutOfRangeException>(content, offset, length);
}
[SkippableFact(typeof(IOException))]
public void CancelsCommand()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
_normSession.CancelCommand();
var expectedEventTypes = new List<NormEventType>();
var actualEventTypes = GetEvents().Select(e => e.Type).ToList();
Assert.Equal(expectedEventTypes, actualEventTypes);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[Fact]
public void SetsRxCacheLimit()
{
var countMax = 5;
_normSession.SetRxCacheLimit(countMax);
}
[SkippableFact(typeof(IOException))]
public void SetsRxSocketBuffer()
{
StartSender();
var bufferSize = 8;
_normSession.SetRxSocketBuffer(bufferSize);
}
[Fact]
public void SetsSilentReceiver()
{
var silent = true;
_normSession.SetSilentReceiver(silent, -1);
}
[Fact]
public void SetsDefaultUnicastNack()
{
var enable = true;
_normSession.SetDefaultUnicastNack(enable);
}
[SkippableFact(typeof(IOException))]
public void SetsUnicastNack()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
actualNode.SetUnicastNack(true);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[Fact]
public void SetsDefaultSyncPolicy_NORM_SYNC_CURRENT()
{
var syncPolicy = NormSyncPolicy.NORM_SYNC_CURRENT;
_normSession.SetDefaultSyncPolicy(syncPolicy);
}
[Fact]
public void SetsDefaultSyncPolicy_NORM_SYNC_STREAM()
{
var syncPolicy = NormSyncPolicy.NORM_SYNC_STREAM;
_normSession.SetDefaultSyncPolicy(syncPolicy);
}
[Fact]
public void SetsDefaultSyncPolicy_NORM_SYNC_ALL()
{
var syncPolicy = NormSyncPolicy.NORM_SYNC_ALL;
_normSession.SetDefaultSyncPolicy(syncPolicy);
}
[Fact]
public void SetsDefaultNackingMode_NORM_NACK_NONE()
{
var nackingMode = NormNackingMode.NORM_NACK_NONE;
_normSession.SetDefaultNackingMode(nackingMode);
}
[Fact]
public void SetsDefaultNackingMode_NORM_NACK_INFO_ONLY()
{
var nackingMode = NormNackingMode.NORM_NACK_INFO_ONLY;
_normSession.SetDefaultNackingMode(nackingMode);
}
[Fact]
public void SetsDefaultNackingMode_NORM_NACK_NORMAL()
{
var nackingMode = NormNackingMode.NORM_NACK_NORMAL;
_normSession.SetDefaultNackingMode(nackingMode);
}
[SkippableFact(typeof(IOException))]
public void SetsNackingMode()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
actualNode.SetNackingMode(NormNackingMode.NORM_NACK_NONE);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[Fact]
public void SetsDefaultRepairBoundary_NORM_BOUNDARY_BLOCK()
{
var repairBoundary = NormRepairBoundary.NORM_BOUNDARY_BLOCK;
_normSession.SetDefaultRepairBoundary(repairBoundary);
}
[Fact]
public void SetsDefaultRepairBoundary_NORM_BOUNDARY_OBJECT()
{
var repairBoundary = NormRepairBoundary.NORM_BOUNDARY_OBJECT;
_normSession.SetDefaultRepairBoundary(repairBoundary);
}
[SkippableFact(typeof(IOException))]
public void SetsRepairBoundary()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
actualNode.SetRepairBoundary(NormRepairBoundary.NORM_BOUNDARY_OBJECT);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[Fact]
public void SetsDefaultRxRobustFactor()
{
var rxRobustFactor = 2;
_normSession.SetDefaultRxRobustFactor(rxRobustFactor);
}
[SkippableFact(typeof(IOException))]
public void SetsRxRobustFactor()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
actualNode.SetRxRobustFactor(2);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void GetsCommand()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
var actualCommand = new byte[expectedCommand.Length];
var actualLength = actualEvent?.Node?.GetCommand(actualCommand, 0, expectedCommand.Length);
Assert.Equal(expectedCommand.Length, actualLength);
Assert.Equal(expectedCommand, actualCommand);
var actualContent = Encoding.ASCII.GetString(actualCommand);
Assert.Equal(expectedContent, actualContent);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void FreesBuffers()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
actualNode.FreeBuffers();
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void RetainsAndReleases()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var expectedContent = GenerateTextContent();
byte[] expectedCommand = Encoding.ASCII.GetBytes(expectedContent);
try
{
_normSession.SendCommand(expectedCommand, 0, expectedCommand.Length, false);
var normEventType = NormEventType.NORM_RX_CMD_NEW;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualNode = actualEvent.Node;
Assert.NotNull(actualNode);
actualNode.Retain();
actualNode.Release();
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void GetsObjectType_DATA()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
Assert.Equal(NormObjectType.NORM_OBJECT_DATA, normData.Type);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void GetsObjectType_FILE()
{
StartSender();
var fileContent = GenerateTextContent();
var fileName = Guid.NewGuid().ToString();
var filePath = Path.Combine(_testPath, fileName);
File.WriteAllText(filePath, fileContent);
try
{
var normFile = _normSession.FileEnqueue(filePath);
Assert.Equal(NormObjectType.NORM_OBJECT_FILE, normFile.Type);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void GetsObjectType_STREAM()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
Assert.Equal(NormObjectType.NORM_OBJECT_STREAM, normStream.Type);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void GetsObjectSize()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
var expectedSize = Encoding.ASCII.GetByteCount(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
Assert.Equal(expectedSize, normData.Size);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void SetsObjectNackingMode_NORM_NACK_NONE()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
normData.SetNackingMode(NormNackingMode.NORM_NACK_NONE);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void SetsObjectNackingMode_NORM_NACK_INFO_ONLY()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
normData.SetNackingMode(NormNackingMode.NORM_NACK_INFO_ONLY);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void SetsObjectNackingMode_NORM_NACK_NORMAL()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
normData.SetNackingMode(NormNackingMode.NORM_NACK_NORMAL);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void GetsBytesPending()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
var expectedBytesPending = (long)0;
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
WaitForEvents();
Assert.Equal(expectedBytesPending, normData.GetBytesPending());
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void CancelsObject()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
normData.Cancel();
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void RetainsObject()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
normData.Retain();
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void ReleasesObject()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
normData.Retain();
normData.Release();
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void GetsSenderThrowsException()
{
StartSender();
var expectedContent = GenerateTextContent();
byte[] expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
Assert.Throws<IOException>(() => normData.Sender);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void GetsSender()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
var normEventType = NormEventType.NORM_RX_OBJECT_COMPLETED;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualObject = actualEvent.Object;
Assert.NotEqual(NormNode.NORM_NODE_INVALID, actualObject!.Sender);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void GetsObjectHashCode()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
var normData = _normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
var normEventType = NormEventType.NORM_RX_OBJECT_COMPLETED;
var actualEvents = GetEvents();
Assert.Contains(normEventType, actualEvents.Select(e => e.Type));
var actualEvent = actualEvents.First(e => e.Type == normEventType);
var actualObject = actualEvent.Object;
var expectedHashCode = (int)actualObject!.Handle;
var actualHashCode = actualObject.GetHashCode();
Assert.Equal(expectedHashCode, actualHashCode);
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void ObjectsEqual()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var expectedContent = GenerateTextContent();
var expectedData = Encoding.ASCII.GetBytes(expectedContent);
using var dataBuffer = ByteBuffer.AllocateDirect(expectedData.Length);
dataBuffer.WriteArray(0, expectedData, 0, expectedData.Length);
try
{
_normSession.DataEnqueue(dataBuffer, 0, expectedData.Length);
var actualEvents = GetEvents();
var firstNormEventType = NormEventType.NORM_RX_OBJECT_NEW;
Assert.Contains(firstNormEventType, actualEvents.Select(e => e.Type));
var firstEvent = actualEvents.First(e => e.Type == firstNormEventType);
var firstObject = firstEvent.Object;
Assert.NotNull(firstObject);
var secondNormEventType = NormEventType.NORM_RX_OBJECT_COMPLETED;
Assert.Contains(secondNormEventType, actualEvents.Select(e => e.Type));
var secondEvent = actualEvents.First(e => e.Type == secondNormEventType);
var secondObject = secondEvent.Object;
Assert.NotNull(secondObject);
Assert.True(firstObject.Equals(secondObject));
}
catch (Exception)
{
throw;
}
finally
{
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamHasVacancy()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
Assert.True(normStream.HasVacancy);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamGetsReadOffset()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
var expectedReadOffset = 0;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
Assert.Equal(expectedReadOffset, normStream.ReadOffset);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamSeeksMsgStart()
{
_normSession.SetLoopback(true);
StartSender();
StartReceiver();
var folderName = Guid.NewGuid().ToString();
var cachePath = Path.Combine(_testPath, folderName);
Directory.CreateDirectory(cachePath);
_normInstance.SetCacheDirectory(cachePath);
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
var dataOffset = 0;
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
var expectedBytesWritten = data.Length;
normStream.Write(data, dataOffset, data.Length);
normStream.MarkEom();
normStream.Flush();
var normEvents = GetEvents();
AssertNormEvents(normEvents);
var expectedNormEventType = NormEventType.NORM_RX_OBJECT_UPDATED;
Assert.Contains(expectedNormEventType, normEvents.Select(e => e.Type));
var normObjectEvent = normEvents.First(e => e.Type == expectedNormEventType);
var receivedNormStream = Assert.IsType<NormStream>(normObjectEvent.Object);
Assert.True(receivedNormStream.SeekMsgStart());
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
StopReceiver();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamSetsPushEnable()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
normStream.SetPushEnable(true);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamSetsAutoFlush_FLUSH_NONE()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
normStream.SetAutoFlush(NormFlushMode.NORM_FLUSH_NONE);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamSetsAutoFlush_FLUSH_PASSIVE()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
normStream.SetAutoFlush(NormFlushMode.NORM_FLUSH_PASSIVE);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
[SkippableFact(typeof(IOException))]
public void NormStreamSetsAutoFlush_FLUSH_ACTIVE()
{
StartSender();
var fileContent = GenerateTextContent();
var data = Encoding.ASCII.GetBytes(fileContent);
NormStream? normStream = null;
try
{
var repairWindowSize = 1024 * 1024;
normStream = _normSession.StreamOpen(repairWindowSize);
normStream.SetAutoFlush(NormFlushMode.NORM_FLUSH_ACTIVE);
}
catch (Exception)
{
throw;
}
finally
{
normStream?.Close(true);
StopSender();
}
}
}
}