public void TestListenForAnnounce() { var testWorkQueue = new WorkQueue(); var testBroadcastListener = new TestBroadcastNetEventListener(); var testNetManager = new TestNetManager(new NetManager(testBroadcastListener)); testNetManager.NetManager.BroadcastReceiveEnabled = true; testNetManager.NetManager.Start(DistributedHost.DefaultListenPort); // the host under test using DistributedHost host = new DistributedHost(testWorkQueue, DistributedHost.DefaultListenPort, isListener: false); // start announcing host.Announce(); // the list of all pollable objects, to ensure forward progress IPollEvents[] pollables = new IPollEvents[] { host, testNetManager }; // should have received Announce message WaitUtils.WaitUntil(pollables, () => testBroadcastListener.ReceivedMessages.Count == 1); Assert.IsTrue(testBroadcastListener.ReceivedMessages.TryDequeue(out object announceMessage)); ValidateAnnounceMessage(announceMessage, host); // now execute pending work testWorkQueue.PollEvents(); // should still be one queued item -- the *next* announce message Assert.AreEqual(1, testWorkQueue.Count); // wait to receive second Announce WaitUtils.WaitUntil(pollables, () => testBroadcastListener.ReceivedMessages.Count == 1); Assert.IsTrue(testBroadcastListener.ReceivedMessages.TryDequeue(out announceMessage)); ValidateAnnounceMessage(announceMessage, host);
public void HostCreateThenUpdate() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // construct second host using DistributedHost host2 = CreateHost(testWorkQueue, false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // should generate announce response and then connection WaitUtils.WaitUntil(new[] { host, host2 }, () => host.PeerCount == 1 && host2.PeerCount == 1); // create object var distributedThing = new DistributedThing(host, new LocalThing()); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host2).Count == 1); // change the state of the owner distributedThing.Enqueue(new[] { 1, 2 }); // verify the proxy gets updated WaitUtils.WaitUntil( new[] { host, host2 }, () => FirstProxyLocalThing(host2).LocalValues.Count() == 2); Assert.IsTrue(Enumerable.SequenceEqual(new[] { 1, 2 }, FirstProxyLocalThing(host2).LocalValues.ToList())); }
public void HostCreateAndDeleteProxyAfterConnection() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // construct second host using DistributedHost host2 = CreateHost(testWorkQueue, false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // create object var distributedThing = new DistributedThing(host, new LocalThing()); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil( new[] { host, host2 }, () => host2.NetPeers.Count() == 1 && ProxiesForFirstPeer(host2).Count == 1); // now delete the proxy ProxiesForFirstPeer(host2)[1].Delete(); // wait until the messages flow around, and make sure there are now no proxies and no owners WaitUtils.WaitUntil( new[] { host, host2 }, () => ProxiesForFirstPeer(host2).Count == 0 && host.Owners.Count == 0); }
public void ConstructHost() { var testWorkQueue = new WorkQueue(); using DistributedHost host = new DistributedHost(testWorkQueue, DistributedHost.DefaultListenPort); Assert.IsNotNull(host); // Should be no work after construction. Assert.AreEqual(0, testWorkQueue.Count); // Start announcing. host.Announce(); // should have sent one Announce message, and queued the action to send the next Assert.AreEqual(1, testWorkQueue.Count); }
public void HostCreateThenProxyUpdate() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // construct second host using DistributedHost host2 = CreateHost(testWorkQueue, false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // should generate announce response and then connection WaitUtils.WaitUntil(new[] { host, host2 }, () => host.PeerCount == 1 && host2.PeerCount == 1); // create object var distributedThing = new DistributedThing(host, new LocalThing()); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host2).Count == 1); // this time update the state of the *proxy* -- or more precisely, send a request to the proxy // to update the owner's state (which will, in turn, update the proxy's state) DistributedThing host2DistributedThing = (DistributedThing)ProxiesForFirstPeer(host2).First().Value; host2DistributedThing.Enqueue(new[] { 1, 2 }); // make sure we didn't actually update the local thing yet; only messages from the owner can do that Assert.AreEqual(0, host2DistributedThing.TypedLocalObject.LocalValues.Count()); // wait until owner gets the proxy's memo WaitUtils.WaitUntil( new[] { host, host2 }, () => distributedThing.TypedLocalObject.LocalValues.Count() == 2); // and now wait until proxy gets the owner's memo WaitUtils.WaitUntil( new[] { host, host2 }, () => host2DistributedThing.TypedLocalObject.LocalValues.Count() == 2); Assert.IsTrue(Enumerable.SequenceEqual(new[] { 1, 2 }, distributedThing.TypedLocalObject.LocalValues.ToList())); Assert.IsTrue(Enumerable.SequenceEqual(new[] { 1, 2 }, host2DistributedThing.TypedLocalObject.LocalValues.ToList())); }
public void HostCreateThenDisconnect() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // create object var distributedThing = new DistributedThing(host, new LocalThing()); // construct second host using (DistributedHost host2 = CreateHost(testWorkQueue, false)) { // consume one owner ID so second object has ID 2 instead of (matching first object) ID 1 host2.NextOwnerId(); // now create an owner object on the other host var distributedThing2 = new DistributedThing(host2, new LocalThing()); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil(new[] { host, host2 }, () => host2.NetPeers.Count() == 1 && ProxiesForFirstPeer(host2).Count == 1 && host.NetPeers.Count() == 1 && ProxiesForFirstPeer(host).Count == 1); IDistributedObject host2Proxy = ProxiesForFirstPeer(host2).Values.First(); Assert.AreEqual(new DistributedId(1), host2Proxy.Id); Assert.False(host2Proxy.IsOwner); IDistributedObject hostProxy = ProxiesForFirstPeer(host).Values.First(); Assert.AreEqual(new DistributedId(2), hostProxy.Id); Assert.False(hostProxy.IsOwner); } // now after things settle down there should be no proxy WaitUtils.WaitUntil(new[] { host }, () => host.PeerCount == 0 && host.ProxyPeerCount == 0); }
public void HostConnectToHost() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = new DistributedHost(testWorkQueue, DistributedHost.DefaultListenPort, isListener: true); // construct second host using DistributedHost host2 = new DistributedHost(testWorkQueue, DistributedHost.DefaultListenPort, isListener: false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // should generate announce response and then connection WaitUtils.WaitUntil(new[] { host, host2 }, () => host.PeerCount == 1 && host2.PeerCount == 1); // Should be one announce received by host, and one announce response received by host2 Assert.AreEqual(1, host.PeerAnnounceCount); Assert.AreEqual(0, host.PeerAnnounceResponseCount); Assert.AreEqual(0, host2.PeerAnnounceCount); Assert.AreEqual(1, host2.PeerAnnounceResponseCount); }
public void HostCreateAfterConnection() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // construct second host using DistributedHost host2 = CreateHost(testWorkQueue, false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // should generate announce response and then connection WaitUtils.WaitUntil(new[] { host, host2 }, () => host.PeerCount == 1 && host2.PeerCount == 1); // create object var distributedThing = new DistributedThing(host, new LocalThing()); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host2).Count == 1); IDistributedObject host2Proxy = ProxiesForFirstPeer(host2).Values.First(); Assert.AreEqual(new DistributedId(1), host2Proxy.Id); Assert.False(host2Proxy.IsOwner); // now create an owner object on the other host var distributedThing2 = new DistributedThing(host2, new LocalThing()); // wait until the proxy for the new object makes it to the first host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host).Count == 1); IDistributedObject hostProxy = ProxiesForFirstPeer(host).Values.First(); Assert.AreEqual(new DistributedId(1), hostProxy.Id); Assert.False(hostProxy.IsOwner); }
public void HostCreateThenProxyBroadcast() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // construct second host using DistributedHost host2 = CreateHost(testWorkQueue, false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // should generate announce response and then connection WaitUtils.WaitUntil(new[] { host, host2 }, () => host.PeerCount == 1 && host2.PeerCount == 1); // create object var distributedThing = new DistributedThing(host, new LocalThing()); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host2).Count == 1); // this time ping the proxy DistributedThing host2DistributedThing = (DistributedThing)ProxiesForFirstPeer(host2).First().Value; host2DistributedThing.Ping("hello".ToCharArray()); // make sure we DID update the local thing; unreliable messages take effect immediately locally Assert.AreEqual("hello", new string(host2DistributedThing.TypedLocalObject.LastMessage)); // wait until owner gets the broadcast WaitUtils.WaitUntil( new[] { host, host2 }, () => distributedThing.TypedLocalObject.LastMessage != null); Assert.AreEqual("hello", new string(distributedThing.TypedLocalObject.LastMessage)); }
public void HostCreateWithState() { var testWorkQueue = new WorkQueue(); // the first host under test using DistributedHost host = CreateHost(testWorkQueue, true); // construct second host using DistributedHost host2 = CreateHost(testWorkQueue, false); // host could start announcing also, but host2 isn't listening so it wouldn't be detectable host2.Announce(); // should generate announce response and then connection WaitUtils.WaitUntil(new[] { host, host2 }, () => host.PeerCount == 1 && host2.PeerCount == 1); // create object var distributedThing = new DistributedThing(host, new LocalThing(new[] { 1, 2 })); // wait until the proxy for the new object makes it to the other host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host2).Count == 1); LocalThing host2LocalThing = FirstProxyLocalThing(host2); Assert.IsTrue(Enumerable.SequenceEqual(new[] { 1, 2 }, host2LocalThing.LocalValues.ToList())); // now create an owner object on the other host var distributedThing2 = new DistributedThing(host2, new LocalThing(new[] { 3, 4 })); // wait until the proxy for the new object makes it to the first host WaitUtils.WaitUntil(new[] { host, host2 }, () => ProxiesForFirstPeer(host).Count == 1); IDistributedObject hostProxy = ProxiesForFirstPeer(host).Values.First(); LocalThing hostLocalThing = (LocalThing)hostProxy.LocalObject; Assert.IsTrue(Enumerable.SequenceEqual(new[] { 3, 4 }, hostLocalThing.LocalValues.ToList())); }