diff --git a/Tank/ConsoleWorker.py b/Tank/ConsoleWorker.py index 4be39a0..b6d33fb 100644 --- a/Tank/ConsoleWorker.py +++ b/Tank/ConsoleWorker.py @@ -2,7 +2,7 @@ Provides class to run TankCore from console environment ''' from Tank.Core import TankCore -from Tank import Utils +from Tank import Core import ConfigParser import fnmatch import logging @@ -81,6 +81,7 @@ class ConsoleTank: self.signal_count = 0 self.scheduled_start = None + self.lock_file = None def set_baseconfigs_dir(self, directory): ''' @@ -179,7 +180,7 @@ class ConsoleTank: info = ConfigParser.ConfigParser() info.read(full_name) pid = info.get(TankCore.SECTION, self.PID_OPTION) - if not Utils.pid_exists(int(pid)): + if not Core.pid_exists(int(pid)): self.log.debug("Lock PID %s not exists, ignoring and trying to remove", pid) try: os.remove(full_name) @@ -220,7 +221,8 @@ class ConsoleTank: else: self.log.warn("Lock files ignored. This is highly unrecommended practice!") - self.core.config.set_out_file(tempfile.mkstemp('.lock', 'lunapark_', self.LOCK_DIR)[1]) + self.lock_file = tempfile.mkstemp('.lock', 'lunapark_', self.LOCK_DIR)[1] + self.core.config.set_out_file(self.lock_file) configs = [] diff --git a/Tank/Core.py b/Tank/Core.py index e8d8a68..c1cc35c 100644 --- a/Tank/Core.py +++ b/Tank/Core.py @@ -3,14 +3,152 @@ The central part of the tool: Core ''' from ConfigParser import NoSectionError import ConfigParser +import datetime +import errno +import itertools import logging import os +import re +import select import shutil +import subprocess import sys import tempfile import time import traceback -import datetime + + +def log_stdout_stderr(log, stdout, stderr, comment=""): + ''' + This function polls stdout and stderr streams and writes their contents to log + ''' + readable = select.select([stdout], [], [] , 0)[0] + if stderr: + exceptional = select.select([stderr], [], [] , 0)[0] + else: + exceptional = [] + + log.debug("Selected: %s, %s", readable, exceptional) + + for handle in readable: + line = handle.read() + readable.remove(handle) + if line: + log.debug("%s stdout: %s", comment, line.strip()) + + for handle in exceptional: + line = handle.read() + exceptional.remove(handle) + if line: + log.warn("%s stderr: %s", comment, line.strip()) + + +def expand_to_milliseconds(str_time): + ''' + converts 1d2s into milliseconds + ''' + return expand_time(str_time, 'ms', 1000) + +def expand_to_seconds(str_time): + ''' + converts 1d2s into seconds + ''' + return expand_time(str_time, 's', 1) + +def expand_time(str_time, default_unit='s', multiplier=1): + ''' + helper for above functions + ''' + parser = re.compile('(\d+)([a-zA-Z]*)') + parts = parser.findall(str_time) + result = 0.0 + for value, unit in parts: + value = int(value) + unit = unit.lower() + if unit == '': + unit = default_unit + + if unit == 'ms': + result += value * 0.001 + continue + elif unit == 's': + result += value + continue + elif unit == 'm': + result += value * 60 + continue + elif unit == 'h': + result += value * 60 * 60 + continue + elif unit == 'd': + result += value * 60 * 60 * 24 + continue + elif unit == 'w': + result += value * 60 * 60 * 24 * 7 + continue + else: + raise ValueError("String contains unsupported unit %s: %s", unit, str_time) + return int(result * multiplier) + +def pid_exists(pid): + """Check whether pid exists in the current process table.""" + if pid < 0: + return False + try: + os.kill(pid, 0) + except OSError, exc: + return exc.errno == errno.EPERM + else: + return True + +def execute(cmd, shell=False, poll_period=1, catch_out=False): + ''' + Wrapper for Popen + ''' + log = logging.getLogger(__name__) + log.debug("Starting: %s", cmd) + + if catch_out: + process = subprocess.Popen(cmd, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + else: + process = subprocess.Popen(cmd, shell=shell) + + while process.poll() == None: + log.debug("Waiting for process to finish: %s", process) + time.sleep(poll_period) + + if catch_out: + for line in process.stderr.readlines(): + log.warn(line.strip()) + for line in process.stdout.readlines(): + log.debug(line.strip()) + + retcode = process.poll() + log.debug("Process exit code: %s", retcode) + return retcode + +def splitstring(string): + """ + >>> string = 'apple orange "banana tree" green' + >>> splitstring(string) + ['apple', 'orange', 'green', '"banana tree"'] + """ + patt = re.compile(r'"[\w ]+"') + if patt.search(string): + quoted_item = patt.search(string).group() + newstring = patt.sub('', string) + return newstring.split() + [quoted_item] + else: + return string.split() + + +def pairs(lst): + ''' + Iterate over pairs in the list + ''' + return itertools.izip(lst[::2], lst[1::2]) + + class TankCore: """ diff --git a/Tank/Plugins/Aggregator.py b/Tank/Plugins/Aggregator.py index f60963d..f630c68 100644 --- a/Tank/Plugins/Aggregator.py +++ b/Tank/Plugins/Aggregator.py @@ -1,4 +1,4 @@ -from Tank import Utils +from Tank import Core from Tank.Core import AbstractPlugin import copy import datetime @@ -31,12 +31,12 @@ class AggregatorPlugin(AbstractPlugin): self.preproc_out_filename = None self.cumulative_data = SecondAggregateDataTotalItem() self.reader = None - self.time_periods = [ Utils.expand_to_milliseconds(x) for x in self.default_time_periods.split(' ') ] + self.time_periods = [ Core.expand_to_milliseconds(x) for x in self.default_time_periods.split(' ') ] self.last_sample_time = 0 def configure(self): periods = self.get_option("time_periods", self.default_time_periods).split(" ") - self.time_periods = [ Utils.expand_to_milliseconds(x) for x in periods ] + self.time_periods = [ Core.expand_to_milliseconds(x) for x in periods ] self.core.set_option(self.SECTION, "time_periods", " ".join([ str(x) for x in periods ])) def start_test(self): diff --git a/Tank/Plugins/ApacheBenchmark.py b/Tank/Plugins/ApacheBenchmark.py index 8b015b8..cf8c3b1 100644 --- a/Tank/Plugins/ApacheBenchmark.py +++ b/Tank/Plugins/ApacheBenchmark.py @@ -1,4 +1,4 @@ -from Tank import Utils +from Tank import Core from Tank.Core import AbstractPlugin from Tank.Plugins.Aggregator import AggregatorPlugin, AbstractReader import os @@ -69,7 +69,7 @@ class ApacheBenchmarkPlugin(AbstractPlugin): return -1 if self.process: - Utils.log_stdout_stderr(self.log, self.process.stdout, self.process.stderr, self.SECTION) + Core.log_stdout_stderr(self.log, self.process.stdout, self.process.stderr, self.SECTION) def end_test(self, retcode): @@ -80,7 +80,7 @@ class ApacheBenchmarkPlugin(AbstractPlugin): self.log.info("Seems ab finished OK") if self.process: - Utils.log_stdout_stderr(self.log, self.process.stdout, self.process.stderr, self.SECTION) + Core.log_stdout_stderr(self.log, self.process.stdout, self.process.stderr, self.SECTION) return retcode diff --git a/Tank/Plugins/Autostop.py b/Tank/Plugins/Autostop.py index 131cc88..8920b39 100644 --- a/Tank/Plugins/Autostop.py +++ b/Tank/Plugins/Autostop.py @@ -1,4 +1,4 @@ -from Tank import Utils +from Tank import Core from Tank.Core import AbstractPlugin from Tank.Plugins.Aggregator import AggregatorPlugin, AggregateResultListener from Tank.Plugins.ConsoleOnline import AbstractInfoWidget, ConsoleOnlinePlugin @@ -150,8 +150,8 @@ class AvgTimeCriteria(AbstractCriteria): def __init__(self, autostop, param_str): AbstractCriteria.__init__(self) self.seconds_count = 0 - self.rt_limit = Utils.expand_to_milliseconds(param_str.split(',')[0]) - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[1]) + self.rt_limit = Core.expand_to_milliseconds(param_str.split(',')[0]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[1]) self.autostop = autostop def notify(self, aggregate_second): @@ -201,7 +201,7 @@ class HTTPCodesCriteria(AbstractCriteria): else: self.level = int(level_str) self.is_relative = False - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[2]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[2]) def notify(self, aggregate_second): @@ -266,7 +266,7 @@ class NetCodesCriteria(AbstractCriteria): else: self.level = int(level_str) self.is_relative = False - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[2]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[2]) def notify(self, aggregate_second): @@ -323,8 +323,8 @@ class QuantileCriteria(AbstractCriteria): AbstractCriteria.__init__(self) self.seconds_count = 0 self.quantile = float(param_str.split(',')[0]) - self.rt_limit = Utils.expand_to_milliseconds(param_str.split(',')[1]) - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[2]) + self.rt_limit = Core.expand_to_milliseconds(param_str.split(',')[1]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[2]) self.autostop = autostop def notify(self, aggregate_second): diff --git a/Tank/Plugins/JMeter.py b/Tank/Plugins/JMeter.py index 5f3b3c4..5e625e2 100644 --- a/Tank/Plugins/JMeter.py +++ b/Tank/Plugins/JMeter.py @@ -1,12 +1,12 @@ +from Tank import Core from Tank.Core import AbstractPlugin -import os -import subprocess -import signal -from Tank import Utils from Tank.Plugins.Aggregator import AbstractReader, AggregatorPlugin, \ AggregateResultListener -import tempfile from Tank.Plugins.ConsoleOnline import ConsoleOnlinePlugin, AbstractInfoWidget +import os +import signal +import subprocess +import tempfile import time @@ -38,7 +38,7 @@ class JMeterPlugin(AbstractPlugin): def prepare_test(self): self.args = [self.jmeter_path, "-n", "-t", self.jmx, '-j', self.jmeter_log, '-Jjmeter.save.saveservice.default_delimiter=\\t'] - self.args += Utils.splitstring(self.user_args) + self.args += Core.splitstring(self.user_args) aggregator = None try: diff --git a/Tank/Plugins/Phantom.py b/Tank/Plugins/Phantom.py index 1313423..f25b3ec 100644 --- a/Tank/Plugins/Phantom.py +++ b/Tank/Plugins/Phantom.py @@ -1,7 +1,7 @@ ''' Contains Phantom Plugin, Console widgets, result reader classes ''' -from Tank import Utils +from Tank import Core from Tank.Core import AbstractPlugin from Tank.Plugins.Aggregator import AggregatorPlugin, AggregateResultListener, \ AbstractReader @@ -116,7 +116,7 @@ class PhantomPlugin(AbstractPlugin): if reverse_name.startswith(self.address): self.address = ip_addr else: - raise ValueError("Address %s reverse-resolved to %s, but must match", self.address, reverse_name) + raise ValueError("Address %s reverse-resolved to %s, but must match" % (self.address, reverse_name)) def __read_phantom_options(self): @@ -286,7 +286,7 @@ class PhantomPlugin(AbstractPlugin): self.config = self.__compose_config() args = [self.phantom_path, 'check', self.config] - retcode = Utils.execute(args, catch_out=True) + retcode = Core.execute(args, catch_out=True) if retcode: raise RuntimeError("Subprocess returned %s",) @@ -322,7 +322,7 @@ class PhantomPlugin(AbstractPlugin): def is_test_finished(self): if not self.phout_import_mode: - Utils.log_stdout_stderr(self.log, self.process.stdout, self.process.stderr, self.SECTION) + Core.log_stdout_stderr(self.log, self.process.stdout, self.process.stderr, self.SECTION) retcode = self.process.poll() if retcode != None: @@ -391,7 +391,7 @@ class PhantomPlugin(AbstractPlugin): Get total test duration ''' duration = 0 - for rps, dur in Utils.pairs(steps): + for rps, dur in Core.pairs(steps): duration += dur self.core.set_option(self.SECTION, self.OPTION_TEST_DURATION, str(duration)) @@ -578,7 +578,7 @@ class PhantomReader(AbstractReader): self.log.debug("Opening phout file: %s", self.phantom.phout_file) self.phout = open(self.phantom.phout_file, 'r') # strange decision to place it here, but no better idea yet - for item in Utils.pairs(self.phantom.steps): + for item in Core.pairs(self.phantom.steps): self.steps.append([item[0], item[1]]) if not self.stat and self.phantom.stat_log and os.path.exists(self.phantom.stat_log): @@ -717,7 +717,7 @@ class UsedInstancesCriteria(AbstractCriteria): else: self.level = int(level_str) self.is_relative = False - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[1]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[1]) try: phantom = autostop.core.get_plugin_of_type(PhantomPlugin) diff --git a/Tank/Plugins/ShellExec.py b/Tank/Plugins/ShellExec.py index 2041704..f2eb6d4 100644 --- a/Tank/Plugins/ShellExec.py +++ b/Tank/Plugins/ShellExec.py @@ -2,7 +2,7 @@ Contains shellexec plugin ''' from Tank.Core import AbstractPlugin -from Tank import Utils +from Tank import Core class ShellExecPlugin(AbstractPlugin): ''' @@ -58,6 +58,6 @@ class ShellExecPlugin(AbstractPlugin): Execute and check exit code ''' self.log.debug("Executing: %s", cmd) - retcode = Utils.execute(cmd, shell=True, poll_period=0.1) + retcode = Core.execute(cmd, shell=True, poll_period=0.1) if retcode: raise RuntimeError("Subprocess returned %s",) diff --git a/Tank/Plugins/Stepper.py b/Tank/Plugins/Stepper.py index 3fbe00b..accf82c 100644 --- a/Tank/Plugins/Stepper.py +++ b/Tank/Plugins/Stepper.py @@ -8,7 +8,7 @@ import operator import os import re import tempfile -from Tank import Utils +from Tank import Core from progressbar import ProgressBar, Percentage, Bar, ETA # TODO: 3 add stpd file size estimation @@ -130,7 +130,7 @@ def load_const(req, duration): ''' Constant load pattern ''' - dur = Utils.expand_to_seconds(duration) + dur = Core.expand_to_seconds(duration) steps = [] steps.append([req, dur]) ls = '%s,const,%s,%s,(%s,%s)\n' % (dur, req, req, req, duration) @@ -144,7 +144,7 @@ def load_line(start, end, duration): ''' Linear load pattern ''' - dur = Utils.expand_to_seconds(duration) + dur = Core.expand_to_seconds(duration) diff_k = float((end - start) / float(dur - 1)) (cnt, last_x, total) = (1, start, 0) ls = '%s,line,%s,%s,(%s,%s,%s)\n' % ( @@ -171,7 +171,7 @@ def load_step(start, end, step, duration,): ''' Stepping load pattern ''' - dur = Utils.expand_to_seconds(duration) + dur = Core.expand_to_seconds(duration) (steps, ls, total) = ([], '', 0) if end > start: for rps_level in range(start, end + 1, step): @@ -331,7 +331,7 @@ def constf(req, duration): pattern = re.match("(\d+)\/(\d+)", req) if pattern: (a, b) = (int(pattern.group(1)), int(pattern.group(2))) - (dur, e) = (Utils.expand_to_seconds(duration), int(a / b)) + (dur, e) = (Core.expand_to_seconds(duration), int(a / b)) fr = '%.3f' % (float(a) / b) ls = '%s,const,%s,%s,(%s,%s)\n' % (dur, fr, fr, req, duration) diff --git a/Tank/Plugins/TotalAutostop.py b/Tank/Plugins/TotalAutostop.py index 897c887..004611a 100644 --- a/Tank/Plugins/TotalAutostop.py +++ b/Tank/Plugins/TotalAutostop.py @@ -1,16 +1,11 @@ -from Tank import Utils +from Tank import Core from Tank.Core import AbstractPlugin -from Tank.Plugins.Aggregator import AggregatorPlugin, AggregateResultListener -from Tank.Plugins.ConsoleOnline import AbstractInfoWidget, ConsoleOnlinePlugin -from Tank.Plugins.Phantom import PhantomPlugin -from Tank.Plugins.Autostop import AbstractCriteria -from Tank.Plugins.Autostop import AutostopPlugin -from Tank.Plugins.Autostop import AutostopWidget - +from Tank.Plugins.Aggregator import AggregateResultListener +from Tank.Plugins.Autostop import AbstractCriteria, AutostopPlugin from collections import deque -import logging import re + class TotalAutostopPlugin(AbstractPlugin, AggregateResultListener): SECTION='autostop' @staticmethod @@ -42,9 +37,9 @@ class TotalFracTimeCriteria(AbstractCriteria): AbstractCriteria.__init__(self) param = param_str.split(',') self.seconds_count = 0 - self.rt_limit = Utils.expand_to_milliseconds(param[0]) + self.rt_limit = Core.expand_to_milliseconds(param[0]) self.frac = param[1][:-1] - self.seconds_limit = Utils.expand_to_seconds(param[2]) + self.seconds_limit = Core.expand_to_seconds(param[2]) self.autostop = autostop self.data = deque() @@ -98,7 +93,7 @@ class TotalHTTPCodesCriteria(AbstractCriteria): else: self.level = int(level_str) self.is_relative = False - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[2]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[2]) def notify(self, aggregate_second): matched_responses = self.count_matched_codes(self.codes_regex, aggregate_second.overall.http_codes) @@ -173,7 +168,7 @@ class TotalNetCodesCriteria(AbstractCriteria): else: self.level = int(level_str) self.is_relative = False - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[2]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[2]) def notify(self, aggregate_second): @@ -244,7 +239,7 @@ class TotalNegativeHTTPCodesCriteria(AbstractCriteria): else: self.level = int(level_str) self.is_relative = False - self.seconds_limit = Utils.expand_to_seconds(param_str.split(',')[2]) + self.seconds_limit = Core.expand_to_seconds(param_str.split(',')[2]) def notify(self, aggregate_second): matched_responses = self.count_matched_codes(self.codes_regex, aggregate_second.overall.http_codes) diff --git a/Tank/Plugins/WebOnline.py b/Tank/Plugins/WebOnline.py index 3c92da0..7bbeba8 100644 --- a/Tank/Plugins/WebOnline.py +++ b/Tank/Plugins/WebOnline.py @@ -1,13 +1,13 @@ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +from Tank import Core from Tank.Core import AbstractPlugin from Tank.Plugins.Aggregator import AggregatorPlugin, AggregateResultListener from threading import Thread +import json import logging import os.path import socket import time -import json -from Tank import Utils class WebOnlinePlugin(AbstractPlugin, Thread, AggregateResultListener): SECTION = "web" @@ -29,7 +29,7 @@ class WebOnlinePlugin(AbstractPlugin, Thread, AggregateResultListener): def configure(self): self.port = int(self.get_option("port", self.port)) - self.interval = int(Utils.expand_to_seconds(self.get_option("interval", '1m'))) + self.interval = int(Core.expand_to_seconds(self.get_option("interval", '1m'))) self.redirect = self.get_option("redirect", self.redirect) def prepare_test(self): diff --git a/Tank/Utils.py b/Tank/Utils.py deleted file mode 100644 index 514f60a..0000000 --- a/Tank/Utils.py +++ /dev/null @@ -1,143 +0,0 @@ -''' -Commonly used utilities contained here -''' - -import errno -import itertools -import logging -import os -import re -import select -import subprocess -import time - -def log_stdout_stderr(log, stdout, stderr, comment=""): - ''' - This function polls stdout and stderr streams and writes their contents to log - ''' - readable = select.select([stdout], [], [] , 0)[0] - if stderr: - exceptional = select.select([stderr], [], [] , 0)[0] - else: - exceptional = [] - - log.debug("Selected: %s, %s", readable, exceptional) - - for handle in readable: - line = handle.read() - readable.remove(handle) - if line: - log.debug("%s stdout: %s", comment, line.strip()) - - for handle in exceptional: - line = handle.read() - exceptional.remove(handle) - if line: - log.warn("%s stderr: %s", comment, line.strip()) - - -def expand_to_milliseconds(str_time): - ''' - converts 1d2s into milliseconds - ''' - return expand_time(str_time, 'ms', 1000) - -def expand_to_seconds(str_time): - ''' - converts 1d2s into seconds - ''' - return expand_time(str_time, 's', 1) - -def expand_time(str_time, default_unit='s', multiplier=1): - ''' - helper for above functions - ''' - parser = re.compile('(\d+)([a-zA-Z]*)') - parts = parser.findall(str_time) - result = 0.0 - for value, unit in parts: - value = int(value) - unit = unit.lower() - if unit == '': - unit = default_unit - - if unit == 'ms': - result += value * 0.001 - continue - elif unit == 's': - result += value - continue - elif unit == 'm': - result += value * 60 - continue - elif unit == 'h': - result += value * 60 * 60 - continue - elif unit == 'd': - result += value * 60 * 60 * 24 - continue - elif unit == 'w': - result += value * 60 * 60 * 24 * 7 - continue - else: - raise ValueError("String contains unsupported unit %s: %s", unit, str_time) - return int(result * multiplier) - -def pid_exists(pid): - """Check whether pid exists in the current process table.""" - if pid < 0: - return False - try: - os.kill(pid, 0) - except OSError, exc: - return exc.errno == errno.EPERM - else: - return True - -def execute(cmd, shell=False, poll_period=1, catch_out=False): - ''' - Wrapper for Popen - ''' - log = logging.getLogger(__name__) - log.debug("Starting: %s", cmd) - - if catch_out: - process = subprocess.Popen(cmd, shell=shell, stderr=subprocess.PIPE, stdout=subprocess.PIPE) - else: - process = subprocess.Popen(cmd, shell=shell) - - while process.poll() == None: - log.debug("Waiting for process to finish: %s", process) - time.sleep(poll_period) - - if catch_out: - for line in process.stderr.readlines(): - log.warn(line.strip()) - for line in process.stdout.readlines(): - log.debug(line.strip()) - - retcode = process.poll() - log.debug("Process exit code: %s", retcode) - return retcode - -def splitstring(string): - """ - >>> string = 'apple orange "banana tree" green' - >>> splitstring(string) - ['apple', 'orange', 'green', '"banana tree"'] - """ - patt = re.compile(r'"[\w ]+"') - if patt.search(string): - quoted_item = patt.search(string).group() - newstring = patt.sub('', string) - return newstring.split() + [quoted_item] - else: - return string.split() - - -def pairs(lst): - ''' - Iterate over pairs in the list - ''' - return itertools.izip(lst[::2], lst[1::2]) - diff --git a/Tests/CommonUtilsTest.py b/Tests/CommonUtilsTest.py index 5cd32c3..6ccdb50 100644 --- a/Tests/CommonUtilsTest.py +++ b/Tests/CommonUtilsTest.py @@ -1,4 +1,4 @@ -from Tank import Utils +from Tank import Core from Tests.TankTests import TankTestCase import unittest @@ -15,11 +15,11 @@ class CommonUtilsTest(TankTestCase): def test_expand_to_seconds(self): for i in self.stest: - self.assertEqual(Utils.expand_to_seconds(i[0]), i[1]) + self.assertEqual(Core.expand_to_seconds(i[0]), i[1]) def test_expand_to_seconds_fail(self): try: - Utils.expand_to_seconds("100n") + Core.expand_to_seconds("100n") raise RuntimeError("Exception expected") except ValueError, ex: # it's ok, we have excpected exception @@ -28,12 +28,12 @@ class CommonUtilsTest(TankTestCase): def test_expand_to_milliseconds(self): for i in self.mstest: - self.assertEqual(Utils.expand_to_milliseconds(i[0]), i[1]) + self.assertEqual(Core.expand_to_milliseconds(i[0]), i[1]) def test_expand_to_milliseconds_fail(self): try: - Utils.expand_to_milliseconds("100n") + Core.expand_to_milliseconds("100n") raise RuntimeError("Exception expected") except ValueError, ex: # it's ok, we have excpected exception diff --git a/debian/install b/debian/install index 2d477dd..726dab3 100644 --- a/debian/install +++ b/debian/install @@ -1,4 +1,8 @@ -Tank usr/lib/yandex-tank +Tank/__init__.py usr/lib/yandex-tank/Tank +Tank/ConsoleWorker.py usr/lib/yandex-tank/Tank +Tank/Plugins usr/lib/yandex-tank/Tank +Tank/MonCollector usr/lib/yandex-tank/Tank + tank.py usr/lib/yandex-tank *.sh usr/lib/yandex-tank yandex-tank.ini etc/yandex-tank diff --git a/debian/rules b/debian/rules index 7d2a885..7d6935d 100755 --- a/debian/rules +++ b/debian/rules @@ -81,6 +81,9 @@ binary-indep: install dh_md5sums dh_builddeb +override_dh_pysupport: + dh_python2 + # Build architecture-dependent files here. binary-arch: install diff --git a/debian/yandex-load-tank-base.pyinstall b/debian/yandex-load-tank-base.pyinstall new file mode 100644 index 0000000..0f6bcbe --- /dev/null +++ b/debian/yandex-load-tank-base.pyinstall @@ -0,0 +1,3 @@ +Tank/__init__.py 2.6- +Tank/Core.py 2.6- +Tank/Utils.py 2.6-