Class ProgramRunner
Used to implement unit tests on command line tools by simulating their execution on a thread rather than forking the tool as a process. This is makes debugging easier and also deals with the fact that unit tests may leave orphan processes running.
Namespace: Neon.Common
Assembly: Neon.Common.dll
Syntax
public sealed class ProgramRunner
Remarks
This class is designed to simulate running a single executable by calling its main entry point. To accomplish this, use the default constructor to create a ProgramRunner instance. The constructor will set Current to itself and then you can call Execute(ProgramEntrypoint, params string[]) to execute the program synchronously (waiting for it to return), or Fork(ProgramEntrypoint, params string[]) to simulate forking the program by running it on a new thread.
Fork(ProgramEntrypoint, params string[]) waits to return until the program calls ProgramReady(). This is used to ensure that program has completed the activities required by the unit tests before the tests are executed.
note
Only one ProgramRunner instance can active at any particular time.
Simulated program entry points that will be called by Fork(ProgramEntrypoint, params string[])
and that run indefinitely, need to call WaitForExit() when
after its started the operation. This returns when the TerminateFork()
is called. The simulated program should stop any operations being
performed, release any important resources and exit cleanly its Main
method cleanly.
The Arguments dictionary can be used to pass additional
arguments into the program being tested. This maps case insensitve keys
to object
values.
note
You should call Dispose() when you're finished with the runner.
Constructors
ProgramRunner(TimeSpan)
Constructor.
Declaration
public ProgramRunner(TimeSpan forkTimeout = default)
Parameters
Type | Name | Description |
---|---|---|
TimeSpan | forkTimeout | Specifies the maximum time for Fork(ProgramEntrypoint, params string[]) to wait for the program to signal that it's ready by calling ProgramReady(). This defaults to 30 seconds. |
Properties
Arguments
Returns a case insensitve dictionary of additional unit test related arguments that can be passed to the program being tested.
Declaration
public Dictionary<string, object> Arguments { get; }
Property Value
Type | Description |
---|---|
Dictionary<string, object> |
Current
Returns the current ProgramRunner or null
.
Declaration
public static ProgramRunner Current { get; }
Property Value
Type | Description |
---|---|
ProgramRunner |
Methods
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Declaration
public void Dispose()
Execute(ProgramEntrypoint, params string[])
Executes a program entry point synchronously, passing arguments and returning the result.
Declaration
public ExecuteResponse Execute(ProgramEntrypoint main, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypoint | main | The program entry point. |
string[] | args | The arguments. |
Returns
Type | Description |
---|---|
ExecuteResponse | The ExecuteResponse returned by the simulated program run. |
ExecuteAsync(ProgramEntrypointAsync, params string[])
Executes a program entry point asynchronously, passing arguments and returning the result.
Declaration
public Task<ExecuteResponse> ExecuteAsync(ProgramEntrypointAsync mainAsync, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypointAsync | mainAsync | The program entry point. |
string[] | args | The arguments. |
Returns
Type | Description |
---|---|
Task<ExecuteResponse> | The ExecuteResponse returned by the simulated program run. |
ExecuteWithInput(ProgramEntrypoint, byte[], params string[])
Executes a program entry point synchronously, streaming some bytes as standard input, passing arguments and returning the result.
Declaration
public ExecuteResponse ExecuteWithInput(ProgramEntrypoint main, byte[] inputBytes, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypoint | main | The program entry point. |
byte[] | inputBytes | The bytes to be passed as standard input. |
string[] | args | The arguments. |
Returns
Type | Description |
---|---|
ExecuteResponse | The ExecuteResponse returned by the simulated program run. |
ExecuteWithInput(ProgramEntrypoint, string, params string[])
Executes a program entry point synchronously, streaming some text as standard input, passing arguments and returning the result.
Declaration
public ExecuteResponse ExecuteWithInput(ProgramEntrypoint main, string inputText, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypoint | main | The program entry point. |
string | inputText | The text to be passed as standard input. |
string[] | args | The arguments. |
Returns
Type | Description |
---|---|
ExecuteResponse | The ExecuteResponse returned by the simulated program run. |
ExecuteWithInputAsync(ProgramEntrypointAsync, byte[], params string[])
Executes a program entry point asynchronously, streaming some bytes as standard input, passing arguments and returning the result.
Declaration
public Task<ExecuteResponse> ExecuteWithInputAsync(ProgramEntrypointAsync mainAsync, byte[] inputBytes, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypointAsync | mainAsync | The program entry point. |
byte[] | inputBytes | The bytes to be passed as standard input. |
string[] | args | The arguments. |
Returns
Type | Description |
---|---|
Task<ExecuteResponse> | The ExecuteResponse returned by the simulated program run. |
ExecuteWithInputAsync(ProgramEntrypointAsync, string, params string[])
Executes a program entry point asynchronously, streaming some text as standard input, passing arguments and returning the result.
Declaration
public Task<ExecuteResponse> ExecuteWithInputAsync(ProgramEntrypointAsync mainAsync, string inputText, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypointAsync | mainAsync | The program entry point. |
string | inputText | The text to be passed as standard input. |
string[] | args | The arguments. |
Returns
Type | Description |
---|---|
Task<ExecuteResponse> | The ExecuteResponse returned by the simulated program run. |
Fork(ProgramEntrypoint, params string[])
Executes a program entry point asynchronously, without waiting for the command to complete. This is useful for commands that don't terminate by themselves. Call TerminateFork() to kill the running command.
note
IMPORTANT: The main
simulated entry point must call
WaitForExit(). This will block until the TerminateFork()
is called, returning when the program is expected to terminate itself.
Declaration
public void Fork(ProgramEntrypoint main, params string[] args)
Parameters
Type | Name | Description |
---|---|---|
ProgramEntrypoint | main | The program entry point. |
string[] | args | The arguments. |
OpenStandardInput()
Opens the standard input stream. This will return a stream with the input specified when ExecuteWithInput(ProgramEntrypoint, byte[], params string[]) or ExecuteWithInput(ProgramEntrypoint, string, params string[]) were called or else it will simply return the result of OpenStandardInput().
Declaration
public Stream OpenStandardInput()
Returns
Type | Description |
---|---|
Stream | The input Stream. |
ProgramReady()
Called by programs executed via Fork(ProgramEntrypoint, params string[]) when the program has initialized itself enough to be ready for testing.
note
This must be called or else Fork(ProgramEntrypoint, params string[]) will never return.
Declaration
public void ProgramReady()
TerminateFork()
Terminates the forked program if one is running.
Declaration
public void TerminateFork()
WaitForExit()
Called by the emulated program entry point for operations that are initiated via Fork(ProgramEntrypoint, params string[]). This method will block until TerminateFork() is called. The emulated program must exit cleanly when this returns.
Declaration
public void WaitForExit()