Skip to content

swittest data model

swittest is a a full EMV functional test automation system which relies on a proprietary data model. swittest uses JSON format for its test and configuration files.

Test suites

A test suite is a document that regroups a certain number of tests together usually under a common criteria, such as:

  • Certification level (EMV Level 2 / EMV Level 3)
  • Scheme (Visa, Mastercard, Amex, ...)
  • Specification version
  • Test environment version

Format

{
    "name": "MCL v3.1.4 TAL2-Testing Env Dec2021",
    "version": "0.2.0",
    "date": "2024-10-05",

    "environment": {
        ...
    },

    "tests": [
        ...
    ]
}

With:

  • name: The name of the test suite. It should more or less contain the same details as the env section.
  • version: The version of the file.
  • date: The date when the file was generated.
  • environment: The test suite details (see Environment).
  • tests: The list of tests to execute (see Test).

Environment

The environment section contains information about the test suite usage. The content of the section is described below:

{
    ...
    "environment": {
        "tool": "eval+",
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },
    ...
}

With:

  • tool: The test tool this test suite is associated with.
  • type: The type of testing this test suite covers (for ex "TA L2" or "TA L3").
  • scheme: The payment scheme (for ex "Mastercard" or "Visa").
  • spec_version: The corresponding specification version.
  • test_plan_version: The test plan version.
  • test_env: The test environment version.

Test

The tests section contains a list of tests to be run as part of the test suite identified by their file name. The content is described below:

{
    ...
    "tests": [
        "3B02-0001_first-trx-5-mutualappls",
        "3B02-0002_first-trx-4-mutualappls",
        ...
    ],
    ...
}

Test files are is JSON format. No need to specify the file extension in the tests list.

Note

The tool will look for the test files under a strict hierarchy of folders defined as follows: <project_root>/${type}/${scheme}/${spec_version}/${test_plan_version}/${test_env}/tests, with each of the ${xxx}parameters belonging to the environment section.

Test suite data organization

The test suite data follow a very scrict orgnization:

  • The test suite(s) must be at the root of the directory.
  • The test suite environment description is an exact representation of the folder structure: <project_root>/${type}/${scheme}/${spec_version}/${test_plan_version}/${test_env}
  • At the end of the environment folder structure should be the capks, crs, emvs and tests directories, holding the corresponding data.

Below an example of what it could look like:

.
├── eval+
   └── L2
       └── Mastercard
           └── v3.1.4
               └── v1.0.1
                   └── Dec 2021
                       ├── capks
                          └── CAPK_MCL_1.json
                       ├── crs
                          └── CR_MCL_1.json
                       ├── emvs
                          └── PPS_MChip_1.json
                       └── tests
                           ├── 3B02-0001_first-trx-5-mutualappls.json
                           └── 3B02-0002_first-trx-4-mutualappls.json
└── L2-Mastercard-v3.1.4-v1.0.1-dec_2021.json

Full example

Below is a full example of what a test suite file could look like:

{
    "name": "MCL v3.1.4 TAL2-Testing Env Dec2021",
    "version": "0.2.0",
    "date": "2024-10-05",

    "environment": {
        "tool": "eval+",
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },

    "tests": [
        "3B02-0001_first-trx-5-mutualappls",
        "3B02-0002_first-trx-4-mutualappls",
    ]
}

Test

A test file is a document that describes the inputs and expected outputs of a perticular transaction (or group of transactions).

Format

{
    "name": "3B02-0001_first-trx-5-mutualappls",
    "version": "0.2.0",
    "date": "2024-10-05",

    "environment": {
        ...
    },

    "description": "...",

    "card": "my-test-card",

    "poi_config": {
       ...
    },

    "payments": [
        ...
    ]
}

With:

  • name: The name of the test suite. It should more or less contain the same details as the env section.
  • version: The version of the file.
  • date: The date when the file was generated.
  • environment: The test suite details (see Environment).
  • description: Optional information about the test (conditions, goal, etc...).
  • card: The virtual card to be used.
  • poi_config: The EMV configuration to be used for the test (see POIConfig).
  • payments: The payment(s) to trigger and their expected results (see Payment).

Environment

The environment section contains information about the test suite usage. The content of the section is described below:

{
    ...
    "environment": {
        "tool": "eval+",
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },
    ...
}

With:

  • tool: The test tool this test suite is associated with.
  • type: The type of testing this test suite covers (for ex "TA L2" or "TA L3").
  • scheme: The payment scheme (for ex "Mastercard" or "Visa").
  • spec_version: The corresponding specification version.
  • test_plan_version: The test plan version.
  • test_env: The test environment version.

POIConfig

The poi_config section gathers the different pieces of configuration to be used for the test. These pieces are references to other files only. The content of the section is described below:

{
    ...
    "poi_config": {
        "name": "POI_Config_1",
        "emv_config": "PPS_MChip_1",
        "capk_list": "CAPK_MCL_1",
        "cr_list": "CR_MCL_1",
    },
    ...
}

With:

  • name: The name of the POI Config.
  • emv_config: The complete EMV config file (e.g. supported combinations or AIDs).
  • capk_list: Set of CAPKs to be allowed for the test (optional).
  • cr_list: Set of revoked certificates to be used for the test (optional).

Payment

A test can hold one or several consecutive payments (e.g. transactions) with expected results (e.g. information to check) for each of them. The payments are gathered into a payments list. Each payment should then be described as below:

{
    ...
    "payments": [
        {
            "randoms": ["AABBCCDD", "BBCCDDEE"],
            "trd": {
                "9C": "00",
                "9F02": "000000001500",
                "5F2A": "0978",
                "5F36": "02",
                "9A": "241015",
                "9F21": "000000",
                "9F53": "46",
                "9F7C": "1122334455667788990011223344556677889900"
            },
            "authorization_response": "",
            "expectations": {
                ...
            }
        },
        ...
    ]
}

With:

  • randoms: A list of randoms to use for the transaction(s) (optional).
  • trd: A list of tags corresponding to the Transaction Related Data. Only the following tags are supported: 9C, 9F02, 5F2A, 5F36, 9A, 9F21, 9F53, 9F7C (mandatory).
  • authorization_response: Authorization response to provide when the cards requires an authorization (optional).
  • expectations: A list of objects, tags, etc... to be verified for each payment (see Expectations).

Expectations

Expectations are a set of payment related data that must be checked in order for a test to be considered 'pass' or 'fail'. The content of the section is described below:

{
    ...
    "payments": [
        {
            ...
            "expectations": {
                "restart": {
                    "error_indication": "0003006A85FF",
                    "outcome_parameter_set": "5020F0F018F0FF00"
                },
                "authorization": {
                    "user_interface_request_data": "1B00000000656E646566720000",
                    "data_record":  {
                        "tags": {
                            "9F39": "07",
                            "9F02": "000000001500",
                            "9F26": "AC123456789ABCDE",
                            "5F24": "491231",
                            "82": "020080",
                            "50": "4D617374657243617264",
                            "5A": "5413339000001513",
                            "9F36": "0002",
                            "9F09": "0002",
                            "9F27": "80",
                            "9F34": "3F0000",
                            "84": "A0000000041010",
                            "9F1E": "3132333435363738",
                            "9F10": "0110000000020000DAC00000000000000000",
                            "9F11": "01",
                            "9F33": "006000",
                            "9F1A": "0056",
                            "9F35": "22",
                            "95": "8000000001",
                            "9F53": "46",
                            "9F15": "0130",
                            "5F2A": "0978",
                            "9A": "241015",
                            "9C": "00",
                            "9F37": "AABBCCDD"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "discretionary_data": {
                        "tags": {
                            "9F5D":"000400",
                            "DF810E": "00",
                            "DF810F": "00",
                            "DF8115": "060000000000FF"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "outcome_parameter_set": "30F0F000B8F00D00"
                },
                "completion": {
                    ... (same as authorization)
                }
            }
        }
    ]
}

With:

  • restart: An expected 'restart' signal to be found in the list of signals provided by the kernel (optional).
  • authorization: Kernel data provided to perform an authorization request (optional).
  • completion: Kernel data provided to perform the transaction completion (optional).

Note: Though authorization and completion are individually optional, there must at least be one of them in the test expectations.

The authorization and completion objects hold the below sub-objects (all of which are optional): * user_interface_request_data (full TLV value). * data_record (list of tags which value or presence should be checked). * discretionary_data (list of tags which value or presence should be checked). * outcome_parameter_set (full TLV value).

Note on data_record and discretionary_data

These objects contains at most 3 sub-objects (all of which are optional): * tags: Holds a list of tags (keys) and their expected values (values). * tags_present: Holds a list of tags which presence should be confirmed (whatever the value). * tags_not_present: Holds a list of tags which absence should be confirmed.

Notes

See below the tags corresponding to the authorization and completionsub-objects: * user_interface_request_data: DF8116 * data_record: FF8105 * discretionary_data: FF8106 * outcome_parameter_set: DF8129

Full example

Below is a full example of what a test suite file could look like:

{
    "name": "3B02-0001_first-trx-5-mutualappls",
    "version": "0.2.0",
    "date": "2024-10-05",

     "environment": {
        "tool": "eval+",
        "type": "TA L2",
        "scheme": "Mastercard",
        "spec_version": "v3.1.4",
        "test_plan_version": "v1.0.1",
        "test_env": "Dec 2021"
    },

    "card": "my-test-card",

    "poi_config": {
        "name": "POI_Config_1",
        "emv_config": "PPS_MChip_1",
        "capk_list": "CAPK_MCL_1",
        "cr_list": "CR_MCL_1"
    },

    "payments": [
        {
            "randoms": ["AABBCCDD", "BBCCDDEE"],
            "trd": {
                "9C": "00",
                "9F02": "000000001500",
                "5F2A": "0978",
                "5F36": "02",
                "9A": "241015",
                "9F21": "000000",
                "9F53": "46",
                "9F7C": "1122334455667788990011223344556677889900"
            },
            "authorization_response": "3030",
            "expectations": {
                "restart": {
                    "error_indication": "0003006A85FF",
                    "outcome_parameter_set": "5020F0F018F0FF00"
                },
                "authorization": {
                    "user_interface_request_data": "1B00000000656E646566720000",
                    "data_record":  {
                        "tags": {
                            "9F39": "07",
                            "9F02": "000000001500",
                            "9F26": "AC123456789ABCDE",
                            "5F24": "491231",
                            "82": "020080",
                            "50": "4D617374657243617264",
                            "5A": "5413339000001513",
                            "9F36": "0002",
                            "9F09": "0002",
                            "9F27": "80",
                            "9F34": "3F0000",
                            "84": "A0000000041010",
                            "9F1E": "3132333435363738",
                            "9F10": "0110000000020000DAC00000000000000000",
                            "9F11": "01",
                            "9F33": "006000",
                            "9F1A": "0056",
                            "9F35": "22",
                            "95": "8000000001",
                            "9F53": "46",
                            "9F15": "0130",
                            "5F2A": "0978",
                            "9A": "241015",
                            "9C": "00",
                            "9F37": "AABBCCDD"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "discretionary_data": {
                        "tags": {
                            "9F5D":"000400",
                            "DF810E": "00",
                            "DF810F": "00",
                            "DF8115": "060000000000FF"
                        },
                        "tags_present": [],
                        "tags_not_present": []
                    },
                    "outcome_parameter_set": "30F0F000B8F00D00"
                }
            }
        },
        {
            "trd": {
                "9C": "00",
                "9F02": "000000001500",
                "5F2A": "0978",
                "5F36": "02",
                "9A": "241015",
                "9F21": "000000",
                "9F53": "46",
                "9F7C": "1122334455667788990011223344556677889900"
            },
            "expectations": {
                "authorization": {
                    "user_interface_request_data": "1B00000000656E646566720000",
                    "data_record":  {
                        "tags": {
                            "9F39": "07",
                            "9F02": "000000001500",
                            "9F26": "AC123456789ABCDE",
                            "5F24": "491231",
                            "82": "020080",
                            "50": "4D617374657243617264",
                            "5A": "5413339000001513",
                            "9F36": "0002",
                            "9F09": "0002",
                            "9F27": "80",
                            "9F34": "3F0000",
                            "84": "A0000000041010",
                            "9F1E": "3132333435363738",
                            "9F10": "0110000000020000DAC00000000000000000",
                            "9F11": "01",
                            "9F33": "006000",
                            "9F1A": "0056",
                            "9F35": "22",
                            "95": "8000000001",
                            "9F53": "46",
                            "9F15": "0130",
                            "5F2A": "0978",
                            "9A": "241015",
                            "9C": "00",
                            "9F37": "AABBCCDD"
                        }
                    },
                    "discretionary_data": {
                        "tags": {
                            "9F5D":"000400",
                            "DF810E": "00",
                            "DF810F": "00",
                            "DF8115": "060000000000FF"
                        }
                    },
                    "outcome_parameter_set": "30F0F000B8F00D00"
                }
            }
        }
    ]
}

POI Config

A POI Config, in switstack's terminology is a set of files representing different layers of an EMV transaction's configuration.

Those layers are:

  • The EMV configuation which holds the supported applications and their respective configurations (TLVs).
  • The list of CA keys which is a list of all supported/authorized CA public keys used during card authentication.
  • The list of revoked certificates which is a list of CA public keys identifiers that must not be used anymore.

EMV Config

The EMV config is a file, that holds a set of applications to be supported by a kernel with their respective configuration. The contents of the file is described just below:

{
    "emvs": {
        "EMV Contactless Visa 1": {
            "technology_type": "CONTACTLESS",
            "kernel": "03",
            "aid": "A0000000031010",
            "transaction_type": "00",
            "asf": true,
            "tlv": "E15EDF810C01039F0607A00000000310109C0100DFA0100101E2459F6604270040009F1B04000027109F820D060000000002009F820E06000000010000DFA02006000000000400DFA0140101DFA0150101DFA0160101DFA01701019F1A020840"
        },
        "EMV Contactless Visa 2": {
            "technology_type": "CONTACTLESS",
            "kernel": "03",
            "aid": "A0000000032010",
            "transaction_type": "00",
            "asf": true,
            "tlv": "E15EDF810C01039F0607A00000000310109C0100DFA0100101E2459F6604270040009F1B04000027109F820D060000000002009F820E06000000010000DFA02006000000000400DFA0140101DFA0150101DFA0160101DFA01701019F1A020840"
        }
    },
    "emv_lists": {
        "EMVList Contactless Visa 1" : {
            "name": "EMVList Contactless Visa 1",
            "emvs": ["EMV Contactless Visa 1", "EMV Contactless Visa 2"]
        }
    },
    "emv_config": { 
        "name": "EMVConfig Contactless Visa 1",
        "emv_nominal_list": "EMVList Contactless Visa 1",
        "emv_failsafe_list": "EMVList Contactless Visa 1"
    }
}

With:

  • emvs: List of individual emv (e.g. combinations or configurations) for a specific quadruplet (technology_type, kernel, aid and transaction_type). Each emv must contain the following elements:
    • technology_type: Either CONTACTor CONTACTLESS.
    • kernel: The kernel ID (see kernels specifications).
    • aid: The Application IDentifier.
    • transaction_type: The type of transaction
      • 00 for Purchase.
      • 01 for Cash.
      • 09 for Purchase with Cashback.
      • 20 for Refund.
    • asf: The Application Selection Flag.
    • tlv: The actual TLV configuration.
  • emv_lists: List of emv_list to group combinations together. An emv_list is represented as follows:
    • name: Name of the list.
    • emvs: List of emv.
  • emv_config: The global config item. It is composed of:
    • name: The config name (for ex PPS_MChip_1).
    • emv_nominal_list: The list of combinations to use in nominal cases (e.g. most of the time).
    • emv_failsafe_list: The list of combinations to use in specific conditions (for ex prolongated offline mode).

CAPK List

The CAPK list is a file, that holds a list of EMV CA public keys to be used by the kernel(s) to perform card authentication. The contents of the file is described just below:

{
    "capks": {
        "mastercard_01": {
            "rid": "A000000004",
            "index": "01",
            "hash_type": "UNDEFINED",
            "algorithm_type": "RSA",
            "modulus": "AABBCCDDEEFF...",
            "exponent": "03",
            "hash": "000...00",
            "expires_at": "2024-12-31"
        },
        "mastercard_02": {
            "rid": "A000000004",
            "index": "02",
            "hash_type": "UNDEFINED",
            "algorithm_type": "RSA",
            "modulus": "AABBCCDDEEFF...",
            "exponent": "03",
            "hash": "000...00",
            "expires_at": "2024-12-31"
        },
        ...
    },
    "capk_list": {
        "name": "My CAPK List",
        "capks": ["mastercard_01", "mastercard_02"]
    }
}

With:

  • capks: A list of individual CAPK objects defined by a name and the following attributes:
    • rid: The RID.
    • index: The key index.
    • hash_type: The key checksum/hash type (UNDEFINED for now).
    • algorithm_type: The key algorithm (RSA for now).
    • moduls: The key modulus.
    • exponent: The key exponent.
    • hash: The key checksum / hash.
    • expires_at: The key expiration date.
  • capk_list: The list of CAPKs. It is composed of:
    • name: The list name.
    • capks: A list of CAPKs defined above in the document identified by their name.

CR List

The CR list is a file, that holds a list of revoked EMV CA public keys that cannot be used by the kernel(s) anymore to perform card authentication. The contents of the file is described just below:

{
    "crs": {
        "mastercard_01": {
            "rid": "A000000004",
            "index": "01",
            "serial_number": "AABBCC"
        },
        "mastercard_02": {
            "rid": "A000000004",
            "index": "02",
            "serial_number": "AABBCC"
        },
        ...
    },
    "cr_list": {
        "name": "My CR List",
        "crs": ["mastercard_01", "mastercard_02"]
    }
}

With:

  • crs: A list of individual CR objects defined by a name and the following attributes:
    • rid: The RID.
    • index: The key index.
    • serial_number: The key serial number (6 hex digits).
  • cr_list: The list of CRs. It is composed of:
    • name: The list name.
    • crs: A list of CRs defined above in the document identified by their name.

Virtual cards

Automated testing relies on virtual cards or, to be more exact, expected exchanges between a terminal and a card. The so called virtual cards can hold one or several transactions and for each of those transactions the full set of C-APDUs/R-APDUs expected to be exchanged between a terminal and what would be the equivalent card.

Info

Virtual card files should end up with a .vcard extension.

A virtual card can only contain APDU data or a specific set of tags: * * * * *

Note

A virtual card shall always start with a tag.

Below is an example of a virtual card file:

<tap>
00A404000E325041592E5359532E444446303100
6F59840E325041592E5359532E4444463031A547BF0C44610C4F07A0000000041010870101610C4F07A0000000043060870103610A4F05B012345678870109610C4F07B0123456781020870108610C4F07B01234567810308701079000
00A4040007A000000004101000
6F3B8407A0000000041010A530870101500A4D6173746572436172645F2D06656E646566729F1101019F38089F02069F33039C01BF0C069F5D030004009000
80A800000C830A0000000015000000080000
770A820200809404100101009000
00B2011400
70485F24034912315A0854133390000015138C0E95059F02069F34039F33039F37048E0A000000000000000000009F0D0500000000009F0E0500000000009F0F0500000000009F4A01829000
80AE40001580000000010000000015003F0000006000D04F877600
77299F2701809F360200029F2608AC123456789ABCDE9F10120110000000020000DAC000000000000000009000
<tap>
00A404000E325041592E5359532E444446303100
6F31840E325041592E5359532E4444463031A51FBF0C1C610C4F07A0000000041010870101610C4F07A00000000430608701039000
00A4040007A000000004101000
6F3B8407A0000000041010A530870101500A4D6173746572436172645F2D06656E646566729F1101019F38089F02069F33039C01BF0C069F5D030004009000
80A800000C830A0000000015000000080000
770A820200809404100101006A85
00A4040007A000000004306000
6F1BA51987010350074D61657374726F5F2D06656E646566729F1101019000

Settings

swittest needs a bit of configuration before it can run properly. In perticular:

  • Information about the target (terminal under tests).
  • Access details to switcloud service.
  • Access details to the test suites (either local or remote).

This configuration must be made through environment variables, described below:

ST_SWITCLOUD_URL=
ST_ORG_ADMIN_EMAIL=
ST_ORG_ADMIN_PASSWORD=
ST_USER_MACHINE_CLIENT_ID=
ST_USER_MACHINE_CLIENT_SECRET=
ST_SOCKET_SERVER_HOST=
ST_SOCKET_SERVER_PORT=
ST_POI_ID=
ST_LOCAL_STORAGE=
ST_LOCAL_STORAGE_BASE_DIR=
ST_AWS_ACCESS_KEY_ID=
ST_AWS_SECRET_ACCESS_KEY=
ST_AWS_REGION_NAME=
ST_AWS_BUCKET_NAME=
ST_AWS_LOCATION=

With:

  • ST_SWITCLOUD_URL= switcloud service URL
  • ST_ORG_ADMIN_EMAIL= switcloud service organization admin email
  • ST_ORG_ADMIN_PASSWORD= switcloud service organization admin password
  • ST_USER_MACHINE_CLIENT_ID= switcloud service terminal client id
  • ST_USER_MACHINE_CLIENT_SECRET = switcloud service terminal client secret
  • ST_SOCKET_SERVER_HOST= IP address where the terminal should connect (default: 127.0.0.1)
  • ST_SOCKET_SERVER_PORT= IP port combine with ST_SOCKET_SERVER_HOST (default: 65432)
  • ST_POI_ID= Terminal POI ID
  • ST_LOCAL_STORAGE= Use local storage for test suites (default: true)

If ST_LOCAL_STORAGE is set to true:

  • ST_LOCAL_STORAGE_BASE_DIR= Path to test suites (default: .)

If ST_LOCAL_STORAGE is set to false:

  • ST_AWS_ACCESS_KEY_ID= Remote test suites storage key ID
  • ST_AWS_SECRET_ACCESS_KEY= Remote test suites storage access key
  • ST_AWS_REGION_NAME= Remote test suites storage region
  • ST_AWS_BUCKET_NAME= Remote test suites storage name
  • ST_AWS_LOCATION= Remote test suites storage directory