Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve how to retrieve process ID #3794

Merged
merged 2 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ dotnet_diagnostic.CA1840.severity = warning # not default, increased severity to
# CA1041: Provide ObsoleteAttribute message
dotnet_diagnostic.CA1041.severity = warning # not default, increased severity to ensure it is applied

# CA1837: Use Environment.ProcessId instead of Process.GetCurrentProcess().Id
dotnet_diagnostic.CA1837.severity = warning # not default, increased severity to ensure it is applied

#### C# Coding Conventions ####

# var preferences
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,11 @@ private bool RunTestInternalWithExecutors(IEnumerable<Tuple<Uri, string>> execut
EqtTrace.Verbose("Attaching to default test host.");

attachedToTestHost = true;
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
var pid = Process.GetCurrentProcess().Id;
#endif
if (!FrameworkHandle.AttachDebuggerToProcess(pid))
{
EqtTrace.Warning(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ public ArtifactProcessingManager(string? testSessionCorrelationId,
{
_testSessionCorrelationId = testSessionCorrelationId;
_processArtifactFolder = Path.Combine(_fileHelper.GetTempPath(), _testSessionCorrelationId);
_testSessionProcessArtifactFolder = Path.Combine(_processArtifactFolder, $"{Process.GetCurrentProcess().Id}_{Guid.NewGuid()}");
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
Copy link
Contributor

@MarcoRossignoli MarcoRossignoli Jun 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it cached by design?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System.Diagnostics.Process.GetCurrentProcess().Id is expensive:

It allocates a Process instance, usually just to get the Id.
The Process instance needs to be disposed, which has a performance impact.
It's easy to forget to call Dispose() on the Process instance.
If nothing else besides Id uses the Process instance, then the linked size grows unnecessarily by increasing the graph of types referenced.
It is somewhat difficult to discover or find this API.
System.Environment.ProcessId avoids all the above.

#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
_testSessionProcessArtifactFolder = Path.Combine(_processArtifactFolder, $"{pid}_{Guid.NewGuid()}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System;
using System.Collections.Generic;
#if !NET5_0_OR_GREATER
using System.Diagnostics;
#endif
using System.Globalization;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -150,7 +152,12 @@ public void StartSession()
if (port > 0)
{
// Fill the parameters
_consoleParameters.ParentProcessId = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
_consoleParameters.ParentProcessId = Environment.ProcessId;
#else
using (var process = Process.GetCurrentProcess())
_consoleParameters.ParentProcessId = process.Id;
#endif
_consoleParameters.PortNumber = port;

// Start vstest.console.exe process
Expand Down Expand Up @@ -576,7 +583,12 @@ public async Task StartSessionAsync()
if (port > 0)
{
// Fill the parameters
_consoleParameters.ParentProcessId = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
_consoleParameters.ParentProcessId = Environment.ProcessId;
#else
using (var process = Process.GetCurrentProcess())
_consoleParameters.ParentProcessId = process.Id;
#endif
_consoleParameters.PortNumber = port;

// Start vstest.console.exe process
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,20 @@ public void SetupChannelShouldAddRunnerProcessIdForTestHost()

_testOperationManager.SetupChannel(Enumerable.Empty<string>(), DefaultRunSettings);

#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif

_mockTestHostManager.Verify(
th =>
th.GetTestHostProcessStartInfo(
It.IsAny<IEnumerable<string>>(),
It.IsAny<Dictionary<string, string>>(),
It.Is<TestRunnerConnectionInfo>(t => t.RunnerProcessId.Equals(Process.GetCurrentProcess().Id))));
It.Is<TestRunnerConnectionInfo>(t => t.RunnerProcessId.Equals(pid))));
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,14 @@ public void LaunchTestHostShouldReturnTestHostProcessId()

Assert.IsTrue(processId.Result);

Assert.AreEqual(Process.GetCurrentProcess().Id, _testHostId);
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
Assert.AreEqual(pid, _testHostId);
}

[TestMethod]
Expand Down Expand Up @@ -471,7 +478,13 @@ public async Task ProcessExitedButNoErrorMessageIfNoDataWritten(int exitCode)
[TestMethod]
public async Task CleanTestHostAsyncShouldKillTestHostProcess()
{
var pid = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
bool isVerified = false;
_mockProcessHelper.Setup(ph => ph.TerminateProcess(It.IsAny<Process>()))
.Callback<object>(p => isVerified = ((Process)p).Id == pid);
Expand All @@ -486,7 +499,13 @@ public async Task CleanTestHostAsyncShouldKillTestHostProcess()
[TestMethod]
public async Task CleanTestHostAsyncShouldNotThrowIfTestHostIsNotStarted()
{
var pid = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
bool isVerified = false;
_mockProcessHelper.Setup(ph => ph.TerminateProcess(It.IsAny<Process>())).Callback<object>(p => isVerified = ((Process)p).Id == pid).Throws<Exception>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,21 @@ public DotnetTestHostManagerTests()
_mockFileHelper.Setup(ph => ph.Exists(_defaultTestHostPath)).Returns(true);
_mockFileHelper.Setup(ph => ph.Exists(DefaultDotnetPath)).Returns(true);

#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif

_mockTestHostLauncher
.Setup(th => th.LaunchTestHost(It.IsAny<TestProcessStartInfo>(), It.IsAny<CancellationToken>()))
.Returns(Process.GetCurrentProcess().Id);
.Returns(pid);

_mockTestHostLauncher
.Setup(th => th.LaunchTestHost(It.IsAny<TestProcessStartInfo>()))
.Returns(Process.GetCurrentProcess().Id);
.Returns(pid);

_defaultTestProcessStartInfo = _dotnetHostManager.GetTestHostProcessStartInfo(new[] { defaultSourcePath }, null, _defaultConnectionInfo);
}
Expand Down Expand Up @@ -430,7 +438,13 @@ public void GetTestHostProcessStartInfoShouldUseTestHostX86ExeFromNugetIfNotFoun
[TestMethod]
public void LaunchTestHostShouldLaunchProcessWithNullEnvironmentVariablesOrArgs()
{
var expectedProcessId = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var expectedProcessId = Environment.ProcessId;
#else
int expectedProcessId;
using (var p = Process.GetCurrentProcess())
expectedProcessId = p.Id;
#endif
_mockTestHostLauncher.Setup(thl => thl.LaunchTestHost(It.IsAny<TestProcessStartInfo>(), It.IsAny<CancellationToken>())).Returns(expectedProcessId);
_mockFileHelper.Setup(ph => ph.Exists("testhost.dll")).Returns(true);
var startInfo = GetDefaultStartInfo();
Expand All @@ -448,7 +462,13 @@ public void LaunchTestHostShouldLaunchProcessWithNullEnvironmentVariablesOrArgs(
[TestMethod]
public void LaunchTestHostAsyncShouldNotStartHostProcessIfCancellationTokenIsSet()
{
var expectedProcessId = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var expectedProcessId = Environment.ProcessId;
#else
int expectedProcessId;
using (var p = Process.GetCurrentProcess())
expectedProcessId = p.Id;
#endif
_mockTestHostLauncher.Setup(thl => thl.LaunchTestHost(It.IsAny<TestProcessStartInfo>())).Returns(expectedProcessId);
_mockFileHelper.Setup(ph => ph.Exists("testhost.dll")).Returns(true);
var startInfo = GetDefaultStartInfo();
Expand Down Expand Up @@ -577,7 +597,13 @@ public async Task LaunchTestHostShouldLaunchProcessWithConnectionInfo()
[TestMethod]
public void LaunchTestHostShouldSetExitCallBackInCaseCustomHost()
{
var expectedProcessId = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var expectedProcessId = Environment.ProcessId;
#else
int expectedProcessId;
using (var p = Process.GetCurrentProcess())
expectedProcessId = p.Id;
#endif
_mockTestHostLauncher.Setup(thl => thl.LaunchTestHost(It.IsAny<TestProcessStartInfo>(), It.IsAny<CancellationToken>())).Returns(expectedProcessId);
_mockFileHelper.Setup(ph => ph.Exists("testhost.dll")).Returns(true);

Expand Down Expand Up @@ -959,7 +985,13 @@ public async Task DotNetCoreProcessExitedButNoErrorMessageIfNoDataWritten(int ex
[TestMethod]
public async Task CleanTestHostAsyncShouldKillTestHostProcess()
{
var pid = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
bool isVerified = false;
_mockProcessHelper.Setup(ph => ph.TerminateProcess(It.IsAny<Process>()))
.Callback<object>(p => isVerified = ((Process)p).Id == pid);
Expand All @@ -975,7 +1007,13 @@ public async Task CleanTestHostAsyncShouldKillTestHostProcess()
[TestMethod]
public async Task CleanTestHostAsyncShouldNotThrowIfTestHostIsNotStarted()
{
var pid = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
bool isVerified = false;
_mockProcessHelper.Setup(ph => ph.TerminateProcess(It.IsAny<Process>())).Callback<object>(p => isVerified = ((Process)p).Id == pid).Throws<Exception>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
#if !NET5_0_OR_GREATER
using System.Diagnostics;
#endif
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -57,7 +60,13 @@ public VsTestConsoleWrapperAsyncTests()
public async Task StartSessionAsyncShouldStartVsTestConsoleWithCorrectArguments()
{
var inputPort = 123;
int expectedParentProcessId = System.Diagnostics.Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var expectedParentProcessId = Environment.ProcessId;
#else
int expectedParentProcessId;
using (var p = Process.GetCurrentProcess())
expectedParentProcessId = p.Id;
#endif
_mockRequestSender.Setup(rs => rs.InitializeCommunicationAsync(It.IsAny<int>())).Returns(Task.FromResult(inputPort));

await _consoleWrapper.StartSessionAsync();
Expand Down
8 changes: 7 additions & 1 deletion test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ public VsTestConsoleWrapperTests()
public void StartSessionShouldStartVsTestConsoleWithCorrectArguments()
{
var inputPort = 123;
int expectedParentProcessId = Process.GetCurrentProcess().Id;
#if NET5_0_OR_GREATER
var expectedParentProcessId = Environment.ProcessId;
#else
int expectedParentProcessId;
using (var p = Process.GetCurrentProcess())
expectedParentProcessId = p.Id;
#endif
_mockRequestSender.Setup(rs => rs.InitializeCommunication()).Returns(inputPort);

_consoleWrapper.StartSession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
#if !NET5_0_OR_GREATER
using System.Diagnostics;
#endif

using Microsoft.VisualStudio.TestPlatform.Client.DesignMode;
using Microsoft.VisualStudio.TestPlatform.Client.RequestHelper;
Expand Down Expand Up @@ -120,12 +122,18 @@ public void ExecutorInitializeShouldSetProcessExitCallback()
{
_executor = new PortArgumentExecutor(CommandLineOptions.Instance, _testRequestManager.Object, _mockProcessHelper.Object);
int port = 2345;
int processId = Process.GetCurrentProcess().Id;
CommandLineOptions.Instance.ParentProcessId = processId;
#if NET5_0_OR_GREATER
var pid = Environment.ProcessId;
#else
int pid;
using (var p = Process.GetCurrentProcess())
pid = p.Id;
#endif
CommandLineOptions.Instance.ParentProcessId = pid;

_executor.Initialize(port.ToString());

_mockProcessHelper.Verify(ph => ph.SetExitCallback(processId, It.IsAny<Action<object?>>()), Times.Once);
_mockProcessHelper.Verify(ph => ph.SetExitCallback(pid, It.IsAny<Action<object?>>()), Times.Once);
}

[TestMethod]
Expand Down