Livt packages
Livt.Net
Version 1.4.1
Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.
Published files (163)
- ethernet
- services
- tftp
- ArpCompositionChecks.lvt
- ArpPacketParserTest.lvt
- ArpResponderTest.lvt
- ChecksumApiTest.lvt
- ChecksumWordSumTest.lvt
- CompactPacketFieldsTest.lvt
- CountingPacketData.lvt
- EthernetFrameBuilderTest.lvt
- EthernetFrameParserTest.lvt
- EthernetLiteDeviceFixture.lvt
- EthernetLiteDriverTest.lvt
- EthernetLiteReceiveWindowTest.lvt
- EthernetLiteResetScenario.lvt
- EthernetLiteResetTest.lvt
- FaultingFrameData.lvt
- FaultingPacketData.lvt
- FrameCapacityTest.lvt
- FrameCompositionTest.lvt
- FrameForwarder.lvt
- FrameLinkTest.lvt
- FrameMii10Link.lvt
- FrameMiiLink.lvt
- FrameMiiPins.lvt
- GenericPacketTest.lvt
- IcmpCapacityChecks.lvt
- IcmpEchoResponderTest.lvt
- IcmpStorageBackendTest.lvt
- InternetChecksumTest.lvt
- Ipv4HeaderBuilderTest.lvt
- Ipv4HeaderChecksumTest.lvt
- Ipv4PacketFieldsTest.lvt
- Ipv4PacketParserTest.lvt
- MiiFrame10Test.lvt
- MiiFrameTest.lvt
- PacketConvenienceTest.lvt
- PacketDataTest.lvt
- PacketMetadataStub.lvt
- PacketMetadataTest.lvt
- PacketParserFailureTest.lvt
- PacketStorageParityTest.lvt
- RamIpv4PacketParserTest.lvt
- ReceiveContractChecks.lvt
- ScheduledWordSumTest.lvt
- SynAckCompositionChecks.lvt
- TcpChecksumTest.lvt
- TcpConnectionRecognizerTest.lvt
- TcpHeaderParserTest.lvt
- TcpMultiSessionArrayStorageTest.lvt
- TcpMultiSessionAutoStorageTest.lvt
- TcpMultiSessionDistributedStorageTest.lvt
- TcpMultiSessionMixedStorageTest.lvt
- TcpMultiSessionStorageChecks.lvt
- TcpMultiSessionTest.lvt
- TcpRamPacketTest.lvt
- TcpRetryTimerTest.lvt
- TcpSegmentBuilderTest.lvt
- TcpSegmentTest.lvt
- TcpStreamServerArrayStorageTest.lvt
- TcpStreamServerAutoStorageTest.lvt
- TcpStreamServerDistributedStorageTest.lvt
- TcpStreamServerMixedStorageTest.lvt
- TcpStreamServerStorageChecks.lvt
- TcpStreamServerTest.lvt
- TelnetSessionTest.lvt
- TransmitContractChecks.lvt
- UdpPacketTest.lvt
tests/FrameLinkTest.lvt
namespace Livt.Net.Tests
using Livt.Net
/**
* Checks RX/TX ownership, backpressure, cancellation and coordinated reset through capability-bound consumers.
*/
@Test
component FrameLinkTest
{
rx: TestFrameReceiver<64>
rxChecks: ReceiveContractChecks<TestFrameReceiver<64>>
region: PacketRegion<TestFrameReceiver<64>>
data: ArrayPacketData<65>
tx: TestFrameTransmitter<ArrayPacketData<65>, 64>
checks: TransmitContractChecks<TestFrameTransmitter<ArrayPacketData<65>, 64>>
faulty: FaultingFrameData
fixedTx: TestFrameTransmitter<FaultingFrameData, 64, false>
fixedChecks: TransmitContractChecks<TestFrameTransmitter<FaultingFrameData, 64, false>>
forwardRx: TestFrameReceiver<64>
forwardTx: TestFrameTransmitter<TestFrameReceiver<64>, 64>
service: FrameForwarder<TestFrameReceiver<64>, TestFrameTransmitter<TestFrameReceiver<64>, 64>>
/**
* Wires simulated links, capability-bound assertions and a forwarder in the same clock context.
*/
new()
{
rx = new TestFrameReceiver<64>()
rxChecks = new ReceiveContractChecks<TestFrameReceiver<64>>(rx)
region = new PacketRegion<TestFrameReceiver<64>>(rx)
data = new ArrayPacketData<65>()
tx = new TestFrameTransmitter<ArrayPacketData<65>, 64>(data)
checks = new TransmitContractChecks<TestFrameTransmitter<ArrayPacketData<65>, 64>>(tx)
faulty = new FaultingFrameData()
fixedTx = new TestFrameTransmitter<FaultingFrameData, 64, false>(faulty)
fixedChecks = new TransmitContractChecks<TestFrameTransmitter<FaultingFrameData, 64, false>>(fixedTx)
forwardRx = new TestFrameReceiver<64>()
forwardTx = new TestFrameTransmitter<TestFrameReceiver<64>, 64>(forwardRx)
service = new FrameForwarder<TestFrameReceiver<64>, TestFrameTransmitter<TestFrameReceiver<64>, 64>>(forwardRx, forwardTx)
}
/**
* Quiesces the test transmitters, closes the view and clears owned source/receiver state.
*/
fn Clean()
{
tx.BeginReset()
tx.CompleteReset()
tx.SetReady(true)
fixedTx.BeginReset()
fixedTx.CompleteReset()
fixedTx.SetReady(true)
region.TryClose()
rx.BeginReset()
rx.CompleteReset()
if (data.IsReady()) {
data.TryRelease()
}
else {
data.TryClear()
}
faulty.Configure(60, -1)
}
/**
* Publishes the requested initialized prefix using deterministic high-bit octets.
*/
fn Prepare(length: int)
{
if (data.IsReady()) {
data.TryRelease()
}
else {
data.TryClear()
}
for (var i = 0; i < length; i++) {
assert data.TryWrite(i, (128 + i) as byte) == PacketDataResult.Success
}
assert data.TryPublish() == PacketDataResult.Success
}
/**
* Checks acquisition, valid-prefix reads and the distinction between known and unknown wire length.
*/
@Test
fn ReceiveOwnershipAndLengthKnowledge()
{
this.Clean()
var value: byte = 0x00
rxChecks.Empty()
assert rx.GetReceiveCapacity() == 64
assert rx.TryAcquire() == FrameLinkResult.NotReady
assert rx.TryRead(0, value) == PacketDataResult.NotReady
assert rx.TryRelease() == FrameLinkResult.Invalid
assert rx.InjectByte(1, 0xFF) == FrameLinkResult.Invalid
assert rx.InjectByte(0, 0x80) == FrameLinkResult.Success
assert rx.InjectByte(1, 0xFF) == FrameLinkResult.Success
assert rx.Publish(true, 1) == FrameLinkResult.Invalid
assert rx.Publish(false, 60) == FrameLinkResult.Invalid
assert rx.Publish(true, 60) == FrameLinkResult.Success
assert rx.HasReceiveFrame() == true
assert rx.IsReady() == false
assert rx.GetAvailableLength() == 0
assert rx.TryRead(0, value) == PacketDataResult.NotReady
assert rx.TryRelease() == FrameLinkResult.Invalid
assert rx.TryAcquire() == FrameLinkResult.Success
assert rx.TryAcquire() == FrameLinkResult.Busy
rxChecks.Acquired(2, true, 60)
assert rx.GetAvailableLength() == 2
assert rx.HasKnownWireLength() == true
assert rx.GetWireLength() == 60
assert rx.InjectByte(0, 0x00) == FrameLinkResult.Busy
assert rx.Publish(false, 0) == FrameLinkResult.Busy
assert rx.FailReceive() == FrameLinkResult.Busy
assert region.TryOpen(1, 1) == PacketDataResult.Success
assert region.TryRead(0, value) == PacketDataResult.Success
assert value == 0xFF
assert rx.TryRead(2, value) == PacketDataResult.Invalid
assert rx.TryRead(-1, value) == PacketDataResult.Invalid
assert region.TryClose() == PacketDataResult.Success
assert rx.TryRelease() == FrameLinkResult.Success
assert rx.HasKnownWireLength() == false
assert rx.TryRead(0, value) == PacketDataResult.NotReady
assert rx.InjectByte(0, 0x42) == FrameLinkResult.Success
assert rx.Publish(false, 0) == FrameLinkResult.Success
assert rx.TryAcquire() == FrameLinkResult.Success
assert rx.HasKnownWireLength() == false
rxChecks.Acquired(1, false, 0)
assert rx.GetAvailableLength() == 1
assert rx.TryRead(0, value) == PacketDataResult.Success
assert value == 0x42
assert rx.TryRead(1, value) == PacketDataResult.Invalid
assert rx.TryRelease() == FrameLinkResult.Success
// A known empty capture must be distinguishable from unknown wire length.
assert rx.Publish(true, 0) == FrameLinkResult.Success
assert rx.TryAcquire() == FrameLinkResult.Success
assert rx.HasKnownWireLength() == true
assert rx.GetWireLength() == 0
assert rx.GetAvailableLength() == 0
assert rx.TryRelease() == FrameLinkResult.Success
}
/**
* Checks RX error acknowledgment and that coordinated reset discards a partial capture.
*/
@Test
fn ReceiveErrorsAndResetDiscardPartialData()
{
this.Clean()
var value: byte = 0x00
assert rx.InjectByte(0, 0xEE) == FrameLinkResult.Success
assert rx.FailReceive() == FrameLinkResult.Success
assert rx.HasReceiveError() == true
assert rx.HasReceiveFrame() == false
assert rx.TryAcquire() == FrameLinkResult.DeviceFailure
assert rx.TryAcquire() == FrameLinkResult.DeviceFailure
assert rx.Publish(false, 0) == FrameLinkResult.DeviceFailure
assert rx.TryAcknowledgeReceiveError() == FrameLinkResult.Success
assert rx.TryAcknowledgeReceiveError() == FrameLinkResult.NotReady
assert rx.InjectByte(1, 0xAA) == FrameLinkResult.Invalid
assert rx.InjectByte(0, 0x80) == FrameLinkResult.Success
assert rx.Publish(true, 60) == FrameLinkResult.Success
assert rx.TryAcquire() == FrameLinkResult.Success
rx.BeginReset()
assert rx.IsReady() == false
assert rx.TryAcquire() == FrameLinkResult.NotReady
assert rx.TryRelease() == FrameLinkResult.NotReady
assert rx.InjectByte(0, 0x00) == FrameLinkResult.NotReady
rx.CompleteReset()
assert rx.HasKnownWireLength() == false
assert rx.TryAcquire() == FrameLinkResult.NotReady
assert rx.TryRead(0, value) == PacketDataResult.NotReady
assert rx.InjectByte(1, 0xEE) == FrameLinkResult.Invalid
assert rx.InjectByte(0, 0x11) == FrameLinkResult.Success
assert rx.Publish(false, 0) == FrameLinkResult.Success
assert rx.TryAcquire() == FrameLinkResult.Success
assert rx.TryRead(0, value) == PacketDataResult.Success
assert value == 0x11
assert rx.TryRelease() == FrameLinkResult.Success
}
/**
* Checks admission errors before a transmitter borrows any source data.
*/
@Test
fn RejectsUnpreparedEmptyAndUnsupportedSources()
{
this.Clean()
assert tx.GetMinimumFrameLength() == 60
assert tx.GetMaximumFrameLength() == 64
assert tx.TrySubmit() == FrameLinkResult.Invalid
assert data.TryWrite(0, 0x80) == PacketDataResult.Success
assert tx.TrySubmit() == FrameLinkResult.Invalid
assert tx.IsSourceBorrowed() == false
assert data.TryPublish() == PacketDataResult.Success
assert tx.TrySubmit() == FrameLinkResult.Unsupported
assert data.IsReady() == true
this.Prepare(0)
assert tx.TrySubmit() == FrameLinkResult.Invalid
this.Prepare(65)
assert tx.TrySubmit() == FrameLinkResult.Unsupported
assert tx.GetCapturedLength() == 0
this.Prepare(60)
tx.SetReady(false)
assert tx.TrySubmit() == FrameLinkResult.NotReady
assert tx.IsSourceBorrowed() == false
tx.SetReady(true)
tx.SetFailure(true)
assert tx.TrySubmit() == FrameLinkResult.DeviceFailure
assert tx.IsSourceBorrowed() == false
tx.SetFailure(false)
assert tx.TrySubmit() == FrameLinkResult.Accepted
checks.Pending()
assert tx.TryCancel() == FrameLinkResult.Accepted
tx.Advance()
checks.Completed(FrameTransmitOutcome.Cancelled)
assert data.TryRelease() == PacketDataResult.Success
}
/**
* Checks source retention under backpressure and explicit acknowledgment of the terminal result.
*/
@Test
fn HoldsSourceThroughBackpressureAndLatchedCompletion()
{
this.Clean()
this.Prepare(64)
var value: byte = 0x00
assert tx.TrySubmit() == FrameLinkResult.Accepted
checks.Pending()
assert tx.GetCapturedLength() == 0
assert data.TryWrite(0, 0x00) == PacketDataResult.Busy
tx.SetReady(false)
tx.Advance()
assert tx.GetCapturedLength() == 0
checks.Pending()
tx.SetReady(true)
for (var i = 0; i < 64; i++) {
tx.Advance()
}
assert tx.GetCapturedLength() == 64
// Reading the last byte does not yet publish a terminal result.
checks.Pending()
tx.Advance()
checks.Completed(FrameTransmitOutcome.Delivered)
for (var i = 0; i < 64; i++) {
assert tx.TryReadCaptured(i, value) == PacketDataResult.Success
assert value == (128 + i) as byte
}
assert tx.TryReadCaptured(64, value) == PacketDataResult.Invalid
assert tx.TryReadCaptured(-1, value) == PacketDataResult.Invalid
assert data.TryRelease() == PacketDataResult.Success
this.Prepare(60)
assert tx.TrySubmit() == FrameLinkResult.Accepted
assert tx.GetCapturedLength() == 0
for (var i = 0; i < 61; i++) {
tx.Advance()
}
checks.Completed(FrameTransmitOutcome.Delivered)
assert data.TryRelease() == PacketDataResult.Success
}
/**
* Checks that cancellation and device failure release the borrow only when reads stop.
*/
@Test
fn CancellationAndFailureReleaseOnlyAtTerminal()
{
this.Clean()
this.Prepare(60)
assert tx.SupportsCancellation() == true
assert tx.TryCancel() == FrameLinkResult.Invalid
assert tx.TrySubmit() == FrameLinkResult.Accepted
tx.Advance()
assert tx.TryCancel() == FrameLinkResult.Accepted
assert tx.TryCancel() == FrameLinkResult.Busy
checks.Pending()
tx.SetReady(false)
tx.Advance()
assert tx.GetCapturedLength() == 1
checks.Completed(FrameTransmitOutcome.Cancelled)
tx.SetReady(true)
assert tx.TrySubmit() == FrameLinkResult.Accepted
tx.Advance()
tx.SetFailure(true)
checks.Pending()
tx.Advance()
checks.Completed(FrameTransmitOutcome.DeviceFailure)
assert tx.TrySubmit() == FrameLinkResult.DeviceFailure
tx.SetFailure(false)
assert data.TryRelease() == PacketDataResult.Success
}
/**
* Checks unsupported cancellation and propagation of a source read failure.
*/
@Test
fn UnsupportedCancellationAndReadFailure()
{
this.Clean()
faulty.Configure(60, 2)
assert fixedTx.SupportsCancellation() == false
assert fixedTx.TrySubmit() == FrameLinkResult.Accepted
assert faulty.GetReadCount() == 0
assert fixedTx.TryCancel() == FrameLinkResult.Unsupported
fixedChecks.Pending()
fixedTx.Advance()
fixedTx.Advance()
assert fixedTx.GetCapturedLength() == 2
fixedTx.Advance()
fixedChecks.Completed(FrameTransmitOutcome.DeviceFailure)
assert faulty.GetReadCount() == 3
fixedTx.Advance()
assert faulty.GetReadCount() == 3
faulty.Configure(60, -1)
assert fixedTx.TrySubmit() == FrameLinkResult.Accepted
for (var i = 0; i < 61; i++) {
fixedTx.Advance()
}
fixedChecks.Completed(FrameTransmitOutcome.Delivered)
assert faulty.GetReadCount() == 60
}
/**
* Checks that beginning reset retains ownership until reset completion guarantees quiescence.
*/
@Test
fn ResetBarrierKeepsBorrowUntilQuiescent()
{
this.Clean()
this.Prepare(60)
var outcome: FrameTransmitOutcome = FrameTransmitOutcome.Delivered
assert tx.TrySubmit() == FrameLinkResult.Accepted
tx.Advance()
tx.BeginReset()
assert tx.IsSourceBorrowed() == true
assert tx.TrySubmit() == FrameLinkResult.NotReady
assert tx.TryCancel() == FrameLinkResult.NotReady
assert tx.TryGetCompletion(outcome) == FrameLinkResult.NotReady
tx.Advance()
assert tx.GetCapturedLength() == 1
tx.CompleteReset()
assert tx.IsSourceBorrowed() == false
assert tx.GetCapturedLength() == 0
assert tx.TryGetCompletion(outcome) == FrameLinkResult.NotReady
assert tx.TrySubmit() == FrameLinkResult.NotReady
assert data.TryRelease() == PacketDataResult.Success
this.Prepare(60)
tx.SetReady(true)
assert tx.TrySubmit() == FrameLinkResult.Accepted
for (var i = 0; i < 61; i++) {
tx.Advance()
}
// Reset also discards a terminal result rather than replaying delivery.
tx.BeginReset()
tx.CompleteReset()
assert tx.TryGetCompletion(outcome) == FrameLinkResult.NotReady
assert data.TryRelease() == PacketDataResult.Success
}
/**
* Forwards a complete received frame without test-adapter controls in the service implementation.
*/
@Test
fn ServiceUsesOnlyReceiverAndTransmitterCapabilities()
{
var outcome: FrameTransmitOutcome = FrameTransmitOutcome.DeviceFailure
var value: byte = 0x00
assert service.TryStart() == FrameLinkResult.NotReady
for (var i = 0; i < 60; i++) {
assert forwardRx.InjectByte(i, (i + 128) as byte) == FrameLinkResult.Success
}
assert forwardRx.Publish(true, 60) == FrameLinkResult.Success
assert service.TryStart() == FrameLinkResult.Accepted
assert service.TryStart() == FrameLinkResult.Busy
assert service.TryFinish(outcome) == FrameLinkResult.NotReady
assert forwardRx.IsReady() == true
for (var i = 0; i < 61; i++) {
forwardTx.Advance()
}
assert service.TryFinish(outcome) == FrameLinkResult.Success
assert outcome == FrameTransmitOutcome.Delivered
assert forwardRx.IsReady() == false
assert forwardRx.HasReceiveFrame() == false
for (var i = 0; i < 60; i++) {
assert forwardTx.TryReadCaptured(i, value) == PacketDataResult.Success
assert value == (i + 128) as byte
}
assert service.TryFinish(outcome) == FrameLinkResult.NotReady
// Rejected submission releases the service's RX acquisition for reuse.
assert forwardRx.InjectByte(0, 0xFF) == FrameLinkResult.Success
assert forwardRx.Publish(true, 60) == FrameLinkResult.Success
assert service.TryStart() == FrameLinkResult.Invalid
assert forwardRx.HasReceiveFrame() == false
assert forwardTx.IsSourceBorrowed() == false
for (var i = 0; i < 60; i++) {
assert forwardRx.InjectByte(i, 0x00) == FrameLinkResult.Success
}
assert forwardRx.Publish(true, 60) == FrameLinkResult.Success
forwardTx.SetReady(false)
assert service.TryStart() == FrameLinkResult.NotReady
assert forwardRx.HasReceiveFrame() == false
forwardTx.SetReady(true)
}
}