Service - Integration Testing: Difference between revisions
No edit summary |
No edit summary |
||
Line 70: | Line 70: | ||
# Invoke [[Service - Integration Test Config:getEventConfig]] to pull inputEventTag config | # Invoke [[Service - Integration Test Config:getEventConfig]] to pull inputEventTag config | ||
# for each <syntaxhighlight lang="JSON" inline>properties</syntaxhighlight> in event config test if value matches | # for each <syntaxhighlight lang="JSON" inline>properties</syntaxhighlight> in event config test if value matches | ||
# prepare TestRecord.stages.results.inputStage values | |||
# check if any tests for this stage remain | |||
## if the stage has <syntaxhighlight lang="JSON" inline>outputEventTag</syntaxhighlight> set, has TestRecord.stages.results.outputStage been set? | |||
## if the stage has <syntaxhighlight lang="JSON" inline>invokes</syntaxhighlight> set, check TestRecord.stages.results.outputStage been set? | |||
# update TestRecord.stages.status to either passed or failed | # update TestRecord.stages.status to either passed or failed | ||
= TestRecord.stages structure = | = TestRecord.stages structure = | ||
Line 82: | Line 85: | ||
status: waiting|passed|failed, | status: waiting|passed|failed, | ||
results: { | results: { | ||
// | inputStage: { | ||
//results at the point of entering the resource (eg a Lambda function is invoked) | |||
timestamp: {when beginStage results were saved}, | |||
requestProperties: {a copy of the requestProperties} | |||
}, | |||
outputStage: { | |||
//results at the point of entering the resource (eg a Lambda function is invoked) | |||
timestamp: {when beginStage results were saved}, | |||
returnValue: {a copy of the value returned by the resource} | |||
//.. maybe other settings for errors etc.. | |||
}, | |||
invokes: { | |||
{serviceName_resourceType_resourceName_inputEventTag_outputEventTag}: { | |||
//results at the point of invoking an external resource (eg the tested Lambda function is invoking another Lambda function) | |||
timestamp: {when beginStage results were saved}, | |||
requestProperties: {a copy of the requestProperties} | |||
}, | |||
.. | |||
} | |||
} | } | ||
Revision as of 08:45, 3 September 2020
Overview
Service that pulls integration tests from the Integration Test Config service, invokes each test and monitors the steps execute as expected.
This service is intended to be run in a deployed AWS environment, all services and resources required for the integration tests need to be operational.
DynamoDB tables
TestRecord
Fields
- integrationTestTag
- (partition key)
- testStartedTimestamp
- (sort key)
- time that the integration test was started/created.
- stages
- an object that holds the details and status of each stage #TestRecord.stages structure
- testStatus
- current status of the integration test, either processing, passed, or failed
Lambda Functions
initiateIntegrationTest
/**
* Starts integration test/s
* @param {string} [integrationTestTag] - Only initiate test with matching integrationTestTag
* @param {string} [serviceName] - Only initiate tests where initialStage serviceName matches
* @param {string} [resourceType] - Only initiate tests where initialStage resourceType matches
* @param {string} [resourceName] - Only initiate tests where initialStage resourceName matches
*
* @returns {boolean} true if the test was initiated successfully, false if the test could not be initiated (? or an error thrown ?)
*/
module.exports.handler = middleware.wrap(async (event, context, callback) => {
logic
- Invoke Service - Integration Test Config:getIntegrationTests to get configurations of all matching tests
- for each integration test:
- save a record into TestRecord table
- store in a variable the config for the initialStage
- we do not want to invoke the initial request until all stages are saved into TestRecord table (to avoid race conditions)
- for the initialStage:
- build initial event to start the test using the initialStage's input event
- add intTest-xx correlation ids
- invoke the initialStage's Lambda function
receiveMsgLambdaBegin
/**
* Triggered when a Lambda function is invoked from an integration test request
* Checks if any stages in integration test config match Lambda invocation, if yes perform tests and record results
* @param {object} requestProperties - The event body for the invoked Lambda
* @param {string} serviceName - Name of the service that owns the Lambda function, matches stage's serviceName
* @param {string} functionName - Name of the invoked Lambda function, matches stage's resourceName
*/
module.exports.handler = middleware.wrap(async (event, context, callback) => {
logic
- use intTest-tag and intTest-time correlation ids in received message to query TestRecord table for test record
- iterate stages to find match
- if no match found can return
- Invoke Service - Integration Test Config:getEventConfig to pull inputEventTag config
- for each
properties
in event config test if value matches - prepare TestRecord.stages.results.inputStage values
- check if any tests for this stage remain
- if the stage has
outputEventTag
set, has TestRecord.stages.results.outputStage been set? - if the stage has
invokes
set, check TestRecord.stages.results.outputStage been set?
- if the stage has
- update TestRecord.stages.status to either passed or failed
TestRecord.stages structure
{
config: {
//straight copy of this stage from integration test config
},
status: waiting|passed|failed,
results: {
inputStage: {
//results at the point of entering the resource (eg a Lambda function is invoked)
timestamp: {when beginStage results were saved},
requestProperties: {a copy of the requestProperties}
},
outputStage: {
//results at the point of entering the resource (eg a Lambda function is invoked)
timestamp: {when beginStage results were saved},
returnValue: {a copy of the value returned by the resource}
//.. maybe other settings for errors etc..
},
invokes: {
{serviceName_resourceType_resourceName_inputEventTag_outputEventTag}: {
//results at the point of invoking an external resource (eg the tested Lambda function is invoking another Lambda function)
timestamp: {when beginStage results were saved},
requestProperties: {a copy of the requestProperties}
},
..
}
}
}
Initiating tests
When the initial request is sent to begin an integration test the middleware LOG_LEVEL is set to DEBUG, this causes all Lambda functions and requests to external services to also add a message to the services MsgOut queue.
The Integration Testing service subscribes to these queues and uses these messages to monitor each stage of the workflow to ensure input and output is as expected, and that the integration test completes fully.
Add the following Correlation Ids to the initial request so we can track the integration test, filter messages, etc.:
- intTest-tag
- matches the test's integrationTestTag
- intTest-time
- matches the test's testStartedTimestamp
These can also be used in production environment to exclude requests that middleware randomly set to debug from requests initiated by Integration Test service.