Skip to content
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
44 changes: 44 additions & 0 deletions src/Build.UnitTests/BackEnd/UnixNodeReuseFixes_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if NET

using Microsoft.Build.Internal;
using Microsoft.Build.Shared;
using Shouldly;
using Xunit;

namespace Microsoft.Build.UnitTests
{
/// <summary>
/// Tests for Unix node reuse bug fixes:
/// - SessionId = 0 on Unix (cross-terminal node reuse)
/// </summary>
public class UnixNodeReuseFixes_Tests
{
[UnixOnlyFact]
public void Handshake_OnUnix_SessionIdIsZero()
{
var handshake = new Handshake(HandshakeOptions.NodeReuse);

// Use the structured accessor rather than parsing the key string
handshake.RetrieveHandshakeComponents().SessionId.ShouldBe(0,
"Unix handshake SessionId should be 0 to enable cross-terminal node reuse");
}

[UnixOnlyFact]
public void Handshake_OnUnix_KeyIsDeterministic()
{
// Two handshakes with same options produce identical keys on Unix
// because SessionId is always 0 (not terminal-specific).
// Note: this runs in a single process, so it validates determinism
// rather than cross-terminal behavior (which requires integration testing).
var h1 = new Handshake(HandshakeOptions.NodeReuse);
var h2 = new Handshake(HandshakeOptions.NodeReuse);

h1.GetKey().ShouldBe(h2.GetKey());
}
Comment thread
JakeRadMSFT marked this conversation as resolved.
}
}

#endif
6 changes: 5 additions & 1 deletion src/Shared/CommunicationsUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,12 @@ protected Handshake(HandshakeOptions nodeType, bool includeSessionId, string too

// Get session ID if needed (expensive call)
int sessionId = 0;
if (includeSessionId)
if (includeSessionId && NativeMethodsShared.IsWindows)
{
// On Windows, SessionId differentiates RDP sessions.
// On Unix, getsid() returns the session leader PID which differs per terminal,
// preventing cross-terminal node reuse. Use 0 since Unix doesn't need
// RDP-style session isolation.
using var currentProcess = Process.GetCurrentProcess();
sessionId = currentProcess.SessionId;
}
Expand Down