From 9823a4654c6476e148d498c329e7aab85d484f3e Mon Sep 17 00:00:00 2001 From: Shyju Krishnankutty Date: Fri, 14 Jun 2024 11:24:49 -0700 Subject: [PATCH] Fixed incorrect function count in the log message when getting function metadata from providers (#10224) * Fixed incorrect function count in the log message.(#10220) * Minor variable rename * Check DefaultOrEmpty before accessing Length of immutable array. * Fix integration test to reflect the change. --- release_notes.md | 3 +- .../Host/FunctionMetadataManager.cs | 7 +-- .../ApplicationInsightsEndToEndTestsBase.cs | 2 +- .../FunctionMetadataManagerTests.cs | 49 +++++++++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/release_notes.md b/release_notes.md index 6530ef8ecb..9dd3ae7228 100644 --- a/release_notes.md +++ b/release_notes.md @@ -15,4 +15,5 @@ - Ensuring proxies are disabled, with a warning, when running in Flex Consumption. - Fixed an issue leading to a race when invocation responses returned prior to HTTP requests being sent in proxied scenarios. - Language worker channels will not be started during placeholder mode if we are in-process (#10161) -- Ordered invocations are now the default (#10201) \ No newline at end of file +- Ordered invocations are now the default (#10201) +- Fixed incorrect function count in the log message.(#10220) \ No newline at end of file diff --git a/src/WebJobs.Script/Host/FunctionMetadataManager.cs b/src/WebJobs.Script/Host/FunctionMetadataManager.cs index a188d537e8..a95ca6831e 100644 --- a/src/WebJobs.Script/Host/FunctionMetadataManager.cs +++ b/src/WebJobs.Script/Host/FunctionMetadataManager.cs @@ -222,14 +222,15 @@ private void AddMetadataFromCustomProviders(IEnumerable funct functionProviderTasks.Add(functionProvider.GetFunctionMetadataAsync()); } - var functionMetadataListArray = Task.WhenAll(functionProviderTasks).GetAwaiter().GetResult(); + var providerFunctionMetadataResults = Task.WhenAll(functionProviderTasks).GetAwaiter().GetResult(); + var totalFunctionsCount = providerFunctionMetadataResults.Where(metadataArray => !metadataArray.IsDefaultOrEmpty).Sum(metadataArray => metadataArray.Length); // This is used to make sure no duplicates are registered var distinctFunctionNames = new HashSet(functionMetadataList.Select(m => m.Name)); - _logger.FunctionsReturnedByProvider(functionMetadataListArray.Length, _metadataProviderName); + _logger.FunctionsReturnedByProvider(totalFunctionsCount, _metadataProviderName); - foreach (var metadataArray in functionMetadataListArray) + foreach (var metadataArray in providerFunctionMetadataResults) { if (!metadataArray.IsDefaultOrEmpty) { diff --git a/test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsEndToEndTestsBase.cs b/test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsEndToEndTestsBase.cs index 78d98ade26..b42674a4a4 100644 --- a/test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsEndToEndTestsBase.cs +++ b/test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsEndToEndTestsBase.cs @@ -278,7 +278,7 @@ public async Task Validate_HostLogs() Assert.True(traces.Length == expectedCount, $"Expected {expectedCount} messages, but found {traces.Length}. Actual logs:{Environment.NewLine}{string.Join(Environment.NewLine, traces.Select(t => t.Message))}"); int idx = 0; - ValidateTrace(traces[idx++], "1 functions found", LogCategories.Startup); + ValidateTrace(traces[idx++], "0 functions found", LogCategories.Startup); ValidateTrace(traces[idx++], "2 functions loaded", LogCategories.Startup); ValidateTrace(traces[idx++], "A function allow list has been specified", LogCategories.Startup); ValidateTrace(traces[idx++], "Found the following functions:\r\n", LogCategories.Startup); diff --git a/test/WebJobs.Script.Tests/FunctionMetadataManagerTests.cs b/test/WebJobs.Script.Tests/FunctionMetadataManagerTests.cs index 6745b6156c..e1260162c9 100644 --- a/test/WebJobs.Script.Tests/FunctionMetadataManagerTests.cs +++ b/test/WebJobs.Script.Tests/FunctionMetadataManagerTests.cs @@ -138,6 +138,55 @@ public void FunctionMetadataManager_DoesNotError_MissingScriptFile_InWebHostMode Assert.False(testFunctionMetadataManager.IsScriptFileDetermined(testMetadata)); } + [Fact] + public void FunctionMetadataManager_GetsMetadata_FromMultipleFunctionProviders_Success() + { + var functionMetadataCollection1 = new Collection + { + GetTestFunctionMetadata("somefile.dll", name: "HelloHttp") + }; + + var functionMetadataCollection2 = new Collection + { + GetTestFunctionMetadata("somefile2.dll", name: "Function1"), + GetTestFunctionMetadata("somefile2.dll", name: "Function2"), + GetTestFunctionMetadata("somefile2.dll", name: "Function3") + }; + + var expectedTotalFunctionsCount = functionMetadataCollection1.Count + functionMetadataCollection2.Count; + + var mockFunctionMetadataProvider = new Mock(); + mockFunctionMetadataProvider.Setup(m => m.GetFunctionMetadataAsync(It.IsAny>(), It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(new Collection().ToImmutableArray())); + mockFunctionMetadataProvider.Setup(m => m.FunctionErrors) + .Returns(new Dictionary>().ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray())); + + var mockFunctionProvider = new Mock(); + mockFunctionProvider.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection1.ToImmutableArray()); + + var mockFunctionProvider2 = new Mock(); + mockFunctionProvider2.Setup(m => m.GetFunctionMetadataAsync()).ReturnsAsync(functionMetadataCollection2.ToImmutableArray()); + + var testLoggerProvider = new TestLoggerProvider(); + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(testLoggerProvider); + + FunctionMetadataManager testFunctionMetadataManager = TestFunctionMetadataManager.GetFunctionMetadataManager( + new OptionsWrapper(_scriptJobHostOptions), + mockFunctionMetadataProvider.Object, + new List() { mockFunctionProvider.Object, mockFunctionProvider2.Object }, + new OptionsWrapper(_defaultHttpWorkerOptions), + loggerFactory, + new TestOptionsMonitor(TestHelpers.GetTestLanguageWorkerOptions())); + + var actualFunctionMetadata = testFunctionMetadataManager.LoadFunctionMetadata(); + + var traces = testLoggerProvider.GetAllLogMessages(); + Assert.Equal(expectedTotalFunctionsCount, actualFunctionMetadata.Length); + Assert.Single(traces.Where(t => t.FormattedMessage.Contains("Reading functions metadata (Custom)"))); + Assert.Single(traces.Where(t => t.FormattedMessage.Contains($"{expectedTotalFunctionsCount} functions found (Custom)"))); + } + [Fact] public void FunctionMetadataManager_GetsMetadata_FromFunctionProviders() {