@@ -182,6 +182,7 @@ public async Task GetExtensionsStartupTypes_AcceptsRequiredBundleVersions(string
182
182
Assert . True ( traces . Any ( m => m . FormattedMessage . Contains ( $ "Loading extension bundle") ) ) ;
183
183
}
184
184
Assert . True ( traces . Any ( m => m . FormattedMessage . Contains ( $ "Loading startup extension 'Storage") ) ) ;
185
+ AssertNoErrors ( traces ) ;
185
186
}
186
187
}
187
188
@@ -310,6 +311,7 @@ public async Task GetExtensionsStartupTypes_AcceptsRequiredExtensionVersions(str
310
311
{
311
312
Assert . True ( traces . Any ( m => m . FormattedMessage . Contains ( $ "Loading startup extension 'Storage") ) ) ;
312
313
}
314
+ AssertNoErrors ( traces ) ;
313
315
}
314
316
}
315
317
@@ -423,6 +425,7 @@ void CopyToBin(string path)
423
425
Assert . Equal ( typeof ( AzureStorageWebJobsStartup ) . FullName , types . Single ( ) . FullName ) ;
424
426
Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , $ "The extension startup type '{ references [ 0 ] . TypeName } ' belongs to a builtin extension") ) ) ;
425
427
Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , $ "The extension startup type '{ references [ 1 ] . TypeName } ' belongs to a builtin extension") ) ) ;
428
+ AssertNoErrors ( traces ) ;
426
429
}
427
430
}
428
431
@@ -516,6 +519,7 @@ void CopyToBin(string path)
516
519
Assert . Equal ( typeof ( AzureStorageWebJobsStartup ) . FullName , types . Single ( ) . FullName ) ;
517
520
Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , $ "The extension startup type '{ references [ 0 ] . TypeName } ' belongs to a builtin extension") ) ) ;
518
521
Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , $ "The extension startup type '{ references [ 1 ] . TypeName } ' belongs to a builtin extension") ) ) ;
522
+ AssertNoErrors ( traces ) ;
519
523
}
520
524
}
521
525
@@ -592,11 +596,13 @@ void CopyToBin(string path)
592
596
593
597
// Act
594
598
var types = await discoverer . GetExtensionsStartupTypesAsync ( ) ;
599
+ var traces = testLoggerProvider . GetAllLogMessages ( ) ;
595
600
596
601
// Assert
597
602
AreExpectedMetricsGenerated ( testMetricsLogger ) ;
598
603
Assert . Equal ( types . Count ( ) , 2 ) ;
599
604
Assert . Equal ( typeof ( AzureStorageWebJobsStartup ) . FullName , types . FirstOrDefault ( ) . FullName ) ;
605
+ AssertNoErrors ( traces ) ;
600
606
}
601
607
}
602
608
@@ -644,11 +650,13 @@ void CopyToBin(string path)
644
650
645
651
// Act
646
652
var types = await discoverer . GetExtensionsStartupTypesAsync ( ) ;
653
+ var traces = testLoggerProvider . GetAllLogMessages ( ) ;
647
654
648
655
// Assert
649
656
AreExpectedMetricsGenerated ( testMetricsLogger ) ;
650
657
Assert . Single ( types ) ;
651
658
Assert . Equal ( typeof ( AzureStorageWebJobsStartup ) . FullName , types . Single ( ) . FullName ) ;
659
+ AssertNoErrors ( traces ) ;
652
660
}
653
661
}
654
662
@@ -698,11 +706,13 @@ void CopyToBin(string path)
698
706
699
707
// Act
700
708
var types = await discoverer . GetExtensionsStartupTypesAsync ( ) ;
709
+ var traces = testLoggerProvider . GetAllLogMessages ( ) ;
701
710
702
711
//Assert
703
712
AreExpectedMetricsGenerated ( testMetricsLogger ) ;
704
713
Assert . Single ( types ) ;
705
714
Assert . Equal ( typeof ( AzureStorageWebJobsStartup ) . FullName , types . Single ( ) . FullName ) ;
715
+ AssertNoErrors ( traces ) ;
706
716
}
707
717
}
708
718
@@ -1144,13 +1154,55 @@ void CopyToBin(string path)
1144
1154
1145
1155
// Act
1146
1156
var types = await discoverer . GetExtensionsStartupTypesAsync ( ) ;
1157
+ var traces = testLoggerProvider . GetAllLogMessages ( ) ;
1147
1158
Environment . SetEnvironmentVariable ( EnvironmentSettingNames . AzureWebJobsFeatureFlags , null ) ;
1148
1159
Environment . SetEnvironmentVariable ( EnvironmentSettingNames . FunctionWorkerRuntime , null ) ;
1149
1160
1150
1161
//Assert that filtering did not take place because of worker indexing
1151
1162
Assert . True ( types . Count ( ) == 1 ) ;
1152
1163
Assert . Equal ( typeof ( AzureStorageWebJobsStartup ) . FullName , types . ElementAt ( 0 ) . FullName ) ;
1164
+ AssertNoErrors ( traces ) ;
1165
+ }
1166
+ }
1167
+
1168
+ [ Fact ]
1169
+ public async Task GetExtensionsStartupTypes_EmptyExtensionsArray ( )
1170
+ {
1171
+ TestMetricsLogger testMetricsLogger = new TestMetricsLogger ( ) ;
1172
+
1173
+ using var directory = new TempDirectory ( ) ;
1174
+ var binPath = Path . Combine ( directory . Path , "bin" ) ;
1175
+ Directory . CreateDirectory ( binPath ) ;
1176
+
1177
+ // extensions.json file with an empty extensions array (simulating extensions.json produced by in-proc app)
1178
+ string extensionJson = """
1179
+ {
1180
+ "extensions": []
1153
1181
}
1182
+ """ ;
1183
+ File . WriteAllText ( Path . Combine ( binPath , "extensions.json" ) , extensionJson ) ;
1184
+
1185
+ TestLoggerProvider testLoggerProvider = new TestLoggerProvider ( ) ;
1186
+ LoggerFactory factory = new LoggerFactory ( ) ;
1187
+ factory . AddProvider ( testLoggerProvider ) ;
1188
+ var testLogger = factory . CreateLogger < ScriptStartupTypeLocator > ( ) ;
1189
+
1190
+ var mockExtensionBundleManager = new Mock < IExtensionBundleManager > ( ) ;
1191
+ mockExtensionBundleManager . Setup ( e => e . IsExtensionBundleConfigured ( ) ) . Returns ( true ) ;
1192
+ mockExtensionBundleManager . Setup ( e => e . GetExtensionBundleDetails ( ) ) . Returns ( Task . FromResult ( new ExtensionBundleDetails ( ) { Id = "bundleID" , Version = "1.0.0" } ) ) ;
1193
+ mockExtensionBundleManager . Setup ( e => e . GetExtensionBundleBinPathAsync ( ) ) . Returns ( Task . FromResult ( binPath ) ) ;
1194
+
1195
+ var languageWorkerOptions = new TestOptionsMonitor < LanguageWorkerOptions > ( new LanguageWorkerOptions ( ) ) ;
1196
+ var mockFunctionMetadataManager = GetTestFunctionMetadataManager ( languageWorkerOptions ) ;
1197
+ OptionsWrapper < ExtensionRequirementOptions > optionsWrapper = new ( new ExtensionRequirementOptions ( ) ) ;
1198
+ var discoverer = new ScriptStartupTypeLocator ( directory . Path , testLogger , mockExtensionBundleManager . Object , mockFunctionMetadataManager , testMetricsLogger , optionsWrapper ) ;
1199
+
1200
+ var types = await discoverer . GetExtensionsStartupTypesAsync ( ) ;
1201
+ var traces = testLoggerProvider . GetAllLogMessages ( ) ;
1202
+
1203
+ AreExpectedMetricsGenerated ( testMetricsLogger ) ;
1204
+ Assert . Empty ( types ) ; // Ensure no types are loaded because the extensions array is empty
1205
+ AssertNoErrors ( traces ) ;
1154
1206
}
1155
1207
1156
1208
private IFunctionMetadataManager GetTestFunctionMetadataManager ( IOptionsMonitor < LanguageWorkerOptions > options , ICollection < FunctionMetadata > metadataCollection = null , bool hasPrecompiledFunction = false , bool hasNodeFunctions = false , bool hasDotnetIsolatedFunctions = false )
@@ -1234,5 +1286,10 @@ private ILogger<ScriptStartupTypeLocator> GetTestLogger()
1234
1286
var testLogger = factory . CreateLogger < ScriptStartupTypeLocator > ( ) ;
1235
1287
return testLogger ;
1236
1288
}
1289
+
1290
+ private static void AssertNoErrors ( IList < LogMessage > traces )
1291
+ {
1292
+ Assert . False ( traces . Any ( m => m . Level == LogLevel . Error || m . Level == LogLevel . Critical ) ) ;
1293
+ }
1237
1294
}
1238
1295
}
0 commit comments