mirror of
https://github.com/valitydev/yandex-tank.git
synced 2024-11-06 10:25:17 +00:00
fix line load plan. Support descending linear load (Issue #22)
This commit is contained in:
parent
e12282252e
commit
835e71a1a9
@ -1,9 +1,8 @@
|
|||||||
'''
|
'''
|
||||||
Load Plan generators
|
Load Plan generators
|
||||||
'''
|
'''
|
||||||
import math
|
|
||||||
import re
|
import re
|
||||||
from util import parse_duration
|
from util import parse_duration, solve_quadratic
|
||||||
from itertools import chain, groupby
|
from itertools import chain, groupby
|
||||||
import info
|
import info
|
||||||
|
|
||||||
@ -48,33 +47,18 @@ class Line(object):
|
|||||||
'''Load plan with linear load'''
|
'''Load plan with linear load'''
|
||||||
|
|
||||||
def __init__(self, minrps, maxrps, duration):
|
def __init__(self, minrps, maxrps, duration):
|
||||||
# FIXME: does not work for negative k (minrps > maxrps)
|
|
||||||
if minrps > maxrps:
|
|
||||||
raise NotImplementedError(
|
|
||||||
"We have no support for descending linear load yet")
|
|
||||||
self.minrps = float(minrps)
|
self.minrps = float(minrps)
|
||||||
self.maxrps = float(maxrps)
|
self.maxrps = float(maxrps)
|
||||||
self.duration = duration / 1000.0
|
self.duration = duration / 1000.0
|
||||||
|
self.b = self.minrps
|
||||||
self.k = (self.maxrps - self.minrps) / self.duration
|
self.k = (self.maxrps - self.minrps) / self.duration
|
||||||
self.b = 1 + 2 * self.minrps / self.k
|
|
||||||
|
|
||||||
|
def ts(self, n):
|
||||||
|
root1, root2 = solve_quadratic(self.k / 2.0, self.b, -n)
|
||||||
|
return int(root2 * 1000)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
k = self.k
|
return (self.ts(n) for n in xrange(0, self.__len__()))
|
||||||
b = self.b
|
|
||||||
|
|
||||||
'''
|
|
||||||
Solve equation:
|
|
||||||
n(t) = k/2 * t^2 + (k/2 + r0) * t
|
|
||||||
where r(t) = k(t + 1/2) + r0 -- rps
|
|
||||||
r0 is initial rps.
|
|
||||||
'''
|
|
||||||
def timestamp(n):
|
|
||||||
return int((math.sqrt(b ** 2 + 8 * n / k) - b) / 2 * 1000) # (sqrt(b^2 + 8 * n / k) - b) / 2 -- time in seconds
|
|
||||||
|
|
||||||
''' Find ammo count given the time '''
|
|
||||||
def number(t):
|
|
||||||
return int(k * (t ** 2) / 2 + (k / 2 + self.minrps) * self.duration)
|
|
||||||
return (timestamp(n) for n in xrange(0, self.__len__()))
|
|
||||||
|
|
||||||
def rps_at(self, t):
|
def rps_at(self, t):
|
||||||
'''Return rps for second t'''
|
'''Return rps for second t'''
|
||||||
@ -89,7 +73,7 @@ class Line(object):
|
|||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
'''Return total ammo count'''
|
'''Return total ammo count'''
|
||||||
return int(self.k * (self.duration ** 2) / 2 + (self.k / 2 + self.minrps) * self.duration)
|
return int(self.k / 2.0 * (self.duration ** 2) + self.b * self.duration)
|
||||||
|
|
||||||
def get_float_rps_list(self):
|
def get_float_rps_list(self):
|
||||||
'''
|
'''
|
||||||
@ -97,7 +81,7 @@ class Line(object):
|
|||||||
with parts durations (float)
|
with parts durations (float)
|
||||||
'''
|
'''
|
||||||
int_rps = xrange(int(self.minrps), int(self.maxrps) + 1)
|
int_rps = xrange(int(self.minrps), int(self.maxrps) + 1)
|
||||||
step_duration = float(self.duration * 1000) / len(int_rps)
|
step_duration = float(self.duration) / len(int_rps)
|
||||||
return [(rps, int(step_duration)) for rps in int_rps]
|
return [(rps, int(step_duration)) for rps in int_rps]
|
||||||
|
|
||||||
def get_rps_list(self):
|
def get_rps_list(self):
|
||||||
@ -193,10 +177,13 @@ def create(rps_schedule):
|
|||||||
>>> from util import take
|
>>> from util import take
|
||||||
|
|
||||||
>>> take(100, create(['line(1, 5, 2s)']))
|
>>> take(100, create(['line(1, 5, 2s)']))
|
||||||
[0, 414, 732, 1000, 1236, 1449, 1645, 1828]
|
[0, 618, 1000, 1302, 1561, 1791]
|
||||||
|
|
||||||
>>> take(100, create(['line(1.1, 5.8, 2s)']))
|
>>> take(100, create(['line(1.1, 5.8, 2s)']))
|
||||||
[0, 369, 656, 900, 1115, 1310, 1490, 1657, 1815]
|
[0, 566, 917, 1196, 1435, 1647]
|
||||||
|
|
||||||
|
>>> take(100, create(['line(5, 1, 2s)']))
|
||||||
|
[0, 208, 438, 697, 1000, 1381]
|
||||||
|
|
||||||
>>> take(100, create(['const(1, 10s)']))
|
>>> take(100, create(['const(1, 10s)']))
|
||||||
[0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000]
|
[0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000]
|
||||||
|
@ -4,6 +4,7 @@ Utilities: parsers, converters, etc.
|
|||||||
import re
|
import re
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
from module_exceptions import StepperConfigurationError
|
from module_exceptions import StepperConfigurationError
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
def take(number, iter):
|
def take(number, iter):
|
||||||
@ -41,3 +42,13 @@ def parse_duration(duration):
|
|||||||
return int(float(time) * 1000)
|
return int(float(time) * 1000)
|
||||||
|
|
||||||
return sum(parse_token(*token) for token in _re_token.findall(duration))
|
return sum(parse_token(*token) for token in _re_token.findall(duration))
|
||||||
|
|
||||||
|
def solve_quadratic(a, b, c):
|
||||||
|
'''
|
||||||
|
>>> solve_quadratic(1.0, 2.0, 1.0)
|
||||||
|
(-1.0, -1.0)
|
||||||
|
'''
|
||||||
|
discRoot = math.sqrt((b * b) - 4 * a * c)
|
||||||
|
root1 = (-b - discRoot) / (2 * a)
|
||||||
|
root2 = (-b + discRoot) / (2 * a)
|
||||||
|
return (root1, root2)
|
||||||
|
Loading…
Reference in New Issue
Block a user