@@ -39,9 +39,9 @@ public class GrpcWorkerChannelTests : IDisposable
39
39
private static string _expectedSystemLogMessage = "Random system log message" ;
40
40
private static string _expectedLoadMsgPartial = "Sending FunctionLoadRequest for " ;
41
41
42
- private readonly Mock < IWorkerProcess > _mockrpcWorkerProcess = new Mock < IWorkerProcess > ( ) ;
42
+ private readonly Mock < IWorkerProcess > _mockRpcWorkerProcess = new Mock < IWorkerProcess > ( ) ;
43
43
private readonly string _workerId = "testWorkerId" ;
44
- private readonly string _scriptRootPath = "c:\t estdir" ;
44
+ private readonly string _scriptRootPath = "c:\\ testdir" ;
45
45
private readonly IScriptEventManager _eventManager = new ScriptEventManager ( ) ;
46
46
private readonly Mock < IScriptHostManager > _mockScriptHostManager = new Mock < IScriptHostManager > ( MockBehavior . Strict ) ;
47
47
private readonly TestMetricsLogger _metricsLogger = new TestMetricsLogger ( ) ;
@@ -57,7 +57,6 @@ public class GrpcWorkerChannelTests : IDisposable
57
57
private readonly IOptionsMonitor < ScriptApplicationHostOptions > _hostOptionsMonitor ;
58
58
private readonly IMemoryMappedFileAccessor _mapAccessor ;
59
59
private readonly ISharedMemoryManager _sharedMemoryManager ;
60
- private readonly IFunctionDataCache _functionDataCache ;
61
60
private readonly IOptions < WorkerConcurrencyOptions > _workerConcurrencyOptions ;
62
61
private readonly ITestOutputHelper _testOutput ;
63
62
private readonly IOptions < FunctionsHostingConfigOptions > _hostingConfigOptions ;
@@ -76,24 +75,24 @@ public GrpcWorkerChannelTests(ITestOutputHelper testOutput)
76
75
_testWorkerConfig . CountOptions . InitializationTimeout = TimeSpan . FromSeconds ( 5 ) ;
77
76
_testWorkerConfig . CountOptions . EnvironmentReloadTimeout = TimeSpan . FromSeconds ( 5 ) ;
78
77
79
- _mockrpcWorkerProcess . Setup ( m => m . StartProcessAsync ( default ) ) . Returns ( Task . CompletedTask ) ;
80
- _mockrpcWorkerProcess . Setup ( m => m . Id ) . Returns ( 910 ) ;
78
+ _mockRpcWorkerProcess . Setup ( m => m . StartProcessAsync ( It . IsAny < CancellationToken > ( ) ) ) . Returns ( Task . CompletedTask ) ;
79
+ _mockRpcWorkerProcess . Setup ( m => m . WaitForExitAsync ( It . IsAny < CancellationToken > ( ) ) ) . Returns ( Task . Delay ( Timeout . Infinite ) ) ;
80
+ _mockRpcWorkerProcess . Setup ( m => m . Id ) . Returns ( 910 ) ;
81
81
_testEnvironment = new TestEnvironment ( ) ;
82
82
_testEnvironment . SetEnvironmentVariable ( FunctionDataCacheConstants . FunctionDataCacheEnabledSettingName , "1" ) ;
83
83
_workerConcurrencyOptions = Options . Create ( new WorkerConcurrencyOptions ( ) ) ;
84
84
_workerConcurrencyOptions . Value . CheckInterval = TimeSpan . FromSeconds ( 1 ) ;
85
85
86
- ILogger < MemoryMappedFileAccessor > mmapAccessorLogger = NullLogger < MemoryMappedFileAccessor > . Instance ;
86
+ ILogger < MemoryMappedFileAccessor > mMapAccessorLogger = NullLogger < MemoryMappedFileAccessor > . Instance ;
87
87
if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
88
88
{
89
- _mapAccessor = new MemoryMappedFileAccessorWindows ( mmapAccessorLogger ) ;
89
+ _mapAccessor = new MemoryMappedFileAccessorWindows ( mMapAccessorLogger ) ;
90
90
}
91
91
else
92
92
{
93
- _mapAccessor = new MemoryMappedFileAccessorUnix ( mmapAccessorLogger , _testEnvironment ) ;
93
+ _mapAccessor = new MemoryMappedFileAccessorUnix ( mMapAccessorLogger , _testEnvironment ) ;
94
94
}
95
95
_sharedMemoryManager = new SharedMemoryManager ( _loggerFactory , _mapAccessor ) ;
96
- _functionDataCache = new FunctionDataCache ( _sharedMemoryManager , _loggerFactory , _testEnvironment ) ;
97
96
98
97
var hostOptions = new ScriptApplicationHostOptions
99
98
{
@@ -127,7 +126,7 @@ private Task CreateDefaultWorkerChannel(bool autoStart = true, IDictionary<strin
127
126
_eventManager ,
128
127
_mockScriptHostManager . Object ,
129
128
_testWorkerConfig ,
130
- _mockrpcWorkerProcess . Object ,
129
+ _mockRpcWorkerProcess . Object ,
131
130
_logger ,
132
131
_metricsLogger ,
133
132
0 ,
@@ -182,6 +181,77 @@ await Assert.ThrowsAsync<TaskCanceledException>(async () =>
182
181
} ) ;
183
182
}
184
183
184
+ [ Fact ]
185
+ public async Task StartWorkerProcessAsync_ProcessExits_Throws ( )
186
+ {
187
+ _mockRpcWorkerProcess . Setup ( m => m . WaitForExitAsync ( It . IsAny < CancellationToken > ( ) ) )
188
+ . Returns ( Task . CompletedTask ) ;
189
+ await CreateDefaultWorkerChannel ( autoStart : false ) ;
190
+
191
+ WorkerProcessExitException ex = await Assert . ThrowsAsync < WorkerProcessExitException > (
192
+ ( ) => _workerChannel . StartWorkerProcessAsync ( default ) )
193
+ . WaitAsync ( TimeSpan . FromMilliseconds ( 100 ) ) ;
194
+ Assert . Equal ( 0 , ex . ExitCode ) ;
195
+ Assert . Equal ( "Worker process exited before initializing." , ex . Message ) ;
196
+ }
197
+
198
+ [ Fact ]
199
+ public async Task StartWorkerProcessAsync_ProcessFaults_Throws ( )
200
+ {
201
+ WorkerProcessExitException expected = new ( "Process has faulted." ) { ExitCode = - 1 } ;
202
+ _mockRpcWorkerProcess . Setup ( m => m . WaitForExitAsync ( It . IsAny < CancellationToken > ( ) ) )
203
+ . ThrowsAsync ( expected ) ;
204
+ await CreateDefaultWorkerChannel ( autoStart : false ) ;
205
+
206
+ WorkerProcessExitException actual = await Assert . ThrowsAsync < WorkerProcessExitException > (
207
+ ( ) => _workerChannel . StartWorkerProcessAsync ( default ) )
208
+ . WaitAsync ( TimeSpan . FromMilliseconds ( 100 ) ) ;
209
+ Assert . Equal ( expected , actual ) ;
210
+ }
211
+
212
+ [ Fact ]
213
+ public async Task StartWorkerProcessAsync_TimesOut ( )
214
+ {
215
+ await CreateDefaultWorkerChannel ( autoStart : false ) ; // suppress for timeout
216
+ var initTask = _workerChannel . StartWorkerProcessAsync ( CancellationToken . None ) ;
217
+ await Assert . ThrowsAsync < TimeoutException > ( async ( ) => await initTask ) ;
218
+ }
219
+
220
+ [ Fact ]
221
+ public async Task StartWorkerProcessAsync_WorkerProcess_Throws ( )
222
+ {
223
+ // note: uses custom worker channel
224
+ Mock < IWorkerProcess > mockrpcWorkerProcessThatThrows = new Mock < IWorkerProcess > ( ) ;
225
+ mockrpcWorkerProcessThatThrows . Setup ( m => m . StartProcessAsync ( default ) ) . Throws < FileNotFoundException > ( ) ;
226
+
227
+ _workerChannel = new GrpcWorkerChannel (
228
+ _workerId ,
229
+ _eventManager ,
230
+ _mockScriptHostManager . Object ,
231
+ _testWorkerConfig ,
232
+ mockrpcWorkerProcessThatThrows . Object ,
233
+ _logger ,
234
+ _metricsLogger ,
235
+ 0 ,
236
+ _testEnvironment ,
237
+ _hostOptionsMonitor ,
238
+ _sharedMemoryManager ,
239
+ _workerConcurrencyOptions ,
240
+ _hostingConfigOptions ,
241
+ _httpProxyService ) ;
242
+ await Assert . ThrowsAsync < FileNotFoundException > ( async ( ) => await _workerChannel . StartWorkerProcessAsync ( CancellationToken . None ) ) ;
243
+ }
244
+
245
+ [ Fact ]
246
+ public async Task StartWorkerProcessAsync_Invoked_SetupFunctionBuffers_Verify_ReadyForInvocation ( )
247
+ {
248
+ await CreateDefaultWorkerChannel ( ) ;
249
+ _mockRpcWorkerProcess . Verify ( m => m . StartProcessAsync ( default ) , Times . Once ) ;
250
+ Assert . False ( _workerChannel . IsChannelReadyForInvocations ( ) ) ;
251
+ _workerChannel . SetupFunctionInvocationBuffers ( GetTestFunctionsList ( "node" ) ) ;
252
+ Assert . True ( _workerChannel . IsChannelReadyForInvocations ( ) ) ;
253
+ }
254
+
185
255
[ Fact ]
186
256
public async Task WorkerChannel_Dispose_With_WorkerTerminateCapability ( )
187
257
{
@@ -221,16 +291,6 @@ public async Task WorkerChannel_Dispose_Without_WorkerTerminateCapability()
221
291
Assert . False ( traces . Any ( m => string . Equals ( m . FormattedMessage , expectedLogMsg ) ) ) ;
222
292
}
223
293
224
- [ Fact ]
225
- public async Task StartWorkerProcessAsync_Invoked_SetupFunctionBuffers_Verify_ReadyForInvocation ( )
226
- {
227
- await CreateDefaultWorkerChannel ( ) ;
228
- _mockrpcWorkerProcess . Verify ( m => m . StartProcessAsync ( default ) , Times . Once ) ;
229
- Assert . False ( _workerChannel . IsChannelReadyForInvocations ( ) ) ;
230
- _workerChannel . SetupFunctionInvocationBuffers ( GetTestFunctionsList ( "node" ) ) ;
231
- Assert . True ( _workerChannel . IsChannelReadyForInvocations ( ) ) ;
232
- }
233
-
234
294
[ Fact ]
235
295
public async Task DisposingChannel_NotReadyForInvocation ( )
236
296
{
@@ -259,14 +319,6 @@ public void SetupFunctionBuffers_Verify_ReadyForInvocation_Returns_False()
259
319
Assert . False ( _workerChannel . IsChannelReadyForInvocations ( ) ) ;
260
320
}
261
321
262
- [ Fact ]
263
- public async Task StartWorkerProcessAsync_TimesOut ( )
264
- {
265
- await CreateDefaultWorkerChannel ( autoStart : false ) ; // suppress for timeout
266
- var initTask = _workerChannel . StartWorkerProcessAsync ( CancellationToken . None ) ;
267
- await Assert . ThrowsAsync < TimeoutException > ( async ( ) => await initTask ) ;
268
- }
269
-
270
322
[ Fact ]
271
323
public async Task SendEnvironmentReloadRequest_Generates_ExpectedMetrics ( )
272
324
{
@@ -283,31 +335,6 @@ public async Task SendEnvironmentReloadRequest_Generates_ExpectedMetrics()
283
335
Assert . True ( _metricsLogger . EventsBegan . Contains ( MetricEventNames . SpecializationEnvironmentReloadRequestResponse ) ) ;
284
336
}
285
337
286
- [ Fact ]
287
- public async Task StartWorkerProcessAsync_WorkerProcess_Throws ( )
288
- {
289
- // note: uses custom worker channel
290
- Mock < IWorkerProcess > mockrpcWorkerProcessThatThrows = new Mock < IWorkerProcess > ( ) ;
291
- mockrpcWorkerProcessThatThrows . Setup ( m => m . StartProcessAsync ( default ) ) . Throws < FileNotFoundException > ( ) ;
292
-
293
- _workerChannel = new GrpcWorkerChannel (
294
- _workerId ,
295
- _eventManager ,
296
- _mockScriptHostManager . Object ,
297
- _testWorkerConfig ,
298
- mockrpcWorkerProcessThatThrows . Object ,
299
- _logger ,
300
- _metricsLogger ,
301
- 0 ,
302
- _testEnvironment ,
303
- _hostOptionsMonitor ,
304
- _sharedMemoryManager ,
305
- _workerConcurrencyOptions ,
306
- _hostingConfigOptions ,
307
- _httpProxyService ) ;
308
- await Assert . ThrowsAsync < FileNotFoundException > ( async ( ) => await _workerChannel . StartWorkerProcessAsync ( CancellationToken . None ) ) ;
309
- }
310
-
311
338
[ Fact ]
312
339
public async Task SendWorkerInitRequest_PublishesOutboundEvent ( )
313
340
{
@@ -547,7 +574,7 @@ public async Task Drain_Verify()
547
574
_eventManager ,
548
575
_mockScriptHostManager . Object ,
549
576
_testWorkerConfig ,
550
- _mockrpcWorkerProcess . Object ,
577
+ _mockRpcWorkerProcess . Object ,
551
578
_logger ,
552
579
_metricsLogger ,
553
580
0 ,
@@ -1256,7 +1283,7 @@ public async Task GetLatencies_StartsTimer_WhenDynamicConcurrencyEnabled()
1256
1283
_eventManager ,
1257
1284
_mockScriptHostManager . Object ,
1258
1285
config ,
1259
- _mockrpcWorkerProcess . Object ,
1286
+ _mockRpcWorkerProcess . Object ,
1260
1287
_logger ,
1261
1288
_metricsLogger ,
1262
1289
0 ,
@@ -1297,7 +1324,7 @@ public async Task GetLatencies_DoesNot_StartTimer_WhenDynamicConcurrencyDisabled
1297
1324
_eventManager ,
1298
1325
_mockScriptHostManager . Object ,
1299
1326
config ,
1300
- _mockrpcWorkerProcess . Object ,
1327
+ _mockRpcWorkerProcess . Object ,
1301
1328
_logger ,
1302
1329
_metricsLogger ,
1303
1330
0 ,
0 commit comments