API v1 (Legacy)

The Mirage API v1 returns JSON. The response always returns the version, and payload. 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.

e.g. an error response

{
   "version": "1.2.3",
   "error": {
       "message": "Session already exists - localhost:first:first_1 in playback mode.",
       "code": 400
   }
}

e.g. a successful response

{
   "version": "1.2.3",
   "data": {
       "status": "playback",
       "message": "Playback mode initiated....",
       "session": "first_1",
       "scenario": "localhost:first"
   }
}

exec/cmds

 exec/cmds  (GET, POST)
    query args:
        cmdfile: URL or a file under /static on the mirage server
         + any user args will be made avaliable to the cmd file template
        session_id: session name to substitute within the cmdfile template, best to prefix this with scenario name if provided (optional)
    response: shows the list of commands (url, return_code) executed, see the Tracker page for responses

Typically command files are used to load stubs into the Mirage db, but you can run any supported commands from a file.

stubo/api/exec/cmds?cmdfile=/static/cmds/demo/first.commands

{
"version": "1.2.3",
"data": {
   "executed_commands": [
      [
         "delete/stubs?scenario=first",
         200
      ],
      [
         "begin/session?scenario=first&session=first_1&mode=record",
         200
      ],
      [
         "put/stub?session=first_1,first.textMatcher,first.response",
         200
      ],
      [
         "end/session?session=first_1",
         200
      ],
      [
         "begin/session?scenario=first&session=first_1&mode=playback",
         200
      ],
      [
         "get/response?session=first_1,first.request",
         200
      ],
      [
         "end/session?session=first_1",
         200
      ]
   ],
   "number_of_requests": 7,
   "number_of_errors": 0
   }
}




stubo/api/exec/cmds?cmdfile=https://your-source-repo/my.commands

Command files can be included in an archive file along with the matcher and response files. You can import your stubs
by running the archive file:

stubo/api/exec/cmds?cmdfile=https://your-source-repo/my.zip

Supported archive formats are zip, tar.gz & jar files.

get/version

get/version (GET, POST)

This call does not touch the db or cache so is useful as a quick 'ping' on the server

stubo/api/get/version

{"version": "1.2.3"}

get/status

get/status (GET, POST)
   query args:
     scenario=name
     session=name (session takes precedence)
     check_database=true|false (default true)
     local_cache=true|false (default true)

stubo/api/get/status?scenario=first

{
"version": "1.2.3",
"data": {
    "cache_server": {
        "status": "ok",
        "local": true
    },
    "info": {
        "cluster": "my-cluster",
        "graphite_host": "http://my-graphite.com/"
    },
    "database_server": {
        "status": "ok"
    },
    "sessions": [
        [
            "first_1",
            "dormant"
        ]
    ]
}

stubo/api/get/status?session=first_1

{
"version": "1.2.3",
"data": {
    "cache_server": {
        "status": "ok",
        "local": true
    },
    "info": {
        "cluster": "my-cluster",
        "graphite_host": "http://my-graphite.com/"
    },
    "session": {
        "status": "dormant",
        "system_date": "2014-10-02",
        "scenario": "localhost:first",
        "last_used": "2014-10-02 16:00:39",
        "scenario_id": "542d76a7ac5f73060fc9c2b4",
        "session": "first_1"
    },
    "database_server": {
        "status": "ok"
    }
}

begin/session

 begin/session (GET, POST)
    query args:
        scenario = scenario name
        session = session name
        mode = playback|record

stubo/api/begin/session?scenario=first&session=first_1&mode=playback

{
    "version": "5.9.9",
    "data": {
        "status": "playback",
        "message": "Playback mode initiated....",
        "session": "first_1",
        "scenario": "localhost:first"
    }
}

Note on duplicate scenarios and sessions:

* A scenario name prefixed with the mirage host name must be unique. One cannot record a new scenario with a duplicate host + scenario name.
* Sessions are instances of scenario's stubs and must be unique within a host.
* Sessions can not be deleted if in playback or record mode
* Scenarios can not be deleted if any session based on it is in playback or record mode.

end/session

end/session (GET, POST)
   query args:
       session: session name

stubo/api/end/session?session=first_1

{
   "version": "1.2.3",
   "data": {
       "message": "Session ended"
   }
}

* Ending a session which does not exist is OK and will complete successfully

end/sessions

end/sessions (GET, POST)
   query args:
       scenario: scenario name

stubo/api/end/sessions?scenario=first

{
    "version": "6.1.3",
    "data": {
        "first_1": {
            "message": "Session ended"
        },
        "first_2": {
            "message": "Session ended"
        }
    }
}

put/scenarios

Scenario names can be changed by providing current scenario name and new name. This operation includes renaming all the stubs that belong to this scenario, as well as changing scenario name value in saved sessions. Sessions will be transfered to new scenario. During rename procedure - all sessions will be set to dormant mode. Returns status code 412 if no name or no query is provided. Returns status code 400 if scenario name has illegal characters. Scenario name check regex: r’[w-]*$’ - letters, numbers, dashes, underscores

put/scenarios/(?P<scenario_name>[^\/]+) (GET)
   query args:
       new_name: new scenario name

stubo/api/put/scenarios/first?new_name=new_first_scenario_name

{
"Scenarios changed": 1,

"Remapped sessions": [
         {
             "name": "myscenario_session2"
         }
     ],
"New name": "localhost:new_first_scenario_name",
"Old name": "localhost:first",
"Stubs changed": 5,
"Pre stubs changed": 0
}

put/stub

 put/stub (POST)
    query args:
         session = session name
         ext_module = external module name without .py extenstion (optional)
         delay_policy =  delay policy name (optional)
         stateful = treat duplicate stubs as stateful otherwise ignore duplicates if stateful=false (default true, optional)
         tracking_level: full or normal (optional, overrides host or global setting)
         + any user args will be made avaliable to the matcher & response templates and any user exit code
 e.g.
 stubo/api/put/stub?session=my_session

 given request=<status>IS_OK</status> & response=<response>YES</response>
 JSON POST data
 {
     "request": {
         "method": "POST",
         "bodyPatterns": [
             { "contains": ["<status>IS_OK</status>"] }
         ]
         },
     "response": {
         "status": 200,
         "body": "<response>YES</response>"
     }
 }
 returns
 {
    "data": {
        "message": "put 54378c0dac5f7302b5cb8e56 stub"
    },
    "version": "1.2.3"
 }

 Treatment of duplicate stubs:

* If both the request and the response already exist for the scenario in record mode, then the stub will not be created.
* If the request exists, but with a different response, the second response will be recorded and the stub becomes a 'stateful stub'.
* Duplicate stubs can exist in different scenarios

Notes:

see stub_reference for stub definitions. see daterolling for an example of using user arguments to perform date rolling

get/stublist

 get/stublist (GET, POST)
    query args:
        scenario: scenario name
        host: host uri to use (defaults to host used in request uri, optional)

 stubo/api/get/stublist?scenario=first

{
 "version": "1.2.3",
 "data": {
     "stubs": [
         {
             "recorded": "2014-10-10",
             "args": {
                 "session": "first_1"
             },
             "request": {
                 "bodyPatterns": [
                     {
                         "contains": [
                             "get my stub\n"
                         ]
                     }
                 ],
                 "method": "POST"
             },
             "response": {
                 "status": 200,
                 "body": "Hello {{1+1}} World\n"
             }
         }
     ],
     "scenario": "first"
 }

put/delay_policy

put/delay_policy (GET, POST)
   query args:
       name: delay name
       delay_type: fixed, normalvariate or weighted
       milliseconds: used with fixed delay_type only
       mean: used with normalvariate delay_type only
       stddev: used with normalvariate delay_type only
       values: used with weighted delay_type only. values is a delimited string of delays.
       For each delay the last value represents the percentage this delay will occur.

stubo/api/put/delay_policy?name=slow&delay_type=fixed&milliseconds=1000

{
   "version": "1.2.3",
   "data": {
       "status": "new",
       "message": "Put Delay Policy Finished",
       "delay_type": "fixed",
       "name": "slow"
   }
}

i.e. to set a weighted percentage of delays with 5% fixed at 30s, 15% having a delay of 5s +/- 1s and 70% having a delay of 1s +/- 0.5s
stubo/api/put/delay_policy?name=pcent_random_samples&delay_type=weighted&delays=fixed,30000,5:normalvariate,5000,1000,15:normalvariate,1000,500,70

{
   "version": "1.2.3",
   "data": {
       "status": "new",
       "message": "Put Delay Policy Finished",
       "delay_type": "weighted",
       "name": "pcent_random_samples"
   }
}

get/delay_policy

get/delay_policy (GET, POST)
   query args:
       name: delay name (optional lists all if not provided)

stubo/api/get/delay_policy?name=slow
{
   "version": "1.2.3",
   "data": {
       "slow": {
           "delay_type": "fixed",
           "name": "slow",
           "milliseconds": "1000"
       }
   }
}

delete/delay_policy

delete/delay_policy (GET, POST)
   query args:
       name: delay name (optional deletes all if not provided)

stubo/api/delete/delay_policy?name=slow

{
   "version": "1.2.3",
   "data": {
       "message": "Deleted 1 delay policies from [u'slow']"
   }
}

get/response

get/response (POST)
   query args:
       session: session name
       tracking_level: full or normal (optional, overrides host or global setting)
   POST data: request payload
   HTTP headers:
     Mirage-Request-Session=123 Optional, can be used in place of session on the URL.
   returns stub response payload in HTTP body if ok
   on error returns mirage json error response

stubo/api/get/response?session=first_1
POST data: get my stub
returns: Hello 2 World

delete/stubs

Stubs should be mastered in a code repository such as SVN. Delete/stubs will remove stubs from the Mirage database. This should be run at the end of each test run.

 delete/stubs (GET, POST)
    query args:
        scenario: scenario name
        host: host uri to use (defaults to host used in request uri, optional)
        force: false or true (optional, defaults to false)

stubo/api/delete/stubs?scenario=first

{
    "version": "1.2.3",
    "data": {
        "scenarios": [
            "localhost:first"
        ],
        "message": "stubs deleted."
    }
}

* All sessions must be in a dormant state to delete the stubs unless force=true is used
* Deleting a scenario that does not exist is OK and will complete successfully

get/export

Export a recorded scenario. To support repeatable testing a recording should be exported with get/export and the resulting archive file saved to your source code repository (GIT etc). The exported archive contains all scenario stubs and a command script to reload them. The get/export call also supports exporting ‘runnable’ scenarios. A ‘runnable’ scenario will add a playback of a previous session to the command script. This can be useful to compare different test runs with each other.

get/export (GET, POST)
   query args:
       scenario: scenario name
       session_id: session id to use within the export (optional, defaults to epoch time)
       export_dir: export dir name (optional, defaults to scenario key)
       runnable: create a runnable scenario of a previous playback (optional)
       playback_session: playback session to use (required with runnable)
       session_id: session name to substitute within the cmdfile template (optional)
returns links to exported archive files (*.zip, *.tar.gz, *.jar)

stubo/api/get/export?scenario=first

{
   "version": "1.2.3",
   "data": {
       "scenario": "first",
       "export_dir_name": "/Users/rowan/dev/eclipse/workspace/stubo/static/exports/localhost_first",
       "links": [
           [
               "first_1412947560_0.response.0",
               "http://Rowan-MacBook-Pro-5.local:8001/static/exports/localhost_first/first_1412947560_0.response.0?v=1d63737c9cdb7b1433d76b52661c9db9"
           ],
           [
               "first_1412947560_0_0.textMatcher",
               "http://Rowan-MacBook-Pro-5.local:8001/static/exports/localhost_first/first_1412947560_0_0.textMatcher?v=088c16fa5004e2467126cfeaf8da3cd3"
           ],
           [
               "first.commands",
               "http://Rowan-MacBook-Pro-5.local:8001/static/exports/localhost_first/first.commands?v=d56a304dddafe558ccfe9340ebdb41e8"
           ],
           [
               "first.zip",
               "http://Rowan-MacBook-Pro-5.local:8001/static/exports/localhost_first/first.zip?v=34c1c698d09e7e3f1a3a10a2834bbbd6"
           ],
           [
               "first.tar.gz",
               "http://Rowan-MacBook-Pro-5.local:8001/static/exports/localhost_first/first.tar.gz?v=8e5ac69d3041941aa4cc5dfdee41326b"
           ],
           [
               "first.jar",
               "http://Rowan-MacBook-Pro-5.local:8001/static/exports/localhost_first/first.jar?v=34c1c698d09e7e3f1a3a10a2834bbbd6"
           ]
       ]
   }
}

& runnable export

stubo/api/get/export?scenario=first&runnable=true&playback_session=first_1

{
    "version": "1.2.3",
    "data": {
        "runnable": {
            "last_used": {
                "start_time": "2015-03-24 16:57:03.248000+00:00",
                "remote_ip": "::1"
            },
            "playback_session": "first_1",
            "number_of_playback_requests": 1
        },
        "scenario": "first",
        "links": [
            [
                "first_1427285580_0.response.0",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first_1427285580_0.response.0?v=1d63737c9cdb7b1433d76b52661c9db9"
            ],
            [
                "first_1427285580_0_0.textMatcher",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first_1427285580_0_0.textMatcher?v=088c16fa5004e2467126cfeaf8da3cd3"
            ],
            [
                "first_1427285580_0.request",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first_1427285580_0.request?v=925721a672115ec9bfc24f55a6979a63"
            ],
            [
                "first.commands",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first.commands?v=98ad4927b82478744dfa004f48f88aff"
            ],
            [
                "first.zip",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first.zip?v=66a370b25ca2065abc4deb347ee77ce6"
            ],
            [
                "first.tar.gz",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first.tar.gz?v=da76a1ce23a9cfe2dc1895955021f3c4"
            ],
            [
                "first.jar",
                "http://vuze-on-pc2.home:8001/static/exports/localhost_first/first.jar?v=66a370b25ca2065abc4deb347ee77ce6"
            ]
        ],
        "export_dir_path": "/Users/rowan/dev/eclipse/workspace/opencredo/stubo/latest/stubo-app/stubo/static/exports/localhost_first"
    }
}

get/stubcount

get/stubcount (GET, POST)
   query args:
       scenario: scenario name (optional)

Returns the number of stubs for a given scenario or all scenarios on host if
the scenario is not provided.

stubo/api/get/stubcount?scenario=first

{
   "version": "1.2.3",
   "data": {
       "count": 1,
       "scenario": "first"
   }
}

put/module

User exits can be applied to perform custom manipulation of Mirage matchers and responses. The user exits are python code defined with the UserExit API. The code is input into mirage with the following API call.

put/module (GET, POST)
   query args:
       name: full path to module can be a uri

stubo/api/put/module?name=/static/cmds/tests/ext/xslt/mangler.py

{
   "version": "1.2.3",
   "data": {
       "message": "added modules: ['localhost_mangler_v1']"
   }
}

Notes:

If the module code has not changed an error is returned indicating that the source has not changed otherwise a new version of the module is added to mirage dynamically.

get/modulelist

get/modulelist (GET, POST)
returns list of loaded modules

stubo/api/get/modulelist

{
   "version": "1.2.3",
   "data": {
       "info": {
           "mangler": {
               "loaded_sys_versions": [
                   "localhost_mangler_v1"
               ],
               "latest_code_version": 1
           }
       },
       "message": "list modules"
   }
}

delete/module

Delete named module.

 delete/module (GET, POST)
    query args:
        name: name of module without .py ext

{
    "version": "1.2.3",
    "data": {
        "deleted": [
            "localhost:mangler"
        ],
        "message": "delete modules: [u'mangler']"
    }
}

delete/modules

Delete all modules from this host URL.

delete/modules (GET, POST)

{
    "version": "6.1.3",
    "data": {
        "deleted": [
            "localhost:strip_ns",
            "localhost:ignore_dates",
        ],
        "message": "delete modules: ['strip_ns', 'ignore_dates']"
    }
}

Set Tracking Level

All API calls to Mirage will result in a tracking record being created. Default level tracking includes:

  • start time
  • duration
  • any user configured delay
  • mirage function
  • return code and data
  • session and scenario names
  • response size
  • server (Mirage server that handled the request)
  • host (DNS of mirage used on the request)
  • remote_ip (IP address of the client)

In addition, get/response calls can optionally force other items to be tracked including:

  • matchers used
  • matcher text before, during and after any mangling
  • response text before, during and after any mangling

To enable/disable logging.

put/setting (GET, POST)
   query args:
       tracking_level=full or normal

stubo/api/put/setting?setting=tracking_level&value=full
{
   "version": "1.2.3",
   "data": {
       "new": "false",
       "host": "localhost",
       "all": false,
       "tracking_level": "full"
   }
}

Click on a get/response item in the Tracker page to see the full tracking data.

get/stats

Obtain the percent of get/response calls that are above a given latency value.

get/stats (GET, POST)
   query args:
       percent_above_value = threshold value in millisecs
       from=start time of metrics

e.g. to find the percent of Mirage responses that take more than 40ms (during the past 30min)

/stubo/api/get/stats?percent_above_value=40&from=-30mins

{
   "version": "5.6.2",
   "data": {
       "from": "-30mins",
       "target": "averageSeries(stats.timers.stubo.aws_cluster1.*.stuboapi.get_response.latency.mean_90)",
       "metric": "latency",
       "to": "now",
       "percent_above_value": 40,
       "pcent": 0.0
   }
}

The key value being "pcent" which in this case is 0.0.