-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix ManagedCommand. Refactor Process management. Add more tests * Add more documentation.
- Loading branch information
Showing
12 changed files
with
370 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
Community.Wsl.Sdk.Tests/UnitTests/ManagedCommandTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Castle.Core.Resource; | ||
using Community.Wsl.Sdk.Strategies.Api; | ||
using Community.Wsl.Sdk.Strategies.Command; | ||
using FakeItEasy; | ||
using FluentAssertions; | ||
using NUnit.Framework; | ||
|
||
namespace Community.Wsl.Sdk.Tests.UnitTests | ||
{ | ||
public class ManagedCommandTests | ||
{ | ||
public ManagedCommand CreateCommand( | ||
string distroName, | ||
string command, | ||
string[] arguments, | ||
CommandExecutionOptions options, | ||
bool asRoot = false, | ||
bool shellExecute = false | ||
) | ||
{ | ||
var io = A.Fake<IIo>(); | ||
var env = A.Fake<IEnvironment>(); | ||
var pm = A.Fake<IProcessManager>(); | ||
|
||
return new ManagedCommand( | ||
distroName, | ||
command, | ||
arguments, | ||
options, | ||
asRoot, | ||
shellExecute, | ||
env, | ||
io, | ||
pm | ||
); | ||
} | ||
|
||
[Test] | ||
public void Test_Constructor() | ||
{ | ||
var cmd = CreateCommand("dn", "", Array.Empty<string>(), new CommandExecutionOptions()); | ||
|
||
cmd.HasExited.Should().BeFalse(); | ||
cmd.HasWaited.Should().BeFalse(); | ||
cmd.IsDisposed.Should().BeFalse(); | ||
cmd.IsStarted.Should().BeFalse(); | ||
} | ||
|
||
[Test] | ||
public void Test_Start() | ||
{ | ||
var distroName = "distro"; | ||
var command = "command"; | ||
var arguments = new string[] { "args" }; | ||
var options = new CommandExecutionOptions(); | ||
|
||
var io = A.Fake<IIo>(); | ||
var env = A.Fake<IEnvironment>(); | ||
var pm = A.Fake<IProcessManager>(); | ||
|
||
var p = A.Fake<IProcess>(); | ||
|
||
ProcessStartInfo actualStartInfo = new ProcessStartInfo(); | ||
A.CallTo(() => pm.Start(A<ProcessStartInfo>._)) | ||
.Invokes((psi) => actualStartInfo = psi.GetArgument<ProcessStartInfo>(0)!) | ||
.Returns(p); | ||
|
||
var cmd = new ManagedCommand( | ||
distroName, | ||
command, | ||
arguments, | ||
options, | ||
false, | ||
false, | ||
env, | ||
io, | ||
pm | ||
); | ||
|
||
var results = cmd.Start(); | ||
|
||
results.StandardOutput.Should().Be(StreamReader.Null); | ||
results.StandardError.Should().Be(StreamReader.Null); | ||
results.StandardInput.Should().Be(StreamWriter.Null); | ||
|
||
A.CallTo(() => pm.Start(A<ProcessStartInfo>._)).MustHaveHappened(); | ||
|
||
actualStartInfo.ArgumentList | ||
.Should() | ||
.BeEquivalentTo("-d", distroName, "--exec", command, arguments[0]); | ||
actualStartInfo.RedirectStandardOutput.Should().BeFalse(); | ||
actualStartInfo.RedirectStandardError.Should().BeFalse(); | ||
actualStartInfo.RedirectStandardInput.Should().BeFalse(); | ||
|
||
actualStartInfo.CreateNoWindow.Should().BeTrue(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Text; | ||
|
||
namespace Community.Wsl.Sdk.Strategies.Api | ||
{ | ||
/// <summary> | ||
/// Wrapper for a <see cref="Process"/>. | ||
/// <inheritdoc cref="Process"/> | ||
/// </summary> | ||
public interface IProcess : IDisposable | ||
{ | ||
/// <summary> | ||
/// <inheritdoc cref="Process.HasExited"/> | ||
/// </summary> | ||
public bool HasExited { get; } | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.StandardOutput"/> | ||
/// </summary> | ||
public StreamReader StandardOutput { get; } | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.StandardError"/> | ||
/// </summary> | ||
public StreamReader StandardError { get; } | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.StandardInput"/> | ||
/// </summary> | ||
public StreamWriter StandardInput { get; } | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.EnableRaisingEvents"/> | ||
/// </summary> | ||
public bool EnableRaisingEvents { get; set; } | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.Exited"/> | ||
/// </summary> | ||
public event EventHandler Exited; | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.ExitCode"/> | ||
/// </summary> | ||
public int ExitCode { get; } | ||
|
||
/// <summary> | ||
/// <inheritdoc cref="Process.WaitForExit()"/> | ||
/// </summary> | ||
public void WaitForExit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Text; | ||
|
||
namespace Community.Wsl.Sdk.Strategies.Api | ||
{ | ||
/// <summary> | ||
/// Wrapper for <see cref="Process.Start(System.Diagnostics.ProcessStartInfo)"/>. | ||
/// Returns an <see cref="Process"/> wrapped in a <see cref="IProcess"/>. | ||
/// </summary> | ||
public interface IProcessManager | ||
{ | ||
/// <summary> | ||
/// <inheritdoc cref="Process.Start(System.Diagnostics.ProcessStartInfo)"/> | ||
/// </summary> | ||
/// <param name="startInfo"><inheritdoc cref="Process.Start(System.Diagnostics.ProcessStartInfo)" path="/param[@name='startInfo']"/></param> | ||
/// <returns></returns> | ||
public abstract IProcess? Start(ProcessStartInfo startInfo); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
|
||
namespace Community.Wsl.Sdk.Strategies.Api; | ||
|
||
internal class Win32Process : IProcess | ||
{ | ||
private readonly Process _process; | ||
|
||
public Win32Process(Process process) | ||
{ | ||
_process = process; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_process.Dispose(); | ||
} | ||
|
||
public bool HasExited => _process.HasExited; | ||
|
||
public StreamReader StandardOutput => _process.StandardOutput; | ||
|
||
public StreamReader StandardError => _process.StandardError; | ||
|
||
public StreamWriter StandardInput => _process.StandardInput; | ||
|
||
public bool EnableRaisingEvents | ||
{ | ||
get => _process.EnableRaisingEvents; | ||
set => _process.EnableRaisingEvents = value; | ||
} | ||
|
||
public event EventHandler? Exited | ||
{ | ||
add => _process.Exited += value; | ||
remove => _process.Exited -= value; | ||
} | ||
|
||
public int ExitCode => _process.ExitCode; | ||
|
||
public void WaitForExit() | ||
{ | ||
_process.WaitForExit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System.Diagnostics; | ||
|
||
namespace Community.Wsl.Sdk.Strategies.Api; | ||
|
||
internal class Win32ProcessManager : IProcessManager | ||
{ | ||
public IProcess? Start(ProcessStartInfo startInfo) | ||
{ | ||
var process = Process.Start(startInfo); | ||
if (process == null) | ||
{ | ||
return null; | ||
} | ||
|
||
return new Win32Process(process); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,29 @@ | ||
namespace Community.Wsl.Sdk.Strategies.Command; | ||
using System.Threading.Tasks; | ||
|
||
namespace Community.Wsl.Sdk.Strategies.Command; | ||
|
||
internal interface IStreamReader | ||
{ | ||
/// <summary> | ||
/// Starts copying the streamed data from the stream to an internal buffer. | ||
/// This is done in a separate thread. | ||
/// </summary> | ||
void Fetch(); | ||
|
||
/// <summary> | ||
/// Copies the contents of the internal buffer to <see cref="CommandResult"/>. | ||
/// </summary> | ||
/// <param name="result"></param> | ||
/// <param name="isStdOut"></param> | ||
void CopyResultTo(ref CommandResult result, bool isStdOut); | ||
|
||
/// <summary> | ||
/// Blocks the current thread until fetching has been finished. | ||
/// </summary> | ||
void Wait(); | ||
|
||
/// <summary> | ||
/// Returns a task which completes when the fetching has been finished. | ||
/// </summary> | ||
Task WaitAsync(); | ||
} |
Oops, something went wrong.