XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using XFESystem.Network;

namespace XFESystem.Network.Tests;

public sealed class DeadlineAndAcknowledgementTests
{
    static void Deliver(PacketFixture peer, E1000HardwareFixture hardware)
    {
        byte[] frame = new byte[2048]; int length;
        while ((length = peer.Receive(frame)) > 0) hardware.Receive(frame[..length]);
    }
    static (Ipv4Network Stack, E1000Device Device, E1000HardwareFixture Hardware, PacketFixture Peer, TestPlatform Clock) Wired()
    {
        var clock = new TestPlatform(); var hardware = new E1000HardwareFixture();
        var device = new E1000Device(hardware, clock, 40); var peer = new PacketFixture();
        hardware.OnTransmit = frame => { peer.Send(frame, long.MaxValue); Deliver(peer, hardware); };
        return (new Ipv4Network(device, clock, Ipv4Configuration.QemuUserNat), device, hardware, peer, clock);
    }
    [Fact]
    public void RealDriverHungArpTransmitCannotReplaceTheTcpOpenDeadline()
    {
        var state = Wired(); using var hardware = state.Hardware; using var device = state.Device;
        hardware.CompleteTx = false;
        Assert.Throws<IOException>(() => state.Stack.OpenTcpUntil("1.2.3.4", 443, 40, 40));
        Assert.Equal(40, state.Clock.Milliseconds);
    }
    [Fact]
    public void RealDriverHungReceiveAckCannotExceedReadTimeout()
    {
        var state = Wired(); using var hardware = state.Hardware; using var device = state.Device;
        Stream stream = state.Stack.OpenTcp("1.2.3.4", 443, 1000); stream.ReadTimeout = stream.WriteTimeout = 40;
        state.Peer.QueueData("actual received bytes"); Deliver(state.Peer, hardware); hardware.CompleteTx = false;
        Assert.Throws<IOException>(() => stream.Read(new byte[100])); Assert.Equal(40, state.Clock.Milliseconds);
        long closing = state.Clock.Milliseconds; stream.Dispose();
        Assert.InRange(state.Clock.Milliseconds - closing, 0, 40);
    }
    [Fact]
    public void RealDriverHungWriteAndCloseEachKeepTheirSingleConfiguredBudget()
    {
        var state = Wired(); using var hardware = state.Hardware; using var device = state.Device;
        Stream stream = state.Stack.OpenTcp("1.2.3.4", 443, 1000); stream.WriteTimeout = 35; stream.ReadTimeout = 40;
        hardware.CompleteTx = false;
        Assert.Throws<IOException>(() => stream.Write("not completed"u8)); Assert.Equal(35, state.Clock.Milliseconds);
        stream.Dispose(); Assert.Equal(70, state.Clock.Milliseconds);
        stream.Dispose(); Assert.Equal(70, state.Clock.Milliseconds);
    }
    [Theory]
    [InlineData(true, false)]
    [InlineData(false, true)]
    public void ResetAndLinkInitializationUseTheAbsoluteOpenDeadline(bool resetStuck, bool linkDown)
    {
        using var hardware = new E1000HardwareFixture { ResetStuck = resetStuck, LinkUp = !linkDown };
        var clock = new TestPlatform(); Assert.Throws<IOException>(() => new E1000Device(hardware, clock, 25));
        Assert.Equal(25, clock.Milliseconds); Assert.Equal(0, hardware.OutstandingDma);
    }
    [Fact]
    public void PciDiscoveryUsesTheDeadlineBeforeWalkingEveryBus()
    {
        using var hardware = new E1000HardwareFixture { Found = false }; var clock = new TestPlatform();
        hardware.PciAccess = () => clock.Wait(1);
        Assert.Throws<IOException>(() => new E1000Device(hardware, clock, 5));
        Assert.Equal(5, clock.Milliseconds); Assert.Equal(0, hardware.OutstandingDma);
    }
    [Fact]
    public void DeviceInitializationTimeDoesNotRestartTheConnectionBudget()
    {
        var state = Wired(); using var hardware = state.Hardware; using var device = state.Device;
        state.Clock.Wait(30); hardware.CompleteTx = false;
        Assert.Throws<IOException>(() => state.Stack.OpenTcpUntil("1.2.3.4", 443, 40, 40));
        Assert.Equal(40, state.Clock.Milliseconds);
    }
    [Fact]
    public void OutOfWindowSameTupleAckCannotCompleteAnOutstandingWrite()
    {
        var peer = new PacketFixture { AcknowledgeData = false }; var clock = new TestPlatform();
        var stack = new Ipv4Network(peer, clock, Ipv4Configuration.QemuUserNat);
        using Stream stream = stack.OpenTcp("1.2.3.4", 443); stream.WriteTimeout = 40;
        peer.DataReceived = () => peer.QueueAcknowledgementAt(peer.PeerNext + 70000, 65535);
        Assert.Throws<IOException>(() => stream.Write("must wait for valid sequence"u8));
        Assert.Equal(40, clock.Milliseconds);
    }
    [Fact]
    public void OutOfWindowZeroWindowAckCannotBlockTheNextWrite()
    {
        var peer = new PacketFixture(); var clock = new TestPlatform();
        var stack = new Ipv4Network(peer, clock, Ipv4Configuration.QemuUserNat);
        using Stream stream = stack.OpenTcp("1.2.3.4", 443); stream.ReadTimeout = 5; stream.WriteTimeout = 40;
        peer.QueueAcknowledgementAt(peer.PeerNext + 70000, 0);
        Assert.Throws<IOException>(() => stream.Read(new byte[1]));
        stream.Write("valid window remains open"u8); Assert.Equal(1, peer.DataSends); Assert.Equal(5, clock.Milliseconds);
    }
    [Fact]
    public void OlderAcceptableSegmentCannotUndoALaterWindowUpdate()
    {
        var peer = new PacketFixture(); var clock = new TestPlatform();
        var stack = new Ipv4Network(peer, clock, Ipv4Configuration.QemuUserNat);
        using Stream stream = stack.OpenTcp("1.2.3.4", 443); stream.ReadTimeout = 5; stream.WriteTimeout = 40;
        peer.QueueAcknowledgementAt(peer.PeerNext + 10, 65535);
        peer.QueueAcknowledgementAt(peer.PeerNext, 0);
        Assert.Throws<IOException>(() => stream.Read(new byte[1]));
        stream.Write("ordered window update"u8); Assert.Equal(1, peer.DataSends); Assert.Equal(5, clock.Milliseconds);
    }
}