Skip to content

Commit 3059c8b

Browse files
authored
Enable PowerShell placeholders (#5998)
1 parent 8deb995 commit 3059c8b

File tree

4 files changed

+32
-15
lines changed

4 files changed

+32
-15
lines changed

src/WebJobs.Script/Workers/Rpc/RpcInitializationService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ public class RpcInitializationService : IManagedHostedService
4949
private List<string> _placeholderPoolWhitelistedRuntimes = new List<string>()
5050
{
5151
RpcWorkerConstants.JavaLanguageWorkerName,
52-
RpcWorkerConstants.NodeLanguageWorkerName
52+
RpcWorkerConstants.NodeLanguageWorkerName,
53+
RpcWorkerConstants.PowerShellLanguageWorkerName
5354
};
5455

5556
public RpcInitializationService(IOptionsMonitor<ScriptApplicationHostOptions> applicationHostOptions, IEnvironment environment, IRpcServer rpcServer, IWebHostRpcWorkerChannelManager rpcWorkerChannelManager, ILogger<RpcInitializationService> logger)

src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,10 @@ private bool UsePlaceholderChannel(string workerRuntime)
134134
{
135135
if (!string.IsNullOrEmpty(workerRuntime))
136136
{
137-
// Special case: node apps must be read-only to use the placeholder mode channel
137+
// Special case: node and PowerShell apps must be read-only to use the placeholder mode channel
138138
// TODO: Remove special casing when resolving https://github.com/Azure/azure-functions-host/issues/4534
139-
if (string.Equals(workerRuntime, RpcWorkerConstants.NodeLanguageWorkerName, StringComparison.OrdinalIgnoreCase))
139+
if (string.Equals(workerRuntime, RpcWorkerConstants.NodeLanguageWorkerName, StringComparison.OrdinalIgnoreCase)
140+
|| string.Equals(workerRuntime, RpcWorkerConstants.PowerShellLanguageWorkerName, StringComparison.OrdinalIgnoreCase))
140141
{
141142
return _environment.IsFileSystemReadOnly();
142143
}

test/WebJobs.Script.Tests/Workers/Rpc/RpcInitializationServiceTests.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
@@ -75,6 +75,7 @@ public async Task RpcInitializationService_Initializes_RpcServerAndChannels_Wind
7575
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Once);
7676
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Never);
7777
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Never);
78+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
7879
Assert.Contains("testserver", testRpcServer.Uri.ToString());
7980
await testRpcServer.ShutdownAsync();
8081
}
@@ -92,6 +93,7 @@ public async Task RpcInitializationService_Initializes_RpcServerOnly_Windows_NoP
9293
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Never);
9394
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Never);
9495
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Never);
96+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
9597
Assert.Contains("testserver", testRpcServer.Uri.ToString());
9698
await testRpcServer.ShutdownAsync();
9799
}
@@ -116,6 +118,7 @@ public async Task RpcInitializationService_Initializes_RpcServerAndChannels_Linu
116118
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Once);
117119
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Once);
118120
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Never);
121+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
119122
Assert.Contains("testserver", testRpcServer.Uri.ToString());
120123
await testRpcServer.ShutdownAsync();
121124

@@ -140,6 +143,7 @@ public async Task RpcInitializationService_Does_Not_Initialize_RpcServerAndChann
140143
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Never);
141144
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Never);
142145
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Never);
146+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
143147
Assert.DoesNotContain("testserver", testRpcServer.Uri.ToString());
144148
await testRpcServer.ShutdownAsync();
145149

@@ -166,6 +170,7 @@ public async Task RpcInitializationService_Initializes_RpcServerOnly_LinuxConsum
166170
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Never);
167171
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Never);
168172
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Never);
173+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
169174
Assert.Contains("testserver", testRpcServer.Uri.ToString());
170175
await testRpcServer.ShutdownAsync();
171176

@@ -187,6 +192,7 @@ public async Task RpcInitializationService_Initializes_RpcServerAndChannels_Linu
187192
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Once);
188193
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Once);
189194
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Never);
195+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
190196
Assert.Contains("testserver", testRpcServer.Uri.ToString());
191197
await testRpcServer.ShutdownAsync();
192198
}
@@ -206,6 +212,7 @@ public async Task RpcInitializationService_Initializes_RpcServerOnly_LinuxAppSer
206212
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PythonLanguageWorkerName), Times.Never);
207213
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName), Times.Never);
208214
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName), Times.Never);
215+
_mockLanguageWorkerChannelManager.Verify(m => m.InitializeChannelAsync(RpcWorkerConstants.PowerShellLanguageWorkerName), Times.Never);
209216
Assert.Contains("testserver", testRpcServer.Uri.ToString());
210217
await testRpcServer.ShutdownAsync();
211218
}
@@ -351,6 +358,10 @@ public void ShouldStartStandbyPlaceholderChannels_Returns_ExpectedValue(string p
351358
[InlineData("0", "node", "1234", false)]
352359
[InlineData("1", "node", "", true)]
353360
[InlineData("1", "Node", "", true)]
361+
[InlineData("1", "powershell", "1234", true)]
362+
[InlineData("0", "powershell", "1234", false)]
363+
[InlineData("1", "powershell", "", true)]
364+
[InlineData("1", "Powershell", "", true)]
354365
[InlineData("1", "java", "1234", true)]
355366
[InlineData("0", "java", "1234", false)]
356367
[InlineData("0", "JAVA", "1234", false)]

test/WebJobs.Script.Tests/Workers/Rpc/WebHostRpcWorkerChannelManagerTests.cs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,19 @@ public async Task ShutdownStandyChannels_WorkerRuntime_Node_Set()
158158
}
159159

160160
[Theory]
161-
[InlineData("nOde")]
162-
[InlineData("Node")]
163-
public async Task SpecializeAsync_Node_ReadOnly_KeepsProcessAlive(string runtime)
161+
[InlineData("nOde", RpcWorkerConstants.NodeLanguageWorkerName)]
162+
[InlineData("Node", RpcWorkerConstants.NodeLanguageWorkerName)]
163+
[InlineData("PowerShell", RpcWorkerConstants.PowerShellLanguageWorkerName)]
164+
[InlineData("pOwerShell", RpcWorkerConstants.PowerShellLanguageWorkerName)]
165+
public async Task SpecializeAsync_ReadOnly_KeepsProcessAlive(string runtime, string languageWorkerName)
164166
{
165167
var testMetricsLogger = new TestMetricsLogger();
166168
_testEnvironment.SetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeSettingName, runtime);
167169
_testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteZipDeployment, "1");
168170

169171
_rpcWorkerChannelManager = new WebHostRpcWorkerChannelManager(_eventManager, _testEnvironment, _loggerFactory, _rpcWorkerChannelFactory, _optionsMonitor, testMetricsLogger, _workerOptionsMonitor);
170172

171-
IRpcWorkerChannel nodeWorkerChannel = CreateTestChannel(RpcWorkerConstants.NodeLanguageWorkerName);
173+
IRpcWorkerChannel workerChannel = CreateTestChannel(languageWorkerName);
172174

173175
await _rpcWorkerChannelManager.SpecializeAsync();
174176
Assert.True(testMetricsLogger.EventsBegan.Contains(MetricEventNames.SpecializationScheduleShutdownStandbyChannels)
@@ -180,8 +182,8 @@ public async Task SpecializeAsync_Node_ReadOnly_KeepsProcessAlive(string runtime
180182
Assert.True(functionLoadLogs.Count() == 1);
181183

182184
// Verify channel
183-
var initializedChannel = await _rpcWorkerChannelManager.GetChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName);
184-
Assert.Equal(nodeWorkerChannel, initializedChannel);
185+
var initializedChannel = await _rpcWorkerChannelManager.GetChannelAsync(languageWorkerName);
186+
Assert.Equal(workerChannel, initializedChannel);
185187
}
186188

187189
[Fact]
@@ -236,17 +238,19 @@ public async Task SpecializeAsync_Java_ReadOnly_KeepsProcessAlive()
236238
Assert.Equal(javaWorkerChannel, initializedChannel);
237239
}
238240

239-
[Fact]
240-
public async Task SpecializeAsync_Node_NotReadOnly_KillsProcess()
241+
[Theory]
242+
[InlineData(RpcWorkerConstants.NodeLanguageWorkerName)]
243+
[InlineData(RpcWorkerConstants.PowerShellLanguageWorkerName)]
244+
public async Task SpecializeAsync_NotReadOnly_KillsProcess(string languageWorkerName)
241245
{
242246
var testMetricsLogger = new TestMetricsLogger();
243-
_testEnvironment.SetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeSettingName, RpcWorkerConstants.NodeLanguageWorkerName);
247+
_testEnvironment.SetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeSettingName, languageWorkerName);
244248
// This is an invalid setting configuration, but just to show that run from zip is NOT set
245249
_testEnvironment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsiteZipDeployment, "0");
246250

247251
_rpcWorkerChannelManager = new WebHostRpcWorkerChannelManager(_eventManager, _testEnvironment, _loggerFactory, _rpcWorkerChannelFactory, _optionsMonitor, testMetricsLogger, _workerOptionsMonitor);
248252

249-
IRpcWorkerChannel nodeWorkerChannel = CreateTestChannel(RpcWorkerConstants.NodeLanguageWorkerName);
253+
IRpcWorkerChannel workerChannel = CreateTestChannel(languageWorkerName);
250254

251255
await _rpcWorkerChannelManager.SpecializeAsync();
252256

@@ -255,7 +259,7 @@ public async Task SpecializeAsync_Node_NotReadOnly_KillsProcess()
255259
Assert.True(traces.Count() == 0);
256260

257261
// Verify channel
258-
var initializedChannel = await _rpcWorkerChannelManager.GetChannelAsync(RpcWorkerConstants.NodeLanguageWorkerName);
262+
var initializedChannel = await _rpcWorkerChannelManager.GetChannelAsync(languageWorkerName);
259263
Assert.Null(initializedChannel);
260264
}
261265

0 commit comments

Comments
 (0)