using System.Net.Sockets; using System.Net; using System.Text; using System.IO; namespace Tests.WeighingTests { public abstract class MockScale : IDisposable { protected readonly TcpListener Server; public int IdentNr { get; set; } = 0; public int Weight { get; set; } = 0; public string? Error { get; set; } = null; protected MockScale(int port) { Server = new TcpListener(IPAddress.Loopback, port); Server.Start(4); } public void Dispose() { Server.Dispose(); GC.SuppressFinalize(this); } } public class CommandMockScale : MockScale { private readonly Func Handler; private readonly Thread ServerThread; private bool IsRunning = true; public CommandMockScale(int port, Func handler) : base(port) { Handler = handler; ServerThread = new Thread(new ParameterizedThreadStart(Serve)); ServerThread.Start(); } private async void Serve(object? parameters) { byte[] buffer = new byte[16]; while (IsRunning) { try { using var client = await Server.AcceptTcpClientAsync(); if (client == null) continue; using var stream = client.GetStream(); while (true) { int read = await stream.ReadAsync(buffer); var (res, inc) = Handler(Encoding.ASCII.GetString(buffer, 0, read), Weight, Error, IdentNr + 1); if (inc) IdentNr++; await stream.WriteAsync(Encoding.ASCII.GetBytes(res)); } } catch (Exception) { // ignore } } } public new void Dispose() { IsRunning = false; ServerThread.Interrupt(); ServerThread.Join(); base.Dispose(); } } public class EventMockScale : MockScale { private readonly Func Handler; private readonly Thread ServerThread; private TcpClient? Client; private bool IsRunning = true; public EventMockScale(int port, Func handler) : base(port) { Handler = handler; ServerThread = new Thread(new ParameterizedThreadStart(Serve)); ServerThread.Start(); } private async void Serve(object? parameters) { while (IsRunning) { try { Client = await Server.AcceptTcpClientAsync(); } catch (Exception) { // ignore } } } public async Task Weigh(int weight) { Weight = weight; await Weigh(); } public async Task Weigh() { var (res, inc) = Handler(Weight, Error, IdentNr + 1); if (inc) IdentNr++; await Client!.GetStream().WriteAsync(Encoding.ASCII.GetBytes(res)); } public new void Dispose() { Client?.Dispose(); IsRunning = false; ServerThread.Interrupt(); ServerThread.Join(); base.Dispose(); } } }