Skip to content

Commit

Permalink
docs for campaign file
Browse files Browse the repository at this point in the history
  • Loading branch information
andgineer committed Apr 20, 2019
1 parent 0185897 commit 3cca408
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 50 deletions.
6 changes: 6 additions & 0 deletions bombard/bombardier.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def process_resp(self, ammo: dict, status: int, resp: str, elapsed: int, size: i
self.reporter.log(True, elapsed, request.get('name'), size)
log.debug(f'{status} reply\n{resp}')
if 'extract' in request:
#todo: auto fire ammo after prepare if no reload
# now extract option is not so useful - you extract something but do not add
# requests that use that. you cannot just have this requests in the same
# section because of unpredictable requests order
# so we wait prepare section scripts to finish and fire ammo section IF no reload
# was registered
try:
data = json.loads(resp)
if not hasattr(request['extract'], 'items'):
Expand Down
2 changes: 1 addition & 1 deletion bombard/examples/get_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Executed after getToken Bombard request (see bombard.yaml).
Get auth token and after that schedule requests.
"""
from bombard.mock_globals import *; master('@examples/bombard.yaml')
from bombard.mock_globals import *; master('bombard://bombard.yaml')
# to have code autocomplete to work. lines with `bombard.examples.mock_globals` (including this one) will be removed before execution


Expand Down
4 changes: 2 additions & 2 deletions bombard/examples/simple.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
supply: # you can redefine it from command line (--supply)
host: https://jsonplaceholder.typicode.com/
prepare: # Get ids from posts and comments.
prepare: # Get ids from posts
postsList:
url: "{host}posts" # use {host} from global supply
script: |
for post in resp[:3]: # add getPost requests for 1st ten posts in the list
for post in resp[:3]: # add getPost requests for 1st three posts in the list
reload(ammo.getPost, id=post['id'])
ammo:
getPost:
Expand Down
2 changes: 1 addition & 1 deletion bombard/mock_globals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
If you use include files for scripts add into them
from bombard.mock_globals import *; mock(<your yaml>)
from bombard.mock_globals import *; master(<your yaml>)
That defines globals so you have valid code and code autocomplete in your IDE editor.
All strings with `bombard.examples.mock_globals` will be automatically removed before running bombard scripts.
Expand Down
146 changes: 146 additions & 0 deletions docs/campaign.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
Campaign file
=============
All sections are optional.

But you need section ``prepare`` or ``ammo`` so Bombard will
fire some requests.

supply
------

Variables you use like ``{name}`` in your requests.
Also you can (re)define this variable using ``--supply`` like::

bombard -s name=value,name2=value2

Also you can (re)define it from requests.

If you have ``extract`` section in a request description, it will
(re)define ``supply`` variable with the name from this section.

And ``script`` section in request also can (re)define variables.

Request description
-------------------

You use this descriptions in sections ``prepare`` and ``ammo``
described below.

Each request should have ``URL`` and basically that's it.
If you need to, you can add other elements like that:

.. code-block:: yaml
getToken: # Name of request by your choice
url: "{base}auth" # we use supply.base var
method: POST # by default GET
body: # JSON object for the request body
email: admin@example.com
password: admin
extract: # extract from request result and add to supply
token:
script
______

In request you can add section ``script`` with Python3 code.
It runs after request.

It can use ``supply`` object and fire requests with ``reload`` function.
Requests definitions from ``ammo`` section available as ``ammo.request_name``.

Response to the request is available in ``resp`` object.

In example below we fire requests ``getPost`` from ``ammo`` section for
1st three posts we get in the response:

.. code-block:: python
for post in resp[:3]:
reload(ammo.getPost, id=post['id'])
Also you can place Python code to separate file and use it like this:

.. code-block:: yaml
script: !include get_token.py
If you add this line it mocks all necessary objects and
you can use code autocomplete in your IDE:

.. code-block:: python
from bombard.mock_globals import *; master('path/to/you/yaml')
extract
_______

Instead of script you can use section ``extract`` in request.
It can contain map of ``name: extract`` pairs. For each pair
Bombard will (re)define ``supply`` var with name ``name`` with
value extracted from the request response as ``['extract']``.

.. code-block:: yaml
extract:
name: extract
name2: extract2
If ``extract`` is empty Bombard will use the ``name``, so
``name:`` is the same as ``name: name``.

Also you can use any custom indices you want like that

.. code-block:: yaml
extract:
token: "['data']['JWT']" # place resp['data']['JWT'] to supply.token
so ``name: ['name']`` is the same as ``name:``.

prepare
-------

If campaign file has this section, Bombard will fire only requests from
this section.

Each request will be repeated ``--repeat`` times as defined in command line
(or by default value for this option).

And scripts in this section are responsible to fire scripts from ``ammo``
section, like this

.. code-block:: yaml
prepare:
postsList: # Get ids from posts
url: "{host}posts"
script: |
for post in resp[:3]: # fire ammo.getPost for 1st three posts in the list
reload(ammo.getPost, id=post['id'])
As you see above you can send some variable not only to global ``supply``
but just to the request you fire.

ammo
----

If campaign file do not have ``prepare`` section, Bombard will fire all requests
from this section.

Each request will be repeated ``--repeat`` times as defined in command line
(or by default value for this option).

Otherwise this requests should be fired from requests from ``prepare`` section
as described above.

Example of ``ammo`` request for the request that you see in ``prepare``
section:

.. code-block:: yaml
ammo:
getPost:
url: "{host}posts/{id}" # use {host} from global supply and {id} in local supply just for this request - see script above
3 changes: 3 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,6 @@

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/': None}

#html_show_sourcelink = True
#html_sidebars = { '**': ['globaltoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'] }
105 changes: 61 additions & 44 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,55 +1,77 @@
bombard your API
================
bombard
=======

Introduction
------------

Bombard is a pure Python application to bombard with
hundreds of HTTP-requests.
Bombard is a tool for stress test and benchmarking your HTTP server.
Especially it's good to simulate a heavy load and initial burst of
simultaneous HTTP requests with complex logic.

This is a tool for stress-testing with extremely simple
configuration.
It is designed to be extremely simple yet powerful tool to
load test functional behavior.

You write requests in simple yaml-file (``bombard campaign book``).
And you can use a couple of Python lines in it.
Thanks to optional Python inlines you can fast and easy describe
complex logic for the tests.

If you need more logic you can include external Python file and debug
it in your IDE.
Test report shows you how many requests per second your server
is capable of serving and with what latency.

The simplest (but not very useful) example
Requests description
--------------------

Requests can be just URL or contain JSON described like this

.. code-block:: yaml
ammo:
postsList:
url: "https://jsonplaceholder.typicode.com/posts"
getToken:
url: "{base}auth" # use custom {base} variable to stay DRY
method: POST
body: # below is JSON object for request body
email: name@example.com
password: admin
extract: # get token for next requests
token:
In first request you can get security token as in example above.

More complex example
And use it in next requests:

.. code-block:: yaml
supply: # you can redefine it from command line (--supply)
host: https://jsonplaceholder.typicode.com/
prepare:
postsList:
url: "{host}posts"
script: |
for post in resp[:3]: # add getPost requests for 1st ten posts in the list
reload(ammo.getPost, id=post['id'])
ammo:
getPost:
url: "{host}posts/{id}"
headers: json
Example above is included into bombard internal examples that you can use with
option ``--example`` like that::
url: "{host}posts"
headers:
Authorization: "Bearer {token}" # we get {token} in 1st request
script: |
for post in resp[:3]: # for 1st three posts from response
# schedule getPost request (from ammo section)
# and provide it with id we got from the response
reload(ammo.getPost, id=post['id'])
bombard --example simple --repeat 2 --threshold 100
Included examples. To list examples

.. code-block:: bash
bombard --examples
Command line
------------

From command line you can change number of threads, loop count,
supply vars, customize report and so on.

Above we also set repetition number to 2 and threshold to 100ms
so anything equal and above that will be in red.
Also you can bootstrap your own ``bombard.yaml`` file from any example you
like::

You will get something like this:
bombard --init --example simple

Report
------

Example of report for the command::

bombard --example simple --repeat 2 --threshold 100

.. image:: _static/simple_stdout.png

Expand All @@ -59,17 +81,12 @@ Source code
`GitHub <https://github.com/masterandrey/bombard/>`_.


.. toctree::
:maxdepth: 2
:caption: Contents:

quickstart.rst

Documentation
-------------

.. toctree::

Indices and tables
==================
quickstart
campaign
report

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
4 changes: 2 additions & 2 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ If you want to use specific Python version you can use something like that
python3.7 -m pip install bombard --upgrade
Quick start
-----------
Bootstrapping
-------------

To create template yaml file you place your requests in use command ``--init``.
By default it copy example ``easy.yaml`` into the current folder, with the name
Expand Down
13 changes: 13 additions & 0 deletions docs/report.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Customizing report
==================

To color in red request that take longer than 100ms

.. code-block:: bash
bombard --threshold
You can reduce output to console with ``--quiet`` or output all the
information with ``--verbose``.

There are a number of other options please look at ``--help``.

0 comments on commit 3cca408

Please sign in to comment.