Skip to content
Tracon

SkillScriptExecutorContract

Namespace Tracon.Testing.Contracts.Scripts · Assembly Tracon.Testing.Contracts.Xunit.dll

Behavior tests for an ISkillScriptExecutor: what a script receives, what the executor reports back, and how it stops.

public abstract class SkillScriptExecutorContract : IAsyncLifetime, IAsyncDisposable
Inheritance
object ← SkillScriptExecutorContract
Implements
IAsyncLifetime, IAsyncDisposable
Inherited Members
object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

Derive one class per executor and return it from SkillScriptExecutorContract.CreateExecutorAsync. Every scenario sends a SkillScriptOrigin.Stored request whose content is a POSIX sh script, so a remote executor needs no file on the test machine. An executor for another runtime overrides SkillScriptExecutorContract.Extension, SkillScriptExecutorContract.Interpreter, and the script bodies (the virtual members that end in Script); each body’s summary says what it must print.

The scenarios do not check isolation. Whether a script can read the host’s files, network, or process memory depends on where the executor runs it, and a contract run on the test machine cannot measure that.

protected SkillScriptExecutorContract()

The skill name every request carries.

protected const string ContractSkillName = "contract-skill"

string

The exit code SkillScriptExecutorContract.FailingScript ends with.

protected const int ExpectedExitCode = 3

int

The text SkillScriptExecutorContract.FailingScript writes to standard error.

protected const string ExpectedStandardError = "contract-standard-error"

string

The script with no content at all.

protected virtual string EmptyScript { get; }

string

The executor under test.

protected ISkillScriptExecutor Executor { get; }

ISkillScriptExecutor

The extension every request carries. Defaults to sh.

protected virtual string Extension { get; }

string

Writes SkillScriptExecutorContract.ExpectedStandardError to standard error and exits with SkillScriptExecutorContract.ExpectedExitCode.

protected virtual string FailingScript { get; }

string

Writes the line 0123456789 four hundred times to standard output (4,400 bytes with line feeds).

protected virtual string FloodScript { get; }

string

The interpreter-allow-list value every request carries. Defaults to /bin/sh; a remote executor may expect a runtime name.

protected virtual string Interpreter { get; }

string

Copies standard input to standard output unchanged.

protected virtual string ReadStandardInputScript { get; }

string

A reason to skip every scenario, or null to run them. The built-in executor returns one when the machine has no /bin/sh.

protected virtual string? SkipReason { get; }

string?

Runs for at least sixty seconds unless it is stopped.

protected virtual string SleepScript { get; }

string

The longest time a stopped script may take to return in the timeout and cancellation scenarios. It is far below SkillScriptExecutorContract.SleepScript’s sixty seconds, so an executor that waits for the script to finish fails.

protected virtual TimeSpan StopTolerance { get; }

TimeSpan

A_call_without_arguments_reads_an_empty_standard_input()

Section titled “ A_call_without_arguments_reads_an_empty_standard_input()”
[Fact]
public Task A_call_without_arguments_reads_an_empty_standard_input()

Task

A_cancelled_call_throws_OperationCanceledException_and_is_not_a_timeout()

Section titled “ A_cancelled_call_throws_OperationCanceledException_and_is_not_a_timeout()”
[Fact]
public Task A_cancelled_call_throws_OperationCanceledException_and_is_not_a_timeout()

Task

A_script_past_its_timeout_is_stopped_and_reported_as_timed_out()

Section titled “ A_script_past_its_timeout_is_stopped_and_reported_as_timed_out()”
[Fact]
public Task A_script_past_its_timeout_is_stopped_and_reported_as_timed_out()

Task

A_stored_request_runs_its_content_and_never_a_path()

Section titled “ A_stored_request_runs_its_content_and_never_a_path()”
[Fact]
public Task A_stored_request_runs_its_content_and_never_a_path()

Task

[Fact]
public Task An_empty_script_runs_and_exits_cleanly()

Task

Arguments_arrive_on_standard_input_as_json()

Section titled “ Arguments_arrive_on_standard_input_as_json()”
[Fact]
public Task Arguments_arrive_on_standard_input_as_json()

Task

Concurrent_calls_do_not_share_a_temp_directory()

Section titled “ Concurrent_calls_do_not_share_a_temp_directory()”
[Fact]
public Task Concurrent_calls_do_not_share_a_temp_directory()

Task

Creates the executor under test.

protected abstract ValueTask<ISkillScriptExecutor> CreateExecutorAsync()

ValueTask<ISkillScriptExecutor>

The executor; the same instance serves every call of one test.

CreateRequest(string, string, string?, TimeSpan?, int)

Section titled “ CreateRequest(string, string, string?, TimeSpan?, int)”

Builds a request for one scenario.

protected virtual SkillScriptExecutionRequest CreateRequest(string scriptName, string content, string? argumentsJson = null, TimeSpan? timeout = null, int maxOutputBytes = 65536)

scriptName string

The script name, a plain file name.

content string

The script body.

argumentsJson string?

The JSON for standard input, or null.

timeout TimeSpan?

The script timeout; thirty seconds when null.

maxOutputBytes int

The byte limit for each output stream.

SkillScriptExecutionRequest

A SkillScriptOrigin.Stored request with its content hash computed.

public ValueTask DisposeAsync()

ValueTask

Prints text and a line break.

protected virtual string EchoScript(string text)

text string

A word of ASCII letters and hyphens.

string

The script body.

Prints [<TRACON_SKILL_NAME>][<present when TRACON_SKILL_TEMP is set>][<value of hostVariable>].

protected virtual string EnvironmentScript(string hostVariable)

hostVariable string

The name of a variable set in the test process.

string

The script body.

Called immediately after the class has been created, before it is used.

public ValueTask InitializeAsync()

ValueTask

Output_past_the_limit_is_cut_and_flagged_without_a_notice()

Section titled “ Output_past_the_limit_is_cut_and_flagged_without_a_notice()”
[Fact]
public Task Output_past_the_limit_is_cut_and_flagged_without_a_notice()

Task

Writes a file named marker into TRACON_SKILL_TEMP, waits a second so that a concurrent call can do the same, and then lists the directory’s file names, one per line.

protected virtual string TempMarkerScript(string marker)

marker string

A word of ASCII letters.

string

The script body.

The_exit_code_and_standard_error_are_reported()

Section titled “ The_exit_code_and_standard_error_are_reported()”
[Fact]
public Task The_exit_code_and_standard_error_are_reported()

Task

The_script_sees_its_two_variables_and_not_the_host_environment()

Section titled “ The_script_sees_its_two_variables_and_not_the_host_environment()”
[Fact]
public Task The_script_sees_its_two_variables_and_not_the_host_environment()

Task