Skip to content

Commit

Permalink
eval strings
Browse files Browse the repository at this point in the history
  • Loading branch information
andgineer committed Apr 23, 2019
1 parent a5a277c commit 8224284
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 19 deletions.
2 changes: 1 addition & 1 deletion bombard/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '1.13.1'
__version__ = '1.14.1'


def version():
Expand Down
46 changes: 29 additions & 17 deletions bombard/bombardier.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,25 @@
AMMO = 'ammo'


def apply_supply(request: dict, supply: dict) -> dict:
def apply_supply(s: str, supply: dict) -> str:
if not isinstance(s, str):
return s
try:
return eval('f"""' + s + '"""', supply)
except Exception as e:
log.error(f'Cannot eval "{s}":\n{e}', exc_info=True)
return s


def apply_supply_dict(request: dict, supply: dict) -> dict:
"""
Use supply to substitute all {name} in request strings.
"""
#todo: use eval with supply and args context
for name in request:
if isinstance(request[name], dict):
request[name] = apply_supply_dict(request[name], supply)
elif isinstance(request[name], str):
request[name] = apply_supply(request[name], supply)
if isinstance(request[name], str):
request[name] = request[name].format(**supply)
return request


Expand Down Expand Up @@ -161,7 +170,7 @@ def worker(self, thread_id, ammo):
request_logging.sending(thread_id, ammo_id, ammo_name)
pretty_url = '' # we use it in `except`
try:
ammo = apply_supply(ammo, dict(self.supply, **ammo['supply']))
ammo = apply_supply_dict(ammo, dict(self.supply, **ammo['supply']))

url = request.get('url', '')
method = request['method'] if 'method' in request else 'GET'
Expand Down Expand Up @@ -214,18 +223,21 @@ def reload(self, requests, repeat=None, prepare=False, **kwargs):
if repeat is None:
repeat = self.args.repeat
for request in requests:
for _ in range(repeat):
for __ in range(request.get('repeat', 1)):
self.job_count += 1
if self.job_count % self.args.threads == 0 \
or self.job_count < self.args.threads and self.job_count % 10 == 0:
# show each 10th response before queue is full and then each time it's full
self.show_response[self.job_count] = f'Got {self.job_count} responses...'
self.put({
'id': self.job_count,
'request': request,
'supply': kwargs
})
try:
_repeat = int(apply_supply(request['repeat'], self.supply))
except (ValueError, KeyError):
_repeat = repeat
for _ in range(_repeat):
self.job_count += 1
if self.job_count % self.args.threads == 0 \
or self.job_count < self.args.threads and self.job_count % 10 == 0:
# show each 10th response before queue is full and then each time it's full
self.show_response[self.job_count] = f'Got {self.job_count} responses...'
self.put({
'id': self.job_count,
'request': request,
'supply': kwargs
})

def report(self):
log.warning(
Expand Down
6 changes: 6 additions & 0 deletions bombard/examples/easy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,36 @@ supply: # you can redefine it from command line (--supply host=http://localhost
iters: 2
prepare: # Get ids from lists
postsList:
repeat: "{iters}"
url: "{host}posts"
headers: json
script: |
for post in resp[:supply.iters]:
reload(ammo.getPost, id=post['id'])
commentsList:
repeat: 1
url: "{host}comments"
headers: json
script: |
for comment in resp[:supply.iters]:
reload(ammo.getComment, id=comment['id'])
todosList:
repeat: "{iters}"
url: "{host}todos"
headers: json
script: |
for todo in resp[:supply.iters]:
reload(ammo.getTodo, id=todo['id'])
ammo: # Request resources by id we see in lists
getPost:
repeat: "{iters*2}"
url: "{host}posts/{id}"
headers: json
getComment:
repeat: "{iters*5}"
url: "{host}comments/{id}"
headers: json
getTodo:
repeat: "{iters*2}"
url: "{host}todos/{id}"
headers: json
6 changes: 6 additions & 0 deletions docs/campaign.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All sections are optional.
But you need section ``prepare`` or ``ammo`` so Bombard will
fire some requests.

Anywhere you can user Python substitution ``{}`` like

.. code-block:: python
repeat: {iters * 2}
HTTP parameters
---------------

Expand Down
2 changes: 1 addition & 1 deletion tests/test_supply.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

class TestHttpRequests(unittest.TestCase):
def testApplySupply(self):
self.assertEqual(bombardier.apply_supply(TEST_REQUEST_TEMPLATE, TEST_SUPPLY)['1']['2'], '4')
self.assertEqual(bombardier.apply_supply_dict(TEST_REQUEST_TEMPLATE, TEST_SUPPLY)['1']['2'], '4')


if __name__ == '__main__':
Expand Down

0 comments on commit 8224284

Please sign in to comment.