Class: Inferno::CLI::ExecuteScript

Inherits:
Object
  • Object
show all
Defined in:
lib/inferno/apps/cli/execute_script.rb

Overview

Orchestrates multi-session Inferno test runs from a YAML configuration file.

YAML format:

sessions:                                  # Controls the creation of Inferno sessions for the execution
                                         #   a session for each indicated suite will be created and
                                         #   a successful run will have the expected results for all sessions.
- suite: my_suite                        # internal ID, title, or short title
  name: my_name                          # required (and unique) in multi-session scripts, optional
                                         #           otherwise; must not contain whitespace, '.', '{', or '}'
  preset: my-preset                      # optional; internal ID or title
  suite_options:                         # optional; option_key and option_value can be the
    option_key: option_value             #           internal values or the displayed titles


comparison_config:                         # optional; Controls the comparison of actual results during a run
                                         #    to the expected results for each created Inferno session.
                                         #    When the configured expected results file for a session does
                                         #    not exist, the run will be considered a failure and the expected
                                         #    results file will be generated using the results from the run.
                                         #    Developers are responsible for verifying that the results match
                                         #    their expectations before committing those expected results.
                                         #    When expected results are present, they must match for the run
                                         #    to be successful. When the results for a session do not match
                                         #    the expected results, an actual results JSON file and a CSV diff
                                         #    are written to the directory of the expected results file for
                                         #    use in evaluating the failure.
normalized_strings:                      # optional; global normalization rules applied to
  - "http://my-server.example.com"       # both expected and actual before comparing.
  - "http://other-value.example.com"     # plain string: replaced with <NORMALIZED>;
                                         # URL-encoded form is also replaced automatically.
  - "/code_challenge=[A-Za-z0-9+\\/=_-]{20,}/"  # regex string (wrapped in /…/): compiled
                                         # to a Regexp and replaced with <NORMALIZED>.
                                         # Supports flags: /pattern/i, /pattern/m, etc.
                                         # URL-encoded form is NOT auto-replaced for regex.
  - pattern: '/code_challenge=[A-Za-z0-9+\\/=_-]{20,}/'  # hash form: use when you need
    replacement: '<CODE_CHALLENGE>'      # a named placeholder instead of <NORMALIZED>.
  - patterns:                            # 'patterns' (plural) shares one replacement
      - '/code_challenge=[A-Za-z0-9+\\/=_-]{20,}/'  # across multiple patterns.
      - '/code_verifier=[A-Za-z0-9+\\/=_-]{20,}/'
    replacement: '<PKCE_VALUE>'

# Single-session scripts: expected file config lives directly under comparison_config.
expected_results_file: expected.json     # optional; relative to yaml file; defaults to
                                         #   <yaml basename>_expected.json
alternate_expected_files:                # optional; tried in order; first matching wins
  - file: alt_expected.json              # required; relative to yaml file
    when:                                # required; all conditions must match (AND logic)
      - field: inputs.url                # required: can be inputs.<name>, configuration_messages,
                                         #   or inferno_base_url
        matches: ^http://                # other values are top-level session detail fields.
                                         # Evaluated against GET api/test_sessions/{id}.

# Multi-session scripts: per-session config is nested under sessions.<name>.
sessions:
  my_name:                               # matches session name key (sessions[*].name or suite)
    expected_results_file: expected.json # optional; defaults to <yaml basename>_<name>_expected.json
    alternate_expected_files:            # optional; same structure as single-session above
      - file: alt_expected.json
        when:
          - field: inputs.url
            matches: ^http://

steps:                                     # Details the steps taken in the execution of the script
- status: created|done|waiting           # required; other status values cannot be matched on
  last_completed: "1.01"                 # optional; required unless the status is created
                                         #           can be a full ID, short ID (e.g. "1.01"), or 'suite'
  session: my_name                       # optional; required when multiple sessions to indicate which session
                                         #           can match this step
  action: END_SCRIPT|NOOP|WAIT           # optional; built-in action (case-insensitive)
                                         #           (mutually exclusive with command/http_get/start_run)
  # OR
  command: "bundle exec ..."             # optional; arbitrary shell command (requires
                                         #           --allow-commands CLI flag)
  # OR
  http_get: "{wait_outputs.KEY}"         # optional; http(s) URL to send a GET request to
                                         #           (e.g. to resume a waiting test); does not
                                         #           require --allow-commands. Fails the script
                                         #           only if the request cannot be made.
                                         #           The request times out after the step's
                                         #           timeout (or the default poll timeout).
  # OR
  start_run:
    session: "my_name"                   # optional; session name or template token
                                         #           (e.g. {session_id}); defaults to current session
    runnable: "1.01"                     # required; can be a short id from the UI,
                                         #           an internal long id, or 'suite'
    inputs:                              # optional; the key must be the internal name
      input_name: "value"                #           for the input
      input_name: "@path/to/file.txt"    #           prefix value with @ to read from a file;
                                         #           relative paths are resolved from the
                                         #           directory containing this script file;
                                         #           template tokens in the file are substituted
                                         #           (JSON-escaped for .json files)
      input_name:                        #           YAML mappings and sequences are
        key: value                       #           automatically JSON-serialized, useful
      input_name:                        #           for auth_info and other JSON inputs
        - item1
  timeout: 300                           # optional; seconds to wait for next match (Default is 120)
  next_poll_session: other_name          # optional; switch polling target after command
  state_description: "..."               # optional; logged when step is matched
  action_description: "..."              # optional; logged when step is matched

Built-in action values:

END_SCRIPT  — terminate script successfully
NOOP        — no-op; keep polling with (optionally updated) timeout or session
WAIT        — keep polling without breaking out of the current poll loop
            (unlike noop, does not restart the loop with a new timeout or session)

Security note:

Steps using command: execute arbitrary shell commands via the system() call. This is
intentional for use cases like browser automation (e.g. Selenium) that must interact
with Inferno's waiting state mid-test. Because of this risk, command: steps are blocked
by default and require the --allow-commands CLI flag to run. Scripts that contain no
command: steps are unaffected and do not need the flag.

Template tokens in command strings, http_get URLs, and start_run input values (including the content of @path file inputs):

{session_id}              — current session's Inferno session ID
{NAME.session_id}         — named session's ID
{result_message}          — current session's wait_result_message
{NAME.result_message}     — named session's wait_result_message
{wait_outputs.KEY}        — current session's wait output by name
{NAME.wait_outputs.KEY}   — named session's wait output by name
{inferno_base_url}        — the Inferno base URL (--inferno-base-url option, or the
                          configured base_url when not provided)

In JSON contexts (YAML mapping/sequence inputs and .json file inputs), tokens are assumed to appear inside double-quoted JSON strings, and substituted values are JSON-escaped accordingly.

Defined Under Namespace

Classes: ExecutionStatus, ScriptSession

Constant Summary collapse

SHORT_ID_PATTERN =
/\A[0-9][0-9.]*\z/
SESSION_NAME =

Session names and wait output keys may not contain braces or whitespace (and names may not contain '.') so that tokens are matched on their own within larger text such as JSON.

/[^{}.\s]+/
WAIT_OUTPUT_KEY =
/[^{}\s]+/
SESSION_NAME_FORMAT =
/\A#{SESSION_NAME}\z/
NAMED_SESSION_ID_TOKEN =
/\{(#{SESSION_NAME})\.session_id\}/
NAMED_RESULT_MESSAGE_TOKEN =
/\{(#{SESSION_NAME})\.result_message\}/
WAIT_OUTPUT_TOKEN =
/\{wait_outputs\.(#{WAIT_OUTPUT_KEY})\}/
NAMED_WAIT_OUTPUT_TOKEN =
/\{(#{SESSION_NAME})\.wait_outputs\.(#{WAIT_OUTPUT_KEY})\}/
LOG_INTERVAL_SECONDS =

Seconds subtracted from the initial last_log_time so the first active-status line is logged immediately rather than after one interval.

30

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(yaml_file, options) ⇒ ExecuteScript

Returns a new instance of ExecuteScript.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/inferno/apps/cli/execute_script.rb', line 170

def initialize(yaml_file, options)
  self.yaml_file = yaml_file
  self.options = options
  validate_yaml_file!
  validate_commands_allowed!
  validate_session_names!
  self.execution_status = ExecutionStatus.new(
    done: false,
    failed: false,
    timed_out: false,
    cancel_pending: false,
    current_session: sessions.first,
    current_timeout: options[:default_poll_timeout],
    poll_start_time: nil,
    cross_session_status: {},
    last_step_signatures: {}
  )
end

Instance Attribute Details

#execution_status ⇒ Object

Returns the value of attribute execution_status.



168
169
170
# File 'lib/inferno/apps/cli/execute_script.rb', line 168

def execution_status
  @execution_status
end

#options ⇒ Object

Returns the value of attribute options.



168
169
170
# File 'lib/inferno/apps/cli/execute_script.rb', line 168

def options
  @options
end

#yaml_file ⇒ Object

Returns the value of attribute yaml_file.



168
169
170
# File 'lib/inferno/apps/cli/execute_script.rb', line 168

def yaml_file
  @yaml_file
end

Instance Method Details

#run ⇒ Object



189
190
191
# File 'lib/inferno/apps/cli/execute_script.rb', line 189

def run
  exit(orchestrate)
end