Merge branch 'master' of github.com:yandex/yandex-tank into new-aggregator

This commit is contained in:
Alexey Lavrenuke 2015-12-08 15:46:35 +03:00
commit 1ae108a272
7 changed files with 130 additions and 22 deletions

8
debian/changelog vendored
View File

@ -1,3 +1,11 @@
yandextank (1.7.23) trusty; urgency=medium
* update pandora plugin
* ssh timeout setting
-- Alexey Lavrenuke (load testing) <direvius@yandex-team.ru> Mon, 7 Dec 2015 17:34:37 +0400
yandextank (1.7.22) trusty; urgency=medium
* log monitoring Auth errors and don't die

View File

@ -311,7 +311,7 @@ BFG is a generic gun that is able to use different kinds of cannons to shoot. To
; Disable phantom:
plugin_phantom=
; Enable BFG instead:
plugin_bfg=Tank/Plugins/BFG.py
plugin_bfg=yandextank.plugins.bfg
; BFG config section:
[bfg]
@ -332,6 +332,35 @@ BFG is a generic gun that is able to use different kinds of cannons to shoot. To
[sql_gun]
db = mysql://user:user@localhost/
Or if you want i.e to call your own module's MyService function shoot:
::
[tank]
; Disable phantom:
plugin_phantom=
; Enable BFG instead:
plugin_bfg=yandextank.plugins.bfg
[bfg]
; process' amount
instances = 10
; threads per process
threads = 40
; ammo file
ammofile=req_json.log
; gun type
gun_type = custom
; ammo type (one line -- one request)
ammo_type = line
; load schedule
rps_schedule=line(1,100,10m)
[custom_gun]
; path to your custom module
module_path = ./my_own_service
; module name (has to provide function shoot)
module_name = MyService
BFG Options
'''''''''''
@ -347,10 +376,17 @@ INI file section: **[sql_gun]**
* **db** - DB uri in format: ``dialect+driver://user:password@host/dbname[?key=value..]``, where dialect is a database name such as mysql, oracle, postgresql, etc., and driver the name of a DBAPI, such as psycopg2, pyodbc, cx_oracle, etc. `details <http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html#database-urls>`_
Custom Gun Options
''''''''''''''''''
INI file section: **[custom_gun]**
* **module_path** - path to your module
* **module_name** - module name, has to provide function shoot, which will be called by bfg's threads to fullfill rps_schedule
Pandora
^^^^^^^
Pandora is a load generator written in Go. For now it supports only SPDY/3, plugins for other protocols
(HTTP/2, HTTP, Websocker, XMPP maybe) are on the way.
`Pandora <https://github.com/yandex/pandora>`_ is a load generator written in Go. For now it supports only SPDY/3 and HTTP(S). Plugins for other protocols
(HTTP/2, Websocket, XMPP) are on the way.
First of all you'll need to obtain a binary of pandora and place it somewhere on your machine.
By default, Yandex.Tank will try to just run ``pandora`` (or you could specify a path to binary in ``pandora_cmd``).
@ -379,6 +415,10 @@ Disable phantom first, enable Pandora plugin and then specify the parameters.
; users are started using this schedule
startup_schedule = periodic(1, 1, 100)
; if shared_schedule is false, then each user is independent,
; in other case they all hold to a common schedule
shared_schedule = 0
; target host and port
target=localhost:3000
@ -398,7 +438,7 @@ Each json doc describes an HTTP request. Some of them may have a tag field, it w
Schedules
'''''''''
Only one schedule type is supported now: a ``periodic`` schedule. It is defined as ``periodic(<batch_size>, <period>, <limit>)``.
The first schedule type is ``periodic`` schedule. It is defined as ``periodic(<batch_size>, <period>, <limit>)``.
Pandora will issue one batch of size ``batch_size``, once in ``period`` seconds, maximum of ``limit`` ticks. Those ticks may be
used in different places, for example as a limiter for user startups or as a limiter for each user request rate.
@ -407,10 +447,35 @@ Example:
startup_schedule = periodic(2, 0.1, 100)
user_schedule = periodic(10, 15, 100)
shared_schedule = 0
Start 2 users every 0.1 seconds, maximum of 100 users. Each user will issue requests in batches of 10 requests, every 15 seconds, maximum
of 100 requests. All users will read from one ammo source.
Second schedule type is ``linear``. It is defined like this: ``linear(<start_rps>, <end_rps>, <time>). Example:
::
user_schedule = linear(.1, 10, 10m)
shared_schedule = 1
The load will raise from .1 RPS (1 request in 10 seconds) until 10 RPS during 10 minutes. Since
``shared_schedule`` is 1, this defines the overall load.
The last schedule type is ``unlimited``. It has no parameters and users will shoot as soon
as possible. It is convenient to use this type of load to find out maximum performance of a
service and its level of parallelism. You should limit the loop number if you want the test
to stop eventually. Example:
::
loop = 1000000
startup_schedule = periodic(2, 10, 50)
user_schedule = unlimited
shared_schedule = 0
Start 2 users every 10 seconds. Every user will shoot without any limits (next request is sended
as soon as the previous response have been received). This is analogous to phantom's instances
schedule mode.
Auto-stop
^^^^^^^^^

View File

@ -118,12 +118,13 @@ Create a file with declared requests: **ammo.txt**
/?drg tag1
/
/buy tag2
[Cookies: test]
/buy/?rt=0&station_to=7&station_from=9
File begins with optional lines [...], that contain headers which will
be added to every request. After that section there is a list of URIs.
Every URI must begin from a new line, with leading '/'.
Each line that begins from '[' is considered a header.
File consist of list of URIs and headers to be added to every request defined below.
Every URI must begin from a new line, with leading ``/``.
Each line that begins from ``[`` is considered as a header.
Headers could be (re)defined in the middle of URIs, as in sample above. I.e request ``/buy/?rt=0&station_to=7&station_from=9`` will be sent with ``Cookies: test``, not ``Cookies: None``.
Request may be marked by tag, you can specify it with whitespace following URI.
URI+POST-style

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name='yandextank',
version='1.7.22',
version='1.7.23',
description='a performance measurement tool',
longer_description='''
Yandex.Tank is a performance measurement and load testing automatization tool.

View File

@ -1,21 +1,42 @@
''' Pandora config generator '''
import json
from pkg_resources import resource_string
from yandextank.stepper.util import parse_duration
def periodic_schedule(batch_size, period, limit):
return {
"LimiterType": "periodic",
"Parameters": {
"BatchSize": batch_size,
"MaxCount": limit,
"Period": period,
},
}
return {
"LimiterType": "periodic",
"Parameters": {
"BatchSize": float(batch_size),
"MaxCount": float(limit),
"Period": float(period),
},
}
def linear_schedule(start_rps, end_rps, period):
return {
"LimiterType": "linear",
"Parameters": {
"StartRps": float(start_rps),
"EndRps": float(end_rps),
"Period": parse_duration(period) / 1000.0,
},
}
def unlimited_schedule(*args):
return {
"LimiterType": "unlimited",
"Parameters": {},
}
step_producers = {
"periodic": periodic_schedule,
"linear": linear_schedule,
"unlimited": unlimited_schedule,
}
@ -26,7 +47,7 @@ def parse_schedule(schedule):
if len(steps) > 1:
raise NotImplementedError("Composite schedules not implemented yet")
schedule_type, params = steps[0].split('(')
params = [float(p.strip()) for p in params.split(',')]
params = [p.strip() for p in params.split(',')]
if schedule_type in step_producers:
return step_producers[schedule_type](*params)
else:
@ -59,7 +80,7 @@ class PoolConfig(object):
self.config["AmmoProvider"]["AmmoSource"] = ammo
def set_loop(self, loop):
self.config["AmmoProvider"]["Loop"] = loop
self.config["AmmoProvider"]["Passes"] = loop
def set_sample_log(self, sample_log):
self.config["ResultListener"]["Destination"] = sample_log
@ -70,9 +91,15 @@ class PoolConfig(object):
def set_user_schedule(self, user_schedule):
self.config["UserLimiter"] = user_schedule
def set_shared_schedule(self, shared_schedule):
self.config["SharedSchedule"] = shared_schedule
def set_target(self, target):
self.config["Gun"]["Parameters"]["Target"] = target
def set_ssl(self, ssl):
self.config["Gun"]["Parameters"]["SSL"] = ssl
def set_gun_type(self, gun_type):
self.config["Gun"]["Type"] = gun_type

View File

@ -1,13 +1,13 @@
{
"Name": "Pool#0",
"Gun": {
"GunType": "spdy",
"GunType": "http",
"Parameters": {
"Target": "localhost:3000"
}
},
"AmmoProvider": {
"AmmoType": "jsonline/spdy",
"AmmoType": "jsonline/http",
"AmmoSource": "./ammo.jsonline",
"Loop": 0
},

View File

@ -72,10 +72,17 @@ class PandoraPlugin(AbstractPlugin):
raise RuntimeError(
"user_schedule not specified")
shared_schedule = bool(int(self.get_option("shared_schedule", "1")))
pool_config.set_shared_schedule(shared_schedule)
target = self.get_option("target", "localhost:3000")
pool_config.set_target(target)
gun_type = self.get_option("gun_type", "spdy")
gun_type = self.get_option("gun_type", "http")
if gun_type is 'https':
pool_config.set_ssl(True)
self.log.info("SSL is on")
gun_type = "http"
self.log.info("Pandora gun type is: %s", gun_type)
pool_config.set_gun_type(gun_type)