7
7
using System . Linq ;
8
8
using System . Threading ;
9
9
using System . Threading . Tasks ;
10
+ using System . Threading . Tasks . Dataflow ;
10
11
using Microsoft . AspNetCore . Hosting ;
12
+ using Microsoft . Azure . WebJobs . Host . Executors . Internal ;
11
13
using Microsoft . Azure . WebJobs . Script . Config ;
12
14
using Microsoft . Azure . WebJobs . Script . Description ;
13
15
using Microsoft . Azure . WebJobs . Script . Diagnostics ;
@@ -631,8 +633,92 @@ public async Task FunctionDispatcher_ErroredWebHostChannel()
631
633
Assert . True ( testLogs . Any ( m => m . FormattedMessage . Contains ( "Removing errored webhost language worker channel for runtime" ) ) ) ;
632
634
}
633
635
634
- private static RpcFunctionInvocationDispatcher GetTestFunctionDispatcher ( int maxProcessCountValue = 1 , bool addWebhostChannel = false ,
635
- Mock < IWebHostRpcWorkerChannelManager > mockwebHostLanguageWorkerChannelManager = null , bool throwOnProcessStartUp = false , TimeSpan ? startupIntervals = null , string runtime = null , bool workerIndexing = false , bool placeholder = false )
636
+ [ Fact ]
637
+ public async Task FunctionDispatcher_InvokeAsync_SystemScope ( )
638
+ {
639
+ FunctionMetadata func1 = new FunctionMetadata ( )
640
+ {
641
+ Name = "func1" ,
642
+ Language = "node"
643
+ } ;
644
+ var functions = new List < FunctionMetadata > ( )
645
+ {
646
+ func1
647
+ } ;
648
+
649
+ ScriptInvocationContext context = new ( )
650
+ {
651
+ FunctionMetadata = func1 ,
652
+ ExecutionContext = new ( )
653
+ {
654
+ InvocationId = Guid . NewGuid ( ) ,
655
+ FunctionName = "func1" ,
656
+ } ,
657
+ ResultSource = new ( ) ,
658
+ CancellationToken = default ,
659
+ Logger = _testLogger ,
660
+ AsyncExecutionContext = System . Threading . ExecutionContext . Capture ( ) ,
661
+ } ;
662
+
663
+ BufferBlock < ScriptInvocationContext > inputBuffer = new ( ) ;
664
+ ActionBlock < ScriptInvocationContext > actionBlock = new ( context =>
665
+ {
666
+ try
667
+ {
668
+ Assert . Equal ( FunctionInvocationScope . System , FunctionInvoker . CurrentScope ) ;
669
+ context . ResultSource . TrySetResult ( null ) ;
670
+ }
671
+ catch ( Exception ex )
672
+ {
673
+ context . ResultSource . TrySetException ( ex ) ;
674
+ }
675
+ } ) ;
676
+
677
+ inputBuffer . LinkTo ( actionBlock ) ;
678
+
679
+ Mock < IDictionary < string , BufferBlock < ScriptInvocationContext > > > mockBufferBlocks = new ( ) ;
680
+ mockBufferBlocks . Setup ( m => m . TryGetValue ( It . IsAny < string > ( ) , out inputBuffer ) ) . Returns ( true ) ;
681
+
682
+ Mock < IRpcWorkerChannel > mockChannel = new ( ) ;
683
+ mockChannel . Setup ( m => m . FunctionInputBuffers ) . Returns ( mockBufferBlocks . Object ) ;
684
+
685
+ IRpcWorkerChannel Create (
686
+ string workerRuntime , string language , IMetricsLogger metricsLogger , int attemptCount , IEnumerable < RpcWorkerConfig > workerConfigs )
687
+ {
688
+ var workerConfig = workerConfigs . SingleOrDefault ( p => language . Equals ( p . Description . Language , StringComparison . OrdinalIgnoreCase ) ) ;
689
+ return new TestRpcWorkerChannel (
690
+ Guid . NewGuid ( ) . ToString ( ) , language , null , _testLogger , false , workerConfig : workerConfig )
691
+ {
692
+ FunctionInputBuffers = mockBufferBlocks . Object ,
693
+ } ;
694
+ }
695
+
696
+ Mock < IRpcWorkerChannelFactory > mockChannelFactory = new ( ) ;
697
+ mockChannelFactory . Setup (
698
+ m => m . Create ( It . IsAny < string > ( ) , It . IsAny < string > ( ) , It . IsAny < IMetricsLogger > ( ) , It . IsAny < int > ( ) , It . IsAny < IEnumerable < RpcWorkerConfig > > ( ) ) )
699
+ . Returns ( Create ) ;
700
+
701
+ RpcFunctionInvocationDispatcher functionDispatcher = GetTestFunctionDispatcher (
702
+ runtime : RpcWorkerConstants . NodeLanguageWorkerName , channelFactory : mockChannelFactory . Object ) ;
703
+
704
+ await functionDispatcher . InitializeAsync ( functions ) ;
705
+ await WaitForFunctionDispactherStateInitialized ( functionDispatcher ) ;
706
+ using FunctionInvoker . Scope scope = FunctionInvoker . BeginUserScope ( ) ;
707
+ await functionDispatcher . InvokeAsync ( context ) ;
708
+ await context . ResultSource . Task ;
709
+ Assert . Equal ( FunctionInvocationScope . User , FunctionInvoker . CurrentScope ) ;
710
+ }
711
+
712
+ private static RpcFunctionInvocationDispatcher GetTestFunctionDispatcher (
713
+ int maxProcessCountValue = 1 ,
714
+ bool addWebhostChannel = false ,
715
+ Mock < IWebHostRpcWorkerChannelManager > mockwebHostLanguageWorkerChannelManager = null ,
716
+ bool throwOnProcessStartUp = false ,
717
+ TimeSpan ? startupIntervals = null ,
718
+ string runtime = null ,
719
+ bool workerIndexing = false ,
720
+ bool placeholder = false ,
721
+ IRpcWorkerChannelFactory channelFactory = null )
636
722
{
637
723
var eventManager = new ScriptEventManager ( ) ;
638
724
var metricsLogger = new Mock < IMetricsLogger > ( ) ;
@@ -667,8 +753,10 @@ private static RpcFunctionInvocationDispatcher GetTestFunctionDispatcher(int max
667
753
WorkerConfigs = TestHelpers . GetTestWorkerConfigs ( processCountValue : maxProcessCountValue , processStartupInterval : intervals ,
668
754
processRestartInterval : intervals , processShutdownTimeout : TimeSpan . FromSeconds ( 1 ) , workerIndexing : workerIndexing )
669
755
} ;
670
- IRpcWorkerChannelFactory testLanguageWorkerChannelFactory = new TestRpcWorkerChannelFactory ( eventManager , _testLogger , scriptOptions . Value . RootScriptPath , throwOnProcessStartUp ) ;
671
- IWebHostRpcWorkerChannelManager testWebHostLanguageWorkerChannelManager = new TestRpcWorkerChannelManager ( eventManager , _testLogger , scriptOptions . Value . RootScriptPath , testLanguageWorkerChannelFactory ) ;
756
+
757
+ channelFactory ??= new TestRpcWorkerChannelFactory ( eventManager , _testLogger , scriptOptions . Value . RootScriptPath , throwOnProcessStartUp ) ;
758
+ IWebHostRpcWorkerChannelManager testWebHostLanguageWorkerChannelManager = new TestRpcWorkerChannelManager (
759
+ eventManager , _testLogger , scriptOptions . Value . RootScriptPath , channelFactory ) ;
672
760
IJobHostRpcWorkerChannelManager jobHostLanguageWorkerChannelManager = new JobHostRpcWorkerChannelManager ( _testLoggerFactory ) ;
673
761
674
762
if ( addWebhostChannel )
@@ -681,6 +769,8 @@ private static RpcFunctionInvocationDispatcher GetTestFunctionDispatcher(int max
681
769
}
682
770
683
771
var mockFunctionDispatcherLoadBalancer = new Mock < IRpcFunctionInvocationDispatcherLoadBalancer > ( ) ;
772
+ mockFunctionDispatcherLoadBalancer . Setup ( m => m . GetLanguageWorkerChannel ( It . IsAny < IEnumerable < IRpcWorkerChannel > > ( ) ) )
773
+ . Returns ( ( IEnumerable < IRpcWorkerChannel > channels ) => channels . FirstOrDefault ( ) ) ;
684
774
var mockHostMetrics = new Mock < IHostMetrics > ( ) ;
685
775
686
776
_javaTestChannel = new TestRpcWorkerChannel ( Guid . NewGuid ( ) . ToString ( ) , "java" , eventManager , _testLogger , false ) ;
@@ -693,7 +783,7 @@ private static RpcFunctionInvocationDispatcher GetTestFunctionDispatcher(int max
693
783
mockApplicationLifetime . Object ,
694
784
eventManager ,
695
785
_testLoggerFactory ,
696
- testLanguageWorkerChannelFactory ,
786
+ channelFactory ,
697
787
optionsMonitor ,
698
788
testWebHostLanguageWorkerChannelManager ,
699
789
jobHostLanguageWorkerChannelManager ,
0 commit comments