@@ -308,10 +308,10 @@ public async Task AddWorkerIfNeeded_Returns_Expected(WorkerConcurrencyOptions op
308308 LatencyHistory = latencies2 . Select ( x => TimeSpan . FromMilliseconds ( x ) )
309309 } ) ;
310310
311- WorkerConcurrencyManager concurrancyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , _testEnvironment , Options . Create ( options ) ,
311+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , _testEnvironment , Options . Create ( options ) ,
312312 _functionsHostingConfigurations , _applicationLifetime , _loggerFactory ) ;
313- await concurrancyManager . StartAsync ( CancellationToken . None ) ;
314- bool value = concurrancyManager . NewWorkerIsRequired ( workerStatuses , elapsedFromLastAdding ) ;
313+ await concurrencyManager . StartAsync ( CancellationToken . None ) ;
314+ bool value = concurrencyManager . NewWorkerIsRequired ( workerStatuses , elapsedFromLastAdding ) ;
315315
316316 Assert . Equal ( value , expected ) ;
317317 }
@@ -323,9 +323,9 @@ public async Task StartAsync_DoesNotGetDispatcher(string workerRuntime)
323323 {
324324 _testEnvironment . SetEnvironmentVariable ( EnvironmentSettingNames . FunctionWorkerRuntime , workerRuntime ) ;
325325 Mock < IFunctionInvocationDispatcherFactory > functionInvocationDispatcherFactory = new Mock < IFunctionInvocationDispatcherFactory > ( MockBehavior . Strict ) ;
326- WorkerConcurrencyManager concurrancyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , _testEnvironment , Options . Create ( new WorkerConcurrencyOptions ( ) ) ,
326+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , _testEnvironment , Options . Create ( new WorkerConcurrencyOptions ( ) ) ,
327327 _functionsHostingConfigurations , _applicationLifetime , _loggerFactory ) ;
328- await concurrancyManager . StartAsync ( CancellationToken . None ) ;
328+ await concurrencyManager . StartAsync ( CancellationToken . None ) ;
329329 }
330330
331331 [ Theory ]
@@ -339,9 +339,9 @@ public async Task StartAsync_GetsDispatcher(string workerRuntime)
339339 Mock < IFunctionInvocationDispatcherFactory > functionInvocationDispatcherFactory = new Mock < IFunctionInvocationDispatcherFactory > ( MockBehavior . Strict ) ;
340340 functionInvocationDispatcherFactory . Setup ( x => x . GetFunctionDispatcher ( ) ) . Returns ( functionInvocationDispatcher . Object ) ;
341341
342- WorkerConcurrencyManager concurrancyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , _testEnvironment , Options . Create ( new WorkerConcurrencyOptions ( ) ) ,
342+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , _testEnvironment , Options . Create ( new WorkerConcurrencyOptions ( ) ) ,
343343 _functionsHostingConfigurations , _applicationLifetime , _loggerFactory ) ;
344- await concurrancyManager . StartAsync ( CancellationToken . None ) ;
344+ await concurrencyManager . StartAsync ( CancellationToken . None ) ;
345345 }
346346
347347 [ Fact ]
@@ -356,10 +356,10 @@ public async Task ActivateWorkerConcurency_FunctionsHostingConfiguration_WorkAsE
356356 conf . Setup ( x => x . FunctionsWorkerDynamicConcurrencyEnabled ) . Returns ( true ) ;
357357 WorkerConcurrencyOptions options = new WorkerConcurrencyOptions ( ) ;
358358
359- WorkerConcurrencyManager concurrancyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , testEnvironment , Options . Create ( options ) , conf . Object ,
359+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , testEnvironment , Options . Create ( options ) , conf . Object ,
360360 _applicationLifetime , _loggerFactory ) ;
361- concurrancyManager . ActivationTimerInterval = TimeSpan . FromMilliseconds ( 100 ) ;
362- await concurrancyManager . StartAsync ( CancellationToken . None ) ;
361+ concurrencyManager . ActivationTimerInterval = TimeSpan . FromMilliseconds ( 100 ) ;
362+ await concurrencyManager . StartAsync ( CancellationToken . None ) ;
363363 await TestHelpers . Await ( ( ) => _loggerProvider . GetAllLogMessages ( ) . SingleOrDefault ( x => x . FormattedMessage . StartsWith ( "Dynamic worker concurrency monitoring was started by activation timer." ) ) != null , timeout : 1000 , pollingInterval : 100 ) ;
364364 conf . Setup ( x => x . FunctionsWorkerDynamicConcurrencyEnabled ) . Returns ( false ) ;
365365 await TestHelpers . Await ( ( ) => _loggerProvider . GetAllLogMessages ( ) . SingleOrDefault ( x => x . FormattedMessage . StartsWith ( "Dynamic worker concurrency monitoring is disabled after activation. Shutting down Functions Host." ) ) != null , timeout : 1000 , pollingInterval : 100 ) ;
@@ -377,14 +377,55 @@ public void IsEnoughMemory_WorkAsExpected(long availableMemory, long hostProcess
377377 Mock < IFunctionsHostingConfiguration > conf = new Mock < IFunctionsHostingConfiguration > ( ) ;
378378 WorkerConcurrencyOptions options = new WorkerConcurrencyOptions ( ) ;
379379
380- WorkerConcurrencyManager concurrancyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , testEnvironment ,
380+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , testEnvironment ,
381381 Options . Create ( options ) , conf . Object , _applicationLifetime , _loggerFactory ) ;
382382
383- Assert . True ( concurrancyManager . IsEnoughMemoryToScale ( hostProcessSize , languageWorkerSizes , availableMemory ) == result ) ;
383+ Assert . True ( concurrencyManager . IsEnoughMemoryToScale ( hostProcessSize , languageWorkerSizes , availableMemory ) == result ) ;
384384 if ( ! result )
385385 {
386386 Assert . Contains ( _loggerProvider . GetAllLogMessages ( ) . Select ( x => x . FormattedMessage ) , x => x . StartsWith ( "Starting new language worker canceled:" ) ) ;
387387 }
388388 }
389+
390+ [ Theory ]
391+ [ InlineData ( 4 , new bool [ ] { true , true , true } , true ) ]
392+ [ InlineData ( 3 , new bool [ ] { true , true , true } , false ) ]
393+ [ InlineData ( 4 , new bool [ ] { true , false , true } , false ) ]
394+ public void CanScale_ReturnsExpected ( int maxWorkerCount , bool [ ] isReadyArray , bool result )
395+ {
396+ TestEnvironment testEnvironment = new TestEnvironment ( ) ;
397+ Mock < IFunctionInvocationDispatcherFactory > functionInvocationDispatcherFactory = new Mock < IFunctionInvocationDispatcherFactory > ( MockBehavior . Strict ) ;
398+ Mock < IFunctionsHostingConfiguration > conf = new Mock < IFunctionsHostingConfiguration > ( ) ;
399+ WorkerConcurrencyOptions options = new WorkerConcurrencyOptions ( ) ;
400+ options . MaxWorkerCount = maxWorkerCount ;
401+
402+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , testEnvironment ,
403+ Options . Create ( options ) , conf . Object , _applicationLifetime , _loggerFactory ) ;
404+
405+ List < IRpcWorkerChannel > workerChannels = new List < IRpcWorkerChannel > ( ) ;
406+ foreach ( bool isReady in isReadyArray )
407+ {
408+ Mock < IRpcWorkerChannel > mock = new Mock < IRpcWorkerChannel > ( ) ;
409+ mock . Setup ( x => x . IsChannelReadyForInvocations ( ) ) . Returns ( isReady ) ;
410+ workerChannels . Add ( mock . Object ) ;
411+ }
412+ Assert . Equal ( concurrencyManager . CanScale ( workerChannels ) , result ) ;
413+ }
414+
415+ [ Fact ]
416+ public void OnTimer_WorksAsExpected_IfPlaceholderMode_Enabled ( )
417+ {
418+ TestEnvironment testEnvironment = new TestEnvironment ( ) ;
419+ Mock < IFunctionInvocationDispatcherFactory > functionInvocationDispatcherFactory = new Mock < IFunctionInvocationDispatcherFactory > ( MockBehavior . Strict ) ;
420+ Mock < IFunctionsHostingConfiguration > conf = new Mock < IFunctionsHostingConfiguration > ( ) ;
421+ WorkerConcurrencyOptions options = new WorkerConcurrencyOptions ( ) ;
422+
423+ WorkerConcurrencyManager concurrencyManager = new WorkerConcurrencyManager ( functionInvocationDispatcherFactory . Object , testEnvironment ,
424+ Options . Create ( options ) , conf . Object , _applicationLifetime , _loggerFactory ) ;
425+
426+ testEnvironment . SetEnvironmentVariable ( EnvironmentSettingNames . AzureWebsitePlaceholderMode , "1" ) ;
427+ concurrencyManager . OnTimer ( null , null ) ;
428+ Assert . Empty ( _loggerProvider . GetAllLogMessages ( ) . Where ( x => x . FormattedMessage == "Error monitoring worker concurrency" ) ) ;
429+ }
389430 }
390431}
0 commit comments