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 theenv
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 thecapks
,crs
,emvs
andtests
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 theenv
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 completion
sub-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 individualemv
(e.g. combinations or configurations) for a specific quadruplet (technology_type
,kernel
,aid
andtransaction_type
). Eachemv
must contain the following elements:technology_type
: EitherCONTACT
orCONTACTLESS
.kernel
: The kernel ID (see kernels specifications).aid
: The Application IDentifier.transaction_type
: The type of transaction00
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 ofemv_list
to group combinations together. Anemv_list
is represented as follows:name
: Name of the list.emvs
: List ofemv
.
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 URLST_ORG_ADMIN_EMAIL
= switcloud service organization admin emailST_ORG_ADMIN_PASSWORD
= switcloud service organization admin passwordST_USER_MACHINE_CLIENT_ID
= switcloud service terminal client idST_USER_MACHINE_CLIENT_SECRET
= switcloud service terminal client secretST_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 IDST_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 IDST_AWS_SECRET_ACCESS_KEY
= Remote test suites storage access keyST_AWS_REGION_NAME
= Remote test suites storage regionST_AWS_BUCKET_NAME
= Remote test suites storage nameST_AWS_LOCATION
= Remote test suites storage directory