2
2
// Licensed under the MIT License. See License.txt in the project root for license information.
3
3
4
4
using System ;
5
+ using System . Collections . Generic ;
5
6
using System . Collections . Immutable ;
6
7
using System . Collections . ObjectModel ;
7
8
using System . Diagnostics ;
8
9
using System . IO ;
9
10
using System . Linq ;
11
+ using System . Text ;
10
12
using System . Threading ;
11
13
using System . Threading . Tasks ;
12
14
using Microsoft . Azure . WebJobs . Script . Binding ;
@@ -25,6 +27,15 @@ namespace Microsoft.Azure.WebJobs.Script.Tests
25
27
{
26
28
public class DotNetFunctionInvokerTests
27
29
{
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
+
28
39
[ Fact ]
29
40
public async Task ReloadScript_WithInvalidCompilationAndMissingMethod_ReportsResults ( )
30
41
{
@@ -83,80 +94,119 @@ await TestHelpers.Await(() =>
83
94
} ) ;
84
95
}
85
96
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 )
88
100
{
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 ) ;
92
106
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 ( ) ;
95
109
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 ) ;
99
113
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
+ } ;
107
121
108
- metadata . Bindings . Add ( new BindingMetadata ( ) { Name = "myQueueItem" , Type = "ManualTrigger" } ) ;
122
+ metadata . Bindings . Add ( new BindingMetadata ( ) { Name = "myQueueItem" , Type = "ManualTrigger" } ) ;
109
123
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 ) ;
111
125
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 ( ) ;
115
139
116
- await invoker . GetFunctionTargetAsync ( ) ;
140
+ string compilationDetails = exc . Diagnostics . Aggregate (
141
+ builder ,
142
+ ( a , d ) => a . AppendLine ( d . ToString ( ) ) ,
143
+ a => a . ToString ( ) ) ;
117
144
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
+ }
120
151
}
121
152
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 )
124
156
{
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 ) ;
128
162
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 ( ) ;
131
165
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 ) ;
134
168
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 ) ;
138
172
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
+ } ;
146
180
147
- metadata . Bindings . Add ( new BindingMetadata ( ) { Name = "myQueueItem" , Type = "ManualTrigger" } ) ;
181
+ metadata . Bindings . Add ( new BindingMetadata ( ) { Name = "myQueueItem" , Type = "ManualTrigger" } ) ;
148
182
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 ) ;
150
184
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 ( ) ) ;
154
202
155
- await invoker . GetFunctionTargetAsync ( ) ;
203
+ throw new Exception ( compilationDetails , exc ) ;
204
+ }
156
205
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
+ }
160
210
}
161
211
162
212
[ Fact ]
0 commit comments