public void Returns_IsLinuxConsumption(string websiteInstanceId, string containerName, bool isLinuxConsumption) { var testEnvironment = new TestEnvironment(); testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteInstanceId, websiteInstanceId); testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerName, containerName); Assert.Equal(isLinuxConsumption, testEnvironment.IsLinuxConsumption()); Assert.Equal(isLinuxConsumption, testEnvironment.IsConsumptionSku()); Assert.Equal(isLinuxConsumption, testEnvironment.IsDynamicSku()); }
public async Task StandbyModeE2E_LinuxContainer() { byte[] bytes = TestHelpers.GenerateKeyBytes(); var encryptionKey = Convert.ToBase64String(bytes); var containerName = "testContainer"; var vars = new Dictionary <string, string> { { EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1" }, { EnvironmentSettingNames.ContainerName, containerName }, { EnvironmentSettingNames.AzureWebsiteHostName, "testapp.azurewebsites.net" }, { EnvironmentSettingNames.AzureWebsiteName, "TestApp" }, { EnvironmentSettingNames.ContainerEncryptionKey, encryptionKey }, { EnvironmentSettingNames.AzureWebsiteContainerReady, null }, { EnvironmentSettingNames.AzureWebsiteSku, "Dynamic" }, { EnvironmentSettingNames.AzureWebsiteZipDeployment, null }, { "AzureWebEncryptionKey", "0F75CA46E7EBDD39E4CA6B074D1F9A5972B849A55F91A248" } }; var environment = new TestEnvironment(vars); Assert.True(environment.IsLinuxConsumption()); await InitializeTestHostAsync("Linux", environment); // Check that the filesystem is not read-only before specialization. var options = _httpServer.Host.Services.GetService <IOptionsMonitor <ScriptApplicationHostOptions> >(); Assert.False(options.CurrentValue.IsFileSystemReadOnly); // verify only the Warmup function is present // generally when in placeholder mode, the list API won't be called // but we're doing this for regression testing var functions = await ListFunctions(); Assert.Equal(1, functions.Length); Assert.Equal("WarmUp", functions[0]); await VerifyWarmupSucceeds(); await VerifyWarmupSucceeds(restart : true); // now specialize the site await Assign(encryptionKey); // immediately call a function - expect the call to block until // the host is fully specialized // the Unauthorized is expected since we haven't specified the key // it's enough here to ensure we don't get a 404 var request = new HttpRequestMessage(HttpMethod.Get, $"api/httptrigger"); request.Headers.Add(ScriptConstants.AntaresColdStartHeaderName, "1"); var response = await _httpClient.SendAsync(request); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); // now that the host is initialized, send a valid key // and expect success var secretManager = _httpServer.Host.Services.GetService <ISecretManagerProvider>().Current; var fd = _httpServer.Host.Services.GetService <IFunctionInvocationDispatcherFactory>(); var keys = await secretManager.GetFunctionSecretsAsync("HttpTrigger"); string key = keys.First().Value; request = new HttpRequestMessage(HttpMethod.Get, $"api/httptrigger?code={key}"); request.Headers.Add(ScriptConstants.AntaresColdStartHeaderName, "1"); response = await _httpClient.SendAsync(request); Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.False(environment.IsPlaceholderModeEnabled()); Assert.True(environment.IsContainerReady()); // verify that after specialization the correct // app content is returned functions = await ListFunctions(); Assert.Equal(1, functions.Length); Assert.Equal("HttpTrigger", functions[0]); // Check options are refreshed after specialization. // The filesystem should be read-only since the app is running from zip. Assert.True(options.CurrentValue.IsFileSystemReadOnly); // verify warmup function no longer there request = new HttpRequestMessage(HttpMethod.Get, "api/warmup"); response = await _httpClient.SendAsync(request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); string hostId = "testapp"; // verify the expected logs var logLines = _loggerProvider.GetAllLogMessages().Where(p => p.FormattedMessage != null).Select(p => p.FormattedMessage).ToArray(); Assert.True(logLines.Count(p => p.Contains("Stopping JobHost")) >= 1); Assert.Equal(1, logLines.Count(p => p.Contains("Creating StandbyMode placeholder function directory"))); Assert.Equal(1, logLines.Count(p => p.Contains("StandbyMode placeholder function directory created"))); Assert.Equal(2, logLines.Count(p => p.Contains("Host is in standby mode"))); Assert.Equal(2, logLines.Count(p => p.Contains("Executed 'Functions.WarmUp' (Succeeded"))); Assert.Equal(1, logLines.Count(p => p.Contains("Validating host assignment context"))); Assert.Equal(1, logLines.Count(p => p.Contains("Starting Assignment"))); Assert.Equal(1, logLines.Count(p => p.Contains("Applying 3 app setting(s)"))); Assert.Equal(2, logLines.Count(p => p.Contains($"Skipping WorkerConfig for language:python"))); Assert.Equal(2, logLines.Count(p => p.Contains($"Skipping WorkerConfig for language:powershell"))); Assert.Equal(2, logLines.Count(p => p.Contains($"Skipping WorkerConfig for language:java"))); Assert.Equal(1, logLines.Count(p => p.Contains($"Extracting files to '{_expectedScriptPath}'"))); Assert.Equal(1, logLines.Count(p => p.Contains("Zip extraction complete"))); Assert.Equal(1, logLines.Count(p => p.Contains("Triggering specialization"))); Assert.Equal(1, logLines.Count(p => p.Contains("Starting host specialization"))); Assert.Equal(3, logLines.Count(p => p.Contains($"Starting Host (HostId={hostId}"))); Assert.Equal(3, logLines.Count(p => p.Contains($"Loading proxies metadata"))); Assert.Equal(3, logLines.Count(p => p.Contains("Initializing Azure Function proxies"))); Assert.Equal(2, logLines.Count(p => p.Contains($"1 proxies loaded"))); Assert.Equal(1, logLines.Count(p => p.Contains($"0 proxies loaded"))); Assert.Contains("Node.js HttpTrigger function invoked.", logLines); // verify cold start log entry var coldStartLog = _loggerProvider.GetAllLogMessages().FirstOrDefault(p => p.Category == ScriptConstants.LogCategoryHostMetrics); JObject coldStartData = JObject.Parse(coldStartLog.FormattedMessage); Assert.Equal("Dynamic", coldStartData["sku"]); // TODO: https://github.com/Azure/azure-functions-host/issues/5389 //Assert.True((int)coldStartData["dispatchDuration"] > 0); Assert.True((int)coldStartData["functionDuration"] > 0); // Verify that the internal cache has reset Assert.NotSame(GetCachedTimeZoneInfo(), _originalTimeZoneInfoCache); }