swittest core
switest core
is the brain or orchestrator of swittest
. Once fed with the necessary information to perform a selected test (e.g. configuration, transaction data and expectation), its role consists in the following tasks:
- Prepare and inject the configuration into
switcloud
. - Prepare and send the payment request data to the system under test.
- Fetch the payment data once the transaction is complete.
- Compare the payment data against the test expectations.
- Provide a test verdict, payment data and potential error details to the calling app.
- Clear the test configuration from
switcloud
.
Installation
Note
swittest-core
is currently only availble as a Python package
To install swittest-core
on your machine, checkout the corresponding GitHub repos or download the pre-built binaries.
Note
swittest-core
is a library and cannot be used as is.
Communication
The communication between swittest core
and switcloud leverages the switcloud-api-py
packages.
The communication between swittest core
and the system under test uses the Nexo Retailer protocol.
Info
While we want to promote Nexo protocols as much as possible, we decided to use a JSON representation of the XML-based specification.
Messages
Note
The below documentation contains only a limited number of examples and therefore may not apply to all cases. For more details and options please refer to the Nexo standard directly.
The communication between swittest core
and the system udertest relies on TCP/IP connection. It is therefore important to protect this communication against insterruptions, latency and any inconveniency that could occur during data transmission in one direction or the other. To do so, and to not over-complicate things for now, we use a very simple protocol consisting in a 64 bits magic number and a 32 bits payload length indicator.
A typical message would then look like:
Info
The magic number we use is 7377697474657374
(hex)
System configuration
To configure the system under test (e.g. pass on the switcloud
service URL and port, the credentials to use for authentication, etc...), we use an Administrative Services Session Management Login request such as below:
{
"SaleToPOISsnMgmtReq": {
"Hdr": {
"MsgFctn": "SASQ",
"PrtcolVrsn": "5.0",
"XchgId": "613",
"CreDtTm": "2020-05-04T18:13:51+01:00",
"InitgPty": {
"Id": "POS",
}
},
"SsnMgmtReq": {
"Envt": null,
"Cntxt": null,
"SvcCntt": "SMIQ",
"LgnReq": {
"LgnDtTm": "2020-05-04T18:13:51+01:00",
"SaleSftwr": {
"Tp": "MRPR",
"Id": null
}
},
"SplmtryData": [
{
"Envlp": {
"SwitcloudURL": "https://switcloud.switstack.io:8000",
"ClientId": "my_client_id",
"ClientSecret": "my_client_secret"
}
}
]
}
}
}
In case of success, the expected response is an administrative response, such as below:
{
"SaleToPOISsnMgmtRspn": {
"Hdr": {
"MsgFctn": "SASP",
"PrtcolVrsn": "5.0",
"XchgId": "613",
"CreDtTm": "2020-05-04T18:13:51+01:00",
"InitgPty": {
"Id": "POI"
}
},
"SsnMgmtRspn": {
"Envt": null,
"Cntxt": null,
"SvcCntt": "SMIP",
"LgnRspn": {
"POIDtTm": "2020-05-04T18:13:51+01:00",
"POISftwr": {
"Tp": "APLI",
"Id": {
"PrvdrId": "Swittest L3"
}
}
},
"Rspn": {
"Rspn": "SUCC"
}
}
}
}
Payment
To trigger a payment, we use a financial request such as below:
{
"SaleToPOISvcReq": {
"Hdr": {
"MsgFctn": "SFSQ",
"PrtcolVrsn": "5.0",
"XchgId": "1a2f17cd",
"CreDtTm": "2024-11-15T15:12:59.914421Z",
"InitgPty": {
"Id": "POS",
}
},
"SvcReq": {
"Envt": null,
"Cntxt": null,
"SvcCntt": "FSPQ",
"SplmtryData": [
{
"Envlp": {
"PaymentId": "3f9ccd8a-43a5-4ecc-97cb-77ae07058f6c",
"VCardData": "...",
}
}
]
}
}
}
In case of success, the expected payment response would be a financial response such as below:
{
"SaleToPOISvcRspn": {
"Hdr": {
"MsgFctn": "SFSP",
"PrtcolVrsn": "5.0",
"XchgId": "1a2f17cd",
"CreDtTm": "2024-11-15T15:12:59.914421Z",
"InitgPty": {
"Id": "POI",
}
},
"SvcRspn": {
"Envt": null,
"Cntxt": null,
"SvcCntt": "FSPP",
"Rspn": {
"Rspn": "SUCC"
}
}
}
}
Error message
Two types of errors are possible here: a message format error and a processing error.
In case of a format error, the swittest
should be sent a Message Rejection error, such as below:
{
"SaleToPOIMessageRejection": {
"Hdr": {
"MsgFctn": "SSRJ",
"PrtcolVrsn": "5.0",
"XchgId": "1a2f17cd",
"CreDtTm": "2024-11-15T15:12:59.914421Z",
"InitgPty": {
"Id": "POI",
},
},
"Rjct": {
"RjctRsn": "PARS"
}
}
}
Note
The RjctRsn
field can take the following values:
- INTP: InitiatingParty: Invalid identification data for the sender InitiatingParty.
- IMSG: InvalidMessage: Invalid envelope message.
- MSGT: MessageType: Type of message the recipient receives is unknow or unsupported
- PARS: ParsingError: Invalid message: At least one of the data element or data structure present, the format, or the content of one data element or one data structure is not corre
- VERS: ProtocolVersion: Version of the protocol couldn't be supported by the recipient.
- RCPP: RecipientParty: Invalid identification data for the receiver RecipientParty.
- SECU: Security: Security error (for example an invalid key or an incorrect MAC value).
- UNPR: UnableToProcess: Not possible to process the message, for instance the security is unavailable, the hardware is unavailable, or there is a problem of resource.
In case of a processing error swittest
should receive a normal message response (as if it was successful) with the Rspn.Rspn
field set to FAIL
.