Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
refactor: replace Environment.MachineName with cached EnvironmentHelp…
…er.MachineName to improve performance
  • Loading branch information
thomhurst committed Nov 1, 2025
commit 83c6ae4c53002d2b7708705c7687e69f2fd755f6
18 changes: 15 additions & 3 deletions TUnit.Core/AbstractExecutableTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using TUnit.Core.Helpers;
using TUnit.Core.Models;

namespace TUnit.Core;
Expand All @@ -8,7 +9,7 @@ public abstract class AbstractExecutableTest
{
public required string TestId { get; init; }

public virtual TestMetadata Metadata { get; init; } = null!;
public TestMetadata Metadata { get; init; } = null!;

public required object?[] Arguments { get; init; }

Expand Down Expand Up @@ -70,15 +71,26 @@ public DateTimeOffset? StartTime
public void SetResult(TestState state, Exception? exception = null)
{
State = state;

// Lazy output building - avoid string allocation when there's no output
var output = Context.GetOutput();
var errorOutput = Context.GetErrorOutput();
var combinedOutput = string.Empty;

if (output.Length > 0 || errorOutput.Length > 0)
{
combinedOutput = string.Concat(output, Environment.NewLine, Environment.NewLine, errorOutput);
}

Context.Execution.Result ??= new TestResult
{
State = state,
Exception = exception,
ComputerName = Environment.MachineName,
ComputerName = EnvironmentHelper.MachineName,
Duration = Duration,
End = EndTime ??= DateTimeOffset.UtcNow,
Start = StartTime ??= DateTimeOffset.UtcNow,
Output = string.Concat(Context.GetOutput(), Environment.NewLine, Environment.NewLine, Context.GetErrorOutput())
Output = combinedOutput
};
}
}
13 changes: 13 additions & 0 deletions TUnit.Core/Helpers/EnvironmentHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace TUnit.Core.Helpers;

/// <summary>
/// Provides cached environment information to avoid repeated system calls.
/// </summary>
internal static class EnvironmentHelper
{
/// <summary>
/// Cached machine name - avoids system call overhead on every test completion.
/// Environment.MachineName requires a P/Invoke call which is expensive when called millions of times.
/// </summary>
public static readonly string MachineName = Environment.MachineName;
}
3 changes: 2 additions & 1 deletion TUnit.Core/TestContext.Execution.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TUnit.Core.Enums;
using TUnit.Core.Helpers;
using TUnit.Core.Interfaces;

namespace TUnit.Core;
Expand Down Expand Up @@ -112,7 +113,7 @@ internal void OverrideResult(TestState state, string reason)
End = DateTimeOffset.UtcNow,
Duration = DateTimeOffset.UtcNow - (TestStart ?? DateTimeOffset.UtcNow),
Exception = exceptionForResult,
ComputerName = Environment.MachineName,
ComputerName = EnvironmentHelper.MachineName,
TestContext = this
};

Expand Down
4 changes: 2 additions & 2 deletions TUnit.Engine/Building/TestBuilderPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ private AbstractExecutableTest CreateFailedTestForDataGenerationError(TestMetada
End = DateTimeOffset.UtcNow,
Duration = TimeSpan.Zero,
Exception = exception,
ComputerName = Environment.MachineName,
ComputerName = EnvironmentHelper.MachineName,
TestContext = context
}
};
Expand Down Expand Up @@ -441,7 +441,7 @@ private AbstractExecutableTest CreateFailedTestForGenericResolutionError(TestMet
End = DateTimeOffset.UtcNow,
Duration = TimeSpan.Zero,
Exception = exception,
ComputerName = Environment.MachineName,
ComputerName = EnvironmentHelper.MachineName,
TestContext = context
}
};
Expand Down
3 changes: 2 additions & 1 deletion TUnit.Engine/Services/TestDependencyResolver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TUnit.Core;
using TUnit.Core.Helpers;

namespace TUnit.Engine.Services;

Expand Down Expand Up @@ -263,7 +264,7 @@ private static void CreateDependencyResolutionFailedResult(AbstractExecutableTes
Duration = TimeSpan.Zero,
Exception = new InvalidOperationException(
$"Could not resolve all dependencies for test {test.Metadata.TestClassType.Name}.{test.Metadata.TestMethodName}"),
ComputerName = Environment.MachineName
ComputerName = EnvironmentHelper.MachineName
};
}
}
11 changes: 6 additions & 5 deletions TUnit.Engine/Services/TestExecution/TestStateManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using TUnit.Core;
using TUnit.Core.Exceptions;
using TUnit.Core.Helpers;

namespace TUnit.Engine.Services.TestExecution;

Expand Down Expand Up @@ -27,7 +28,7 @@ public Task MarkCompletedAsync(AbstractExecutableTest test)
End = now,
Duration = now - test.StartTime.GetValueOrDefault(),
Exception = null,
ComputerName = Environment.MachineName
ComputerName = EnvironmentHelper.MachineName
};

test.State = test.Result.State;
Expand Down Expand Up @@ -55,7 +56,7 @@ public Task MarkFailedAsync(AbstractExecutableTest test, Exception exception)
Start = test.StartTime,
End = test.EndTime,
Duration = test.EndTime - test.StartTime.GetValueOrDefault(),
ComputerName = Environment.MachineName
ComputerName = EnvironmentHelper.MachineName
};
}

Expand All @@ -81,7 +82,7 @@ public Task MarkSkippedAsync(AbstractExecutableTest test, string reason)
Start = test.StartTime.Value,
End = test.EndTime,
Duration = test.EndTime - test.StartTime.GetValueOrDefault(),
ComputerName = Environment.MachineName
ComputerName = EnvironmentHelper.MachineName
};

return Task.CompletedTask;
Expand All @@ -98,7 +99,7 @@ public Task MarkCircularDependencyFailedAsync(AbstractExecutableTest test, Excep
Start = now,
End = now,
Duration = TimeSpan.Zero,
ComputerName = Environment.MachineName
ComputerName = EnvironmentHelper.MachineName
};

return Task.CompletedTask;
Expand All @@ -117,7 +118,7 @@ public Task MarkDependencyResolutionFailedAsync(AbstractExecutableTest test, Exc
Start = now,
End = now,
Duration = TimeSpan.Zero,
ComputerName = Environment.MachineName
ComputerName = EnvironmentHelper.MachineName
};

return Task.CompletedTask;
Expand Down