mirror of
https://github.com/valitydev/yandex-tank.git
synced 2024-11-06 10:25:17 +00:00
commit
e6d9395c0e
1
setup.py
1
setup.py
@ -60,5 +60,6 @@ analytic tools for the results they produce.
|
||||
'yandextank.plugins.Pandora': ['config/*'],
|
||||
'yandextank.plugins.Aggregator': ['config/*'],
|
||||
'yandextank.plugins.Telegraf': ['config/*'],
|
||||
'yandextank.plugins.Android': ['binary/*'],
|
||||
},
|
||||
use_2to3=False, )
|
||||
|
1
yandextank/plugins/Android/__init__.py
Normal file
1
yandextank/plugins/Android/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from plugin import Plugin # noqa:F401
|
BIN
yandextank/plugins/Android/binary/lightning.apk
Normal file
BIN
yandextank/plugins/Android/binary/lightning.apk
Normal file
Binary file not shown.
208
yandextank/plugins/Android/plugin.py
Normal file
208
yandextank/plugins/Android/plugin.py
Normal file
@ -0,0 +1,208 @@
|
||||
import logging
|
||||
import subprocess
|
||||
import time
|
||||
import urllib
|
||||
import sys
|
||||
import glob
|
||||
import os
|
||||
from multiprocessing import Process
|
||||
from signal import SIGKILL
|
||||
|
||||
try:
|
||||
from volta.analysis import grab, uploader
|
||||
except Exception:
|
||||
raise RuntimeError("Please install volta. https://github.com/yandex-load/volta")
|
||||
|
||||
from pkg_resources import resource_filename
|
||||
from ...common.interfaces import AbstractPlugin, GeneratorPlugin
|
||||
from .reader import AndroidReader, AndroidStatsReader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Plugin(AbstractPlugin, GeneratorPlugin):
|
||||
SECTION = "android"
|
||||
|
||||
def __init__(self, core):
|
||||
super(Plugin, self).__init__(core)
|
||||
self.apk_path = None
|
||||
self.test_path = None
|
||||
self.package = None
|
||||
self.package_test = None
|
||||
self.clazz = None
|
||||
self.device = None
|
||||
self.test_runner = None
|
||||
self.process_test = None
|
||||
self.process_stderr = None
|
||||
self.process_grabber = None
|
||||
self.apk = "./app.apk"
|
||||
self.test = "./app-test.apk"
|
||||
self.grab_log = "./output.bin"
|
||||
self.event_log = "./events.log"
|
||||
|
||||
@staticmethod
|
||||
def get_key():
|
||||
return __file__
|
||||
|
||||
def get_available_options(self):
|
||||
opts = ["package", "test_package", "apk", "test_apk", "class", "test_runner"]
|
||||
return opts
|
||||
|
||||
def configure(self):
|
||||
# plugin part
|
||||
self.apk_path = self.get_option("apk")
|
||||
self.test_path = self.get_option("test_apk")
|
||||
self.clazz = self.get_option("class")
|
||||
self.package = self.get_option("package")
|
||||
self.package_test = self.get_option("test_package")
|
||||
self.test_runner = self.get_option("test_runner")
|
||||
|
||||
def prepare_test(self):
|
||||
aggregator = self.core.job.aggregator_plugin
|
||||
|
||||
if aggregator:
|
||||
aggregator.reader = AndroidReader()
|
||||
aggregator.stats_reader = AndroidStatsReader()
|
||||
|
||||
ports = None
|
||||
logger.info("Trying to find device")
|
||||
if sys.platform.startswith('linux'):
|
||||
ports = glob.glob('/dev/ttyUSB[0-9]*')
|
||||
elif sys.platform.startswith('darwin'):
|
||||
ports = glob.glob('/dev/cu.wchusbserial[0-9]*')
|
||||
else:
|
||||
logger.info('Your OS is not supported yet')
|
||||
|
||||
logger.info("Ports = " + ''.join(ports))
|
||||
try:
|
||||
self.device = [port for port in ports if 'Bluetooth' not in port][0]
|
||||
logger.info("Found device = " + self.device)
|
||||
except Exception:
|
||||
logger.info("Device not found")
|
||||
|
||||
logger.info("Download apk...")
|
||||
urllib.urlretrieve(self.apk_path, self.apk)
|
||||
|
||||
logger.info("Download test...")
|
||||
urllib.urlretrieve(self.test_path, self.test)
|
||||
|
||||
logger.info("Uninstall the lightning...")
|
||||
subprocess.check_output(["adb", "uninstall", "net.yandex.overload.lightning"])
|
||||
|
||||
logger.info("Uninstall the app...")
|
||||
subprocess.check_output(["adb", "uninstall", self.package])
|
||||
|
||||
logger.info("Uninstall the test...")
|
||||
subprocess.check_output(["adb", "uninstall", self.package_test])
|
||||
|
||||
lightning = resource_filename(__name__, 'binary/lightning.apk')
|
||||
logger.info("Get from resources " + lightning)
|
||||
|
||||
logger.info("Install the lightning...")
|
||||
subprocess.check_output(["adb", "install", lightning])
|
||||
|
||||
logger.info("Install the apk...")
|
||||
subprocess.check_output(["adb", "install", self.apk])
|
||||
|
||||
logger.info("Install the test...")
|
||||
subprocess.check_output(["adb", "install", self.test])
|
||||
|
||||
logger.info("Clear logcat...")
|
||||
subprocess.check_output(["adb", "logcat", "-c"])
|
||||
|
||||
def start_test(self):
|
||||
if self.device:
|
||||
logger.info("Start grabber...")
|
||||
args = {
|
||||
'device': self.device,
|
||||
'seconds': 10800,
|
||||
'output': self.grab_log,
|
||||
'debug': False,
|
||||
'binary': False
|
||||
}
|
||||
self.process_grabber = Process(target=grab.main, args=(args,))
|
||||
self.process_grabber.start()
|
||||
|
||||
process_stderr_file = self.core.mkstemp(".log", "android_")
|
||||
self.core.add_artifact_file(process_stderr_file)
|
||||
self.process_stderr = open(process_stderr_file, 'w')
|
||||
|
||||
logger.info("Start flashlight...")
|
||||
args = ["adb", "shell", "am", "start", "-n",
|
||||
"net.yandex.overload.lightning/net.yandex.overload.lightning.MainActivity"]
|
||||
subprocess.Popen(args)
|
||||
time.sleep(12)
|
||||
|
||||
args = ["adb", "shell", "am", "instrument", "-w", "-e", "class", self.clazz,
|
||||
'{package}/{runner}'.format(package=self.package_test, runner=self.test_runner)]
|
||||
logger.info("Starting: %s", args)
|
||||
self.process_test = subprocess.Popen(
|
||||
args,
|
||||
stderr=self.process_stderr,
|
||||
stdout=self.process_stderr,
|
||||
close_fds=True
|
||||
)
|
||||
|
||||
def is_test_finished(self):
|
||||
retcode = self.process_test.poll()
|
||||
if retcode is not None:
|
||||
logger.info("Subprocess done its work with exit code: %s", retcode)
|
||||
return abs(retcode)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def end_test(self, retcode):
|
||||
if self.process_grabber:
|
||||
logger.info("Kill grabber...")
|
||||
os.kill(self.process_grabber.pid, SIGKILL)
|
||||
|
||||
logger.info("Get logcat dump...")
|
||||
subprocess.check_call('adb logcat -d > {file}'.format(file=self.event_log), shell=True)
|
||||
|
||||
if os.path.exists(self.grab_log):
|
||||
logger.info("Upload logs...")
|
||||
args = {
|
||||
'filename': self.grab_log,
|
||||
'events': self.event_log,
|
||||
'samplerate': 500,
|
||||
'slope': 1,
|
||||
'offset': 0,
|
||||
'bynary': False,
|
||||
'job_config': {
|
||||
'task': self.core.job.task,
|
||||
'jobname': self.core.job.name,
|
||||
'dsc': self.core.job.description,
|
||||
'component': self.core.get_option('meta', 'component')
|
||||
}
|
||||
}
|
||||
process_uploader = Process(target=uploader.main, args=(args,))
|
||||
process_uploader.start()
|
||||
process_uploader.join()
|
||||
|
||||
if self.process_test and self.process_test.poll() is None:
|
||||
logger.info("Terminating tests with PID %s", self.process_test.pid)
|
||||
self.process_test.terminate()
|
||||
if self.process_stderr:
|
||||
self.process_stderr.close()
|
||||
|
||||
logger.info("Uninstall the app...")
|
||||
subprocess.check_output(["adb", "uninstall", self.package])
|
||||
|
||||
logger.info("Uninstall the test...")
|
||||
subprocess.check_output(["adb", "uninstall", self.package_test])
|
||||
|
||||
return retcode
|
||||
|
||||
def get_info(self):
|
||||
return AndroidInfo()
|
||||
|
||||
|
||||
class AndroidInfo(object):
|
||||
def __init__(self):
|
||||
self.address = ''
|
||||
self.port = 80
|
||||
self.ammo_file = ''
|
||||
self.duration = 0
|
||||
self.loop_count = 1
|
||||
self.instances = 1
|
||||
self.rps_schedule = ''
|
14
yandextank/plugins/Android/reader.py
Normal file
14
yandextank/plugins/Android/reader.py
Normal file
@ -0,0 +1,14 @@
|
||||
class AndroidReader(object):
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def __iter__(self):
|
||||
yield None
|
||||
|
||||
|
||||
class AndroidStatsReader(object):
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def __iter__(self):
|
||||
yield None
|
Loading…
Reference in New Issue
Block a user