public void Create_RetriesTheCreateWhenRequestStatusReturnsFailed()
        {
            using (SpinLoop.ForTests(i => { }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();
                var createCallCount = 0;
                var requestId = 12345;
                Action incrCallCount = () =>
                {
                    createCallCount++;
                    api.NextRequestId = (++requestId).ToString();
                };

                api.Script.Add(incrCallCount);
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.InProgress);
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Failed);
                api.Script.Add(incrCallCount);
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Succeeded);

                var azureManagement = new AzureManagementApiWithRetries( api, 2, TimeSpan.FromMilliseconds(30000));

                var config = MockRepository.GenerateStub<IDeploymentConfiguration>();
                azureManagement.Create(FooUri, config);
                Assert.That(createCallCount, Is.EqualTo(2));
                var expectedUri = FooUri.ToRequestUri(api.NextRequestId);
                Assert.That(api.LastCheckRequestStatusRequestUri, Is.EqualTo(expectedUri));
            }
        }
        public void Create_CallsCreateWithExpectedArgs()
        {
            var api = new ScriptedAzureManagementLowLevelApiFake();

            var wasCalled = false;
            api.Script.Add(() => wasCalled = true);
            api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Succeeded);

            var azureManagement = new AzureManagementApiWithRetries(api, 2, TimeSpan.FromMilliseconds(30000));

            var config = MockRepository.GenerateStub<IDeploymentConfiguration>();
            azureManagement.Create(FooUri, config);

            Assert.That(wasCalled, "was called");
            Assert.That(api.BeginCreateDeploymentUri, Is.EqualTo(FooUri), "deployment uri");
            Assert.That(api.BeginCreateConfiguration, Is.SameAs(config));
        }
        public void Create_RetriesOnExpectedExceptionAndThrowsOnUnexpected()
        {
            using (SpinLoop.ForTests(i => { }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => { throw new ArgumentException(); });
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Succeeded);

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                var config = MockRepository.GenerateStub<IDeploymentConfiguration>();
                Assert.That(
                    () => azureManagement.Create(FooUri, config),
                    Throws.ArgumentException);
            }
        }
        public void Create_RetriesTheRightNumberOfTimesThenGivesUpAndThrowsIfException()
        {
            var sleepCount = 0;
            using (SpinLoop.ForTests(i => { sleepCount++; }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Succeeded);

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                var config = MockRepository.GenerateStub<IDeploymentConfiguration>();
                Assert.That(
                    () => azureManagement.Create(FooUri, config),
                    Throws.TypeOf<MaxRetriesExceededException>().With.InnerException.TypeOf<UnhandledHttpException>());
                Assert.That(sleepCount, Is.EqualTo(2));
            }
        }
        public void WaitForDeploymentStatus_ReturnsOnExpectedStatusAndRetriesOnUnexpectedStatus()
        {
            var retryCount = 0;
            using (SpinLoop.ForTests(i => retryCount++))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Running);
                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Suspended);

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                azureManagement.WaitForDeploymentStatus(FooUri, AzureDeploymentCheckOutcome.Suspended);

                Assert.That(retryCount, Is.EqualTo(1));
            }
        }
        public void WaitForDeploymentStatus_RethrowsIfUnexpectedExceptionThrown()
        {
            using (SpinLoop.ForTests(i => { }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Running );
                api.Script.Add(() => { throw new ArgumentException(); });

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                Assert.That(
                    () => azureManagement.WaitForDeploymentStatus(FooUri, AzureDeploymentCheckOutcome.Suspended),
                    Throws.ArgumentException);
            }
        }
        public void WaitForDeploymentStatus_CallsCheckDeploymentStatusWithCorrectUri()
        {
            var api = new ScriptedAzureManagementLowLevelApiFake();

            api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Running);

            var azureManagement = new AzureManagementApiWithRetries(api, 2, TimeSpan.FromMilliseconds(30000));

            azureManagement.WaitForDeploymentStatus(FooUri, AzureDeploymentCheckOutcome.Running);

            Assert.That(api.CheckStatusDeploymentUri, Is.EqualTo(FooUri));
        }
        public void Suspend_RetriesTheRightNumberOfTimesThenGivesUpAndThrowsIfException()
        {
            var sleepCount = 0;
            using (SpinLoop.ForTests(i => { sleepCount++; }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => { throw new UnhandledHttpException(); });

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                Assert.That(
                    () => azureManagement.Suspend(FooUri),
                    Throws.TypeOf<MaxRetriesExceededException>().With.InnerException.TypeOf<UnhandledHttpException>());
                Assert.That(sleepCount, Is.EqualTo(2));
            }
        }
        public void Suspend_RetriesOnExpectedExceptionAndThrowsOnUnexpected()
        {
            using (SpinLoop.ForTests(i => { }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => { throw new UnhandledHttpException(); });
                api.Script.Add(() => { throw new ArgumentException(); });

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                Assert.That(
                    () => azureManagement.Suspend(FooUri),
                    Throws.ArgumentException);
            }
        }
        public void Suspend_CallsBeginSuspend()
        {
            var api = new ScriptedAzureManagementLowLevelApiFake();

            var wasCalled = false;
            api.Script.Add(() => wasCalled = true);
            api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Succeeded);

            var azureManagement = new AzureManagementApiWithRetries(
                api, 2, TimeSpan.FromMilliseconds(30000));

            azureManagement.Suspend(FooUri);

            Assert.That(wasCalled, "was called");
            Assert.That(api.BeginSuspendDeploymentUri, Is.EqualTo(FooUri), "expected URI");
        }
        public void DoesDeploymentExist_ThrowsRetryExceptionIfFailedTooManyTimes()
        {
            var retryElapsedTime = 0;
            using(SpinLoop.ForTests(i => retryElapsedTime += i))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Failed);
                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Failed);
                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Failed);

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(20));

                Assert.That(
                    () => azureManagement.DoesDeploymentExist(FooUri),
                    Throws.TypeOf<MaxRetriesExceededException>());

                Assert.That(retryElapsedTime, Is.EqualTo(40));
            }
        }
        public void DoesDeploymentExist_ReturnsTrueIfSuspended()
        {
            var api = new ScriptedAzureManagementLowLevelApiFake();

            api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Suspended);

            var azureManagement = new AzureManagementApiWithRetries(api, 2, TimeSpan.FromMilliseconds(30000));

            Assert.That(azureManagement.DoesDeploymentExist(FooUri), Is.EqualTo(true), "return value");
            Assert.That(api.CheckStatusDeploymentUri, Is.EqualTo(FooUri), "deployment uri");
        }
        public void DoesDeploymentExist_RetriesOnFailed()
        {
            using (SpinLoop.ForTests(i => { }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();

                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Failed);
                api.Script.Add(() => api.NextDeploymentCheckOutcome = AzureDeploymentCheckOutcome.Running);

                var azureManagement = new AzureManagementApiWithRetries(api, 2, TimeSpan.FromMilliseconds(30000));

                Assert.That(azureManagement.DoesDeploymentExist(FooUri), Is.EqualTo(true), "return value");
                Assert.That(api.CheckStatusCounter, Is.EqualTo(2), "check status called the appropriate number of times");
            }
        }
        public void Delete_RetriesTheDeleteWhenRequestStatusReturnsFailed()
        {
            using (SpinLoop.ForTests(i => { }))
            {
                var api = new ScriptedAzureManagementLowLevelApiFake();
                var createCallCount = 0;
                var requestId = 12345;
                Action handleCall = () =>
                {
                    createCallCount++;
                    api.NextRequestId = (++requestId).ToString();
                };

                api.Script.Add(handleCall);
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.InProgress);
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Failed);
                api.Script.Add(handleCall);
                api.Script.Add(() => api.NextRequestStatus = AzureRequestStatus.Succeeded);

                var azureManagement = new AzureManagementApiWithRetries(
                    api, 2, TimeSpan.FromMilliseconds(30000));

                azureManagement.Delete(FooUri);
                Assert.That(createCallCount, Is.EqualTo(2));

                var expectedUri = FooUri.ToRequestUri(api.NextRequestId);
                Assert.That(api.LastCheckRequestStatusRequestUri, Is.EqualTo(expectedUri));
            }
        }
Beispiel #15
0
        static int Main(string[] args)
        {
            var consoleTraceListener = new OurConsoleTraceListener();
            OurTrace.AddListener(consoleTraceListener);
            OurTrace.Source.Switch.Level = SourceLevels.All;

            if(args.Length < 1)
            {
                Usage();
                return 0;
            }

            var tryToUseUpgradeDeployment = false;
            var fallbackToReplaceDeployment = false;
            var doNotRedeploy = false;
            if (args.Length > 1)
            {
                if (args.Contains("--try-to-use-upgrade-deployment"))
                    tryToUseUpgradeDeployment = true;
                if (args.Contains("--fallback-to-replace-deployment"))
                    fallbackToReplaceDeployment = true;
                if (args.Contains("--delete"))
                    doNotRedeploy = true;
            }

            var configuration = ConfigurationParser.ParseConfiguration(args[0]);
            var certificate = new X509Certificate2(configuration.CertFileName, configuration.CertPassword);
            var http = new Http(certificate);
            var azureDeploymentDeploymentLowLevelApi = new AzureManagementLowLevelApi(http);
            var managementApiWithRetries = new AzureManagementApiWithRetries(azureDeploymentDeploymentLowLevelApi, configuration.MaxRetries, TimeSpan.FromSeconds(configuration.RetryIntervalInSeconds));

            try
            {
                var deploymentSlotManager = new AzureDeploymentSlot(managementApiWithRetries, configuration.DeploymentSlotUri);
                if (doNotRedeploy)
                {
                    deploymentSlotManager.DeleteDeployment();
                    return 0;
                }

                var subscriptionId = configuration.DeploymentSlotUri.SubscriptionId;
                if (configuration.StorageAccountKey == null || configuration.StorageAccountName == null)
                {
                    OurTrace.TraceInfo("Attempting to guess account name and key based on certificate.");

                    if (string.IsNullOrWhiteSpace(configuration.StorageAccountName))
                    {
                        OurTrace.TraceInfo("Looking up storage accounts for the subscription.");
                        var storageAccounts = azureDeploymentDeploymentLowLevelApi.ListStorageAccounts(subscriptionId);
                        configuration.StorageAccountName = storageAccounts.FirstOrDefault();

                        if (string.IsNullOrWhiteSpace(configuration.StorageAccountName))
                        {
                            OurTrace.TraceError("Couldn't find any suitable storage accounts.");
                            throw new InvalidOperationException("No suitable storage accounts.");
                        }

                        if (!string.IsNullOrWhiteSpace(configuration.BlobPathToDeploy))
                        {
                            // don't allow BlobPathToDeploy if we're guessing the storage account.
                            OurTrace.TraceInfo("Ignoring BlobPathToDeploy because we're guessing the storage account.");
                            configuration.BlobPathToDeploy = null;
                        }
                    }

                    if (string.IsNullOrWhiteSpace(configuration.StorageAccountKey))
                    {
                        OurTrace.TraceInfo(string.Format("Looking up storage keys for account: {0}", configuration.StorageAccountName));
                        var storageKeys = azureDeploymentDeploymentLowLevelApi.GetStorageAccountKeys(subscriptionId, configuration.StorageAccountName);

                        configuration.StorageAccountKey = storageKeys.FirstOrDefault();

                        if (string.IsNullOrWhiteSpace(configuration.StorageAccountKey))
                        {
                            OurTrace.TraceError(string.Format("Couldn't find any keys for storage account: {0}", configuration.StorageAccountName));
                            throw new InvalidOperationException("No suitable storage account keys.");
                        }
                    }
                }

                var csPkg = configuration.PackageFileName;
                if (!string.IsNullOrWhiteSpace(configuration.ChangeVMSize))
                {
                    csPkg = Path.GetTempFileName();
                    File.Copy(configuration.PackageFileName, csPkg, true);
                    ChangeVmSize(csPkg, configuration.ChangeVMSize);
                }

                UploadBlob(csPkg, configuration.PackageUrl, configuration.StorageAccountName, configuration.StorageAccountKey);
                if(!string.IsNullOrWhiteSpace(configuration.BlobPathToDeploy))
                    DeployBlobs(configuration.BlobPathToDeploy, configuration.StorageAccountName, configuration.StorageAccountKey);

                if (tryToUseUpgradeDeployment && managementApiWithRetries.DoesDeploymentExist(configuration.DeploymentSlotUri))
                {
                    try
                    {
                        deploymentSlotManager.UpgradeDeployment(configuration);
                    }
                    catch(BadRequestException ex)
                    {
                        OurTrace.TraceError(string.Format("Upgrade failed with message: {0}\r\n, **** {1}", ex, fallbackToReplaceDeployment ? "falling back to replace." : "exiting."));
                        // retry using CreateOrReplaceDeployment, since we might have tried to do something that isn't allowed with UpgradeDeployment.
                        if (fallbackToReplaceDeployment)
                            deploymentSlotManager.CreateOrReplaceDeployment(configuration);
                        else
                            throw;
                    }
                }
                else
                {
                    deploymentSlotManager.CreateOrReplaceDeployment(configuration);
                }

                DeleteBlob(configuration.PackageUrl, configuration.StorageAccountName, configuration.StorageAccountKey);
            }
            catch(Exception ex)
            {
                OurTrace.TraceError(string.Format("exception!\n{0}", ex));
                return -1;
            }
            return 0;
        }
Beispiel #16
0
        static int Main(string[] args)
        {
            var consoleTraceListener = new OurConsoleTraceListener();
            OurTrace.AddListener(consoleTraceListener);
            OurTrace.Source.Switch.Level = SourceLevels.All;

            if(args.Length < 1)
            {
                Usage();
                return 0;
            }

            var tryToUseUpgradeDeployment = false;
            var fallbackToReplaceDeployment = false;
            var doNotRedeploy = false;
            if (args.Length > 1)
            {
                if (args.Contains("--try-to-use-upgrade-deployment"))
                    tryToUseUpgradeDeployment = true;
                if (args.Contains("--fallback-to-replace-deployment"))
                    fallbackToReplaceDeployment = true;
                if (args.Contains("--delete"))
                    doNotRedeploy = true;
            }

            var configuration = ConfigurationParser.ParseConfiguration(args[0]);
            var certificate = new X509Certificate2(configuration.CertFileName, configuration.CertPassword);
            var http = new Http(certificate);
            var azureDeploymentDeploymentLowLevelApi = new AzureManagementLowLevelApi(http);
            var managementApiWithRetries = new AzureManagementApiWithRetries(azureDeploymentDeploymentLowLevelApi, configuration.MaxRetries, TimeSpan.FromSeconds(configuration.RetryIntervalInSeconds));

            try
            {
                var deploymentSlotManager = new AzureDeploymentSlot(managementApiWithRetries, configuration.DeploymentSlotUri);
                if (doNotRedeploy)
                {
                    deploymentSlotManager.DeleteDeployment();
                    return 0;
                }

                UploadBlob(configuration.PackageFileName, configuration.PackageUrl, configuration.StorageAccountName, configuration.StorageAccountKey);

                if (tryToUseUpgradeDeployment && managementApiWithRetries.DoesDeploymentExist(configuration.DeploymentSlotUri))
                {
                    try
                    {
                        deploymentSlotManager.UpgradeDeployment(configuration);
                    }
                    catch(BadRequestException ex)
                    {
                        OurTrace.TraceError(string.Format("Upgrade failed with message: {0}\r\n, **** {1}", ex, fallbackToReplaceDeployment ? "falling back to replace." : "exiting."));
                        // retry using CreateOrReplaceDeployment, since we might have tried to do something that isn't allowed with UpgradeDeployment.
                        if (fallbackToReplaceDeployment)
                            deploymentSlotManager.CreateOrReplaceDeployment(configuration);
                        else
                            throw;
                    }
                }
                else
                {
                    deploymentSlotManager.CreateOrReplaceDeployment(configuration);
                }

                DeleteBlob(configuration.PackageUrl, configuration.StorageAccountName, configuration.StorageAccountKey);
            }
            catch(Exception ex)
            {
                OurTrace.TraceError(string.Format("exception!\n{0}", ex));
                return -1;
            }
            return 0;
        }