From 8f74ad79c07eb26a77cb9983d4b737014004463a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6llner?= Date: Mon, 20 Apr 2020 21:22:12 +0200 Subject: [PATCH] testsuite now using full loopback IP address range to avoid conflicts with existing/stale TCP ports --- Capnp.Net.Runtime.Tests/TcpRpc.cs | 61 +++---- .../TcpRpcAdvancedStuff.cs | 51 ++++-- Capnp.Net.Runtime.Tests/TcpRpcInterop.cs | 171 ++++++++++-------- Capnp.Net.Runtime.Tests/TcpRpcStress.cs | 59 +++--- Capnp.Net.Runtime.Tests/Util/TcpManager.cs | 32 ++++ Capnp.Net.Runtime.Tests/Util/TestBase.cs | 51 ++---- 6 files changed, 222 insertions(+), 203 deletions(-) create mode 100644 Capnp.Net.Runtime.Tests/Util/TcpManager.cs diff --git a/Capnp.Net.Runtime.Tests/TcpRpc.cs b/Capnp.Net.Runtime.Tests/TcpRpc.cs index 2abdc4e..f419f33 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpc.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpc.cs @@ -10,6 +10,7 @@ using System.Diagnostics; using System.Threading.Tasks.Dataflow; using Capnp.Net.Runtime.Tests.GenImpls; using Capnproto_test.Capnp.Test; +using Capnp.Net.Runtime.Tests.Util; namespace Capnp.Net.Runtime.Tests { @@ -56,7 +57,8 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ConnectNoServer() { - using (var client = new TcpRpcClient("localhost", TcpPort)) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var client = new TcpRpcClient(addr.ToString(), port)) { Assert.IsTrue(Assert.ThrowsExceptionAsync(() => client.WhenConnected).Wait(10000)); } @@ -692,35 +694,15 @@ namespace Capnp.Net.Runtime.Tests } } - static void RobustStartAccepting(TcpRpcServer server) - { - int retry = 0; - - do - { - try - { - server.StartAccepting(IPAddress.Any, TcpPort); - break; - } - catch (SocketException) - { - if (retry++ == 100) - throw; - - IncrementTcpPort(); - } - } while (true); - } - [TestMethod] public void Server1() - { + { var cbb = new BufferBlock(); var server = new TcpRpcServer(); server.Main = new TestInterfaceImpl2(); bool init = true; var tracer = new FrameTracing.RpcFrameTracer(Console.Out); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); server.OnConnectionChanged += (s, a) => { var c = a.Connection; @@ -734,7 +716,7 @@ namespace Capnp.Net.Runtime.Tests Assert.IsFalse(c.IsWaitingForData); Assert.AreEqual(ConnectionState.Initializing, c.State); Assert.IsNotNull(c.RemotePort); - Assert.AreEqual(TcpPort, c.LocalPort); + Assert.AreEqual(port, c.LocalPort); Assert.AreEqual(0L, c.RecvCount); Assert.AreEqual(0L, c.SendCount); } @@ -750,14 +732,14 @@ namespace Capnp.Net.Runtime.Tests Assert.ThrowsException(() => server.StopListening()); - RobustStartAccepting(server); + server.StartAccepting(addr, port); Assert.IsTrue(server.IsAlive); - Assert.ThrowsException(() => server.StartAccepting(IPAddress.Any, TcpPort)); + Assert.ThrowsException(() => server.StartAccepting(addr, port)); var server2 = new TcpRpcServer(); - Assert.ThrowsException(() => server2.StartAccepting(IPAddress.Any, TcpPort)); + Assert.ThrowsException(() => server2.StartAccepting(addr, port)); - var client1 = new TcpRpcClient("localhost", TcpPort); + var client1 = new TcpRpcClient(addr.ToString(), port); var c1 = cbb.Receive(TimeSpan.FromMilliseconds(MediumNonDbgTimeout)); Assert.IsNotNull(c1); Assert.AreEqual(1, server.ConnectionCount); @@ -768,7 +750,7 @@ namespace Capnp.Net.Runtime.Tests Assert.IsTrue(c1.RecvCount > 0); Assert.IsTrue(c1.SendCount > 0); - var client2 = new TcpRpcClient("localhost", TcpPort); + var client2 = new TcpRpcClient(addr.ToString(), port); var c2 = cbb.Receive(TimeSpan.FromMilliseconds(MediumNonDbgTimeout)); Assert.IsNotNull(c2); Assert.AreEqual(2, server.ConnectionCount); @@ -795,7 +777,7 @@ namespace Capnp.Net.Runtime.Tests for (int i = 0; i < 100; i++) { - server.StartAccepting(IPAddress.Any, TcpPort); + server.StartAccepting(addr, port); Assert.IsTrue(server.IsAlive); server.StopListening(); Assert.IsFalse(server.IsAlive); @@ -815,9 +797,10 @@ namespace Capnp.Net.Runtime.Tests server.Dispose(); }; - RobustStartAccepting(server); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.StartAccepting(addr, port); - var client1 = new TcpRpcClient("localhost", TcpPort); + var client1 = new TcpRpcClient(addr.ToString(), port); Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout), "Did not connect"); Assert.IsTrue(SpinWait.SpinUntil(() => client1.State == ConnectionState.Down, MediumNonDbgTimeout), $"Connection did not go down: {client1.State}"); @@ -835,9 +818,10 @@ namespace Capnp.Net.Runtime.Tests a.Connection.Close(); }; - RobustStartAccepting(server); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.StartAccepting(addr, port); - var client1 = new TcpRpcClient("localhost", TcpPort); + var client1 = new TcpRpcClient(addr.ToString(), port); Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout)); Assert.IsTrue(SpinWait.SpinUntil(() => client1.State == ConnectionState.Down, MediumNonDbgTimeout)); } @@ -856,13 +840,14 @@ namespace Capnp.Net.Runtime.Tests Assert.ThrowsException(() => client.GetMain()); Assert.ThrowsException(() => client.AttachTracer(null)); Assert.ThrowsException(() => client.InjectMidlayer(null)); - RobustStartAccepting(server); - client.Connect("localhost", TcpPort); - Assert.ThrowsException(() => client.Connect("localhost", TcpPort)); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + server.StartAccepting(addr, port); + client.Connect(addr.ToString(), port); + Assert.ThrowsException(() => client.Connect(addr.ToString(), port)); Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); Assert.ThrowsException(() => client.AttachTracer(new FrameTracing.RpcFrameTracer(Console.Out, false))); Assert.ThrowsException(() => client.InjectMidlayer(_ => _)); - Assert.AreEqual(TcpPort, client.RemotePort); + Assert.AreEqual(port, client.RemotePort); Assert.IsTrue(client.LocalPort != 0); Assert.AreEqual(0L, client.SendCount); Assert.AreEqual(0L, client.RecvCount); diff --git a/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs b/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs index 0014891..1e81bf4 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcAdvancedStuff.cs @@ -1,4 +1,5 @@ using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Net.Runtime.Tests.Util; using Capnp.Rpc; using Capnproto_test.Capnp.Test; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -16,7 +17,8 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void MultiConnect() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); var tcs = new TaskCompletionSource(); @@ -24,7 +26,7 @@ namespace Capnp.Net.Runtime.Tests for (int i = 1; i <= 10; i++) { - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { //client.WhenConnected.Wait(); @@ -54,13 +56,14 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void TwoClients() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - using (var client1 = SetupClient()) - using (var client2 = SetupClient()) + using (var client1 = SetupClient(addr, port)) + using (var client2 = SetupClient(addr, port)) { //Assert.IsTrue(client1.WhenConnected.Wait(MediumNonDbgTimeout)); //Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); @@ -95,12 +98,13 @@ namespace Capnp.Net.Runtime.Tests { for (int i = 0; i < 100; i++) { - var server = SetupServer(); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + var server = SetupServer(addr, port); var counters = new Counters(); var tcs = new TaskCompletionSource(); server.Main = new TestInterfaceImpl(counters, tcs); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { client.WhenConnected.Wait(); @@ -125,12 +129,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void InheritFromGenericInterface() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new B2Impl(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { //client.WhenConnected.Wait(); @@ -148,11 +153,12 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void Issue25() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { server.Main = new Issue25BImpl(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { //client.WhenConnected.Wait(); @@ -177,12 +183,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ExportCapToThirdParty() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl3(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); @@ -190,11 +197,13 @@ namespace Capnp.Net.Runtime.Tests { var held = main.GetHeld().Eager(); - using (var server2 = SetupServer()) + (addr, port) = TcpManager.Instance.GetLocalAddressAndPort(); + + using (var server2 = SetupServer(addr, port)) { server2.Main = new TestMoreStuffImpl2(); - using (var client2 = SetupClient()) + using (var client2 = SetupClient(addr, port)) { //Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); @@ -215,11 +224,12 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ExportTailCallCapToThirdParty() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { server.Main = new TestTailCallerImpl2(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); @@ -230,7 +240,7 @@ namespace Capnp.Net.Runtime.Tests Assert.IsTrue(fooTask.Wait(MediumNonDbgTimeout)); using (var c = fooTask.Result.C) - using (var client2 = SetupClient()) + using (var client2 = SetupClient(addr, port)) { //Assert.IsTrue(client2.WhenConnected.Wait(MediumNonDbgTimeout)); @@ -249,11 +259,12 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void SalamiTactics() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { server.Main = new TestMoreStuffImpl3(); - using (var client = SetupClient()) + using (var client = SetupClient(addr, port)) { //client.WhenConnected.Wait(); diff --git a/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs b/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs index 6ec007a..de99fa4 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs @@ -1,5 +1,6 @@ using Capnp.FrameTracing; using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Net.Runtime.Tests.Util; using Capnp.Rpc; using Capnproto_test.Capnp.Test; using Microsoft.Extensions.Logging; @@ -9,6 +10,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; +using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -37,7 +39,7 @@ namespace Capnp.Net.Runtime.Tests Process _currentProcess; - bool TryLaunchCompatTestProcess(string whichTest, Action test) + bool TryLaunchCompatTestProcess(IPAddress addr, int port, string whichTest, Action test) { string myPath = Path.GetDirectoryName(typeof(TcpRpcInterop).Assembly.Location); string config; @@ -48,7 +50,7 @@ namespace Capnp.Net.Runtime.Tests #endif string path = Path.Combine(myPath, $@"..\..\..\..\{config}\CapnpCompatTest.exe"); path = Path.GetFullPath(path); - string arguments = $"{whichTest} 127.0.0.1:{TcpPort}"; + string arguments = $"{whichTest} {addr}:{port}"; var startInfo = new ProcessStartInfo(path, arguments) { UseShellExecute = false, @@ -96,15 +98,13 @@ namespace Capnp.Net.Runtime.Tests } } - void LaunchCompatTestProcess(string whichTest, Action test) + void LaunchCompatTestProcess(string whichTest, IPAddress addr, int port, Action test) { for (int retry = 0; retry < 5; retry++) { - if (TryLaunchCompatTestProcess(whichTest, test)) + if (TryLaunchCompatTestProcess(addr, port, whichTest, test)) return; - if (whichTest.StartsWith("server:")) - PrepareNextTest(); } Assert.Fail("Problem after launching test process"); @@ -122,18 +122,13 @@ namespace Capnp.Net.Runtime.Tests Assert.AreEqual(expected, line.Result); } - [TestInitialize] - public void PrepareNextTest() - { - IncrementTcpPort(); - } - [TestMethod] public void BasicClient() { - LaunchCompatTestProcess("server:Interface", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:Interface", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -162,12 +157,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void BasicServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestInterfaceImpl(counters); - LaunchCompatTestProcess("client:Basic", stdout => + LaunchCompatTestProcess("client:Basic", addr, port, stdout => { AssertOutput(stdout, "Basic test start"); AssertOutput(stdout, "Basic test end"); @@ -179,11 +175,12 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void PipelineClient() { - LaunchCompatTestProcess("server:Pipeline", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:Pipeline", addr, port, stdout => { stdout.ReadToEndAsync().ContinueWith(t => Console.WriteLine(t.Result)); - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -216,12 +213,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void PipelineServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestPipelineImpl(counters); - LaunchCompatTestProcess("client:Pipelining", stdout => + LaunchCompatTestProcess("client:Pipelining", addr, port, stdout => { AssertOutput(stdout, "Pipelining test start"); AssertOutput(stdout, "foo 123 1"); @@ -235,9 +233,10 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ReleaseClient() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -268,12 +267,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ReleaseServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Release", stdout => + LaunchCompatTestProcess("client:Release", addr, port, stdout => { AssertOutput(stdout, "Release test start"); AssertOutput(stdout, "sync"); @@ -301,9 +301,10 @@ namespace Capnp.Net.Runtime.Tests // later on verify that the handle count is 0. int iterationCount = 5000; - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -380,12 +381,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ReleaseOnCancelServer() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:ReleaseOnCancel", stdout => + LaunchCompatTestProcess("client:ReleaseOnCancel", addr, port, stdout => { AssertOutput(stdout, "ReleaseOnCancel test start"); AssertOutput(stdout, "ReleaseOnCancel test end"); @@ -398,14 +400,15 @@ namespace Capnp.Net.Runtime.Tests [TestCategory("Coverage")] public void TestTailCallClient() { - LaunchCompatTestProcess("server:TailCaller", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:TailCaller", addr, port, stdout => { using (var client = new TcpRpcClient()) { var tracer = new RpcFrameTracer(Console.Out); client.AttachTracer(tracer); - client.Connect("localhost", TcpPort); + client.Connect(addr.ToString(), port); //client.WhenConnected.Wait(); @@ -441,8 +444,8 @@ namespace Capnp.Net.Runtime.Tests // For details on why this test is ignored, see https://github.com/capnproto/capnproto/issues/876 public void TestTailCallServer() { - - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var tracer = new RpcFrameTracer(Console.Out); @@ -455,7 +458,7 @@ namespace Capnp.Net.Runtime.Tests var counters = new Counters(); server.Main = new TestTailCallerImpl(counters); - LaunchCompatTestProcess("client:TailCall", stdout => + LaunchCompatTestProcess("client:TailCall", addr, port, stdout => { AssertOutput(stdout, "TailCall test start"); AssertOutput(stdout, "foo"); @@ -469,11 +472,12 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void CancelationServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { stdout.ReadToEndAsync().ContinueWith(t => Console.WriteLine(t.Result)); - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -499,12 +503,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void CancelationClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Cancelation", stdout => + LaunchCompatTestProcess("client:Cancelation", addr, port, stdout => { AssertOutput(stdout, "Cancelation test start"); AssertOutput(stdout, "~"); @@ -516,9 +521,10 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void PromiseResolveServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -560,12 +566,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void PromiseResolveClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:PromiseResolve", stdout => + LaunchCompatTestProcess("client:PromiseResolve", addr, port, stdout => { AssertOutput(stdout, "PromiseResolve test start"); AssertOutput(stdout, "foo 123 1"); @@ -583,11 +590,12 @@ namespace Capnp.Net.Runtime.Tests var destructionPromise = new TaskCompletionSource(); var destructionTask = destructionPromise.Task; - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { stdout.ReadToEndAsync().ContinueWith(t => Console.WriteLine(t.Result)); - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -658,12 +666,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void RetainAndReleaseClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:RetainAndRelease", stdout => + LaunchCompatTestProcess("client:RetainAndRelease", addr, port, stdout => { AssertOutput(stdout, "RetainAndRelease test start"); AssertOutput(stdout, "foo 123 1"); @@ -678,9 +687,10 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void CancelServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -719,12 +729,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void CancelClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Cancel", stdout => + LaunchCompatTestProcess("client:Cancel", addr, port, stdout => { AssertOutput(stdout, "Cancel test start"); AssertOutput(stdout, "~"); @@ -736,9 +747,10 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void SendTwiceServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -780,12 +792,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void SendTwiceClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:SendTwice", stdout => + LaunchCompatTestProcess("client:SendTwice", addr, port, stdout => { AssertOutput(stdout, "SendTwice test start"); AssertOutput(stdout, "foo 123 1"); @@ -800,9 +813,10 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout), "client connect"); @@ -864,12 +878,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoServer2() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { int retry = 0; label: - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout), "client connect"); @@ -947,12 +962,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:Embargo", stdout => + LaunchCompatTestProcess("client:Embargo", addr, port, stdout => { AssertOutput(stdout, "Embargo test start"); AssertOutput(stdout, "Embargo test end"); @@ -960,9 +976,9 @@ namespace Capnp.Net.Runtime.Tests } } - public void EmbargoErrorImpl(StreamReader stdout) + public void EmbargoErrorImpl(IPAddress addr, int port, StreamReader stdout) { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //Assert.IsTrue(client.WhenConnected.Wait(MediumNonDbgTimeout)); @@ -1017,17 +1033,19 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoErrorServer() { - LaunchCompatTestProcess("server:MoreStuff", EmbargoErrorImpl); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, r => EmbargoErrorImpl(addr, port, r)); } [TestMethod, Timeout(240000)] public void RepeatedEmbargoError() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { for (int i = 0; i < 20; i++) { - EmbargoErrorImpl(stdout); + EmbargoErrorImpl(addr, port, stdout); } }); } @@ -1035,12 +1053,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoErrorClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:EmbargoError", stdout => + LaunchCompatTestProcess("client:EmbargoError", addr, port, stdout => { AssertOutput(stdout, "EmbargoError test start"); AssertOutput(stdout, "EmbargoError test end"); @@ -1051,12 +1070,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoNullServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { int retry = 0; label: - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -1111,12 +1131,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void EmbargoNullClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:EmbargoNull", stdout => + LaunchCompatTestProcess("client:EmbargoNull", addr, port, stdout => { AssertOutput(stdout, "EmbargoNull test start"); AssertOutput(stdout, "EmbargoNull test end"); @@ -1127,9 +1148,10 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void CallBrokenPromiseServer() { - LaunchCompatTestProcess("server:MoreStuff", stdout => + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + LaunchCompatTestProcess("server:MoreStuff", addr, port, stdout => { - using (var client = new TcpRpcClient("localhost", TcpPort)) + using (var client = new TcpRpcClient(addr.ToString(), port)) { //client.WhenConnected.Wait(); @@ -1164,12 +1186,13 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void CallBrokenPromiseClient() { - using (var server = SetupServer()) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + using (var server = SetupServer(addr, port)) { var counters = new Counters(); server.Main = new TestMoreStuffImpl(counters); - LaunchCompatTestProcess("client:CallBrokenPromise", stdout => + LaunchCompatTestProcess("client:CallBrokenPromise", addr, port, stdout => { AssertOutput(stdout, "CallBrokenPromise test start"); AssertOutput(stdout, "CallBrokenPromise test end"); diff --git a/Capnp.Net.Runtime.Tests/TcpRpcStress.cs b/Capnp.Net.Runtime.Tests/TcpRpcStress.cs index b5de959..b24095c 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcStress.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcStress.cs @@ -1,4 +1,5 @@ using Capnp.Net.Runtime.Tests.GenImpls; +using Capnp.Net.Runtime.Tests.Util; using Capnp.Rpc; using Capnproto_test.Capnp.Test; using Microsoft.Extensions.Logging; @@ -20,7 +21,6 @@ namespace Capnp.Net.Runtime.Tests for (int i = 0; i < count; i++) { Logger.LogTrace("Repetition {0}", i); - IncrementTcpPort(); action(); } } @@ -109,45 +109,36 @@ namespace Capnp.Net.Runtime.Tests [TestMethod] public void ScatteredTransfer() { - for (int retry = 0; retry < 10; retry++) + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + + using (var server = new TcpRpcServer(addr, port)) + using (var client = new TcpRpcClient()) { - try + server.InjectMidlayer(s => new ScatteringStream(s, 7)); + client.InjectMidlayer(s => new ScatteringStream(s, 10)); + client.Connect(addr.ToString(), port); + //client.WhenConnected.Wait(); + + var counters = new Counters(); + server.Main = new TestInterfaceImpl(counters); + using (var main = client.GetMain()) { - using (var server = new TcpRpcServer(IPAddress.Any, TcpPort)) - using (var client = new TcpRpcClient()) + for (int i = 0; i < 100; i++) { - server.InjectMidlayer(s => new ScatteringStream(s, 7)); - client.InjectMidlayer(s => new ScatteringStream(s, 10)); - client.Connect("localhost", TcpPort); - //client.WhenConnected.Wait(); + var request1 = main.Foo(123, true, default); + var request3 = Assert.ThrowsExceptionAsync(() => main.Bar(default)); + var s = new TestAllTypes(); + Common.InitTestMessage(s); + var request2 = main.Baz(s, default); - var counters = new Counters(); - server.Main = new TestInterfaceImpl(counters); - using (var main = client.GetMain()) - { - for (int i = 0; i < 100; i++) - { - var request1 = main.Foo(123, true, default); - var request3 = Assert.ThrowsExceptionAsync(() => main.Bar(default)); - var s = new TestAllTypes(); - Common.InitTestMessage(s); - var request2 = main.Baz(s, default); + Assert.IsTrue(request1.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(request2.Wait(MediumNonDbgTimeout)); + Assert.IsTrue(request3.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request1.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request2.Wait(MediumNonDbgTimeout)); - Assert.IsTrue(request3.Wait(MediumNonDbgTimeout)); - - Assert.AreEqual("foo", request1.Result); - Assert.AreEqual(2, counters.CallCount); - counters.CallCount = 0; - } - } + Assert.AreEqual("foo", request1.Result); + Assert.AreEqual(2, counters.CallCount); + counters.CallCount = 0; } - return; - } - catch (SocketException) - { - IncrementTcpPort(); } } } diff --git a/Capnp.Net.Runtime.Tests/Util/TcpManager.cs b/Capnp.Net.Runtime.Tests/Util/TcpManager.cs new file mode 100644 index 0000000..102d352 --- /dev/null +++ b/Capnp.Net.Runtime.Tests/Util/TcpManager.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; + +namespace Capnp.Net.Runtime.Tests.Util +{ + class TcpManager + { + public static readonly TcpManager Instance = new TcpManager(); + + readonly byte[] _nextAddress; + int _nextPort = 50005; + + public TcpManager() + { + _nextAddress = new byte[] { 127, 0, 0, 1 }; + } + + public (IPAddress, int) GetLocalAddressAndPort() + { + if (++_nextAddress[2] == 0 && + ++_nextAddress[1] == 0 && + ++_nextAddress[0] == 0) + { + _nextAddress[0] = 2; + } + + return (new IPAddress(_nextAddress), _nextPort); + } + } +} diff --git a/Capnp.Net.Runtime.Tests/Util/TestBase.cs b/Capnp.Net.Runtime.Tests/Util/TestBase.cs index dc94dd3..443e660 100644 --- a/Capnp.Net.Runtime.Tests/Util/TestBase.cs +++ b/Capnp.Net.Runtime.Tests/Util/TestBase.cs @@ -1,4 +1,5 @@ -using Capnp.Rpc; +using Capnp.Net.Runtime.Tests.Util; +using Capnp.Rpc; using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; @@ -344,14 +345,13 @@ namespace Capnp.Net.Runtime.Tests } } - public static int TcpPort = 49152; public static int MediumNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 5000; public static int LargeNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 20000; public static int ShortTimeout => 500; protected ILogger Logger { get; set; } - protected static TcpRpcClient SetupClient(TcpRpcTestOptions options = TcpRpcTestOptions.None) + protected static TcpRpcClient SetupClient(IPAddress addr, int port, TcpRpcTestOptions options = TcpRpcTestOptions.None) { var client = new TcpRpcClient(); client.AddBuffering(); @@ -360,7 +360,7 @@ namespace Capnp.Net.Runtime.Tests if (options.HasFlag(TcpRpcTestOptions.ClientFluctStream)) client.InjectMidlayer(s => new FluctStream(s)); if (!options.HasFlag(TcpRpcTestOptions.ClientNoConnect)) - client.Connect("localhost", TcpPort); + client.Connect(addr.ToString(), port); return client; } @@ -373,36 +373,21 @@ namespace Capnp.Net.Runtime.Tests ClientNoConnect = 4 } - protected static TcpRpcServer SetupServer() + protected static TcpRpcServer SetupServer(IPAddress addr, int port) { - int attempt = 0; - - while (true) - { - try - { - var server = new TcpRpcServer(IPAddress.Any, TcpPort); - server.AddBuffering(); - return server; - } - catch (SocketException) - { - // If the TCP listening port is occupied by some other process, retry with a different one - // TIME_WAIT is 4min: http://blog.davidvassallo.me/2010/07/13/time_wait-and-port-reuse/ - if (attempt == 2400) - throw; - } - - IncrementTcpPort(); - ++attempt; - Thread.Sleep(100); - } + var server = new TcpRpcServer(); + server.AddBuffering(); + server.StartAccepting(addr, port); + return server; } protected static (TcpRpcServer, TcpRpcClient) SetupClientServerPair(TcpRpcTestOptions options = TcpRpcTestOptions.None) { - var server = SetupServer(); - var client = SetupClient(options); + (var addr, int port) = TcpManager.Instance.GetLocalAddressAndPort(); + + var server = SetupServer(addr, port); + var client = SetupClient(addr, port, options); + return (server, client); } @@ -413,14 +398,6 @@ namespace Capnp.Net.Runtime.Tests return (CapabilityReflection.CreateProxy(pair.Endpoint2.QueryMain()) as T); } - public static void IncrementTcpPort() - { - if (++TcpPort > 49200) - { - TcpPort = 49152; - } - } - protected static DtbdctTestbed NewDtbdctTestbed() => new DtbdctTestbed(); protected static LocalhostTcpTestbed NewLocalhostTcpTestbed(TcpRpcTestOptions options = TcpRpcTestOptions.None) => new LocalhostTcpTestbed(options);