public async Task ProcessRemove()
        {
            bool calledActual = false;
            string nameActual = null;

            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                DeleteClusterAsyncFunc = name =>
                {
                    nameActual = name;
                    calledActual = true;
                    return Task.FromResult(true);
                }
            };

            ClusterConfig config = new ClusterConfig();
            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);

            Cluster cluster = this.CreateCluster(ClusterStatus.Remove);

            Cluster actual = await target.ProcessClusterStatusAsync(cluster);

            Assert.IsTrue(calledActual);
            Assert.AreEqual(ClusterStatus.Deleting, actual.Status);
        }
        public async Task ProcessDeletingSuccessful()
        {
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = domain => Task.FromResult(ClusterOperationStatus.ClusterNotFound)
            };

            ClusterConfig config = new ClusterConfig();
            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);

            Cluster cluster = this.CreateCluster(ClusterStatus.Deleting);

            Cluster actual = await target.ProcessClusterStatusAsync(cluster);

            Assert.AreEqual(ClusterStatus.Deleted, actual.Status);
        }
        public async Task ProcessCreatingClusterSuccess()
        {
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = name => Task.FromResult(ClusterOperationStatus.Ready)
            };

            ClusterConfig config = new ClusterConfig();
            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);
            Cluster cluster = this.CreateCluster(ClusterStatus.Creating);

            Cluster actual = await target.ProcessClusterStatusAsync(cluster);

            Assert.AreEqual(ClusterStatus.Ready, actual.Status);
            Assert.IsTrue(actual.CreatedOn.ToUniversalTime() <= DateTimeOffset.UtcNow);
            actual.Ports.SequenceEqual(await clusterOperator.GetClusterPortsAsync(""));
        }
        public async Task ProcessCreatingClusterFailed()
        {
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = name => Task.FromResult(ClusterOperationStatus.CreateFailed)
            };

            ClusterConfig config = new ClusterConfig();
            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);
            Cluster cluster = this.CreateCluster(ClusterStatus.Creating);

            Cluster actual = await target.ProcessClusterStatusAsync(cluster);

            Assert.AreEqual(ClusterStatus.Remove, actual.Status);
            Assert.AreEqual(0, actual.Ports.Count());
            Assert.AreEqual(0, actual.Users.Count());
        }
        public async Task ProcessClustersAsyncDelete()
        {
            int key = 1;
            MockReliableStateManager stateManager = new MockReliableStateManager();
            ClusterConfig config = new ClusterConfig();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = (name) => Task.FromResult(ClusterOperationStatus.ClusterNotFound)
            };

            IReliableDictionary<int, Cluster> dictionary =
                await stateManager.GetOrAddAsync<IReliableDictionary<int, Cluster>>(ClusterService.ClusterDictionaryName);

            Cluster original = this.CreateCluster(ClusterStatus.Deleting);
            using (ITransaction tx = stateManager.CreateTransaction())
            {
                await dictionary.SetAsync(tx, key, original);
            }

            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);

            await target.ProcessClustersAsync();

            using (ITransaction tx = stateManager.CreateTransaction())
            {
                ConditionalResult<Cluster> actual = await dictionary.TryGetValueAsync(tx, key);

                Assert.IsFalse(actual.HasValue);
            }
        }
        public async Task ProcessNewCluster()
        {
            bool calledActual = false;
            string nameTemplate = "Test:{0}";
            string nameActual = null;

            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                CreateClusterAsyncFunc = name =>
                {
                    nameActual = name;
                    calledActual = true;
                    return Task.FromResult(String.Format(nameTemplate, name));
                }
            };

            ClusterConfig config = new ClusterConfig();
            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);

            Cluster cluster = this.CreateCluster(ClusterStatus.New);

            Cluster actual = await target.ProcessClusterStatusAsync(cluster);

            Assert.IsTrue(calledActual);
            Assert.AreEqual(ClusterStatus.Creating, actual.Status);
            Assert.AreEqual(String.Format(nameTemplate, nameActual), actual.Address);
        }
        public async Task TestProcessRemoveTimeLimit()
        {
            bool calledActual = false;

            ClusterConfig config = new ClusterConfig()
            {
                MaxClusterUptime = TimeSpan.FromHours(2)
            };
             
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                DeleteClusterAsyncFunc = name =>
                {
                    calledActual = true;
                    return Task.FromResult(true);
                }
            };

            ClusterService target = new ClusterService(clusterOperator, stateManager)
            {
                Config = config
            };

            Cluster cluster = new Cluster()
            {
                Status = ClusterStatus.Ready,
                CreatedOn = DateTimeOffset.UtcNow - config.MaxClusterUptime
            };

            await target.ProcessClusterStatusAsync(cluster);

            Assert.IsTrue(calledActual);
            Assert.AreEqual(ClusterStatus.Deleting, cluster.Status);
        }
        public async Task ProcessClustersAsyncSaveChanges()
        {
            int key = 1;
            string nameTemplate = "Test:{0}";
            MockReliableStateManager stateManager = new MockReliableStateManager();
            ClusterConfig config = new ClusterConfig();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                CreateClusterAsyncFunc = name => { return Task.FromResult(String.Format(nameTemplate, name)); }
            };

            IReliableDictionary<int, Cluster> dictionary =
                await stateManager.GetOrAddAsync<IReliableDictionary<int, Cluster>>(ClusterService.ClusterDictionaryName);

            Cluster original = this.CreateCluster(ClusterStatus.New);
            using (ITransaction tx = stateManager.CreateTransaction())
            {
                await dictionary.SetAsync(tx, key, original);
            }

            ClusterService target = new ClusterService(
                clusterOperator,
                null,
                new MockApplicationDeployService(),
                stateManager,
                this.CreateServiceParameters(),
                config);

            await target.ProcessClustersAsync();

            using (ITransaction tx = stateManager.CreateTransaction())
            {
                Cluster actual = (await dictionary.TryGetValueAsync(tx, key)).Value;

                Assert.AreNotEqual(original, actual);
            }
        }
        public async Task TestProcessDeletingSuccessful()
        {
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = domain => Task.FromResult(ClusterOperationStatus.ClusterNotFound)
            };

            ClusterService target = new ClusterService(clusterOperator, stateManager);

            Cluster cluster = new Cluster()
            {
                Status = ClusterStatus.Deleting
            };

            await target.ProcessClusterStatusAsync(cluster);
            
            Assert.AreEqual(ClusterStatus.Deleted, cluster.Status);
        }
        public async Task TestProcessRemove()
        {
            bool calledActual = false;
            string nameActual = null;

            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                DeleteClusterAsyncFunc = name =>
                {
                    nameActual = name;
                    calledActual = true;
                    return Task.FromResult(true);
                }
            };

            ClusterService target = new ClusterService(clusterOperator, stateManager);

            Cluster cluster = new Cluster()
            {
                Status = ClusterStatus.Remove
            };

            await target.ProcessClusterStatusAsync(cluster);

            Assert.IsTrue(calledActual);
            Assert.AreEqual(ClusterStatus.Deleting, cluster.Status);
        }
        public async Task TestProcessCreatingClusterFailed()
        {
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = name => Task.FromResult(ClusterOperationStatus.CreateFailed)
            };

            ClusterService target = new ClusterService(clusterOperator, stateManager);
            Cluster cluster = new Cluster()
            {
                Status = ClusterStatus.Creating
            };

            await target.ProcessClusterStatusAsync(cluster);

            Assert.AreEqual(ClusterStatus.New, cluster.Status);
            Assert.AreEqual(0, cluster.Ports.Count());
            Assert.AreEqual(0, cluster.Users.Count());
        }
        public async Task TestProcessCreatingClusterSuccess()
        {
            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                GetClusterStatusAsyncFunc = name => Task.FromResult(ClusterOperationStatus.Ready)
            };

            ClusterService target = new ClusterService(clusterOperator, stateManager);
            Cluster cluster = new Cluster()
            {
                Status = ClusterStatus.Creating
            };

            await target.ProcessClusterStatusAsync(cluster);
            
            Assert.AreEqual(ClusterStatus.Ready, cluster.Status);
            Assert.IsTrue(cluster.CreatedOn.ToUniversalTime() <= DateTimeOffset.UtcNow);
            cluster.Ports.SequenceEqual(await clusterOperator.GetClusterPortsAsync(""));
        }
        public async Task TestProcessNewCluster()
        {
            bool calledActual = false;
            string nameTemplate = "Test:{0}";
            string nameActual = null;

            MockReliableStateManager stateManager = new MockReliableStateManager();
            MockClusterOperator clusterOperator = new MockClusterOperator()
            {
                CreateClusterAsyncFunc = name =>
                {
                    nameActual = name;
                    calledActual = true;
                    return Task.FromResult(String.Format(nameTemplate, name));
                }
            };

            ClusterService target = new ClusterService(clusterOperator, stateManager);

            Cluster cluster = new Cluster()
            {
                Status = ClusterStatus.New
            };

            await target.ProcessClusterStatusAsync(cluster);

            Assert.IsTrue(calledActual);
            Assert.AreEqual(ClusterStatus.Creating, cluster.Status);
            Assert.AreEqual(String.Format(nameTemplate, nameActual), cluster.Address);
        }