Skip to content

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.

git clone git@github.com:switstack/swittest-core-py.git

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 coreand 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:

[MAGIC NUMBER][LENGTH][PAYLOAD]
    64 bit     32 bit    var

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.