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