REST API v2¶
Mirage REST API v2 returns JSON. The response always returns the version, and payload. Responses are similar to v1 API responses. The payload is either contained under ‘data’ if the response is successful or ‘error’ for errors. Errors contain a descriptive message under ‘message’ and the http error code under ‘code’. Successful responses depend on the call made and are described below.
Encoding “application/json”
Create scenario object¶
Creates scenario object. Client must specify scenario name in the request body.
URL: /api/v2/scenarios
Method: PUT
Response codes:
201 - scenario created
422 - scenario with that name already exists
400 - something is missing (e.g. name)
Example request body:
{ "scenario": "scenario_name" }
Upload scenario with session & stubs¶
You can upload existing scenarios directly into Mirage via this API call. Currently it only accepts .zip format and only .yaml configuration file.
- URL: /api/v2/scenarios/upload
- Method: POST
- Encoding: “multipart/form-data”
- Response codes:
- 200 - Scenario uploaded successfully.
- 415 - Content type not supported (format not accepted).
- 400 - Configuration file found, however failed to read it.
- 422 - Scenario already exists.
Example scenario_x.zip content structure:
scenario_x.yaml
stub_0.json
stub_1.json
stub_2.json
stub_3.json
stub_4.json
As you can see - everything is expected to be in the same directory, no inner directory structure is expected.
Defining .yaml configuration:
recording:
scenario: scenario_x
session: session_x
Note that by default Mirage exported yaml file looks like this:
recording:
scenario: scenario_x
session: session_x
stubs:
- file: stub_0.json
- file: stub_1.json
- file: stub_2.json
- file: stub_3.json
- file: stub_4.json
Although, during upload it ignores “stubs” key and treats every .json file in the archived zip as a separate stub.
When Mirage finds yaml configuration - it gets scenario name and creates it. After that - reads every file from the archive that ends with ”.json”. After all the stubs were added to the database - starts a session in playback mode. Scenario is then ready for testing.
Example stub .json structure:
{
"priority": 9903,
"args": {
"priority": "9903"
},
"request": {
"bodyPatterns": {
"contains": [
"<tag> matcher here </tag>"
]
},
"method": "POST"
},
"response": {
"body": "<response> Response here </response>\n",
"headers":
"status": 200
}
}
Example upload (Python)¶
Below is an example pseudocode for uploading files to Mirage:
def upload(file_name, mirage_uri):
"""
file_name - path to zip archive.
mirage_uri - full Mirage URL (http://miragehostname:8001)
"""
# reading file
with open(file_name, 'r') as stream:
# preparing data
files = [('files', (file_name, stream, 'application/zip'))]
data = {}
resp = requests.post(mirage_uri + "/api/v2/scenarios/upload",
files=files, data=data)
if resp.status_code == 200:
print("Upload success!")
return
You can upload multiple archives at once. Every archive should be self contained - yaml configuration and stubs archived together.
Get scenario list¶
Returns a list of scenarios with their name and scenarioRef attributes. This attribute can the be used to get scenario details (sessions, stubs, size, etc...). Your application can look for these keys and use them to directly access resource instead of generating URL on client side.
URL: /api/v2/scenarios
Method: GET
Response codes:
200 - scenario list returned
Example output:
{ "data": [ {"scenarioRef": "/api/v2/scenarios/objects/localhost:scenario_1", "name": "localhost:scenario_1"}, {"scenarioRef": "/api/v2/scenarios/objects/localhost:scenario_10", "name": "localhost:scenario_10"}, ..., ..., ] }
Returns a list of scenarios with details.
URL: /api/v2/scenarios/detail
Method: GET
Response codes:
200 - scenario list with details returned
Example output:
{ "data": [ { "space_used_kb": 0, "name": "localhost:scenario_1", "sessions": [], "scenarioRef": "/api/v2/scenarios/objects/localhost:scenario_1", "recorded": "-", "stub_count": 0}, { "space_used_kb": 544, "name": "localhost:scenario_10", "sessions": [ { "status": "playback", "loaded": "2015-07-20", "name": "playback_10", "last_used": "2015-07-20 13:09:05"} ], "scenarioRef": "/api/v2/scenarios/objects/localhost:scenario_10", "recorded": "2015-07-20", "stub_count": 20}, ..., ..., ] }
Get scenario details¶
Returns specified scenario details. Scenario name can be provided with a host, for example stubo_c1.yourcorporateaddress.com:scenario_name_x
URL: /api/v2/scenarios/objects/
Method: GET
Response codes:
200 - specified scenario details
404 - specified scenario not found
Example output:
{ "space_used_kb": 697, "name": "localhost:scenario_13", "sessions": [ {"status": "playback", "loaded": "2015-07-20", "name": "playback_13", "last_used": "2015-07-20 13:09:05"} ], "stubs": 26, "recorded": "2015-07-20", "scenarioRef": "/api/v2/scenarios/objects/localhost:scenario_13" }
Delete scenario¶
Deletes scenario object and removed it’s stubs from cache.
- URL: /api/v2/scenarios/objects/
- Method: DELETE
- Response codes:
- 200 - scenario deleted
- 412 - precondition failed - specified scenario does not exist
Begin session and set mode¶
Begins session for specified scenario. Client has to specify session name and mode in request body. Session mode can be either ‘record’ and ‘playback’.
URL: /api/v2/scenarios/objects//action
Method: POST
Response codes:
200 - begins session
400 - something went wrong (e.g. session already exists)
Example request body:
{ "begin": null, "session": "session_name", "mode": "record" }
Example output:
{ "version": "0.6.6", "error": {"message": "Scenario (localhost:scenario_10) has existing stubs, delete them before recording or create another scenario!", "code": 400} }
End session¶
Ends specified session. Client has to specify session name in request body.
URL: /api/v2/scenarios/objects//action
Method: POST
Response codes:
200 - session ended.
Example request body:
{ "end": null, "session": "playback_28" }
Example output:
{ "version": "0.6.6", "data": { "message": "Session ended"} }
End all sessions for specific scenario¶
Ends all sessions for specified scenario
- URL: /api/v2/scenarios/objects//action
- Method: POST
- Response codes:
- 200 - scenario list with details returned
- Example request body:
{
"end": "sessions"
}
- Example output:
{
"version": "0.6.6",
"data": {
"playback_20": {"message": "Session ended"}
}
}
Add stub¶
Add stub to scenario
URL: /api/v2/scenarios/objects/(?P[^\/]+)/stubs
Method: PUT
Response codes:
201 - inserted
200 - updated or ignored
Example request body:
{ "request": { "method": "POST", "bodyPatterns": [ { "contains": ["<status>IS_OK2</status>"] } ] }, "response": { "status": 200, "body": "<response>YES</response>" } }
Example output: If updated (status code 200)
{ version: "0.7" data: { message: "updated with stateful response" } }
or inserted (status code 201).
{
version: "0.6.6"
data: {
message: "inserted scenario_stub: 55d5e7ebfc4562fb398dc697"
}
Here this ID - 55d5e7ebfc4562fb398dc697 is an object _id field from database. Proxy or an integrator could actually go directly to database with this key and retrieve response.
Getting response with stub¶
URL: /api/v2/scenarios/objects/(?P[^\/]+)/stubs
Method: POST
Response codes:
__*__ - any HTTTP response that user defined during stub insertion
Example request header: session: your_session_name
Example request body:
matcher here
Getting request response data (JSON)¶
This call is similar to “Getting response with stub”, however this one is intended to give all the data to the client to build original response instead of returning original response. This enables storing encoded/encrypted responses. Users have to provide a scenario:session key in headers.
URL: /api/v2/matcher
Method: POST
Response codes:
200 - Response found
404 - Response not found
Example request header: session: scenario_name:session_name
Example request body:
matcher here
Example response body: ```javascript { “body”: “body bytes or plain text here”, “headers”: { “key”: “value”, “key1”: “value1” } “statusCode”: 200 }
```
Get all stubs for specific scenario¶
- URL: /api/v2/scenarios/objects/(?P[^\/]+)/stubs
- Method: GET
- Response codes:
- 200 - stub list returned
{
"version": "0.7",
"data": [
{
"stub": {
"priority": -1,
"request": {
"bodyPatterns": {
"contains": [
"<status>IS_OK2</status>"
]
},
"method": "POST"
},
"args": {},
"recorded": "2015-10-08",
"response": {
"status": 123,
"body": "<response>YES</response>"
}
},
"matchers_hash": "a92fa6cf96f218598d3723f2827a6815",
"space_used": 219,
"recorded": "2015-10-08",
"scenario": "localhost:scenario_name_1"
}
]
}
Delete all scenario stubs¶
- URL: /api/v2/scenarios/objects/(?P[^\/]+)/stubs
- Method: DELETE
- Response codes:
- 200 - stubs deleted
- 409 - precondition failed - there are active sessions either in playback or record mode
Get delay policy list¶
Gets all defined delay policies
- URL: /api/v2/delay-policy/detail
- Method: GET
- Response codes:
- 200 - list with delay policies returned
- Example output:
{
"version": "0.6.6",
"data": [
{
"delay_type": "fixed",
"delayPolicyRef": "/api/v2/delay-policy/objects/slow",
"name": "slow",
"milliseconds": "1000"
},
{
"delay_type": "fixed_2",
"delayPolicyRef": "/api/v2/delay-policy/objects/slow",
"name": "slower",
"milliseconds": "5000"
}
]
}
Get specific delay policy details¶
- URL: /api/v2/delay-policy/objects/
- Method: GET
- Response codes:
- 200 - delay policy returned
- 404 - delay policy not found
- Example output:
{
"version": "0.6.6",
"data": [
{
"delay_type": "fixed",
"delayPolicyRef": "/api/v2/delay-policy/objects/slow",
"name": "slow",
"milliseconds": "1000"
}
]
}
Add delay policy¶
Creates a delay policy. Returns 201 status code if successful or 409 if request body options are wrong (type fixed provided with mean and stddev options)
URL: /api/v2/delay-policy
Method: PUT
Response codes:
201 - scenario list with details returned
400 - bad request
409 - wrong combination of options was used
Example request body:
{ "name": "delay_name", "delay_type": "fixed", "milliseconds": 50 }
or:
{
"name": "delay_name",
"delay_type": "normalvariate",
"mean": "mean_value",
"stddev": "val"
}
or:
{
"name": "weighted_delay_name",
"delay_type": "weighted",
"delays": "fixed,30000,5:normalvariate,5000,1000,15:normalvariate,1000,500,70"}
- Example output:
{
"status_code": 201,
"version": "0.6.6",
"data":
{
"status": "new",
"message": "Put Delay Policy Finished",
"delay_type": "fixed",
"delayPolicyRef": "/api/v2/delay-policy/objects/my_delay",
"name": "my_delay"
}
}
Delete delay policy¶
- URL: /api/v2/delay-policy/objects/
- Method: DELETE
- Response codes:
- 200 - delay policy deleted
- Example output:
{
"version": "0.6.6",
"data":
{
"message": "Deleted 1 delay policies from [u'my_delay']"
}
}
Get records from tracker¶
Gets records from tracker. Since this collection becomes quite big over time - pagination is available. Your client application can define how many records it wants to skip and current item limit. Mirage also provides “href” - links to every record for additional information.
Available parameters: + limit - maximum records to return + skip - how many records should be skipped + q - query. Query can be simple string to search based on API call path, scenario. You can also supply values to search for specific status codes and response times. For example I would want to find a scenario named “my_test_suite_x” and to see only HTTP calls that produced status codes between 200 and 201, also, I would want to see only those requests that took longer than 200 ms to complete, my query would look like: “my_test_suite_x sc:>=200 sc:<=201 rt:>200”
- URL: /api/v2/tracker/records
- Method: GET
- Response codes:
- 200 - list with tracker entries returned
- Example output:
{
"paging": {
"last": "/api/v2/tracker/records?skip=23172&limit=2",
"next": "/api/v2/tracker/records?skip=2&limit=2",
"currentLimit": 2,
"totalItems": 23174,
"previous": null,
"first": "/api/v2/tracker/records?skip=0&limit=2"
},
"data": [
{
"function": "/api/v2/scenarios/objects/localhost:scenario_100/stubs",
"request_params": {},
"start_time": "2015-10-27 11:18:24",
"return_code": 200,
"href": "/api/v2/tracker/records/objects/562f5d8137dd1220d73a0cbf",
"duration_ms": 902,
"stubo_response": "",
"id": "562f5d8137dd1220d73a0cbf"
},
{
"function": "/api/v2/scenarios/objects/localhost:scenario_14/action",
"request_params": {},
"scenario": "localhost:scenario_14",
"start_time": "2015-10-27 10:15:01",
"return_code": 200,
"href": "/api/v2/tracker/records/objects/562f4ea537dd1220d73a0ca1",
"duration_ms": 24,
"stubo_response": "",
"id": "562f4ea537dd1220d73a0ca1"
}
]
}
Get tracker record details¶
Gets detail information about specified tracker object ID.
- URL: /api/v2/tracker/records/objects/
- Method: GET
- Response codes:
- 200 - tracker record found, returned.
- 404 - tracker record not found
- Example output:
{
"data":{
"function":"/api/v2/scenarios/objects/localhost:scenario_100/stubs",
"request_params":{
},
"tracking_level":"normal",
"start_time":"2015-10-27 11:18:24",
"return_code":200,
"server":"karoliss-macbook-pro.local",
"request_size":0,
"response_headers":{
"Date":"Tue, 27 Oct 2015 11:18:24 GMT",
"Content-Length":"5835405",
"Content-Type":"application/json; charset=UTF-8",
"Server":"TornadoServer/4.1"
},
"request_headers":{
"Accept-Language":"en-US,en;q=0.8,lt;q=0.6",
"Accept-Encoding":"gzip, deflate, sdch",
"Connection":"keep-alive",
"Accept":"*/*",
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36",
"Dnt":"1",
"Host":"localhost:8001",
"X-Requested-With":"XMLHttpRequest",
"Referer":"http://localhost:8001/manage/scenarios/details?scenario=/api/v2/scenarios/objects/localhost:scenario_100"
},
"host":"localhost",
"request_method":"GET",
"id":"562f5d8137dd1220d73a0cbf",
"response_size":5835405,
"duration_ms":902,
"stubo_response":"",
"port":"8001",
"remote_ip":"::1"
}
}