private async Task Assign(HostAssignmentContext assignmentContext)
        {
            try
            {
                // set a flag which will cause any incoming http requests to buffer
                // until specialization is complete
                WebScriptHostManager.DelayRequests = true;

                // first make all environment and file system changes required for
                // the host to be specialized
                await ApplyContext(assignmentContext);

                // all assignment settings/files have been applied so we can flip
                // the switch now on specialization
                _logger.LogInformation("Triggering specialization");
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Assign failed");
                throw;
            }
            finally
            {
                WebScriptHostManager.DelayRequests = false;
            }
        }
Пример #2
0
        public void IsWarmUpRequest_ReturnsExpectedValue()
        {
            var request = new HttpRequestMessage(HttpMethod.Post, "http://azure.com/api/warmup");

            Assert.False(StandbyManager.IsWarmUpRequest(request));

            var vars = new Dictionary <string, string>
            {
                { EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0" },
                { EnvironmentSettingNames.AzureWebsiteInstanceId, null }
            };

            using (var env = new TestScopedEnvironmentVariable(vars))
            {
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");
                Assert.False(StandbyManager.IsWarmUpRequest(request));

                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteInstanceId, "12345");
                Assert.True(StandbyManager.IsWarmUpRequest(request));

                request = new HttpRequestMessage(HttpMethod.Post, "http://azure.com/api/csharphttpwarmup");
                Assert.True(StandbyManager.IsWarmUpRequest(request));

                request = new HttpRequestMessage(HttpMethod.Post, "http://azure.com/api/warmup");
                request.Headers.Add(ScriptConstants.AntaresLogIdHeaderName, "xyz123");
                Assert.False(StandbyManager.IsWarmUpRequest(request));

                request = new HttpRequestMessage(HttpMethod.Post, "http://azure.com/api/foo");
                Assert.False(StandbyManager.IsWarmUpRequest(request));
            }
        }
Пример #3
0
        private async Task Specialize(HostAssignmentContext assignmentContext)
        {
            try
            {
                var zip = assignmentContext.ZipUrl;
                if (!string.IsNullOrEmpty(zip))
                {
                    // download zip and extract
                    var filePath = Path.GetTempFileName();

                    await DownloadAsync(new Uri(zip), filePath);

                    assignmentContext.ApplyAppSettings();

                    ZipFile.ExtractToDirectory(filePath, _webHostSettings.ScriptPath, overwriteFiles: true);
                }
                else
                {
                    assignmentContext.ApplyAppSettings();
                }

                // set flags which will trigger specialization
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error calling {nameof(Specialize)}");
            }
        }
Пример #4
0
        private async Task Assign(HostAssignmentContext assignmentContext)
        {
            try
            {
                // set a flag which will cause any incoming http requests to buffer
                // until specialization is complete
                // the host is guaranteed not to receive any requests until AFTER assign
                // has been initiated, so setting this flag here is sufficient to ensure
                // that any subsequent incoming requests while the assign is in progress
                // will be delayed until complete
                WebScriptHostManager.DelayRequests = true;

                // first make all environment and file system changes required for
                // the host to be specialized
                await ApplyContext(assignmentContext);

                // all assignment settings/files have been applied so we can flip
                // the switch now on specialization
                _logger.LogInformation("Triggering specialization");
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0");
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteContainerReady, "1");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Assign failed");
                throw;
            }
            finally
            {
                WebScriptHostManager.DelayRequests = false;
            }
        }
Пример #5
0
        private void SetVariables()
        {
            foreach (var item in _variables)
            {
                _existingVariables.Add(item.Key, _settingsManager.GetSetting(item.Key));

                _settingsManager.SetSetting(item.Key, item.Value);
            }
        }
Пример #6
0
        public void IsWarmUpRequest_ReturnsExpectedValue()
        {
            var request = HttpTestHelpers.CreateHttpRequest("POST", "http://azure.com/api/warmup");

            Assert.False(StandbyManager.IsWarmUpRequest(request));

            var vars = new Dictionary <string, string>
            {
                { EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0" },
                { EnvironmentSettingNames.AzureWebsiteInstanceId, null }
            };

            using (var env = new TestScopedEnvironmentVariable(vars))
            {
                // in this test we're forcing a transition from non-placeholder mode to placeholder mode
                // which can't happen in the wild, so we force a reset here
                WebScriptHostManager.ResetStandbyMode();

                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");
                Assert.False(StandbyManager.IsWarmUpRequest(request));

                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteInstanceId, "12345");
                Assert.True(StandbyManager.IsWarmUpRequest(request));

                request = HttpTestHelpers.CreateHttpRequest("POST", "http://azure.com/api/csharphttpwarmup");
                Assert.True(StandbyManager.IsWarmUpRequest(request));

                request = HttpTestHelpers.CreateHttpRequest("POST", "http://azure.com/api/warmup");
                request.Headers.Add(ScriptConstants.AntaresLogIdHeaderName, "xyz123");
                Assert.False(StandbyManager.IsWarmUpRequest(request));

                request = HttpTestHelpers.CreateHttpRequest("POST", "http://azure.com/api/foo");
                Assert.False(StandbyManager.IsWarmUpRequest(request));
            }

            vars = new Dictionary <string, string>
            {
                { EnvironmentSettingNames.AzureWebsitePlaceholderMode, "0" },
                { EnvironmentSettingNames.AzureWebsiteInstanceId, null }
            };
            using (var env = new TestScopedEnvironmentVariable(vars))
            {
                WebScriptHostManager.ResetStandbyMode();

                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");
                Assert.False(StandbyManager.IsWarmUpRequest(request));

                request = HttpTestHelpers.CreateHttpRequest("POST", "http://azure.com/api/warmup");
                _settingsManager.SetSetting(EnvironmentSettingNames.ContainerName, "TestContainer");
                Assert.True(_settingsManager.IsLinuxContainerEnvironment);
                Assert.True(StandbyManager.IsWarmUpRequest(request));
            }
        }
        public SystemTraceWriterTests()
        {
            _settingsManager = new ScriptSettingsManager();

            _subscriptionId = "e3235165-1600-4819-85f0-2ab362e909e4";
            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteOwnerName, $"{_subscriptionId}+westuswebspace");

            _websiteName = "functionstest";
            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHostName, $"{_websiteName}.azurewebsites.net");

            _mockEventGenerator = new Mock <IEventGenerator>(MockBehavior.Strict);
            _traceWriter        = new SystemTraceWriter(_mockEventGenerator.Object, _settingsManager, TraceLevel.Verbose);
        }
Пример #8
0
            public void Dispose()
            {
                Reset();

                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHomePath, _prevHome);
                try
                {
                    Directory.Delete(_home, recursive: true);
                }
                catch
                {
                    // best effort
                }
            }
        public SystemLoggerTests()
        {
            _settingsManager = ScriptSettingsManager.Instance;

            _subscriptionId = "e3235165-1600-4819-85f0-2ab362e909e4";
            _hostInstanceId = Guid.NewGuid().ToString();
            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteOwnerName, $"{_subscriptionId}+westuswebspace");

            _websiteName = "functionstest";
            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteName, _websiteName);

            _mockEventGenerator = new Mock <IEventGenerator>(MockBehavior.Strict);

            _category = LogCategories.CreateFunctionCategory(_functionName);
            _logger   = new SystemLogger(_hostInstanceId, _category, _mockEventGenerator.Object, _settingsManager);
        }
        public void Dispose()
        {
            if (Directory.Exists(_runPath))
            {
                Directory.Delete(_runPath, true);
            }

            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHomePath, _oldHomeEnv);
        }
Пример #11
0
            public TestEnvironment()
            {
                _settingsManager = ScriptSettingsManager.Instance;
                _prevHome        = _settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath);

                _home = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                Directory.CreateDirectory(_home);
                _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHomePath, _home);

                Reset();
            }
        public void Dispose()
        {
            if (Directory.Exists(_runPath))
            {
                try
                {
                    Directory.Delete(_runPath, true);
                }
                catch
                {
                    // best effort cleanup
                }
            }

            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHomePath, _oldHomeEnv);
        }
        public async Task StartAssignment_AppliesAssignmentContext()
        {
            var envValue = new
            {
                Name  = Path.GetTempFileName().Replace(".", string.Empty),
                Value = Guid.NewGuid().ToString()
            };

            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");
            WebScriptHostManager.ResetStandbyMode();
            var context = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>
                {
                    { envValue.Name, envValue.Value }
                }
            };
            bool result = _instanceManager.StartAssignment(context);

            Assert.True(result);
            Assert.True(WebScriptHostManager.InStandbyMode);

            // specialization is done in the background
            await Task.Delay(500);

            var value = Environment.GetEnvironmentVariable(envValue.Name);

            Assert.Equal(value, envValue.Value);

            // verify logs
            var logs = _loggerProvider.GetAllLogMessages().Select(p => p.FormattedMessage).ToArray();

            Assert.Collection(logs,
                              p => Assert.StartsWith("Starting Assignment", p),
                              p => Assert.StartsWith("Applying 1 app setting(s)", p),
                              p => Assert.StartsWith("Triggering specialization", p));

            // calling again should return false, since we're no longer
            // in placeholder mode
            _loggerProvider.ClearAllLogMessages();
            result = _instanceManager.StartAssignment(context);
            Assert.False(result);

            logs = _loggerProvider.GetAllLogMessages().Select(p => p.FormattedMessage).ToArray();
            Assert.Collection(logs,
                              p => Assert.StartsWith("Assign called while host is not in placeholder mode", p));
        }
        public PackageAssemblyResolverTests()
        {
            _settingsManager        = ScriptSettingsManager.Instance;
            _runPath                = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            _lockFilePath           = Path.Combine(_runPath, DotNetConstants.ProjectLockFileName);
            _oldHomeEnv             = _settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath);
            _targetAssemblyPath     = Path.Combine(_runPath, "data\\Functions\\packages\\nuget\\Test.Package\\1.0.0\\lib\\net45");
            _targetAssemblyFilePath = Path.Combine(_targetAssemblyPath, Path.GetFileName(this.GetType().Assembly.Location));
            Directory.CreateDirectory(_targetAssemblyPath);

            // Copy current assembly to target package reference location
            File.Copy(this.GetType().Assembly.Location, _targetAssemblyFilePath);

            // Create our Lock file using the current assembly as the target
            File.WriteAllText(_lockFilePath, string.Format(Resources.ProjectLockFileFormatString, Path.GetFileName(this.GetType().Assembly.Location)));

            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHomePath, _runPath);
        }
        public async Task StartAssignment_AppliesAssignmentContext()
        {
            var loggerFactory   = MockNullLogerFactory.CreateLoggerFactory();
            var settingsManager = new ScriptSettingsManager();
            var instanceManager = new InstanceManager(settingsManager, null, loggerFactory, null);
            var envValue        = new
            {
                Name  = Path.GetTempFileName().Replace(".", string.Empty),
                Value = Guid.NewGuid().ToString()
            };

            settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");
            WebScriptHostManager.ResetStandbyMode();
            var context = new HostAssignmentContext
            {
                Environment = new Dictionary <string, string>
                {
                    { envValue.Name, envValue.Value }
                }
            };
            bool result = instanceManager.StartAssignment(context);

            Assert.True(result);

            // specialization is done in the background
            await Task.Delay(500);

            var value = Environment.GetEnvironmentVariable(envValue.Name);

            Assert.Equal(value, envValue.Value);

            // calling again should return false, since we're no longer
            // in placeholder mode
            result = instanceManager.StartAssignment(context);
            Assert.False(result);
        }
        public async Task GetHostSecrets_WhenTooManyBackups_ThrowsException()
        {
            using (var directory = new TempDirectory())
            {
                string functionName         = "testfunction";
                string expectedTraceMessage = string.Format(Resources.ErrorTooManySecretBackups, ScriptConstants.MaximumSecretBackupCount, functionName,
                                                            string.Format(Resources.ErrorSameSecrets, "test0,test1"));
                string functionSecretsJson =
                    @"{
    'keys': [
        {
            'name': 'Key1',
            'value': 'FunctionValue1',
            'encrypted': true
        },
        {
            'name': 'Key2',
            'value': 'FunctionValue2',
            'encrypted': false
        }
    ]
}";
                ILoggerFactory     loggerFactory  = new LoggerFactory();
                TestLoggerProvider loggerProvider = new TestLoggerProvider();
                loggerFactory.AddProvider(loggerProvider);
                var logger = loggerFactory.CreateLogger(LogCategories.CreateFunctionCategory("Test1"));
                IDictionary <string, string> functionSecrets;
                ISecretsRepository           repository = new FileSystemSecretsRepository(directory.Path);

                using (var secretManager = new SecretManager(_settingsManager, repository, logger))
                {
                    InvalidOperationException ioe = null;
                    try
                    {
                        for (int i = 0; i < ScriptConstants.MaximumSecretBackupCount + 20; i++)
                        {
                            File.WriteAllText(Path.Combine(directory.Path, functionName + ".json"), functionSecretsJson);

                            // If we haven't hit the exception yet, pause to ensure the file contents are being flushed.
                            if (i >= ScriptConstants.MaximumSecretBackupCount)
                            {
                                await Task.Delay(500);
                            }

                            string hostName = "test" + (i % 2).ToString();
                            _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHostName, hostName);
                            functionSecrets = await secretManager.GetFunctionSecretsAsync(functionName);
                        }
                    }
                    catch (InvalidOperationException ex)
                    {
                        ioe = ex;
                    }
                    finally
                    {
                        _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHostName, null);
                    }
                }

                Assert.True(Directory.GetFiles(directory.Path, $"{functionName}.{ScriptConstants.Snapshot}*").Length >= ScriptConstants.MaximumSecretBackupCount);
                Assert.True(loggerProvider.GetAllLogMessages().Any(
                                t => t.Level == LogLevel.Debug && t.FormattedMessage.IndexOf(expectedTraceMessage, StringComparison.OrdinalIgnoreCase) > -1),
                            "Expected Trace message not found");
            }
        }
 public void Dispose()
 {
     _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteOwnerName, null);
     _settingsManager.SetSetting(EnvironmentSettingNames.AzureWebsiteHostName, null);
 }