public async Task ReloadScript_WithInvalidCompilationAndMissingMethod_ReportsResults() { // Create the compilation exception we expect to throw during the reload var descriptor = new DiagnosticDescriptor(DotNetConstants.MissingFunctionEntryPointCompilationCode, "Test compilation exception", "Test compilation error", "AzureFunctions", DiagnosticSeverity.Error, true); var exception = new CompilationErrorException("Test compilation exception", ImmutableArray.Create(Diagnostic.Create(descriptor, Location.None))); // Create the invoker dependencies and setup the appropriate method to throw the exception RunDependencies dependencies = CreateDependencies(); dependencies.Compilation.Setup(c => c.GetEntryPointSignature(It.IsAny<IFunctionEntryPointResolver>())) .Throws(exception); dependencies.Compilation.Setup(c => c.EmitAndLoad(It.IsAny<CancellationToken>())) .Returns(typeof(object).Assembly); string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(rootFunctionsFolder); // Create a dummy file to represent our function string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx"); File.WriteAllText(filePath, string.Empty); var metadata = new FunctionMetadata { ScriptFile = filePath, Name = Guid.NewGuid().ToString(), ScriptType = ScriptType.CSharp }; metadata.Bindings.Add(new BindingMetadata() { Name = "Test", Type = "ManualTrigger" }); var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<Script.Binding.FunctionBinding>(), new Collection<FunctionBinding>(), dependencies.EntrypointResolver.Object, new FunctionAssemblyLoader(string.Empty), dependencies.CompilationServiceFactory.Object, dependencies.TraceWriterFactory.Object); // Update the file to trigger a reload File.WriteAllText(filePath, string.Empty); await TestHelpers.Await(() => { return dependencies.TraceWriter.Traces.Any(t => t.Message.Contains("Compilation failed.")) && dependencies.TraceWriter.Traces.Any(t => t.Message.Contains(DotNetConstants.MissingFunctionEntryPointCompilationCode)); }); dependencies.TraceWriter.Traces.Clear(); CompilationErrorException resultException = await Assert.ThrowsAsync<CompilationErrorException>(() => invoker.GetFunctionTargetAsync()); await TestHelpers.Await(() => { return dependencies.TraceWriter.Traces.Any(t => t.Message.Contains("Function compilation error")) && dependencies.TraceWriter.Traces.Any(t => t.Message.Contains(DotNetConstants.MissingFunctionEntryPointCompilationCode)); }); }
public async Task Compilation_WithMissingBindingArguments_LogsAF004Warning() { // Create the compilation exception we expect to throw during the reload string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(rootFunctionsFolder); // Create the invoker dependencies and setup the appropriate method to throw the exception RunDependencies dependencies = CreateDependencies(); // Create a dummy file to represent our function string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx"); File.WriteAllText(filePath, Resources.TestFunctionWithMissingBindingArgumentsCode); var metadata = new FunctionMetadata { ScriptFile = filePath, Name = Guid.NewGuid().ToString(), ScriptType = ScriptType.CSharp }; metadata.Bindings.Add(new BindingMetadata() { Name = "myQueueItem", Type = "ManualTrigger" }); var testBinding = new Mock<FunctionBinding>(null, new BindingMetadata() { Name = "TestBinding", Type = "blob" }, FileAccess.Write); var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<FunctionBinding>(), new Collection<FunctionBinding> { testBinding.Object }, new FunctionEntryPointResolver(), new FunctionAssemblyLoader(string.Empty), new DotNetCompilationServiceFactory(NullTraceWriter.Instance), dependencies.TraceWriterFactory.Object); await invoker.GetFunctionTargetAsync(); Assert.Contains(dependencies.TraceWriter.Traces, t => t.Message.Contains($"warning {DotNetConstants.MissingBindingArgumentCompilationCode}") && t.Message.Contains("'TestBinding'")); }
public async Task Compilation_OnSecondaryHost_SuppressesLogs() { // Create the compilation exception we expect to throw during the reload string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(rootFunctionsFolder); // Create the invoker dependencies and setup the appropriate method to throw the exception RunDependencies dependencies = CreateDependencies(); // Set the host to secondary dependencies.Host.SetupGet(h => h.IsPrimary).Returns(false); // Create a dummy file to represent our function string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx"); File.WriteAllText(filePath, Resources.TestFunctionWithMissingBindingArgumentsCode); var metadata = new FunctionMetadata { ScriptFile = filePath, Name = Guid.NewGuid().ToString(), ScriptType = ScriptType.CSharp }; metadata.Bindings.Add(new BindingMetadata() { Name = "myQueueItem", Type = "ManualTrigger" }); var testBinding = new Mock<FunctionBinding>(null, new BindingMetadata() { Name = "TestBinding", Type = "blob" }, FileAccess.Write); var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<FunctionBinding>(), new Collection<FunctionBinding> { testBinding.Object }, new FunctionEntryPointResolver(), new FunctionAssemblyLoader(string.Empty), new DotNetCompilationServiceFactory(NullTraceWriter.Instance), dependencies.TraceWriterFactory.Object); await invoker.GetFunctionTargetAsync(); // Verify that logs on the second instance were suppressed int count = dependencies.TraceWriter.Traces.Count(); Assert.Equal(0, count); }