Skip to content

Commit 7546f3e

Browse files
committed
Test fixes. Ensuring encoding is set on syntax tree in release mode
1 parent 78fc9c4 commit 7546f3e

File tree

3 files changed

+115
-67
lines changed

3 files changed

+115
-67
lines changed

src/WebJobs.Script/Description/DotNet/Compilation/CSharp/CSharpCompilationService.cs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,17 @@ private Compilation GetScriptCompilation(Script<object> script, FunctionMetadata
6969
{
7070
Compilation compilation = script.GetCompilation();
7171

72-
if (_optimizationLevel == OptimizationLevel.Debug)
73-
{
74-
string scriptFileName = Path.GetFileName(functionMetadata.ScriptFile);
75-
SyntaxTree scriptTree = compilation.SyntaxTrees.FirstOrDefault(t => string.Equals(t.FilePath, scriptFileName));
76-
var debugTree = SyntaxFactory.SyntaxTree(scriptTree.GetRoot(),
77-
encoding: UTF8WithNoBOM,
78-
path: scriptFileName,
79-
options: new CSharpParseOptions(kind: SourceCodeKind.Script));
80-
81-
compilation = compilation
82-
.RemoveAllSyntaxTrees()
83-
.AddSyntaxTrees(debugTree);
84-
}
72+
string scriptFileName = Path.GetFileName(functionMetadata.ScriptFile);
73+
SyntaxTree scriptTree = compilation.SyntaxTrees.FirstOrDefault(t => string.Equals(t.FilePath, scriptFileName));
74+
scriptTree = SyntaxFactory.SyntaxTree(
75+
scriptTree.GetRoot(),
76+
encoding: UTF8WithNoBOM,
77+
path: scriptFileName,
78+
options: new CSharpParseOptions(kind: SourceCodeKind.Script));
79+
80+
compilation = compilation
81+
.RemoveAllSyntaxTrees()
82+
.AddSyntaxTrees(scriptTree);
8583

8684
return compilation.WithOptions(compilation.Options.WithOptimizationLevel(_optimizationLevel))
8785
.WithAssemblyName(FunctionAssemblyLoader.GetAssemblyNameFromMetadata(functionMetadata, compilation.AssemblyName));

src/WebJobs.Script/Host/ScriptHostManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public ScriptHostManager(ScriptHostConfiguration config,
7474

7575
EventManager = eventManager ?? new ScriptEventManager();
7676

77-
_structuredLogWriter = new StructuredLogWriter(eventManager, config.RootLogPath);
77+
_structuredLogWriter = new StructuredLogWriter(EventManager, config.RootLogPath);
7878
}
7979

8080
protected IScriptEventManager EventManager { get; }

test/WebJobs.Script.Tests/Description/DotNet/DotNetFunctionInvokerTests.cs

Lines changed: 103 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
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;
56
using System.Collections.Immutable;
67
using System.Collections.ObjectModel;
78
using System.Diagnostics;
89
using System.IO;
910
using System.Linq;
11+
using System.Text;
1012
using System.Threading;
1113
using System.Threading.Tasks;
1214
using Microsoft.Azure.WebJobs.Script.Binding;
@@ -25,6 +27,15 @@ namespace Microsoft.Azure.WebJobs.Script.Tests
2527
{
2628
public class DotNetFunctionInvokerTests
2729
{
30+
public static IEnumerable<object[]> CompilationEnvironment
31+
{
32+
get
33+
{
34+
yield return new object[] { new Dictionary<string, string> { { EnvironmentSettingNames.CompilationReleaseMode, bool.TrueString } } };
35+
yield return new object[] { new Dictionary<string, string> { { EnvironmentSettingNames.CompilationReleaseMode, bool.FalseString } } };
36+
}
37+
}
38+
2839
[Fact]
2940
public async Task ReloadScript_WithInvalidCompilationAndMissingMethod_ReportsResults()
3041
{
@@ -83,80 +94,119 @@ await TestHelpers.Await(() =>
8394
});
8495
}
8596

86-
[Fact]
87-
public async Task Compilation_WithMissingBindingArguments_LogsAF004Warning()
97+
[Theory]
98+
[MemberData(nameof(CompilationEnvironment))]
99+
public async Task Compilation_WithMissingBindingArguments_LogsAF004Warning(IDictionary<string, string> environment)
88100
{
89-
// Create the compilation exception we expect to throw during the reload
90-
string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
91-
Directory.CreateDirectory(rootFunctionsFolder);
101+
using (var testEnvironment = new TestScopedEnvironmentVariable(environment))
102+
{
103+
// Create the compilation exception we expect to throw during the reload
104+
string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
105+
Directory.CreateDirectory(rootFunctionsFolder);
92106

93-
// Create the invoker dependencies and setup the appropriate method to throw the exception
94-
RunDependencies dependencies = CreateDependencies();
107+
// Create the invoker dependencies and setup the appropriate method to throw the exception
108+
RunDependencies dependencies = CreateDependencies();
95109

96-
// Create a dummy file to represent our function
97-
string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx");
98-
File.WriteAllText(filePath, Resources.TestFunctionWithMissingBindingArgumentsCode);
110+
// Create a dummy file to represent our function
111+
string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx");
112+
File.WriteAllText(filePath, Resources.TestFunctionWithMissingBindingArgumentsCode);
99113

100-
var metadata = new FunctionMetadata
101-
{
102-
ScriptFile = filePath,
103-
FunctionDirectory = Path.GetDirectoryName(filePath),
104-
Name = Guid.NewGuid().ToString(),
105-
ScriptType = ScriptType.CSharp
106-
};
114+
var metadata = new FunctionMetadata
115+
{
116+
ScriptFile = filePath,
117+
FunctionDirectory = Path.GetDirectoryName(filePath),
118+
Name = Guid.NewGuid().ToString(),
119+
ScriptType = ScriptType.CSharp
120+
};
107121

108-
metadata.Bindings.Add(new BindingMetadata() { Name = "myQueueItem", Type = "ManualTrigger" });
122+
metadata.Bindings.Add(new BindingMetadata() { Name = "myQueueItem", Type = "ManualTrigger" });
109123

110-
var testBinding = new Mock<FunctionBinding>(null, new BindingMetadata() { Name = "TestBinding", Type = "blob" }, FileAccess.Write);
124+
var testBinding = new Mock<FunctionBinding>(null, new BindingMetadata() { Name = "TestBinding", Type = "blob" }, FileAccess.Write);
111125

112-
var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<FunctionBinding>(),
113-
new Collection<FunctionBinding> { testBinding.Object }, new FunctionEntryPointResolver(), new FunctionAssemblyLoader(string.Empty),
114-
new DotNetCompilationServiceFactory(NullTraceWriter.Instance, null));
126+
var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<FunctionBinding>(),
127+
new Collection<FunctionBinding> { testBinding.Object }, new FunctionEntryPointResolver(), new FunctionAssemblyLoader(string.Empty),
128+
new DotNetCompilationServiceFactory(NullTraceWriter.Instance, null));
129+
130+
try
131+
{
132+
await invoker.GetFunctionTargetAsync();
133+
}
134+
catch (CompilationErrorException exc)
135+
{
136+
var builder = new StringBuilder();
137+
builder.AppendLine(Resources.TestFunctionWithMissingBindingArgumentsCode);
138+
builder.AppendLine();
115139

116-
await invoker.GetFunctionTargetAsync();
140+
string compilationDetails = exc.Diagnostics.Aggregate(
141+
builder,
142+
(a, d) => a.AppendLine(d.ToString()),
143+
a => a.ToString());
117144

118-
Assert.Contains(dependencies.TraceWriter.Traces,
119-
t => t.Message.Contains($"warning {DotNetConstants.MissingBindingArgumentCompilationCode}") && t.Message.Contains("'TestBinding'"));
145+
throw new Exception(compilationDetails, exc);
146+
}
147+
148+
Assert.Contains(dependencies.TraceWriter.Traces,
149+
t => t.Message.Contains($"warning {DotNetConstants.MissingBindingArgumentCompilationCode}") && t.Message.Contains("'TestBinding'"));
150+
}
120151
}
121152

122-
[Fact]
123-
public async Task Compilation_OnSecondaryHost_SuppressesLogs()
153+
[Theory]
154+
[MemberData(nameof(CompilationEnvironment))]
155+
public async Task Compilation_OnSecondaryHost_SuppressesLogs(IDictionary<string, string> environment)
124156
{
125-
// Create the compilation exception we expect to throw during the reload
126-
string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
127-
Directory.CreateDirectory(rootFunctionsFolder);
157+
using (new TestScopedEnvironmentVariable(environment))
158+
{
159+
// Create the compilation exception we expect to throw during the reload
160+
string rootFunctionsFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
161+
Directory.CreateDirectory(rootFunctionsFolder);
128162

129-
// Create the invoker dependencies and setup the appropriate method to throw the exception
130-
RunDependencies dependencies = CreateDependencies();
163+
// Create the invoker dependencies and setup the appropriate method to throw the exception
164+
RunDependencies dependencies = CreateDependencies();
131165

132-
// Set the host to secondary
133-
dependencies.Host.SetupGet(h => h.IsPrimary).Returns(false);
166+
// Set the host to secondary
167+
dependencies.Host.SetupGet(h => h.IsPrimary).Returns(false);
134168

135-
// Create a dummy file to represent our function
136-
string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx");
137-
File.WriteAllText(filePath, Resources.TestFunctionWithMissingBindingArgumentsCode);
169+
// Create a dummy file to represent our function
170+
string filePath = Path.Combine(rootFunctionsFolder, Guid.NewGuid().ToString() + ".csx");
171+
File.WriteAllText(filePath, Resources.TestFunctionWithMissingBindingArgumentsCode);
138172

139-
var metadata = new FunctionMetadata
140-
{
141-
ScriptFile = filePath,
142-
FunctionDirectory = Path.GetDirectoryName(filePath),
143-
Name = Guid.NewGuid().ToString(),
144-
ScriptType = ScriptType.CSharp
145-
};
173+
var metadata = new FunctionMetadata
174+
{
175+
ScriptFile = filePath,
176+
FunctionDirectory = Path.GetDirectoryName(filePath),
177+
Name = Guid.NewGuid().ToString(),
178+
ScriptType = ScriptType.CSharp
179+
};
146180

147-
metadata.Bindings.Add(new BindingMetadata() { Name = "myQueueItem", Type = "ManualTrigger" });
181+
metadata.Bindings.Add(new BindingMetadata() { Name = "myQueueItem", Type = "ManualTrigger" });
148182

149-
var testBinding = new Mock<FunctionBinding>(null, new BindingMetadata() { Name = "TestBinding", Type = "blob" }, FileAccess.Write);
183+
var testBinding = new Mock<FunctionBinding>(null, new BindingMetadata() { Name = "TestBinding", Type = "blob" }, FileAccess.Write);
150184

151-
var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<FunctionBinding>(),
152-
new Collection<FunctionBinding> { testBinding.Object }, new FunctionEntryPointResolver(), new FunctionAssemblyLoader(string.Empty),
153-
new DotNetCompilationServiceFactory(NullTraceWriter.Instance, null));
185+
var invoker = new DotNetFunctionInvoker(dependencies.Host.Object, metadata, new Collection<FunctionBinding>(),
186+
new Collection<FunctionBinding> { testBinding.Object }, new FunctionEntryPointResolver(), new FunctionAssemblyLoader(string.Empty),
187+
new DotNetCompilationServiceFactory(NullTraceWriter.Instance, null));
188+
try
189+
{
190+
await invoker.GetFunctionTargetAsync();
191+
}
192+
catch (CompilationErrorException exc)
193+
{
194+
var builder = new StringBuilder();
195+
builder.AppendLine(Resources.TestFunctionWithMissingBindingArgumentsCode);
196+
builder.AppendLine();
197+
198+
string compilationDetails = exc.Diagnostics.Aggregate(
199+
builder,
200+
(a, d) => a.AppendLine(d.ToString()),
201+
a => a.ToString());
154202

155-
await invoker.GetFunctionTargetAsync();
203+
throw new Exception(compilationDetails, exc);
204+
}
156205

157-
// Verify that logs on the second instance were suppressed
158-
int count = dependencies.TraceWriter.Traces.Count();
159-
Assert.Equal(0, count);
206+
// Verify that logs on the second instance were suppressed
207+
int count = dependencies.TraceWriter.Traces.Count();
208+
Assert.Equal(0, count);
209+
}
160210
}
161211

162212
[Fact]

0 commit comments

Comments
 (0)