Livt packages
Livt.Net
Version 1.4.1
Ethernet, IPv4, TCP, UDP, ARP, TFTP, and Telnet networking components for Livt hardware.
Published files (163)
tests/services/NetworkServiceTest.lvt
namespace Livt.Net.Tests
using Livt.Net
/**
* Exercises successive protocol requests and held response ownership through a test link.
*/
@Test
component NetworkServiceTest
{
// Shared request parsers; source remains owned by this fixture.
ethernet: EthernetFrameParser<TestFrameReceiver<128>>
ipv4: Ipv4PacketParser<EthernetFrameParser<TestFrameReceiver<128>>>
receiver: TestFrameReceiver<128>
service: NetworkService<TestFrameReceiver<128>>
transmitter: TestFrameTransmitter<NetworkService<TestFrameReceiver<128>>>
endpoint: FrameService<TestFrameReceiver<128>, NetworkService<TestFrameReceiver<128>>, TestFrameTransmitter<NetworkService<TestFrameReceiver<128>>>>
/**
* Builds the fixed link, common service and lifecycle coordinator.
*/
new()
{
this.receiver = new TestFrameReceiver<128>()
var mac: byte[6] = [0x00,0x00,0x5E,0x00,0xFA,0xCE]
var ip: byte[4] = [10,0,0,1]
this.ethernet = new EthernetFrameParser<TestFrameReceiver<128>>(this.receiver)
this.ipv4 = new Ipv4PacketParser<EthernetFrameParser<TestFrameReceiver<128>>>(this.ethernet)
this.service = new NetworkService<TestFrameReceiver<128>>(this.receiver, this.ethernet, this.ipv4, mac, ip)
this.transmitter = new TestFrameTransmitter<NetworkService<TestFrameReceiver<128>>>(this.service)
this.endpoint = new FrameService<TestFrameReceiver<128>, NetworkService<TestFrameReceiver<128>>, TestFrameTransmitter<NetworkService<TestFrameReceiver<128>>>>(this.receiver, this.service, this.transmitter)
}
/**
* Publishes a fresh initialized frame independently of response storage.
*/
fn Inject(frame: byte[60])
{
for (var i = 0; i < 60; i++) {
assert this.receiver.InjectByte(i, frame[i]) == FrameLinkResult.Success
}
assert this.receiver.Publish(false, 0) == FrameLinkResult.Success
}
/**
* Checks every emitted byte and retained completion, then permits the next request.
*/
fn Complete(expected: byte[60])
{
for (var i = 0; i <= 60; i++) {
this.transmitter.Advance()
}
assert this.endpoint.Poll() == FrameServiceProgress.Completed
assert !this.service.IsReady()
assert !this.transmitter.IsSourceBorrowed()
var value: byte = 0xEE
for (var i = 0; i < 60; i++) {
assert this.transmitter.TryReadCaptured(i, value) == PacketDataResult.Success
assert value == expected[i]
}
var outcome = FrameTransmitOutcome.DeviceFailure
assert this.endpoint.TryGetCompletion(outcome) == FrameLinkResult.Success
assert outcome == FrameTransmitOutcome.Delivered
assert this.endpoint.Poll() == FrameServiceProgress.Completed
assert this.endpoint.TryGetCompletion(outcome) == FrameLinkResult.Success
assert outcome == FrameTransmitOutcome.Delivered
assert this.endpoint.TryAcknowledgeCompletion() == FrameLinkResult.Success
assert this.endpoint.TryGetCompletion(outcome) == FrameLinkResult.NotReady
}
/**
* Covers ARP/ICMP byte equivalence, admission stalls, busy graphs and terminal cleanup.
*/
@Test
fn HandlesSuccessiveRequestsWithoutOverwritingHeldResponses()
{
assert this.endpoint.Poll() == FrameServiceProgress.Idle
this.transmitter.SetReady(false)
this.Inject(ServicePackets.ARP)
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert !this.receiver.HasReceiveFrame()
assert this.service.GetResponseProtocol() == NetworkProtocol.Arp
assert this.service.TryHandle() == ServiceResult.Busy
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert !this.transmitter.IsSourceBorrowed()
assert this.service.IsReady()
this.Inject(ServicePackets.ICMP)
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert this.receiver.HasReceiveFrame()
assert !this.receiver.IsReady()
assert this.service.GetResponseProtocol() == NetworkProtocol.Arp
this.transmitter.SetReady(true)
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert this.transmitter.IsSourceBorrowed()
assert this.service.TryHandle() == ServiceResult.Busy
this.Complete(ServicePackets.ARP_REPLY)
assert this.receiver.HasReceiveFrame()
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert !this.receiver.HasReceiveFrame()
assert this.service.GetResponseProtocol() == NetworkProtocol.Icmp
assert this.endpoint.Poll() == FrameServiceProgress.Pending
this.Complete(ServicePackets.ICMP_REPLY)
var unknown: byte[60] = ServicePackets.ARP
unknown[12] = 0x88
unknown[13] = 0xB5
this.Inject(unknown)
assert this.endpoint.Poll() == FrameServiceProgress.Ignored
assert !this.service.IsReady()
var value: byte = 0xEE
assert this.service.TryRead(0, value) == PacketDataResult.NotReady
assert value == 0x00
assert this.receiver.InjectByte(0, 0x00) == FrameLinkResult.Success
assert this.receiver.Publish(false, 0) == FrameLinkResult.Success
assert this.endpoint.Poll() == FrameServiceProgress.Rejected
assert !this.receiver.HasReceiveFrame()
// A rejected admission cleans up the response without a TX borrow.
this.Inject(ServicePackets.ARP)
assert this.endpoint.Poll() == FrameServiceProgress.Pending
this.transmitter.SetFailure(true)
assert this.endpoint.Poll() == FrameServiceProgress.Completed
assert !this.service.IsReady()
var outcome = FrameTransmitOutcome.Delivered
assert this.endpoint.TryGetCompletion(outcome) == FrameLinkResult.Success
assert outcome == FrameTransmitOutcome.DeviceFailure
assert this.endpoint.TryAcknowledgeCompletion() == FrameLinkResult.Success
this.transmitter.SetFailure(false)
// Cancellation acceptance never releases the graph before terminal quiescence.
this.Inject(ServicePackets.ICMP)
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert this.endpoint.Poll() == FrameServiceProgress.Pending
assert this.endpoint.TryCancel() == FrameLinkResult.Accepted
assert this.service.IsReady()
assert this.endpoint.Poll() == FrameServiceProgress.Pending
this.transmitter.Advance()
assert this.endpoint.Poll() == FrameServiceProgress.Completed
assert !this.service.IsReady()
assert this.endpoint.TryGetCompletion(outcome) == FrameLinkResult.Success
assert outcome == FrameTransmitOutcome.Cancelled
assert this.endpoint.TryAcknowledgeCompletion() == FrameLinkResult.Success
}
}