207e7429e4
- New cmdlet Start-InfisicalProcess: launches a child process with InfisicalSecret
objects decrypted directly into ProcessStartInfo.Environment (optional -Prefix),
additional -EnvironmentVariables, stdout/stderr capture, -AcceptableExitCodeList,
-ParsingExpression regex parsing, -ExecutionTimeout / -ExecutionTimeoutInterval,
-NoWait, -WindowStyle / -CreateNoWindow parameter sets, -Priority,
-StandardInputObjectList, -SecureArgumentList, -LogOutput, -ContinueOnError, and
ShouldProcess support. Secret plaintext is never written to user or machine scope.
- Stream capture uses event-based OutputDataReceived/ErrorDataReceived with
BeginOutputReadLine/BeginErrorReadLine (no Task / ReadToEndAsync /
GetAwaiter().GetResult()) to avoid PowerShell SynchronizationContext deadlocks.
- Restored the do { log; sleep } while (!HasExited) polling pattern using
Thread.Sleep(pollInterval) so verbose "has been running for X" / "Checking again
in Y" messages fire at the configured cadence even when no -ExecutionTimeout is
supplied.
- TimeSpan values in verbose logs and on the result now use a friendly format
("7 seconds, and 364 milliseconds", "1 minute, and 30 seconds", "N/A" when zero)
matching the legacy Start-ProcessWithOutput GetTimeSpanMessage scriptblock.
- Added DurationFriendly property to InfisicalProcessResult and a "The command
execution took X" verbose line at completion.
- build.ps1 CmdletsToExport and Test-ModuleImports expected list contain 42 cmdlets.
- Added 9 xUnit tests covering FormatFriendly singular/plural, multi-unit joining,
zero, sub-millisecond, and skip-zero-components behavior.
76 lines
3.1 KiB
C#
76 lines
3.1 KiB
C#
using System;
|
|
using PSInfisicalAPI.Process;
|
|
using Xunit;
|
|
|
|
namespace PSInfisicalAPI.Tests
|
|
{
|
|
public class InfisicalProcessRunnerHelpersTests
|
|
{
|
|
[Fact]
|
|
public void FormatFriendly_Zero_Returns_NotAvailable()
|
|
{
|
|
Assert.Equal("N/A", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Single_Unit_Plural()
|
|
{
|
|
Assert.Equal("30 seconds", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromSeconds(30)));
|
|
Assert.Equal("5 minutes", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromMinutes(5)));
|
|
Assert.Equal("250 milliseconds", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromMilliseconds(250)));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Single_Unit_Singular()
|
|
{
|
|
Assert.Equal("1 second", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromSeconds(1)));
|
|
Assert.Equal("1 minute", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromMinutes(1)));
|
|
Assert.Equal("1 hour", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromHours(1)));
|
|
Assert.Equal("1 day", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromDays(1)));
|
|
Assert.Equal("1 millisecond", InfisicalProcessRunnerHelpers.FormatFriendly(TimeSpan.FromMilliseconds(1)));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Two_Units_Uses_And_Join()
|
|
{
|
|
TimeSpan value = TimeSpan.FromSeconds(7) + TimeSpan.FromMilliseconds(364);
|
|
Assert.Equal("7 seconds, and 364 milliseconds", InfisicalProcessRunnerHelpers.FormatFriendly(value));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Multiple_Units_Uses_Comma_And_Trailing_And()
|
|
{
|
|
TimeSpan value = TimeSpan.FromHours(1) + TimeSpan.FromMinutes(2) + TimeSpan.FromSeconds(3) + TimeSpan.FromMilliseconds(45);
|
|
Assert.Equal("1 hour, 2 minutes, 3 seconds, and 45 milliseconds", InfisicalProcessRunnerHelpers.FormatFriendly(value));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Skips_Zero_Components()
|
|
{
|
|
TimeSpan value = TimeSpan.FromHours(2) + TimeSpan.FromMilliseconds(500);
|
|
Assert.Equal("2 hours, and 500 milliseconds", InfisicalProcessRunnerHelpers.FormatFriendly(value));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Mixed_Singular_And_Plural()
|
|
{
|
|
TimeSpan value = TimeSpan.FromMinutes(1) + TimeSpan.FromSeconds(30);
|
|
Assert.Equal("1 minute, and 30 seconds", InfisicalProcessRunnerHelpers.FormatFriendly(value));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_Days_Component()
|
|
{
|
|
TimeSpan value = TimeSpan.FromDays(2) + TimeSpan.FromHours(3);
|
|
Assert.Equal("2 days, and 3 hours", InfisicalProcessRunnerHelpers.FormatFriendly(value));
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatFriendly_SubMillisecond_Returns_NotAvailable()
|
|
{
|
|
TimeSpan value = TimeSpan.FromTicks(100);
|
|
Assert.Equal("N/A", InfisicalProcessRunnerHelpers.FormatFriendly(value));
|
|
}
|
|
}
|
|
}
|