public async Task InvokeGroupAsync_WhenOneDisconnected_ShouldDeliverOthers()
        {
            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                    using (var client3 = new TestClient())
                    {
                        var manager     = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), _fixture.ClientProvider);
                        var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                        var connection2 = HubConnectionContextUtils.Create(client2.Connection);
                        var connection3 = HubConnectionContextUtils.Create(client3.Connection);

                        await manager.OnConnectedAsync(connection1);

                        await manager.OnConnectedAsync(connection2);

                        var groupName = "gunit";
                        await manager.AddToGroupAsync(connection1.ConnectionId, groupName);

                        await manager.AddToGroupAsync(connection2.ConnectionId, groupName);

                        await manager.AddToGroupAsync(connection3.ConnectionId, groupName);

                        await manager.SendGroupAsync(groupName, "Hello", new object[] { "World" });

                        await AssertMessageAsync(client1);
                        await AssertMessageAsync(client2);
                    }
        }
        public async Task InvokeGroupAsync_WritesTo_AllConnections_InGroup_Output()
        {
            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var output1 = Channel.CreateUnbounded <HubMessage>();
                    var output2 = Channel.CreateUnbounded <HubMessage>();

                    var manager     = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
                    var connection1 = new HubConnectionContext(output1, client1.Connection);
                    var connection2 = new HubConnectionContext(output2, client2.Connection);

                    await manager.OnConnectedAsync(connection1);

                    await manager.OnConnectedAsync(connection2);

                    await manager.AddGroupAsync(connection1.ConnectionId, "gunit");

                    await manager.InvokeGroupAsync("gunit", "Hello", new object[] { "World" });

                    AssertMessage(output1);

                    Assert.False(output2.In.TryRead(out var item));
                }
        }
        public async Task InvokeAsync_WhenNotConnectedAfterFailedAttemptsExceeds_ShouldForceDisconnect()
        {
            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var manager     = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), _fixture.ClientProvider);
                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1);

                    var groupName = "flex";
                    await manager.AddToGroupAsync(connection1.ConnectionId, groupName);

                    await manager.AddToGroupAsync(connection2.ConnectionId, groupName);

                    await manager.SendGroupAsync(groupName, "Hello", new object[] { "World" });

                    var grain            = _fixture.ClientProvider.GetClient().GetGroupGrain("MyHub", groupName);
                    var connectionsCount = await grain.Count();

                    await AssertMessageAsync(client1);

                    Assert.Equal(2, connectionsCount);

                    await manager.SendGroupAsync(groupName, "Hello", new object[] { "World" });

                    await manager.SendGroupAsync(groupName, "Hello", new object[] { "World" });

                    connectionsCount = await grain.Count();

                    Assert.Equal(1, connectionsCount);
                }
        }
        public async Task InvokeAllAsync_ForSpecificHub_WithMultipleServers_WritesTo_AllConnections_Output()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
            var manager3 = new OrleansHubLifetimeManager <DifferentHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <DifferentHub> >(), this._fixture.ClientProvider);

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                    using (var client3 = new TestClient())
                    {
                        var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                        var connection2 = HubConnectionContextUtils.Create(client2.Connection);
                        var connection3 = HubConnectionContextUtils.Create(client3.Connection);

                        await manager1.OnConnectedAsync(connection1);

                        await manager2.OnConnectedAsync(connection2);

                        await manager3.OnConnectedAsync(connection3);

                        await manager1.SendAllAsync("Hello", new object[] { "World" });

                        await AssertMessageAsync(client1);
                        await AssertMessageAsync(client2);

                        Assert.Null(client3.TryRead());
                    }
        }
        public async Task RemoveGroupAsync_ForConnection_OnDifferentServer_Works()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);

            using (var client = new TestClient())
            {
                var output = Channel.CreateUnbounded <HubMessage>();

                var connection = new HubConnectionContext(output, client.Connection);

                await manager1.OnConnectedAsync(connection);

                await manager1.AddGroupAsync(connection.ConnectionId, "snoop");

                await manager2.InvokeGroupAsync("snoop", "Hello", new object[] { "World" });

                AssertMessage(output);

                await manager2.RemoveGroupAsync(connection.ConnectionId, "snoop");

                await manager2.InvokeGroupAsync("snoop", "Hello", new object[] { "World" });

                Assert.False(output.In.TryRead(out var item));
            }
        }
        public async Task InvokeAllAsync_ForSpecificHub_WithMultipleServers_WritesTo_AllConnections_Output()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
            var manager3 = new OrleansHubLifetimeManager <DifferentHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <DifferentHub> >(), this._fixture.Client);

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                    using (var client3 = new TestClient())
                    {
                        var output1 = Channel.CreateUnbounded <HubMessage>();
                        var output2 = Channel.CreateUnbounded <HubMessage>();
                        var output3 = Channel.CreateUnbounded <HubMessage>();

                        var connection1 = new HubConnectionContext(output1, client1.Connection);
                        var connection2 = new HubConnectionContext(output2, client2.Connection);
                        var connection3 = new HubConnectionContext(output3, client3.Connection);

                        await manager1.OnConnectedAsync(connection1);

                        await manager2.OnConnectedAsync(connection2);

                        await manager3.OnConnectedAsync(connection3);

                        await manager1.InvokeAllAsync("Hello", new object[] { "World" });

                        AssertMessage(output1);
                        AssertMessage(output2);
                        Assert.False(output3.In.TryRead(out var item));
                    }
        }
        public async Task InvokeConnectionAsync_WritesToConnections_Output()
        {
            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var manager     = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1);

                    await manager.OnConnectedAsync(connection2);

                    await manager.SendConnectionsAsync(new string[] { connection1.ConnectionId, connection2.ConnectionId }, "Hello", new object[] { "World" });

                    await AssertMessageAsync(client1);
                    await AssertMessageAsync(client2);
                }
        }
        public async Task InvokeGroupAsync_WritesTo_AllConnections_InGroup_Output()
        {
            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var manager     = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1);

                    await manager.OnConnectedAsync(connection2);

                    await manager.AddToGroupAsync(connection1.ConnectionId, "gunit");

                    await manager.SendGroupAsync("gunit", "Hello", new object[] { "World" });

                    await AssertMessageAsync(client1);

                    Assert.Null(client2.TryRead());
                }
        }
        public async Task RemoveGroup_FromLocalConnection_NotInGroup_DoesNothing()
        {
            var manager = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.RemoveFromGroupAsync(connection.ConnectionId, "does-not-exists");
            }
        }
        public async Task InvokeConnectionAsync_WritesToConnection_Output()
        {
            using (var client = new TestClient())
            {
                var manager    = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), _fixture.ClientProvider);
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.SendConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" });

                await AssertMessageAsync(client);
            }
        }
        public async Task InvokeAllAsync_DoesNotWriteTo_DisconnectedConnections_Output()
        {
            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var manager = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1);

                    await manager.OnConnectedAsync(connection2);

                    await manager.OnDisconnectedAsync(connection2);

                    await manager.SendAllAsync("Hello", new object[] { "World" });

                    await AssertMessageAsync(client1);

                    Assert.Null(client2.TryRead());
                }
        }
        public async Task RemoveGroup_FromConnection_OnDifferentServer_NotInGroup_DoesNothing()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), _fixture.ClientProvider);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), _fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager1.OnConnectedAsync(connection);

                await manager2.RemoveFromGroupAsync(connection.ConnectionId, "does-not-exist-server");
            }
        }
        public async Task InvokeConnectionAsync_WritesToConnection_Output()
        {
            using (var client = new TestClient())
            {
                var output     = Channel.CreateUnbounded <HubMessage>();
                var manager    = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
                var connection = new HubConnectionContext(output, client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.InvokeConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" });

                AssertMessage(output);
            }
        }
        public async Task RemoveGroup_FromLocalConnection_NotInGroup_DoesNothing()
        {
            var manager = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);

            using (var client = new TestClient())
            {
                var output = Channel.CreateUnbounded <HubMessage>();

                var connection = new HubConnectionContext(output, client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.RemoveGroupAsync(connection.ConnectionId, "does-not-exists");
            }
        }
        public async Task HubUsingGenericBase_NonInterfaceMatchingNaming_Output()
        {
            using (var client1 = new TestClient())
            {
                var manager = new OrleansHubLifetimeManager <DaHubUsingBase>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <DaHubUsingBase> >(), _fixture.ClientProvider);

                var connection1 = HubConnectionContextUtils.Create(client1.Connection);

                await manager.OnConnectedAsync(connection1).OrTimeout();

                await manager.SendAllAsync("Hello", new object[] { "World" }).OrTimeout();

                await AssertMessageAsync(client1);
            }
        }
        public async Task InvokeGroupAsync_OnServer_WithoutConnection_WritesOutputTo_GroupConnection()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager1.OnConnectedAsync(connection);

                await manager1.AddToGroupAsync(connection.ConnectionId, "tupac");

                await manager2.SendGroupAsync("tupac", "Hello", new object[] { "World" });

                await AssertMessageAsync(client);
            }
        }
        public async Task AddGroupAsync_ForConnection_OnDifferentServer_Works()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager1.OnConnectedAsync(connection);

                await manager2.AddToGroupAsync(connection.ConnectionId, "ice-cube");

                await manager2.SendGroupAsync("ice-cube", "Hello", new object[] { "World" });

                await AssertMessageAsync(client);
            }
        }
        public async Task DisconnectConnection_RemovesConnection_FromGroup()
        {
            var manager = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.AddToGroupAsync(connection.ConnectionId, "dre");

                await manager.OnDisconnectedAsync(connection);

                var grain  = this._fixture.ClientProvider.GetClient().GetGroupGrain("MyHub", "dre");
                var result = await grain.Count();

                Assert.Equal(0, result);
            }
        }
        public async Task InvokeGroupAsync_OnServer_WithoutConnection_WritesOutputTo_GroupConnection()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);

            using (var client = new TestClient())
            {
                var output = Channel.CreateUnbounded <HubMessage>();

                var connection = new HubConnectionContext(output, client.Connection);

                await manager1.OnConnectedAsync(connection);

                await manager1.AddGroupAsync(connection.ConnectionId, "tupac");

                await manager2.InvokeGroupAsync("tupac", "Hello", new object[] { "World" });

                AssertMessage(output);
            }
        }
        public async Task AddGroupAsync_ForLocalConnection_AlreadyInGroup_SkipsDuplicate()
        {
            var manager = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.AddToGroupAsync(connection.ConnectionId, "dmx");

                await manager.AddToGroupAsync(connection.ConnectionId, "dmx");

                var grain  = this._fixture.ClientProvider.GetClient().GetGroupGrain("MyHub", "dmx");
                var result = await grain.Count();

                Assert.Equal(1, result);
            }
        }
        public async Task InvokeConnectionAsync_ForLocalConnection_DoesNotPublish()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.ClientProvider);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                // Add connection to both "servers" to see if connection receives message twice
                await manager1.OnConnectedAsync(connection);

                await manager2.OnConnectedAsync(connection);

                await manager1.SendConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" });

                await AssertMessageAsync(client);

                Assert.Null(client.TryRead());
            }
        }
        public async Task InvokeConnectionAsync_ForLocalConnection_DoesNotPublish()
        {
            var manager1 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);
            var manager2 = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);

            using (var client = new TestClient())
            {
                var output = Channel.CreateUnbounded <HubMessage>();

                var connection = new HubConnectionContext(output, client.Connection);

                // Add connection to both "servers" to see if connection receives message twice
                await manager1.OnConnectedAsync(connection);

                await manager2.OnConnectedAsync(connection);

                await manager1.InvokeConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" });

                AssertMessage(output);
                Assert.False(output.In.TryRead(out var item));
            }
        }
        public async Task DisconnectConnection_RemovesConnection_FromGroup()
        {
            var manager = new OrleansHubLifetimeManager <MyHub>(new LoggerFactory().CreateLogger <OrleansHubLifetimeManager <MyHub> >(), this._fixture.Client);

            using (var client = new TestClient())
            {
                var output = Channel.CreateUnbounded <HubMessage>();

                var connection = new HubConnectionContext(output, client.Connection);

                await manager.OnConnectedAsync(connection);

                await manager.AddGroupAsync(connection.ConnectionId, "dre");

                await manager.OnDisconnectedAsync(connection);

                var grain  = this._fixture.Client.GetGroupGrain("MyHub", "dre");
                var result = await grain.Count();

                Assert.Equal(0, result);
            }
        }