Skip to content

Commit

Permalink
Added locust integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Chudnovets committed Jul 11, 2014
1 parent 54adec7 commit 0a8d785
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 93 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
to run master:
To run benchmark:

locust -f magnetodb.py -H http://192.168.56.101:8480 --master -n 1000
sudo python benchmark_runner.py /path/to/benchmark_runner.cfg /path/to/locust_file.py

to run slave:
Example:
sudo python benchmark_runner.py /home/alex/benchmark_runner.cfg /home/alex/locust/test_query.py

locust -f magnetodb.py -H http://192.168.56.101:8480 --no-web --slave
FIXME:
locust should be installed as package. I used venv in this script.
4 changes: 0 additions & 4 deletions bench_runner.cfg

This file was deleted.

16 changes: 16 additions & 0 deletions benchmark_runner.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[global]
base_dir=/home/alex
result_dir_prefix=test

[locust]
host_to_test=http://192.168.56.101:8480
requests_count=1000
master_ip=192.168.56.102
master_port=5557
worker_ips=192.168.56.102,192.168.56.102
master_user=alex
master_password=password

[192.168.56.102]
user=alex
password=password
76 changes: 60 additions & 16 deletions benchmark_runner.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import datetime
import ConfigParser
import os
import re
import subprocess
import sys
import uuid

from fabric.operations import run, sudo, put
from fabric.context_managers import settings, prefix, cd


def change_rrd_dir(conf, rrd_dir):
Expand Down Expand Up @@ -40,12 +46,44 @@ def set_collectd_conf(conf, conf_path='/etc/collectd/collectd.conf'):
open(conf_path, 'w').write(conf)


def start_load():
# Run loading tool here
# Simulate test run for now
import time
import random
time.sleep(random.randrange(60, 180))
def start_load(cfg, locust_file):
host = cfg.get('locust', 'host_to_test')
requests_count = cfg.get('locust', 'requests_count')
master_ip = cfg.get('locust', 'master_ip')
master_port = cfg.get('locust', 'master_port')
master_user = cfg.get('locust', 'master_user')
master_password = cfg.get('locust', 'master_password')

worker_ips = cfg.get('locust', 'worker_ips')
if not worker_ips:
# TODO: shutdown all
sys.exit(-1)

for slave_ip in worker_ips.split(','):
slave_user = cfg.get(slave_ip, 'user')
slave_password = cfg.get(slave_ip, 'password')
start_locust_slave(slave_ip, slave_user, slave_password, locust_file, host, master_ip, master_port)

start_locust_master(master_ip, master_port, master_user, master_password, locust_file, host, requests_count)


def runbg(cmd, sockname="dtach"):
return run('dtach -n `mktemp -u /tmp/%s.XXXX` %s' % (sockname, cmd))

def start_locust_master(master_ip, master_port, master_user, master_password, locust_file, host, requests_count):
with (settings(host_string=master_ip, user=master_user, password=master_password)):
with cd('locust'), prefix('source .venv/bin/activate'):
cmd = 'locust -f %s -H %s --master -n %s --master-bind-host=%s --master-bind-port=%s'
run(cmd % (locust_file, host, requests_count, master_ip, master_port))


def start_locust_slave(slave_ip, slave_user, slave_password, locust_file, host, master_ip, master_port):
with (settings(host_string=slave_ip, user=slave_user, password=slave_password)):
with cd('locust'), prefix('source .venv/bin/activate'):
cmd = 'locust -f %s -H %s --no-web --slave --master-host=%s --master-port=%s'
slave_locust_file = '/tmp/%s.py' % uuid.uuid4()
put(locust_file, slave_locust_file)
runbg(cmd % (slave_locust_file, host, master_ip, master_port))


def get_timestamp_str(timestamp=None):
Expand All @@ -59,10 +97,19 @@ def store_results(results_dir):
os.rename(results_dir, '%s_%s' % (results_dir,
get_timestamp_str()))

def run_bench(results_dir):

def main(cfg_file, locust_file):
cfg = ConfigParser.ConfigParser()
cfg.read(cfg_file)

base_dir =cfg.get('global', 'base_dir')
prefix = cfg.get('global', 'result_dir_prefix')
dir_name = '%s_%s' % (prefix, get_timestamp_str())
results_dir = os.path.join(base_dir, dir_name)

print ("Setup monitioring...")
stop_monitoring()

rrd_dir = os.path.join(results_dir, 'rrd')
os.makedirs(rrd_dir)
conf = get_collectd_conf()
Expand All @@ -71,19 +118,16 @@ def run_bench(results_dir):
start_monitoring()

print ("Start loading...")
start_load()
start_load(cfg, locust_file)

print ("Saving results...")
store_results(results_dir)

print ("Done.")


def main():
base_dir = '/home/alex'
dir_name = 'test_%s' % get_timestamp_str()
run_bench(os.path.join(base_dir, dir_name))


if __name__ == '__main__':
main()
if len(sys.argv) < 3:
print "Usage: %s /path/to/config.cfg /path/to/locust_file.py" % sys.argv[0]
sys.exit(-1)
main(sys.argv[1], sys.argv[2])
57 changes: 0 additions & 57 deletions magnetodb.py

This file was deleted.

12 changes: 0 additions & 12 deletions query.json

This file was deleted.

62 changes: 62 additions & 0 deletions token → tests/test_query.py
Original file line number Diff line number Diff line change
@@ -1 +1,63 @@
import locust


IS_FIRST_RUN = True
SLAVE_COUNT = 2
LOCUST_COUNT = 100
HATCH_RATE = 10

QUERY_RQ = """
{
"key_conditions": {
"ForumName": {
"attribute_value_list": [
{
"S": "MagnetoDB"
}
],
"comparison_operator": "EQ"
}
}
}
"""

TOKEN = """
MIIIAQYJKoZIhvcNAQcCoIIH8jCCB+4CAQExCTAHBgUrDgMCGjCCBlcGCSqGSIb3DQEHAaCCBkgEggZEeyJ0b2tlbiI6IHsibWV0aG9kcyI6IFsicGFzc3dvcmQiXSwgInJvbGVzIjogW3siaWQiOiAiYWVlNzBhM2ZlY2QyNGViZGFiZGZiN2NlZjNjNGNjNTEiLCAibmFtZSI6ICJNZW1iZXIifV0sICJleHBpcmVzX2F0IjogIjIwMTQtMDctMThUMTg6Mjg6MjYuMDcxMzc0WiIsICJwcm9qZWN0IjogeyJkb21haW4iOiB7ImlkIjogIjE0MDI2OGUxZjgzMzRkYmU4ZDc2OTM3MjcxYWIxMWEyIiwgIm5hbWUiOiAiZG9tYWluMSJ9LCAiaWQiOiAiZTg1MmI1YmE1MDc0NDBmZDk5ZWVlNzU1OTNiM2EzNWYiLCAibmFtZSI6ICJwcm9qZWN0MSJ9LCAiY2F0YWxvZyI6IFt7ImVuZHBvaW50cyI6IFt7InVybCI6ICJodHRwOi8vMTkyLjE2OC41Ni4xMDE6ODQ4MC92MS9lODUyYjViYTUwNzQ0MGZkOTllZWU3NTU5M2IzYTM1ZiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVyZmFjZSI6ICJhZG1pbiIsICJpZCI6ICIxODYxYTFkYjk5ZWQ0NzZlODg5YzE1Y2IzYmNmMjBhYyJ9LCB7InVybCI6ICJodHRwOi8vMTkyLjE2OC41Ni4xMDE6ODQ4MC92MS9lODUyYjViYTUwNzQ0MGZkOTllZWU3NTU5M2IzYTM1ZiIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVyZmFjZSI6ICJwdWJsaWMiLCAiaWQiOiAiM2FiZjlkMGQzNzI2NGU5Mjg1NDU4MjFlZDU0NzIxOWUifSwgeyJ1cmwiOiAiaHR0cDovLzE5Mi4xNjguNTYuMTAxOjg0ODAvdjEvZTg1MmI1YmE1MDc0NDBmZDk5ZWVlNzU1OTNiM2EzNWYiLCAicmVnaW9uIjogIlJlZ2lvbk9uZSIsICJpbnRlcmZhY2UiOiAiaW50ZXJuYWwiLCAiaWQiOiAiNTU0MDJjYTgwNmU3NGM2MDg2ZjIyYjFlMDZlMmZhODkifV0sICJ0eXBlIjogImt2LXN0b3JhZ2UiLCAiaWQiOiAiZTlmMmMzOWIxMDI5NDUwZWI4Y2RiZDZlZTZkMzk0ZjMiLCAibmFtZSI6ICJtYWduZXRvZGIifSwgeyJlbmRwb2ludHMiOiBbeyJ1cmwiOiAiaHR0cDovLzE5Mi4xNjguNTYuMTAxOjM1MzU3L3YyLjAiLCAicmVnaW9uIjogIlJlZ2lvbk9uZSIsICJpbnRlcmZhY2UiOiAiYWRtaW4iLCAiaWQiOiAiMTRmYzAyNTY2YjQwNGFjNGI0YTc5OTk5MTlkNDZiYjcifSwgeyJ1cmwiOiAiaHR0cDovLzE5Mi4xNjguNTYuMTAxOjUwMDAvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVyZmFjZSI6ICJpbnRlcm5hbCIsICJpZCI6ICIyMDEyMTdiMjJlMGY0NDc3OTg5ZTQ5Mzc1YzQzZTkxZSJ9LCB7InVybCI6ICJodHRwOi8vMTkyLjE2OC41Ni4xMDE6NTAwMC92Mi4wIiwgInJlZ2lvbiI6ICJSZWdpb25PbmUiLCAiaW50ZXJmYWNlIjogInB1YmxpYyIsICJpZCI6ICI1NGEwMTdkZGQxZjg0ODQ2YjNmN2FkNzhmYjM4ZTI5YiJ9XSwgInR5cGUiOiAiaWRlbnRpdHkiLCAiaWQiOiAiZjlmOWY4NTEzMzkzNDllYWIxZGY4OGFkMTA4OTAzOWIiLCAibmFtZSI6ICJrZXlzdG9uZSJ9XSwgImV4dHJhcyI6IHt9LCAidXNlciI6IHsiZG9tYWluIjogeyJpZCI6ICIxNDAyNjhlMWY4MzM0ZGJlOGQ3NjkzNzI3MWFiMTFhMiIsICJuYW1lIjogImRvbWFpbjEifSwgImlkIjogImExMTMxMzA5Y2Y4MjRhMjY5MDIyNDExNmZlMjM2MjY1IiwgIm5hbWUiOiAidXNlcjEifSwgImlzc3VlZF9hdCI6ICIyMDE0LTA2LTE4VDE4OjI4OjI2LjA3MTQzMVoifX0xggGBMIIBfQIBATBcMFcxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVVbnNldDEOMAwGA1UEBwwFVW5zZXQxDjAMBgNVBAoMBVVuc2V0MRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20CAQEwBwYFKw4DAhowDQYJKoZIhvcNAQEBBQAEggEAhzdBEX+wTCNO0IXVtOkVoDjuk-TGZbq17s12WxczFg8pUIIwa+5jaXeIw9s6cfacP5tSs+7rghZz+ClXEsI8SIVrLroPJsp5uQMQmmHYKZhLbBnUL2xnhibaD8zTlzCn7ExXnP0lBQ5zMS78Z1tGwodj29DQfLGxsbzwYlk4yrdLT-vcRWpclpiQDCwV8ABBT4ME4jv7qWYSS229DNHAYui2Aponbln8Pe785XYOC01VipLW-BOAyZik1zdeVfuU2IIZjylLCgVibAY1-bnfFT6J0acGmeol+vbT1F+T1yPHLfHPmUUcx0dyJ8vcDktlM0CaJpPqNWGFQvxUtGOY6Q==
"""


class UserBehavior(locust.TaskSet):
@locust.task
def query(self):
req_url = ('/v1/e852b5ba507440fd99eee75593b3a35f'
'/data/tables/Thread/query')
req_headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Auth-Token': TOKEN.strip()
}
self.client.post(req_url, QUERY_RQ.strip(), headers=req_headers)


class MagnetoDBUser(locust.HttpLocust):
task_set = UserBehavior
min_wait = 5000
max_wait = 9000


# Master code
def on_slave_report(client_id, data):
global IS_FIRST_RUN
runner = locust.runners.locust_runner

if IS_FIRST_RUN and runner.slave_count == SLAVE_COUNT:
runner.start_hatching(LOCUST_COUNT, HATCH_RATE)
IS_FIRST_RUN = False

num_rq = sum([val.num_requests for val in
runner.request_stats.itervalues()])
if runner.num_requests and num_rq >= runner.num_requests:
raise KeyboardInterrupt()


locust.events.slave_report += on_slave_report

0 comments on commit 0a8d785

Please sign in to comment.