Skip to main content

Implementing Lifecycle Endpoints

In addition to step endpoints, a step plugin must provide a standard set of lifecycle endpoints. The Cycle engine will call these endpoints at predetermined lifecycle phases during test execution. Lifecycle endpoints are required: Cycle will not be able to run the step plugin correctly without them.

Step plugin lifecycle

Cycle will run one local instance of each step plugin for the duration of one test suite launch. The Cycle engine runs through the following lifecycle phases for each step plugin instance. In certain phases, the Cycle engine calls lifecycle endpoints as documented below.

OrderPhaseDescription
1startupWhen Cycle starts running a test suite, it starts one local instance of the step plugin service using the plugin's "start" command.
2statusThe Cycle engine calls the GET /status endpoint to verify that the step plugin is ready. It times out with an error if status is not positive after 60 seconds.
3scenario-startWhen a test scenario starts, the Cycle engine calls the POST /scenario-start endpoint. It may pass in any Cycle variables or properties as inputs, and it may receive any Cycle variables as outputs.
4testingThe Cycle engine runs scenarios and calls step endpoints when those steps appear in the scenarios.
5scenario-endWhen a test scenario ends, the Cycle engine calls the POST /scenario-end endpoint. It may pass in any Cycle variables or properties as inputs, and it may receive any Cycle variables as outputs.
6shutdownWhen all testing is complete, the Cycle engine calls the POST /shutdown endpoint to safely shut down the step plugin and clean up any of its resources.

Lifecycle endpoints

A step plugin requires the following endpoints to be part of its API and the OpenAPI spec file:

  • GET /status
    • for health checks
    • returns HTTP 200 OK for success
    • may optionally return a body with helpful info like start time and uptime
  • POST /scenario-start
    • to start a new test case
    • returns HTTP 200 OK for success
    • may set up shared state or sessions for the steps
    • may optionally take Cycle variable and property inputs via request body
    • may optionally return a body with Cycle variables
  • POST /scenario-end
    • to end a test case
    • returns HTTP 200 OK for success
    • may clean up shared state or sessions for the steps
    • may optionally take Cycle variable and property inputs via request body
    • may optionally return a body with Cycle variables
  • POST /shutdown
    • to cleanly shut down the step plugin
    • return HTTP 202 Accepted for success
    • may optionally return a body with helpful info

These endpoints should be grouped together with a common OpenAPI tag (like Lifecycle).

Status example

The GET /status endpoint simply needs to provide proof-of-life for the step plugin service. Its OpenAPI path definition could look like this:

  /status:
get:
tags: [Lifecycle]
operationId: status
description: Gets the status of the service.
responses:
'200':
description: |
Reports the service uptime status.
Uptime is reported in seconds.

The response body could also have content for information like start time and uptime. This is optional.

Scenario start/end example

A step plugin may need to set up resources before a scenario and/or clean up resources after a scenario. For example, a step plugin that uses a database connection may want to establish a new session in the scenario-start phase and close the session in the scenario-end phase.

The best way to share the database session is to use a Cycle variable. It could be named DB_SESSION. The step plugin's POST /scenario-start endpoint could internally create the database session, store the session object in a map-like data structure with a universally-unique identifier (UUID) for a key, and return the key value for the session as the DB_SESSION Cycle variable. The OpenAPI path definition would look like this:

  /scenario-start:
post:
tags: [Lifecycle]
operationId: scenarioStart
description: Start a scenario with a new database session.
responses:
'200':
description: The scenario has started.
content:
application/json:
schema:
type: object
properties:
variables:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
required:
- variables
'400':
description: Failure to start the scenario.
content:
application/json:
schema:
type: object
properties:
error:
type: string

The response body would contain the DB_SESSION variable like this:

{
"variables":
[
{
"name": "DB_SESSION",
"value": "d2c7958a-ef78-45f5-9325-e7f42367d4d6",
}
]
}

Steps could take in the DB_SESSION variable as an input to use the session. Likewise, the POST /scenario-end endpoint could accept it as an input and close the session with the following OpenAPI spec:

  /scenario-end:
post:
tags: [Lifecycle]
operationId: scenarioEnd
description: End a scenario and close the database session.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
DB_SESSION:
type: string
format: uuid
responses:
'200':
description: Scenario ended successfully.
content:
application/json:
schema:
type: object
properties:
message:
type: string
'400':
description: Failure to end the scenario.
content:
application/json:
schema:
type: object
properties:
error:
type: string

Shutdown example

The POST /shutdown endpoint is the final call made to the step plugin. It should perform shutdown operations, including any forced cleanup of resources and ultimately terminating the plugin service's process. The OpenAPI spec could look like this:

  /shutdown:
post:
tags: [Lifecycle]
operationId: shutdown
description: |
Safely shut down the step plugin service.
responses:
'202':
description: The step plugin has been shut down.