Skip to content

Commit 0b946c1

Browse files
committed
adding mocked SystemLogger and MetricsLogger tests
1 parent 03862df commit 0b946c1

22 files changed

+293
-82
lines changed

src/WebJobs.Script.WebHost/WebScriptHostBuilderExtension.cs

+2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ public static IHostBuilder AddWebScriptHost(this IHostBuilder builder, IServiceP
9292
// Hosted services
9393
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, HttpInitializationService>());
9494
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, FileMonitoringService>());
95+
96+
ConfigureRegisteredBuilders(services, rootServiceProvider);
9597
});
9698

9799
var debugStateProvider = rootServiceProvider.GetService<IDebugStateProvider>();

test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsEndToEndTestsBase.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
using Microsoft.ApplicationInsights.Extensibility.Implementation;
1414
using Microsoft.Azure.WebJobs.Host;
1515
using Microsoft.Azure.WebJobs.Logging;
16+
using Microsoft.Azure.WebJobs.Script.Diagnostics;
17+
using Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics;
1618
using Microsoft.Extensions.Configuration;
1719
using Microsoft.Extensions.DependencyInjection;
1820
using Microsoft.Extensions.Hosting;
@@ -78,16 +80,15 @@ public async Task Validate_Manual()
7880
}
7981
}
8082

81-
// TODO: Re-enable this when we can override IMetricsLogger
8283
// App Insights logs first, so wait until this metric appears
83-
// string metricKey = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, functionName);
84-
// IEnumerable<string> GetMetrics() => _fixture.MetricsLogger.LoggedEvents.Where(p => p == metricKey);
84+
string metricKey = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, functionName);
85+
IEnumerable<string> GetMetrics() => _fixture.MetricsLogger.LoggedEvents.Where(p => p == metricKey);
8586

8687
// TODO: Remove this check when metrics are supported in Node:
8788
// https://github.com/Azure/azure-functions-host/issues/2189
88-
// int expectedCount = this is ApplicationInsightsCSharpEndToEndTests ? 10 : 5;
89-
// await TestHelpers.Await(() => GetMetrics().Count() == expectedCount,
90-
// timeout: 15000, userMessageCallback: () => string.Join(Environment.NewLine, GetMetrics().Select(p => p.ToString())));
89+
int expectedCount = this is ApplicationInsightsCSharpEndToEndTests ? 10 : 5;
90+
await TestHelpers.Await(() => GetMetrics().Count() == expectedCount,
91+
timeout: 15000, userMessageCallback: () => string.Join(Environment.NewLine, GetMetrics().Select(p => p.ToString())));
9192
}
9293

9394
[Fact]

test/WebJobs.Script.Tests.Integration/ApplicationInsights/ApplicationInsightsTestFixture.cs

+5-6
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,20 @@ public ApplicationInsightsTestFixture(string scriptRoot, string testId)
3232
};
3333

3434
TestHost = new TestFunctionHost(scriptPath, logPath,
35-
jobHostBuilder =>
35+
configureScriptHostServices: s =>
3636
{
37-
jobHostBuilder.Services.AddSingleton<ITelemetryChannel>(_ => Channel);
38-
jobHostBuilder.Services.AddSingleton<IMetricsLogger>(_ => MetricsLogger);
39-
40-
jobHostBuilder.Services.Configure<ScriptJobHostOptions>(o =>
37+
s.AddSingleton<ITelemetryChannel>(_ => Channel);
38+
s.Configure<ScriptJobHostOptions>(o =>
4139
{
4240
o.Functions = new[]
4341
{
4442
"Scenarios",
4543
"HttpTrigger-Scenarios"
4644
};
4745
});
46+
s.AddSingleton<IMetricsLogger>(_ => MetricsLogger);
4847
},
49-
configurationBuilder =>
48+
configureScriptHostAppConfiguration: configurationBuilder =>
5049
{
5150
configurationBuilder.AddInMemoryCollection(new Dictionary<string, string>
5251
{

test/WebJobs.Script.Tests.Integration/CosmosDB/CosmosDBEndToEndTestsBase.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ protected override ExtensionPackageReference[] GetExtensionsToInstall()
102102
};
103103
}
104104

105-
public override void ConfigureJobHost(IWebJobsBuilder webJobsBuilder)
105+
public override void ConfigureScriptHost(IWebJobsBuilder webJobsBuilder)
106106
{
107107
webJobsBuilder.Services.Configure<ScriptJobHostOptions>(o =>
108108
{

test/WebJobs.Script.Tests.Integration/EventHubs/EventHubsEndToEndTestsBase.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Threading.Tasks;
7-
using Microsoft.Azure.EventHubs;
87
using Microsoft.Azure.WebJobs.Script.Models;
98
using Microsoft.Azure.WebJobs.Script.Rpc;
109
using Microsoft.Extensions.DependencyInjection;
11-
using Microsoft.Extensions.Hosting;
1210
using Newtonsoft.Json.Linq;
1311
using Xunit;
1412

@@ -72,7 +70,7 @@ protected override ExtensionPackageReference[] GetExtensionsToInstall()
7270
};
7371
}
7472

75-
public override void ConfigureJobHost(IWebJobsBuilder webJobsBuilder)
73+
public override void ConfigureScriptHost(IWebJobsBuilder webJobsBuilder)
7674
{
7775
webJobsBuilder.Services.Configure<ScriptJobHostOptions>(o =>
7876
{

test/WebJobs.Script.Tests.Integration/Host/StandbyManager/StandbyInitializationTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ public async Task IsPlaceholderMode_ThroughoutInitialization_EvaluatesCorrectly(
6666
Specialize(e);
6767
});
6868
})
69-
.AddScriptHostBuilder(webJobsBuilder =>
69+
.ConfigureScriptHostServices(s =>
7070
{
71-
webJobsBuilder.Services.PostConfigure<ScriptJobHostOptions>(o =>
71+
s.PostConfigure<ScriptJobHostOptions>(o =>
7272
{
7373
// Only load the function we care about, but not during standby
7474
if (o.RootScriptPath != standbyPath)

test/WebJobs.Script.Tests.Integration/Host/WebJobsScriptHostServiceTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public WebJobsScriptHostServiceTests()
6969
.Returns(() => _underHighLoad);
7070

7171
_testHost = new TestFunctionHost(testScriptPath, testLogPath,
72-
configureServices: services =>
72+
configureWebHostServices: services =>
7373
{
7474
services.AddSingleton<IOptions<HostHealthMonitorOptions>>(wrappedHealthMonitorOptions);
7575
services.AddSingleton<IScriptJobHostEnvironment>(_mockJobHostEnvironment.Object);

test/WebJobs.Script.Tests.Integration/TestFunctionHost.cs

+70-25
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ public class TestFunctionHost : IDisposable
3737
private readonly WebJobsScriptHostService _hostService;
3838

3939
public TestFunctionHost(string scriptPath, string logPath,
40-
Action<IWebJobsBuilder> configureJobHost = null,
41-
Action<IConfigurationBuilder> configureAppConfiguration = null,
42-
Action<IServiceCollection> configureServices = null)
40+
Action<IServiceCollection> configureWebHostServices = null,
41+
Action<IWebJobsBuilder> configureScriptHostWebJobsBuilder = null,
42+
Action<IConfigurationBuilder> configureScriptHostAppConfiguration = null,
43+
Action<ILoggingBuilder> configureScriptHostLogging = null,
44+
Action<IServiceCollection> configureScriptHostServices = null)
4345
{
4446
_appRoot = scriptPath;
4547

@@ -65,32 +67,37 @@ public TestFunctionHost(string scriptPath, string logPath,
6567
services.Replace(new ServiceDescriptor(typeof(IOptions<ScriptApplicationHostOptions>), new OptionsWrapper<ScriptApplicationHostOptions>(_hostOptions)));
6668
services.Replace(new ServiceDescriptor(typeof(IOptionsMonitor<ScriptApplicationHostOptions>), optionsMonitor));
6769

68-
services.AddSingleton<IConfigureBuilder<IConfigurationBuilder>>(_ => new DelegatedConfigureBuilder<IConfigurationBuilder>(c =>
69-
{
70-
c.AddTestSettings();
71-
configureAppConfiguration?.Invoke(c);
72-
}));
73-
74-
configureServices?.Invoke(services);
75-
})
76-
.AddScriptHostBuilder(webJobsBuilder =>
77-
{
78-
webJobsBuilder.Services.AddLogging(loggingBuilder =>
79-
{
80-
loggingBuilder.AddProvider(_scriptHostLoggerProvider);
81-
loggingBuilder.AddFilter<TestLoggerProvider>(_ => true);
82-
});
83-
84-
webJobsBuilder.AddAzureStorage();
85-
86-
configureJobHost?.Invoke(webJobsBuilder);
70+
// Allows us to configure services as the last step, thereby overriding anything
71+
services.AddSingleton(new PostConfigureServices(configureWebHostServices));
8772
})
88-
.UseStartup<Startup>();
73+
.ConfigureScriptHostWebJobsBuilder(scriptHostWebJobsBuilder =>
74+
{
75+
scriptHostWebJobsBuilder.AddAzureStorage();
76+
configureScriptHostWebJobsBuilder?.Invoke(scriptHostWebJobsBuilder);
77+
})
78+
.ConfigureScriptHostAppConfiguration(scriptHostConfigurationBuilder =>
79+
{
80+
scriptHostConfigurationBuilder.AddTestSettings();
81+
configureScriptHostAppConfiguration?.Invoke(scriptHostConfigurationBuilder);
82+
})
83+
.ConfigureScriptHostLogging(scriptHostLoggingBuilder =>
84+
{
85+
scriptHostLoggingBuilder.AddProvider(_scriptHostLoggerProvider);
86+
scriptHostLoggingBuilder.AddFilter<TestLoggerProvider>(_ => true);
87+
configureScriptHostLogging?.Invoke(scriptHostLoggingBuilder);
88+
})
89+
.ConfigureScriptHostServices(scriptHostServices =>
90+
{
91+
configureScriptHostServices?.Invoke(scriptHostServices);
92+
})
93+
.UseStartup<TestStartup>();
8994

9095
_testServer = new TestServer(builder);
9196

92-
HttpClient = new HttpClient(new UpdateContentLengthHandler(_testServer.CreateHandler()));
93-
HttpClient.BaseAddress = new Uri("https://localhost/");
97+
HttpClient = new HttpClient(new UpdateContentLengthHandler(_testServer.CreateHandler()))
98+
{
99+
BaseAddress = new Uri("https://localhost/")
100+
};
94101

95102
var manager = _testServer.Host.Services.GetService<IScriptHostManager>();
96103
_hostService = manager as WebJobsScriptHostService;
@@ -254,5 +261,43 @@ protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage reques
254261
return base.SendAsync(request, cancellationToken);
255262
}
256263
}
264+
265+
private class TestStartup
266+
{
267+
private Startup _startup;
268+
private readonly PostConfigureServices _postConfigure;
269+
270+
public TestStartup(IConfiguration configuration, PostConfigureServices postConfigure)
271+
{
272+
_startup = new Startup(configuration);
273+
_postConfigure = postConfigure;
274+
}
275+
276+
public void ConfigureServices(IServiceCollection services)
277+
{
278+
_startup.ConfigureServices(services);
279+
_postConfigure?.ConfigureServices(services);
280+
}
281+
282+
public void Configure(AspNetCore.Builder.IApplicationBuilder app, AspNetCore.Hosting.IApplicationLifetime applicationLifetime, AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory)
283+
{
284+
_startup.Configure(app, applicationLifetime, env, loggerFactory);
285+
}
286+
}
287+
288+
private class PostConfigureServices
289+
{
290+
private readonly Action<IServiceCollection> _postConfigure;
291+
292+
public PostConfigureServices(Action<IServiceCollection> postConfigure)
293+
{
294+
_postConfigure = postConfigure;
295+
}
296+
297+
public void ConfigureServices(IServiceCollection services)
298+
{
299+
_postConfigure?.Invoke(services);
300+
}
301+
}
257302
}
258303
}

test/WebJobs.Script.Tests.Integration/TestScripts/Node/Scenarios/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ module.exports = function (context, input) {
4444
console.log('console log');
4545

4646
context.done();
47+
48+
context.log('after done');
4749
}
4850
else if (scenario === 'bindingData') {
4951
var bindingData = context.bindingData;

test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/CSharpEndToEndTests.cs

+11-5
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,10 @@ await TestHelpers.Await(() =>
109109

110110
logs.Single(p => p.EndsWith($"From TraceWriter: {guid1}"));
111111
logs.Single(p => p.EndsWith($"From ILogger: {guid2}"));
112-
113-
// TODO: Re-enable once we can override the IMetricsLogger
112+
114113
// Make sure we get a metric logged from both ILogger and TraceWriter
115114
var key = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, "Scenarios");
116-
// Assert.Equal(2, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());
115+
Assert.Equal(2, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());
117116

118117
// Make sure we've gotten a log from the aggregator
119118
IEnumerable<LogMessage> getAggregatorLogs() => Fixture.Host.GetScriptHostLogMessages().Where(p => p.Category == LogCategories.Aggregator);
@@ -122,6 +121,13 @@ await TestHelpers.Await(() =>
122121

123122
var aggregatorLogs = getAggregatorLogs();
124123
Assert.Equal(1, aggregatorLogs.Count());
124+
125+
// Make sure that no user logs made it to the EventGenerator (which the SystemLogger writes to)
126+
IEnumerable<FunctionTraceEvent> allLogs = Fixture.EventGenerator.GetFunctionTraceEvents();
127+
Assert.False(allLogs.Any(l => l.Summary.Contains("From ")));
128+
Assert.False(allLogs.Any(l => l.Source.EndsWith(".User")));
129+
Assert.False(allLogs.Any(l => l.Source == LanguageWorkerConstants.FunctionConsoleLogCategoryName));
130+
Assert.NotEmpty(allLogs);
125131
}
126132

127133
[Fact]
@@ -426,9 +432,9 @@ public string GetSecondaryValue()
426432
primaryCompilation.Emit(Path.Combine(sharedAssembliesPath, "PrimaryDependency.dll"));
427433
}
428434

429-
public override void ConfigureJobHost(IWebJobsBuilder webJobsBuilder)
435+
public override void ConfigureScriptHost(IWebJobsBuilder webJobsBuilder)
430436
{
431-
base.ConfigureJobHost(webJobsBuilder);
437+
base.ConfigureScriptHost(webJobsBuilder);
432438

433439
webJobsBuilder.AddAzureStorage();
434440
webJobsBuilder.Services.Configure<ScriptJobHostOptions>(o =>

test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/EndToEndTestFixture.cs

+21-11
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.IO;
76
using System.Linq;
87
using System.Net.Http;
98
using System.Threading.Tasks;
10-
using Microsoft.Azure.WebJobs.Script.ExtensionBundle;
119
using Microsoft.Azure.WebJobs.Script.BindingExtensions;
1210
using Microsoft.Azure.WebJobs.Script.Diagnostics;
11+
using Microsoft.Azure.WebJobs.Script.ExtensionBundle;
1312
using Microsoft.Azure.WebJobs.Script.Models;
1413
using Microsoft.Azure.WebJobs.Script.Rpc;
14+
using Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics;
15+
using Microsoft.Azure.WebJobs.Script.WebHost.Management;
1516
using Microsoft.Extensions.Configuration;
1617
using Microsoft.Extensions.DependencyInjection;
1718
using Microsoft.Extensions.Logging.Abstractions;
@@ -20,9 +21,8 @@
2021
using Microsoft.WindowsAzure.Storage.Blob;
2122
using Microsoft.WindowsAzure.Storage.Queue;
2223
using Microsoft.WindowsAzure.Storage.Table;
23-
using Xunit;
24-
using Microsoft.Azure.WebJobs.Script.WebHost.Management;
2524
using Moq;
25+
using Xunit;
2626

2727
namespace Microsoft.Azure.WebJobs.Script.Tests
2828
{
@@ -67,6 +67,8 @@ protected EndToEndTestFixture(string rootPath, string testId, string functionsWo
6767

6868
public Mock<IFunctionsSyncManager> FunctionsSyncManagerMock { get; private set; }
6969

70+
public TestEventGenerator EventGenerator { get; private set; } = new TestEventGenerator();
71+
7072
protected virtual ExtensionPackageReference[] GetExtensionsToInstall()
7173
{
7274
return null;
@@ -100,12 +102,20 @@ public async Task InitializeAsync()
100102
FunctionsSyncManagerMock = new Mock<IFunctionsSyncManager>(MockBehavior.Strict);
101103
FunctionsSyncManagerMock.Setup(p => p.TrySyncTriggersAsync(It.IsAny<bool>())).ReturnsAsync(new SyncTriggersResult { Success = true });
102104

103-
Host = new TestFunctionHost(_copiedRootPath, logPath, webJobsBuilder =>
104-
{
105-
webJobsBuilder.Services.AddSingleton<IMetricsLogger>(_ => MetricsLogger);
106-
webJobsBuilder.Services.AddSingleton<IFunctionsSyncManager>(_ => FunctionsSyncManagerMock.Object);
107-
ConfigureJobHost(webJobsBuilder);
108-
});
105+
Host = new TestFunctionHost(_copiedRootPath, logPath,
106+
configureScriptHostWebJobsBuilder: webJobsBuilder =>
107+
{
108+
ConfigureScriptHost(webJobsBuilder);
109+
},
110+
configureScriptHostServices: s =>
111+
{
112+
s.AddSingleton<IFunctionsSyncManager>(_ => FunctionsSyncManagerMock.Object);
113+
s.AddSingleton<IMetricsLogger>(_ => MetricsLogger);
114+
},
115+
configureWebHostServices: s =>
116+
{
117+
s.AddSingleton<IEventGenerator>(_ => EventGenerator);
118+
});
109119

110120
string connectionString = Host.JobHostServices.GetService<IConfiguration>().GetWebJobsConnectionString(ConnectionStringNames.Storage);
111121
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
@@ -117,7 +127,7 @@ public async Task InitializeAsync()
117127
await CreateTestStorageEntities();
118128
}
119129

120-
public virtual void ConfigureJobHost(IWebJobsBuilder webJobsBuilder)
130+
public virtual void ConfigureScriptHost(IWebJobsBuilder webJobsBuilder)
121131
{
122132
}
123133

test/WebJobs.Script.Tests.Integration/WebHostEndToEnd/NodeEndToEndTests.cs

+11-5
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,19 @@ await TestHelpers.Await(() =>
226226
// verify the console log
227227
Assert.Equal("console log", consoleLog);
228228

229-
// TODO: Re-enable once we can override IMetricsLogger
230229
// We only expect 9 user log metrics to be counted, since
231230
// verbose logs are filtered by default (the TestLogger explicitly
232231
// allows all levels for testing purposes)
233232
var key = MetricsEventManager.GetAggregateKey(MetricEventNames.FunctionUserLog, "Scenarios");
234-
//Assert.Equal(9, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());
235-
//Assert.Contains($"{MetricEventNames.HostStartupRuntimeLanguage}.node", Fixture.MetricsLogger.LoggedEvents);
233+
Assert.Equal(9, Fixture.MetricsLogger.LoggedEvents.Where(p => p == key).Count());
234+
235+
// Make sure that no user logs made it to the EventGenerator (which the SystemLogger writes to)
236+
IEnumerable<FunctionTraceEvent> allLogs = Fixture.EventGenerator.GetFunctionTraceEvents();
237+
Assert.False(allLogs.Any(l => l.Summary.Contains("loglevel")));
238+
Assert.False(allLogs.Any(l => l.Summary.Contains("after done")));
239+
Assert.False(allLogs.Any(l => l.Source.EndsWith(".User")));
240+
Assert.False(allLogs.Any(l => l.Source == LanguageWorkerConstants.FunctionConsoleLogCategoryName));
241+
Assert.NotEmpty(allLogs);
236242
}
237243

238244
[Fact]
@@ -891,9 +897,9 @@ public TestFixture() : base(@"TestScripts\Node", "node", LanguageWorkerConstants
891897
{
892898
}
893899

894-
public override void ConfigureJobHost(IWebJobsBuilder webJobsBuilder)
900+
public override void ConfigureScriptHost(IWebJobsBuilder webJobsBuilder)
895901
{
896-
base.ConfigureJobHost(webJobsBuilder);
902+
base.ConfigureScriptHost(webJobsBuilder);
897903

898904
webJobsBuilder.AddAzureStorage()
899905
.Services.Configure<ScriptJobHostOptions>(o =>

0 commit comments

Comments
 (0)