diff options
| author | Andrew Morrow <andrew.morrow@10gen.com> | 2019-12-10 20:05:44 +0000 |
|---|---|---|
| committer | evergreen <evergreen@mongodb.com> | 2019-12-10 20:05:44 +0000 |
| commit | 825f7246e8a973f134c533d0d1f3b68abeeba010 (patch) | |
| tree | c33d63d86281bb300da2c019ae08928b7d215307 /buildscripts | |
| parent | 711b443933b323f7cb9c9fa4256a37a777bf58e2 (diff) | |
| download | mongo-825f7246e8a973f134c533d0d1f3b68abeeba010.tar.gz | |
SERVER-44546 Remove mobile variants and embedded benchmarksr4.0.14-rc0
(cherry picked from commit be05c9ea62d6f01895545628992f1899426b88c4)
(cherry picked from commit c51ba0a06ede1d87cd8df637f379bb3ceabad6fa)
Diffstat (limited to 'buildscripts')
22 files changed, 4 insertions, 1490 deletions
diff --git a/buildscripts/bypass_compile_and_fetch_binaries.py b/buildscripts/bypass_compile_and_fetch_binaries.py index 831d864a582..7c46063a595 100644..100755 --- a/buildscripts/bypass_compile_and_fetch_binaries.py +++ b/buildscripts/bypass_compile_and_fetch_binaries.py @@ -269,8 +269,6 @@ def main(): # pylint: disable=too-many-locals,too-many-statements extract_files = [ executable_name("dbtest"), executable_name("mongobridge"), - executable_name("mongoebench"), - executable_name("mongoed"), "build/integration_tests.txt", ] with tarfile.open(filename, "r:gz") as tar: diff --git a/buildscripts/mobile/README-Android.md b/buildscripts/mobile/README-Android.md deleted file mode 100644 index ed9cc744eb9..00000000000 --- a/buildscripts/mobile/README-Android.md +++ /dev/null @@ -1,40 +0,0 @@ -# Profiling an Application on Android -How to profile a test application for Android - -## Set up Your Local Environment -1. Download ADB SDK -1. Add the SDK platform-tools to your PATH - * export PATH="$PATH:$HOME/Library/Android/sdk/platform-tools" - -## Run the ADB profiler -The ADB profiler is a custom script which provides - * Battery statistics - battery.csv - * Memory statistics - memory.csv - * CPU statistics - cpu.json -`python buildscripts/mobile/adb_monitor.py` - - -## Enable USB Debugging on Android Device -Enabling USB debugging can differ by device, see https://developer.android.com/studio/debug/dev-options -1. Enable USB debugging via ADB, example - * Select Settings/About phone(or tablet) - * Select Build number 7 times, to enable Developer Options - * Select Settings/Developer Options/USB Debugging -1. Connect the Android device to the computer via USB cable -1. Select "Aways allow from this computer" and OK, when the prompt "Allow USB debugging?" appears on the device - -## Run the ADB Profiler Wirelessly -1. Ensure the local computer and Android device are on the same network -1. Connect the Android device to the computer via USB cable -1. Set the Android device's ADB listening port - * `adb devices` - * `adb tcpip 5555` -1. Disconnect the USB cable -1. Identify the Android's IP address - * Settings/About phone(or tablet)/Status - * `adb_ip=<ip_address>`, i.e., adb_ip=10.4.123.244 -1. Connect wirelessly to the Android device - * `adb connect $adb_ip` -1. Ensure you can connect to the Android device - * `adb shell uptime` -1. Run the ADB profiler as detailed above diff --git a/buildscripts/mobile/__init__.py b/buildscripts/mobile/__init__.py deleted file mode 100644 index 4b7a2bb941b..00000000000 --- a/buildscripts/mobile/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Empty.""" diff --git a/buildscripts/mobile/adb_monitor.py b/buildscripts/mobile/adb_monitor.py deleted file mode 100644 index d33a37e08d8..00000000000 --- a/buildscripts/mobile/adb_monitor.py +++ /dev/null @@ -1,437 +0,0 @@ -#!/usr/bin/env python -"""ADB utilities to collect adb samples from a locally connected Android device.""" - -import distutils.spawn # pylint: disable=no-name-in-module -import logging -import optparse -import os -import pipes -import re -import shlex -import sys -import tempfile -import threading -import time -import warnings - -# pylint: disable=wrong-import-position -# Get relative imports to work when the package is not installed on the PYTHONPATH. -if __name__ == "__main__" and __package__ is None: - sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) - -from buildscripts.util import fileops -from buildscripts.util import runcommand - -# Initialize the global logger. -LOGGER = logging.getLogger(__name__) - - -class Adb(object): - """Class to abstract calls to adb.""" - - def __init__(self, adb_binary="adb", logger=LOGGER): - """Initialize the Adb object.""" - self._cmd = None - self.logger = logger - self.adb_path = distutils.spawn.find_executable(adb_binary) - if not self.adb_path: - raise EnvironmentError( - "Executable '{}' does not exist or is not in the PATH.".format(adb_binary)) - - # We support specifying a path the adb binary to use; however, systrace.py only - # knows how to find it using the PATH environment variable. It is possible that - # 'adb_binary' is an absolute path specified by the user, so we add its parent - # directory to the PATH manually. - adb_dir = os.path.dirname(self.adb_path) - os.environ["PATH"] = "{}{}{}".format(os.environ["PATH"], os.path.pathsep, adb_dir) - - # systrace.py should be in <adb_dir>/systrace/systrace.py - self.systrace_script = os.path.join(adb_dir, "systrace", "systrace.py") - if not os.path.isfile(self.systrace_script): - raise EnvironmentError("Script '{}' cannot be found.".format(self.systrace_script)) - self._tempfile = None - - @staticmethod - def adb_cmd(adb_command, output_file=None, append_file=False, output_string=False): - """Run an adb command and return result.""" - cmd = runcommand.RunCommand("adb {}".format(adb_command), output_file, append_file) - if output_string or not output_file: - return cmd.execute_with_output() - return cmd.execute_save_output() - - @staticmethod - def shell(adb_shell_command): - """Run an adb shell command and return output_string. - - Raise an exception if the exit status is non-zero. - - Since the adb shell command does not return an exit status. We simulate it by - saving the exit code in the output and then stripping if off. - - See https://stackoverflow.com/questions/9379400/adb-error-codes - """ - cmd_prefix = "set -o errexit; function _exit_ { echo __EXIT__:$?; } ; trap _exit_ EXIT ;" - cmd = runcommand.RunCommand("adb shell {} {}".format(cmd_prefix, adb_shell_command)) - cmd_output = cmd.execute_with_output() - if "__EXIT__" in cmd_output: - exit_code = int(cmd_output.split()[-1].split(":")[1]) - cmd_output_stripped = re.split("__EXIT__.*\n", cmd_output)[0] - if exit_code: - raise RuntimeError("{}: {}".format(exit_code, cmd_output_stripped)) - return cmd_output_stripped - return cmd_output - - def devices(self): - """Return the available ADB devices and the uptime.""" - return self.adb_cmd("devices -l", output_string=True) - - def device_available(self): - """Return the the uptime of the connected device.""" - # If the device is not available this will throw an exception. - return self.adb_cmd("shell uptime", output_string=True) - - def push(self, files, remote_dir, sync=False): - """Push a list of files over adb to remote_dir.""" - # We can specify files as a single file name or a list of files. - if isinstance(files, list): - files = " ".join(files) - sync_opt = "--sync " if sync else "" - return self.adb_cmd("push {}{} {}".format(sync_opt, files, remote_dir), output_string=True) - - def pull(self, files, local_dir): - """Pull a list of remote files over adb to local_dir.""" - # We can specify files as a single file name or a list of files. - if isinstance(files, list): - files = " ".join(files) - return self.adb_cmd("pull {} {}".format(files, local_dir), output_string=True) - - def _battery_cmd(self, option, output_file=None, append_file=False): - self.adb_cmd("shell dumpsys batterystats {}".format(option), output_file, append_file) - - def battery(self, reset=False, output_file=None, append_file=False): - """Collect the battery stats and save to the output_file.""" - if reset: - self._battery_cmd("--reset") - self._battery_cmd("--checkin", output_file, append_file) - - def memory(self, output_file=None, append_file=False): - """Collect the memory stats and save to the output_file.""" - self.adb_cmd("shell dumpsys meminfo -c -d", output_file, append_file) - - def systrace_start(self, output_file=None): - """Start the systrace.py script to collect CPU usage.""" - self._tempfile = tempfile.NamedTemporaryFile(delete=False).name - self._cmd = runcommand.RunCommand(output_file=self._tempfile, propagate_signals=False) - self._cmd.add_file(sys.executable) - self._cmd.add_file(self.systrace_script) - self._cmd.add("--json") - self._cmd.add("-o") - self._cmd.add_file(output_file) - self._cmd.add("dalvik sched freq idle load") - self._cmd.start_process() - - def systrace_stop(self, output_file=None): - """Stop the systrace.py script.""" - self._cmd.send_to_process("bye") - with open(self._tempfile) as fh: - buff = fh.read() - os.remove(self._tempfile) - self.logger.debug("systrace_stop: %s", buff) - if "Wrote trace" not in buff: - self.logger.error("CPU file not saved: %s", buff) - if os.path.isfile(output_file): - os.remove(output_file) - - -class AdbControl(object): # pylint: disable=too-many-instance-attributes - """Class to controls calls to adb.""" - - _JOIN_TIMEOUT = 24 * 60 * 60 # 24 hours (a long time to have the monitor run for) - - def __init__( # pylint: disable=too-many-arguments - self, adb, logger=LOGGER, battery_file=None, memory_file=None, cpu_file=None, - append_file=False, num_samples=0, collection_time_secs=0, sample_interval_ms=0): - """Initialize AdbControl object.""" - - self.adb = adb - - self.logger = logger - - output_files = [battery_file, memory_file, cpu_file] - if not any(output_files): - raise ValueError("There are no collection sample files selected.") - self.battery_file = battery_file - self.memory_file = memory_file - self.cpu_file = cpu_file - - # The AdbResourceMonitor will always append results to the specified file. - # If append_file is specified in this init, then if there's an existing file - # we do not overwrite it. - for output_file in output_files: - if not append_file: - fileops.create_empty(output_file) - - self.append_file = append_file - # collection_time_secs overrides num_samples - self.num_samples = num_samples if collection_time_secs == 0 else 0 - self.collection_time_secs = collection_time_secs - self.sample_interval_ms = sample_interval_ms - - self.should_stop = threading.Event() - self.should_stop.clear() - self.sample_based_threads = [] - self.all_threads = [] - - def start(self): - """Start adb sample collection.""" - if self.cpu_file: - monitor = AdbContinuousResourceMonitor(self.cpu_file, self.should_stop, - self.adb.systrace_start, self.adb.systrace_stop) - self.all_threads.append(monitor) - monitor.start() - - if self.battery_file: - monitor = AdbSampleBasedResourceMonitor(self.battery_file, self.should_stop, - self.adb.battery, self.num_samples, - self.sample_interval_ms) - self.sample_based_threads.append(monitor) - self.all_threads.append(monitor) - monitor.start() - - if self.memory_file: - monitor = AdbSampleBasedResourceMonitor(self.memory_file, self.should_stop, - self.adb.memory, self.num_samples, - self.sample_interval_ms) - self.sample_based_threads.append(monitor) - self.all_threads.append(monitor) - monitor.start() - - def stop(self): - """Stop adb sample collection.""" - self.should_stop.set() - self.wait() - - def wait(self): - """Wait for all sample collections to complete.""" - try: - # We either wait for the specified amount of time or for the sample-based monitors - # to have collected the specified number of samples. - if self.collection_time_secs > 0: - self.should_stop.wait(self.collection_time_secs) - else: - for thread in self.sample_based_threads: - # We must specify a timeout to threading.Thread.join() to ensure that the - # wait is interruptible. The main thread would otherwise never be able to - # receive a KeyboardInterrupt. - thread.join(self._JOIN_TIMEOUT) - except KeyboardInterrupt: - # The user has interrupted the script, so we signal to all of the monitor threads - # that they should exit as quickly as they can. - pass - finally: - self.should_stop.set() - # Wait for all of the monitor threads to exit, by specifying a timeout to - # threading.Thread.join() in case the user tries to interrupt the script again. - for thread in self.all_threads: - thread.join(self._JOIN_TIMEOUT) - - self.logger.info("Collections stopped.") - - # If any of the monitor threads encountered an error, then reraise the exception in the - # main thread. - for thread in self.all_threads: - if thread.exception is not None: - raise thread.exception - - -class AdbResourceMonitor(threading.Thread): - """Thread to collect information about a specific resource using adb.""" - - def __init__(self, output_file, should_stop, logger=LOGGER): - """Initialize the AdbResourceMonitor object.""" - threading.Thread.__init__(self, name="AdbResourceMonitor {}".format(output_file)) - self._output_file = output_file - self._should_stop = should_stop - self.logger = logger - self.exception = None - - def run(self): - """Collect adb samples.""" - try: - self._do_monitoring() - except Exception as err: # pylint: disable=broad-except - self.logger.error("%s: Encountered an error: %s", self._output_file, err) - self.exception = err - self._should_stop.set() - - -class AdbSampleBasedResourceMonitor(AdbResourceMonitor): - """Subclass for ADB sample based monitor.""" - - def __init__( # pylint: disable=too-many-arguments - self, output_file, should_stop, adb_cmd, num_samples, sample_interval_ms): - """Initialize AdbSampleBasedResourceMonitor.""" - AdbResourceMonitor.__init__(self, output_file, should_stop) - self.adb_cmd = adb_cmd - self._num_samples = num_samples - self._sample_interval_ms = sample_interval_ms - - def _do_monitoring(self): - """Monitor function.""" - collected_samples = 0 - now = time.time() - - while not self._should_stop.is_set(): - if self._num_samples > 0 and collected_samples >= self._num_samples: - break - if collected_samples > 0: - self.logger.debug("%s: Sleeping %d ms.", self._output_file, - self._sample_interval_ms) - self._should_stop.wait(self._sample_interval_ms / 1000.0) - collected_samples += 1 - self._take_sample(collected_samples) - - total_time_ms = (time.time() - now) * 1000 - self.logger.info("%s: Stopping monitoring, %d samples collected in %d ms.", - self._output_file, collected_samples, total_time_ms) - - def _take_sample(self, collected_samples): - """Collect sample.""" - self.logger.debug("%s: Collecting sample %d of %d", self._output_file, collected_samples, - self._num_samples) - self.adb_cmd(output_file=self._output_file, append_file=True) - - -class AdbContinuousResourceMonitor(AdbResourceMonitor): - """Subclass for ADB continuous sample based monitoring.""" - - def __init__(self, output_file, should_stop, adb_start_cmd, adb_stop_cmd): - """Initialize AdbContinuousResourceMonitor.""" - AdbResourceMonitor.__init__(self, output_file, should_stop) - self._adb_start_cmd = adb_start_cmd - self._adb_stop_cmd = adb_stop_cmd - - def _do_monitoring(self): - """Monitor function.""" - self.logger.debug("%s: Starting monitoring.", self._output_file) - now = time.time() - self._adb_start_cmd(output_file=self._output_file) - self._should_stop.wait() - total_time_ms = (time.time() - now) * 1000 - self.logger.info("%s: Stopping monitoring after %d ms.", self._output_file, total_time_ms) - self._adb_stop_cmd(output_file=self._output_file) - - -def main(): #pylint: disable=too-many-statements - """Execute Main program.""" - - logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO) - logging.Formatter.converter = time.gmtime - - parser = optparse.OptionParser() - - program_options = optparse.OptionGroup(parser, "Program Options") - battery_options = optparse.OptionGroup(parser, "Battery Options") - memory_options = optparse.OptionGroup(parser, "Memory Options") - systrace_options = optparse.OptionGroup(parser, "Systrace Options") - - program_options.add_option("--adbBinary", dest="adb_binary", - help="The path for adb. Defaults to '%default', which is in $PATH.", - default="adb") - - program_options.add_option( - "--samples", dest="num_samples", - help="Number of samples to collect, 0 indicates infinite. [Default: %default]", type=int, - default=0) - - program_options.add_option( - "--collectionTime", dest="collection_time_secs", - help="Time in seconds to collect samples, if specifed overrides '--samples'.", type=int, - default=0) - - program_options.add_option( - "--sampleIntervalMs", dest="sample_interval_ms", - help="Time in milliseconds between collecting a sample. [Default: %default]", type=int, - default=500) - - log_levels = ["debug", "error", "info", "warning"] - program_options.add_option( - "--logLevel", dest="log_level", choices=log_levels, - help="The log level. Accepted values are: {}. [default: '%default'].".format(log_levels), - default="info") - - battery_options.add_option( - "--batteryFile", dest="battery_file", - help="The destination file for battery stats (CSV format). [Default: %default].", - default="battery.csv") - - battery_options.add_option("--noBattery", dest="no_battery", - help="Disable collection of battery samples.", action="store_true", - default=False) - - memory_options.add_option( - "--memoryFile", dest="memory_file", - help="The destination file for memory stats (CSV format). [Default: %default].", - default="memory.csv") - - memory_options.add_option("--noMemory", dest="no_memory", - help="Disable collection of memory samples.", action="store_true", - default=False) - - systrace_options.add_option( - "--cpuFile", dest="cpu_file", - help="The destination file for CPU stats (JSON format). [Default: %default].", - default="cpu.json") - - systrace_options.add_option("--noCpu", dest="no_cpu", help="Disable collection of CPU samples.", - action="store_true", default=False) - - parser.add_option_group(program_options) - parser.add_option_group(battery_options) - parser.add_option_group(memory_options) - parser.add_option_group(systrace_options) - - options, _ = parser.parse_args() - - output_files = {} - if options.no_battery: - options.battery_file = None - else: - output_files[options.battery_file] = fileops.getmtime(options.battery_file) - - if options.no_memory: - options.memory_file = None - else: - output_files[options.memory_file] = fileops.getmtime(options.memory_file) - - if options.no_cpu: - options.cpu_file = None - else: - output_files[options.cpu_file] = fileops.getmtime(options.cpu_file) - - LOGGER.setLevel(options.log_level.upper()) - LOGGER.info("This program can be cleanly terminated by issuing the following command:" - "\n\t\t'kill -INT %d'", os.getpid()) - - adb = Adb(options.adb_binary) - LOGGER.info("Detected devices by adb:\n%s%s", adb.devices(), adb.device_available()) - - adb_control = AdbControl(adb=adb, battery_file=options.battery_file, - memory_file=options.memory_file, cpu_file=options.cpu_file, - num_samples=options.num_samples, - collection_time_secs=options.collection_time_secs, - sample_interval_ms=options.sample_interval_ms) - - adb_control.start() - try: - adb_control.wait() - finally: - files_saved = [] - for path in output_files: - if fileops.getmtime(path) > output_files[path] and not fileops.is_empty(path): - files_saved.append(path) - LOGGER.info("Files saved: %s", files_saved) - - -if __name__ == "__main__": - main() diff --git a/buildscripts/mobile/benchrun_embedded_setup_android.py b/buildscripts/mobile/benchrun_embedded_setup_android.py deleted file mode 100644 index f2aaac544bd..00000000000 --- a/buildscripts/mobile/benchrun_embedded_setup_android.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python -"""Setup an Android device to run the benchrun_embedded test suite.""" - -from __future__ import print_function - -import glob -import logging -import optparse -import os -import posixpath -import shutil -import sys -import tarfile -import tempfile -import time -import urllib - -# pylint: disable=wrong-import-position -# Get relative imports to work when the package is not installed on the PYTHONPATH. -if __name__ == "__main__" and __package__ is None: - sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) - -from buildscripts.mobile import adb_monitor - -# Initialize the global logger. -LOGGER = logging.getLogger(__name__) - - -def download_and_untar(url, root_dir): - """Download url and untar into root_dir.""" - temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".tgz").name - LOGGER.info("Downloading %s", url) - urllib.urlretrieve(url, temp_file) - with tarfile.open(temp_file, "r:gz") as tar: - tar.extractall(root_dir) - os.remove(temp_file) - - -def push_directory_contents(adb, local_dir, remote_dir): - """Push contents of local_dir to remote_dir via adb.""" - # Push the contents of temp_dir. - paths = glob.glob(os.path.join(local_dir, "*")) - paths.sort() - paths_msg = paths - if isinstance(paths, list): - paths_msg = [os.path.basename(path) for path in paths] - paths_msg = "{}{}".format(paths_msg[:5], "" if len(paths) <= 5 else " ...") - LOGGER.info("Pushing %s to %s", paths_msg, remote_dir) - adb.push(paths, remote_dir) - - -def download_and_push(adb, url, remote_dir, local_dir=None): - """Download url and push directory to remote_dir via adb. - - If local_dir is defined, then save the unzipped tar there. - """ - temp_dir = tempfile.mkdtemp() - download_and_untar(url, temp_dir) - push_directory_contents(adb, temp_dir, remote_dir) - if local_dir: - if os.path.exists(local_dir): - LOGGER.info("Removing local path %s", local_dir) - shutil.rmtree(local_dir) - LOGGER.info("Saving local copy to %s", local_dir) - shutil.move(temp_dir, local_dir) - else: - shutil.rmtree(temp_dir) - - -def create_empty_remote_dirs(adb, dirs): - """Create empty remote directories via adb.""" - # We can specify dirs as a single directory name or as list. - if isinstance(dirs, str): - dirs = [dirs] - # Keep directories in order, so we do not delete a root level later. - dirs.sort() - for remote_dir in dirs: - LOGGER.info("Creating remote directory %s", remote_dir) - adb.shell( - "if [ -d {remote_dir} ]; then rm -fr {remote_dir}; fi; mkdir -p {remote_dir}".format( - remote_dir=remote_dir)) - - -def move_sdk_files(adb, sdk_root_dir): - """Move all the files in bin and lib into sdk_root_dir.""" - LOGGER.info("Moving SDK bin & lib files to %s", sdk_root_dir) - adb_command = "lib_dir=$(find {} -name 'lib')".format(sdk_root_dir) - adb_command = "{}; bin_dir=$(find {} -name 'bin')".format(adb_command, sdk_root_dir) - adb_command = "{}; mv $lib_dir/* $bin_dir/* {}".format(adb_command, sdk_root_dir) - adb.shell(adb_command) - - -def main(): - """Execute Main program.""" - - logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO) - logging.Formatter.converter = time.gmtime - - benchrun_root = "/data/local/tmp/benchrun_embedded" - - parser = optparse.OptionParser() - program_options = optparse.OptionGroup(parser, "Program Options") - device_options = optparse.OptionGroup(parser, "Device Options") - sdk_options = optparse.OptionGroup(parser, "Embedded Test SDK Options") - json_options = optparse.OptionGroup(parser, "JSON benchrun file Options") - - program_options.add_option("--adbBinary", dest="adb_binary", - help="The path for adb. Defaults to '%default', which is in $PATH.", - default="adb") - - device_options.add_option( - "--rootRemoteDir", dest="embedded_root_dir", - help="The remote root directory to store the files. Defaults to '%default'.", - default=benchrun_root) - - device_options.add_option( - "--dbDir", dest="db_dir", - help=("The remote dbpath directory used by mongoebench." - " Will be created if it does not exist. Defaults to '%default'."), - default=posixpath.join(benchrun_root, "db")) - - device_options.add_option( - "--resultsDir", dest="results_dir", - help=("The remote directory to store the mongoebench results." - " Will be created if it does not exist. Defaults to '%default'."), - default=posixpath.join(benchrun_root, "results")) - - device_options.add_option( - "--sdkRemoteDir", dest="sdk_remote_dir", - help="The remote directory to store the embedded SDK files. Defaults to '%default'.", - default=posixpath.join(benchrun_root, "sdk")) - - device_options.add_option("--benchrunJsonRemoteDir", dest="json_remote_dir", - help="The remote directory to store the benchrun JSON files." - " Defaults to '%default'.", default=posixpath.join( - benchrun_root, "testcases")) - - sdk_url = "https://s3.amazonaws.com/mciuploads/mongodb-mongo-v4.0/embedded-sdk-test/embedded-sdk-android-arm64-latest.tgz" - sdk_options.add_option( - "--sdkUrl", dest="sdk_url", - help=("The embedded SDK test URL. This tarball must contain mongoebench and" - " any required shared object (.so) libraries. Defaults to '%default'."), - default=sdk_url) - - sdk_options.add_option("--sdkLocalDir", dest="sdk_local_dir", - help="The local directory of embedded SDK files to be copied." - "If specified, overrides --sdkUrl.", default=None) - - sdk_options.add_option( - "--sdkSaveLocalDir", dest="sdk_save_local_dir", - help=("The local directory to save the downloaded embedded SDK as an unzipped tarball." - " Only used if the embedded SDK tarball is downloaded. Note - this will delete" - " the existing directory."), default=None) - - json_url = "https://s3.amazonaws.com/mciuploads/mongodb-mongo-v4.0/benchrun_embedded/benchrun_json_files.tgz" - json_options.add_option( - "--benchrunJsonUrl", dest="json_url", - help=("The benchrun JSON files URL. This tarball must contain all the JSON" - " files to be used in the benchrun embedded test." - " Defaults to '%default'."), default=json_url) - - json_options.add_option("--benchrunJsonLocalDir", dest="json_local_dir", - help="The local directory of benchrun JSON files to be copied." - "If specified, overrides --benchrunJsonUrl.", default=None) - - json_options.add_option( - "--benchrunJsonSaveLocalDir", dest="json_save_local_dir", - help=("The local directory to save the downloaded benchrun JSON as an unzipped tarball." - " Only used if the benchrun JSON files tarball is downloaded. Note - this will" - " delete the existing directory. Defaults to '%default'."), default=os.path.join( - "benchrun_embedded", "testcases")) - - json_options.add_option( - "--noBenchrunJsonSaveLocal", action="store_true", dest="no_json_save_local_dir", - help=("Disable saving downloaded benchrun JSON as an unzipped tarball."), default=False) - - parser.add_option_group(program_options) - parser.add_option_group(device_options) - parser.add_option_group(sdk_options) - parser.add_option_group(json_options) - options, _ = parser.parse_args() - - if options.no_json_save_local_dir: - options.json_save_local_dir = None - - adb = adb_monitor.Adb(options.adb_binary) - adb.device_available() - LOGGER.info("Detected devices by adb:\n%s%s", adb.devices(), adb.device_available()) - - # Create/empty remote directories. - create_empty_remote_dirs(adb, [ - options.embedded_root_dir, options.db_dir, options.results_dir, options.sdk_remote_dir, - options.json_remote_dir - ]) - - # Download, untar and push Embedded SDK Tests & Benchrun JSON files. - # Unfortunately gunzip may not exist on the Android device, so we cannot use this remote command: - # curl URL | tar -xzv -C LOCAL_DIR - - if options.sdk_local_dir: - push_directory_contents(adb, options.sdk_local_dir, options.sdk_remote_dir) - else: - download_and_push(adb, options.sdk_url, options.sdk_remote_dir, options.sdk_save_local_dir) - move_sdk_files(adb, options.sdk_remote_dir) - - if options.json_local_dir: - push_directory_contents(adb, options.json_local_dir, options.json_remote_dir) - else: - download_and_push(adb, options.json_url, options.json_remote_dir, - options.json_save_local_dir) - - -if __name__ == "__main__": - main() diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml deleted file mode 100644 index 6db291dcde1..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml +++ /dev/null @@ -1,10 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/aggregation*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml deleted file mode 100644 index c44747998c6..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml +++ /dev/null @@ -1,10 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/commands*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml deleted file mode 100644 index 55350189472..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml +++ /dev/null @@ -1,10 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/insert*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml deleted file mode 100644 index 56896e5b6e1..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml +++ /dev/null @@ -1,19 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/*.json - exclude_files: - - benchrun_embedded/testcases/**/aggregation*.json - - benchrun_embedded/testcases/**/commands*.json - - benchrun_embedded/testcases/**/insert*.json - - benchrun_embedded/testcases/**/mixed*.json - - benchrun_embedded/testcases/**/multi*.json - - benchrun_embedded/testcases/**/queries*.json - - benchrun_embedded/testcases/**/remove*.json - - benchrun_embedded/testcases/**/update*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml deleted file mode 100644 index cd0deb1d09f..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml +++ /dev/null @@ -1,11 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/mixed*.json - - benchrun_embedded/testcases/**/multi*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml deleted file mode 100644 index 9ba8ef7db43..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml +++ /dev/null @@ -1,10 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/queries*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml deleted file mode 100644 index f625a2e874b..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml +++ /dev/null @@ -1,10 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/remove*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml deleted file mode 100644 index a9ad8734a1b..00000000000 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml +++ /dev/null @@ -1,10 +0,0 @@ -test_kind: benchrun_embedded_test - -selector: - roots: - - benchrun_embedded/testcases/**/update*.json - -executor: - hooks: - - class: CollectEmbeddedResources - - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokelib/config.py b/buildscripts/resmokelib/config.py index b6429d5498c..f0886877bfc 100644 --- a/buildscripts/resmokelib/config.py +++ b/buildscripts/resmokelib/config.py @@ -26,7 +26,6 @@ MONGO_RUNNER_SUBDIR = "mongorunner" # Default path for where to look for executables. DEFAULT_DBTEST_EXECUTABLE = os.path.join(os.curdir, "dbtest") DEFAULT_MONGO_EXECUTABLE = os.path.join(os.curdir, "mongo") -DEFAULT_MONGOEBENCH_EXECUTABLE = os.path.join(os.curdir, "mongoebench") DEFAULT_MONGOD_EXECUTABLE = os.path.join(os.curdir, "mongod") DEFAULT_MONGOS_EXECUTABLE = os.path.join(os.curdir, "mongos") @@ -43,9 +42,6 @@ DEFAULTS = { "archive_limit_mb": 5000, "archive_limit_tests": 10, "base_port": 20000, - "benchrun_device": "Desktop", - "benchrun_embedded_root": "/data/local/tmp/benchrun_embedded", - "benchrun_report_root": "benchrun_embedded/results", "buildlogger_url": "https://logkeeper.mongodb.org", "continue_on_failure": False, "dbpath_prefix": None, @@ -57,7 +53,6 @@ DEFAULTS = { "mongo_executable": None, "mongod_executable": None, "mongod_set_parameters": None, - "mongoebench_executable": None, "mongos_executable": None, "mongos_set_parameters": None, "no_journal": False, @@ -277,9 +272,6 @@ MONGOD_EXECUTABLE = None # The --setParameter options passed to mongod. MONGOD_SET_PARAMETERS = None -# The path to the mongoebench executable used by resmoke.py. -MONGOEBENCH_EXECUTABLE = None - # The path to the mongos executable used by resmoke.py. MONGOS_EXECUTABLE = None @@ -368,11 +360,6 @@ BENCHMARK_LIST_TESTS = None BENCHMARK_MIN_TIME = None BENCHMARK_REPETITIONS = None -# Embedded Benchrun Test options. -BENCHRUN_DEVICE = None -BENCHRUN_EMBEDDED_ROOT = None -BENCHRUN_REPORT_ROOT = None - ## # Internally used configuration options that aren't exposed to the user ## @@ -394,5 +381,4 @@ DEFAULT_INTEGRATION_TEST_LIST = "build/integration_tests.txt" # External files or executables, used as suite selectors, that are created during the build and # therefore might not be available when creating a test membership map. EXTERNAL_SUITE_SELECTORS = (DEFAULT_BENCHMARK_TEST_LIST, DEFAULT_UNIT_TEST_LIST, - DEFAULT_INTEGRATION_TEST_LIST, DEFAULT_DBTEST_EXECUTABLE, - DEFAULT_MONGOEBENCH_EXECUTABLE) + DEFAULT_INTEGRATION_TEST_LIST, DEFAULT_DBTEST_EXECUTABLE) diff --git a/buildscripts/resmokelib/parser.py b/buildscripts/resmokelib/parser.py index 63c8e3f9e4d..d209d70e230 100644 --- a/buildscripts/resmokelib/parser.py +++ b/buildscripts/resmokelib/parser.py @@ -112,10 +112,6 @@ def _make_parser(): # pylint: disable=too-many-statements " started by resmoke.py. The argument is specified as bracketed YAML -" " i.e. JSON with support for single quoted and unquoted keys.")) - parser.add_option("--mongoebench", dest="mongoebench_executable", metavar="PATH", - help=("The path to the mongoebench (benchrun embedded) executable for" - " resmoke.py to use.")) - parser.add_option("--mongos", dest="mongos_executable", metavar="PATH", help="The path to the mongos executable for resmoke.py to use.") @@ -303,23 +299,9 @@ def _make_parser(): # pylint: disable=too-many-statements benchmark_options.add_option("--benchmarkRepetitions", type="int", dest="benchmark_repetitions", metavar="BENCHMARK_REPETITIONS", help=benchmark_repetitions_help) - benchrun_devices = ["Android", "Desktop"] - benchmark_options.add_option("--benchrunDevice", dest="benchrun_device", metavar="DEVICE", - type="choice", action="store", choices=benchrun_devices, - help=("The device to run the benchrun test on, choose from {}." - " Defaults to DEVICE='%default'.".format(benchrun_devices))) - - benchmark_options.add_option("--benchrunReportRoot", dest="benchrun_report_root", - metavar="PATH", help="The root path for benchrun test report.") - - benchmark_options.add_option("--benchrunEmbeddedRoot", dest="benchrun_embedded_root", - metavar="PATH", - help="The root path on the mobile device, for a benchrun test.") - - parser.set_defaults(benchrun_device="Desktop", dry_run="off", find_suites=False, - list_suites=False, logger_file="console", prealloc_journal="off", - shuffle="auto", stagger_jobs="off", suite_files="with_server", - majority_read_concern="on") + parser.set_defaults(dry_run="off", find_suites=False, list_suites=False, logger_file="console", + prealloc_journal="off", shuffle="auto", stagger_jobs="off", + suite_files="with_server", majority_read_concern="on") return parser @@ -384,8 +366,6 @@ def _update_config_vars(values): # pylint: disable=too-many-statements _config.ARCHIVE_LIMIT_MB = config.pop("archive_limit_mb") _config.ARCHIVE_LIMIT_TESTS = config.pop("archive_limit_tests") _config.BASE_PORT = int(config.pop("base_port")) - _config.BENCHRUN_DEVICE = config.pop("benchrun_device") - _config.BENCHRUN_EMBEDDED_ROOT = config.pop("benchrun_embedded_root") _config.BUILDLOGGER_URL = config.pop("buildlogger_url") _config.DBPATH_PREFIX = _expand_user(config.pop("dbpath_prefix")) _config.DBTEST_EXECUTABLE = _expand_user(config.pop("dbtest_executable")) @@ -398,7 +378,6 @@ def _update_config_vars(values): # pylint: disable=too-many-statements _config.MONGO_EXECUTABLE = _expand_user(config.pop("mongo_executable")) _config.MONGOD_EXECUTABLE = _expand_user(config.pop("mongod_executable")) _config.MONGOD_SET_PARAMETERS = config.pop("mongod_set_parameters") - _config.MONGOEBENCH_EXECUTABLE = _expand_user(config.pop("mongoebench_executable")) _config.MONGOS_EXECUTABLE = _expand_user(config.pop("mongos_executable")) _config.MONGOS_SET_PARAMETERS = config.pop("mongos_set_parameters") _config.NO_JOURNAL = config.pop("no_journal") @@ -443,7 +422,6 @@ def _update_config_vars(values): # pylint: disable=too-many-statements if benchmark_min_time is not None: _config.BENCHMARK_MIN_TIME = datetime.timedelta(seconds=benchmark_min_time) _config.BENCHMARK_REPETITIONS = config.pop("benchmark_repetitions") - _config.BENCHRUN_REPORT_ROOT = config.pop("benchrun_report_root") shuffle = config.pop("shuffle") if shuffle == "auto": diff --git a/buildscripts/resmokelib/selector.py b/buildscripts/resmokelib/selector.py index 197102b16b0..0ed27403cbc 100644 --- a/buildscripts/resmokelib/selector.py +++ b/buildscripts/resmokelib/selector.py @@ -676,7 +676,6 @@ _SELECTOR_REGISTRY = { "cpp_integration_test": (_CppTestSelectorConfig, _CppTestSelector), "cpp_unit_test": (_CppTestSelectorConfig, _CppTestSelector), "benchmark_test": (_CppTestSelectorConfig, _CppTestSelector), - "benchrun_embedded_test": (_JsonTestSelectorConfig, _Selector), "db_test": (_DbTestSelectorConfig, _DbTestSelector), "fsm_workload_test": (_JSTestSelectorConfig, _JSTestSelector), "parallel_fsm_workload_test": (_MultiJSTestSelectorConfig, _MultiJSTestSelector), diff --git a/buildscripts/resmokelib/testing/hooks/collect_embedded_resources.py b/buildscripts/resmokelib/testing/hooks/collect_embedded_resources.py deleted file mode 100644 index f6ddffc3963..00000000000 --- a/buildscripts/resmokelib/testing/hooks/collect_embedded_resources.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Module for generating and collecting embedded resource results.""" - -from __future__ import absolute_import - -import os - -from buildscripts.mobile import adb_monitor -from buildscripts.resmokelib import config as _config -from buildscripts.resmokelib.testing.hooks import interface - - -class CollectEmbeddedResources(interface.Hook): # pylint: disable=too-many-instance-attributes - """CollectEmbeddedResources class. - - CollectEmbeddedResources starts and stops the resource monitoring for each test. - """ - - DESCRIPTION = "Embedded resources" - - def __init__(self, hook_logger, fixture, sample_interval_ms=500, threads=1): - """Initialize CollectEmbeddedResources.""" - interface.Hook.__init__(self, hook_logger, fixture, CollectEmbeddedResources.DESCRIPTION) - self.hook_logger = hook_logger - self.adb = None - self.adb_control = None - if _config.BENCHRUN_DEVICE == "Android": - self.report_root = _config.BENCHRUN_REPORT_ROOT - self.sample_interval_ms = sample_interval_ms - self.threads = threads - self.battery_file = "battery.csv" - self.cpu_file = "cpu.json" - self.memory_file = "memory.csv" - self.adb = adb_monitor.Adb(logger=hook_logger) - - def before_test(self, test, test_report): - """Start ADB monitoring.""" - if self.adb: - battery_file = self._report_path(test, "battery.csv") - cpu_file = self._report_path(test, "cpu.json") - memory_file = self._report_path(test, "memory.csv") - self.adb_control = adb_monitor.AdbControl( - self.adb, logger=self.hook_logger, battery_file=battery_file, cpu_file=cpu_file, - memory_file=memory_file, sample_interval_ms=self.sample_interval_ms) - self.hook_logger.info("Starting ADB monitoring for test %s", test.short_name()) - self.hook_logger.info("ADB resource files: %s %s %s", battery_file, cpu_file, - memory_file) - self.adb_control.start() - - def after_test(self, test, test_report): - """Stop ADB monitoring.""" - if self.adb_control: - self.hook_logger.info("Stopping ADB monitoring for test %s", test.short_name()) - self.adb_control.stop() - - def _report_path(self, test, report_name): - """Return the report path. Reports are stored in <report_root>/<testname>/thread<num>/.""" - return os.path.join(self.report_root, test.short_name(), "thread{}".format(self.threads), - report_name) diff --git a/buildscripts/resmokelib/testing/hooks/combine_benchrun_embedded_results.py b/buildscripts/resmokelib/testing/hooks/combine_benchrun_embedded_results.py deleted file mode 100644 index b70e57d8741..00000000000 --- a/buildscripts/resmokelib/testing/hooks/combine_benchrun_embedded_results.py +++ /dev/null @@ -1,156 +0,0 @@ -"""Module for generating the test results file fed into the perf plugin.""" - -from __future__ import absolute_import -from __future__ import division - -import collections -import datetime -import glob -import json -import os -import re - -from buildscripts.resmokelib import config as _config -from buildscripts.resmokelib.testing.hooks import combine_benchmark_results as cbr - - -class CombineBenchrunEmbeddedResults(cbr.CombineBenchmarkResults): - """CombineBenchrunEmbeddedResults class. - - The CombineBenchrunEmbeddedResults hook combines test results from - individual benchmark embedded files to a single file. This is useful for - generating the json file to feed into the Evergreen performance - visualization plugin. - """ - - DESCRIPTION = "Combine JSON results from embedded benchrun" - - def __init__(self, hook_logger, fixture): - """Initialize CombineBenchrunEmbeddedResults.""" - cbr.CombineBenchmarkResults.__init__(self, hook_logger, fixture) - self.report_root = _config.BENCHRUN_REPORT_ROOT - - def before_test(self, test, test_report): - """Remove any existing mongoebench reports for this test.""" - for bm_report in self._test_result_files(test): - os.remove(bm_report) - - def after_test(self, test, test_report): - """Update test report.""" - for bm_report in self._test_result_files(test): - test_name = test.short_name() - thread_count = self._parse_report_name(bm_report) - with open(bm_report, "r") as report_file: - report_dict = json.load(report_file) - if test_name not in self.benchmark_reports: - self.benchmark_reports[test_name] = _BenchrunEmbeddedThreadsReport() - self.benchmark_reports[test_name].add_report(thread_count, report_dict) - - def before_suite(self, test_report): - """Set suite start time.""" - self.create_time = datetime.datetime.now() - # Remove any existing perf reports. - if self.report_file and os.path.isfile(self.report_file): - os.remove(self.report_file) - - def _generate_perf_plugin_report(self): - """Format the data to look like a perf plugin report.""" - perf_report = { - "start": self._strftime(self.create_time), - "end": self._strftime(self.end_time), - "errors": [], # There are no errors if we have gotten this far. - "results": [] - } - - for name, report in self.benchmark_reports.items(): - test_report = {"name": name, "results": report.generate_perf_plugin_dict()} - - perf_report["results"].append(test_report) - - return perf_report - - def _test_result_files(self, test): - """Return a list of existing test result files based on the test.short_name().""" - return glob.glob( - os.path.join(self.report_root, test.short_name(), "**", "mongoebench[.]*[.]json")) - - def _parse_report_name(self, report_path): - """Parse mongoebench report path and return thread_count. - - The format of the mongoebench report file name is defined in - ../testing/testcases/benchrun_embedded_test.py - as self.report_root/<test_name>/thread<num threads>/mongoebench.<iteration num>.json - """ - _, report_subpath = report_path.split(self.report_root + os.sep) - _, thread_name, _ = report_subpath.split(os.sep) - return re.findall(r"\d+", thread_name)[0] - - -class _BenchrunEmbeddedThreadsReport(object): - """_BenchrunEmbeddedThreadsReport class. - - Class representation of a report for all thread levels of a single - benchmark test. Each report is designed to correspond to one graph - in the Evergreen perf plugin. - - A raw mongoebench report looks like the following: - { - "note" : "values per second", - "errCount" : { "$numberLong" : "0" }, - "trapped" : "error: not implemented", - "insertLatencyAverageMicros" : 389.4926654182272, - "totalOps" : { "$numberLong" : "12816" }, - "totalOps/s" : 2563.095938304905, - "findOne" : 0, - "insert" : 2563.095938304905, - "delete" : 0, - "update" : 0, - "query" : 0, - "command" : 0, - "findOnes" : { "$numberLong" : "0" }, - "inserts" : { "$numberLong" : "12816" }, - "deletes" : { "$numberLong" : "0" }, - "updates" : { "$numberLong" : "0" }, - "queries" : { "$numberLong" : "0" }, - "commands" : { "$numberLong" : "0" } - } - """ - - def __init__(self): - # list of benchmark runs for each thread. - self.thread_benchmark_map = collections.defaultdict(list) - - def add_report(self, thread_count, report): - """Add to report.""" - self.thread_benchmark_map[thread_count].append(report) - - def generate_perf_plugin_dict(self): - """Generate perf plugin data points of the following format. - - "1": { - "error_values": [ - 0, - 0, - 0 - ], - "ops_per_sec": 9552.108279243452, - "ops_per_sec_values": [ - 9574.812658450564, - 9522.642340821469, - 9536.252775275878 - ] - }, - """ - - res = {} - for thread_count, reports in self.thread_benchmark_map.items(): - thread_report = {"error_values": [], "ops_per_sec_values": []} - - for report in reports: - thread_report["error_values"].append(report["errCount"]["$numberLong"]) - thread_report["ops_per_sec_values"].append(report["totalOps/s"]) - thread_report["ops_per_sec"] = sum(thread_report["ops_per_sec_values"]) / len(reports) - - res[thread_count] = thread_report - - return res diff --git a/buildscripts/resmokelib/testing/testcases/benchrun_embedded_test.py b/buildscripts/resmokelib/testing/testcases/benchrun_embedded_test.py deleted file mode 100644 index 89b95424cdb..00000000000 --- a/buildscripts/resmokelib/testing/testcases/benchrun_embedded_test.py +++ /dev/null @@ -1,149 +0,0 @@ -"""The unittest.TestCase for tests using benchrun embedded (mongoebench).""" - -from __future__ import absolute_import - -import os -import posixpath - -from buildscripts.mobile import adb_monitor -from buildscripts.resmokelib import config as _config -from buildscripts.resmokelib import core -from buildscripts.resmokelib import parser -from buildscripts.resmokelib import utils -from buildscripts.resmokelib.testing.testcases import interface - - -class BenchrunEmbeddedTestCase( # pylint: disable=too-many-instance-attributes - interface.ProcessTestCase): - """A Benchrun embedded test to execute.""" - - REGISTERED_NAME = "benchrun_embedded_test" - - def __init__(self, logger, mongoebench_config_file, program_options=None): - """Initialize the BenchrunEmbeddedTestCase with the executable to run.""" - - interface.ProcessTestCase.__init__(self, logger, "Benchmark embedded test", - mongoebench_config_file) - parser.validate_benchmark_options() - - self.benchrun_config_file = mongoebench_config_file - - # Command line options override the YAML configuration. - self.benchrun_executable = utils.default_if_none(_config.MONGOEBENCH_EXECUTABLE, - _config.DEFAULT_MONGOEBENCH_EXECUTABLE) - self.benchrun_repetitions = utils.default_if_none(_config.BENCHMARK_REPETITIONS, - _config.DEFAULT_BENCHMARK_REPETITIONS) - self.suite_benchrun_options = program_options - self.benchrun_threads = 1 - if program_options and "threads" in program_options: - self.benchrun_threads = program_options["threads"] - self.report_root = _config.BENCHRUN_REPORT_ROOT - self.benchrun_options = {} - - # Set the dbpath. - dbpath = utils.default_if_none(_config.DBPATH_PREFIX, _config.DEFAULT_DBPATH_PREFIX) - self.dbpath = os.path.join(dbpath, "mongoebench") - - self.android_device = _config.BENCHRUN_DEVICE == "Android" - # If Android device, then the test runs via adb shell. - if self.android_device: - self.adb = adb_monitor.Adb() - self.android_benchrun_root = _config.BENCHRUN_EMBEDDED_ROOT - self.device_report_root = posixpath.join(self.android_benchrun_root, "results") - self.dbpath = posixpath.join(self.android_benchrun_root, "db") - self.benchrun_config_file = posixpath.join(self.android_benchrun_root, "testcases", - os.path.basename(self.benchrun_config_file)) - ld_library_path = "LD_LIBRARY_PATH={}".format( - posixpath.join(self.android_benchrun_root, "sdk")) - mongoebench = posixpath.join(self.android_benchrun_root, "sdk", "mongoebench") - self.benchrun_executable = "adb shell {} {}".format(ld_library_path, mongoebench) - - def configure(self, fixture, *args, **kwargs): - """Configure BenchrunEmbeddedTestCase.""" - interface.ProcessTestCase.configure(self, fixture, *args, **kwargs) - - # 1. Set the default benchmark options. - benchrun_options = {"time": _config.DEFAULT_BENCHMARK_MIN_TIME.total_seconds()} - - # 2. Override Benchmark options with options set through `program_options` in the suite - # configuration. - suite_benchrun_options = utils.default_if_none(self.suite_benchrun_options, {}) - benchrun_options.update(suite_benchrun_options) - - # 3. Override Benchmark options with options set through resmoke's command line. - resmoke_benchrun_options = {"dbpath": self.dbpath, "time": _config.BENCHMARK_MIN_TIME} - - for key, value in resmoke_benchrun_options.items(): - if value is not None: - # 4. sanitize options before passing them to Benchmark's command line. - if key == "time": - value = value.total_seconds() - benchrun_options[key] = value - - self.benchrun_options = benchrun_options - - # Create the test report directory. - utils.rmtree(self._report_dir(), ignore_errors=True) - try: - os.makedirs(self._report_dir()) - except os.error: - # Directory already exists. - pass - - # Create the dbpath. - if self.android_device: - self.adb.shell("rm -fr {}".format(self.dbpath)) - self.adb.shell("mkdir {}".format(self.dbpath)) - else: - utils.rmtree(self.dbpath, ignore_errors=True) - try: - os.makedirs(self.dbpath) - except os.error: - # Directory already exists. - pass - - def run_test(self): - """Run the test for specified number of iterations.""" - for iter_num in xrange(self.benchrun_repetitions): - # Set the output file for each iteration. - local_report_path = self._report_path(iter_num) - device_report_path = self._device_report_path(iter_num) - self.benchrun_options["output"] = device_report_path - interface.ProcessTestCase.run_test(self) - self._move_report(device_report_path, local_report_path) - - def _move_report(self, remote_path, local_path): - """Move report from device to local directory.""" - if self.android_device: - # Pull test result from the Android device and then delete it from the device. - self.logger.info("Moving report %s from device to local %s ...", remote_path, - local_path) - self.adb.pull(remote_path, local_path) - self.adb.shell("rm {}".format(remote_path)) - - def _device_report_path(self, iter_num): - """Return the device report path.""" - if self.android_device: - # The mongoebench report is generated on the remote device. - return posixpath.join(self.device_report_root, self._report_name(iter_num)) - return self._report_path(iter_num) - - def _report_path(self, iter_num): - """Return the local report path.""" - return os.path.join(self._report_dir(), self._report_name(iter_num)) - - def _report_dir(self): - """Return the report directory. Reports are stored in <report_root>/<testname>/<thread>.""" - return os.path.join(self.report_root, self.short_name(), "thread{}".format( - self.benchrun_threads)) - - @staticmethod - def _report_name(iter_num): - """Return the constructed report name of the form mongoebench.<iteration num>.json.""" - return "mongoebench.{}.json".format(iter_num) - - def _make_process(self): - # The 'commands' argument for core.programs.generic_program must be a list. - commands = self.benchrun_executable.split() - commands.append(self.benchrun_config_file) - return core.programs.generic_program(self.logger, commands, **self.benchrun_options) diff --git a/buildscripts/tests/mobile/__init__.py b/buildscripts/tests/mobile/__init__.py deleted file mode 100644 index 4b7a2bb941b..00000000000 --- a/buildscripts/tests/mobile/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Empty.""" diff --git a/buildscripts/tests/mobile/test_adb_monitor.py b/buildscripts/tests/mobile/test_adb_monitor.py deleted file mode 100644 index c6680d6dd67..00000000000 --- a/buildscripts/tests/mobile/test_adb_monitor.py +++ /dev/null @@ -1,136 +0,0 @@ -""" Unit tests for adb_monitor. """ - -from __future__ import absolute_import - -import distutils.spawn # pylint: disable=no-name-in-module -import os -import shutil -import sys -import tempfile -import unittest - -import buildscripts.mobile.adb_monitor as adb_monitor - -_IS_WINDOWS = sys.platform == "win32" or sys.platform == "cygwin" - -if _IS_WINDOWS: - import win32file - -# pylint: disable=missing-docstring,protected-access - - -def mock_adb_and_systrace(directory): - """Mock adb and systrace.py.""" - # Create mock 'adb', which is really 'echo'. - adb_binary = os.path.join(directory, "adb") - echo_binary = distutils.spawn.find_executable("echo") - if _IS_WINDOWS: - adb_binary = "{}.exe".format(adb_binary) - shutil.copyfile(echo_binary, adb_binary) - else: - os.symlink(echo_binary, adb_binary) - os.environ["PATH"] = "{}{}{}".format(directory, os.path.pathsep, os.environ["PATH"]) - - # Create mock 'systrace.py'. - systrace_dir = os.path.join(directory, "systrace") - os.mkdir(systrace_dir) - systrace = os.path.join(systrace_dir, "systrace.py") - with open(systrace, "w") as fh: - fh.write("import optparse\n") - fh.write("raw_input('waiting...')\n") - fh.write("print('Wrote trace')\n") - fh.write("parser = optparse.OptionParser()\n") - fh.write("parser.add_option('-o', dest='output_file')\n") - fh.write("parser.add_option('--json', dest='json_opts', action='store_true')\n") - fh.write("options, args = parser.parse_args()\n") - fh.write("with open(options.output_file, 'w') as fh:\n") - fh.write("\tfh.write('{hello:1}')\n") - - -def file_contents(path): - with open(path, "r") as fh: - return fh.read() - - -class AdbTestCase(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.temp_dir = tempfile.mkdtemp() - mock_adb_and_systrace(cls.temp_dir) - cls.adb = adb_monitor.Adb() - - @classmethod - def tearDownClass(cls): - shutil.rmtree(cls.temp_dir) - - -class AdbTest(AdbTestCase): - def test_bad_adb(self): - self.assertRaises(EnvironmentError, lambda: adb_monitor.Adb("bad_adb")) - - def test_devices(self): - self.adb.devices() - - def test_battery(self): - temp_file = os.path.join(self.temp_dir, "battery_output") - self.adb.battery(output_file=temp_file) - self.assertTrue(os.path.isfile(temp_file)) - - def test_memory(self): - temp_file = os.path.join(self.temp_dir, "memory_output") - self.adb.memory(output_file=temp_file) - self.assertTrue(os.path.isfile(temp_file)) - - def test_systrace(self): - temp_file = os.path.join(self.temp_dir, "systrace_output") - self.adb.systrace_start(output_file=temp_file) - self.adb.systrace_stop() - self.assertTrue(os.path.isfile(temp_file)) - - -class AdbControlTestCase(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.temp_dir = tempfile.mkdtemp() - mock_adb_and_systrace(cls.temp_dir) - cls.adb = adb_monitor.Adb() - - @classmethod - def tearDownClass(cls): - shutil.rmtree(cls.temp_dir) - - -class AdbControlTest(AdbControlTestCase): - def _test_files(self, num_samples=1, collection_time_secs=0, sample_interval_ms=500, - arg_list=None): - args = {} - arg_file_list = [] - for arg_name in arg_list: - arg_test_file = tempfile.NamedTemporaryFile(delete=False).name - args[arg_name] = arg_test_file - arg_file_list.append(arg_test_file) - adb_control = adb_monitor.AdbControl(self.adb, collection_time_secs=collection_time_secs, - num_samples=num_samples, - sample_interval_ms=sample_interval_ms, **args) - adb_control.start() - adb_control.wait() - for arg_file in arg_file_list: - self.assertGreater(os.stat(arg_file).st_size, 0) - os.remove(arg_file) - - def test_all_files_num_samples(self): - self._test_files(num_samples=5, arg_list=["battery_file", "cpu_file", "memory_file"]) - - def test_all_files_collection_time_secs(self): - self._test_files(collection_time_secs=3, - arg_list=["battery_file", "cpu_file", "memory_file"]) - - def test_all_files_collection_and_samples(self): - self._test_files(collection_time_secs=3, num_samples=5, - arg_list=["battery_file", "cpu_file", "memory_file"]) - - def test_no_file_arg(self): - self.assertRaises(ValueError, lambda: adb_monitor.AdbControl(self.adb)) - - def test_bad_file_arg(self): - self.assertRaises(TypeError, lambda: self._test_files(arg_list=["bad_file_arg"])) diff --git a/buildscripts/tests/resmokelib/testing/hooks/test_combine_benchrun_embedded_results.py b/buildscripts/tests/resmokelib/testing/hooks/test_combine_benchrun_embedded_results.py deleted file mode 100755 index 02248602f4b..00000000000 --- a/buildscripts/tests/resmokelib/testing/hooks/test_combine_benchrun_embedded_results.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python -"""Unit tests for the resmokelib.testing.hooks.combine_benchrun_embedded_results module.""" - -from __future__ import absolute_import - -import datetime -import os -import unittest - -import mock - -import buildscripts.resmokelib.testing.hooks.combine_benchrun_embedded_results as cber - -# pylint: disable=missing-docstring,protected-access,attribute-defined-outside-init - -_BM_REPORT_INSERT_1 = { - "note": "values per second", "errCount": {"$numberLong": "0"}, - "trapped": "error: not implemented", "insertLatencyAverageMicros": 389.4926654182272, - "totalOps": {"$numberLong": "12816"}, "totalOps/s": 2563.095938304905, "findOne": 0, - "insert": 2563.095938304905, "delete": 0, "update": 0, "query": 0, "command": 0, "findOnes": { - "$numberLong": "0" - }, "inserts": {"$numberLong": "12816"}, "deletes": {"$numberLong": "0"}, "updates": { - "$numberLong": "0" - }, "queries": {"$numberLong": "0"}, "commands": {"$numberLong": "0"} -} - -_BM_REPORT_INSERT_2 = { - "note": "values per second", "errCount": {"$numberLong": "0"}, - "trapped": "error: not implemented", "insertLatencyAverageMicros": 2563.095938304905, - "totalOps": {"$numberLong": "7404"}, "totalOps/s": 2409.05, "findOne": 0, "insert": 2409.05, - "delete": 0, "update": 0, "query": 0, "command": 0, "findOnes": {"$numberLong": "0"}, - "inserts": {"$numberLong": "7404"}, "deletes": {"$numberLong": "0"}, "updates": { - "$numberLong": "0" - }, "queries": {"$numberLong": "0"}, "commands": {"$numberLong": "0"} -} - -_BM_REPORT_DELETE = { - "note": "values per second", "errCount": {"$numberLong": "0"}, - "trapped": "error: not implemented", "insertLatencyAverageMicros": "1234.56", "totalOps": { - "$numberLong": "2345" - }, "totalOps/s": 1234.56, "findOne": 0, "insert": 0, "delete": 1234.56, "update": 0, "query": 0, - "command": 0, "findOnes": {"$numberLong": "0"}, "inserts": {"$numberLong": "0"}, "deletes": { - "$numberLong": "2345" - }, "updates": {"$numberLong": "0"}, "queries": {"$numberLong": "0"}, - "commands": {"$numberLong": "0"} -} - -_BM_REPORT_UPDATE = { - "note": "values per second", "errCount": {"$numberLong": "0"}, - "trapped": "error: not implemented", "insertLatencyAverageMicros": 654.321, "totalOps": { - "$numberLong": "4521" - }, "totalOps/s": 4521.00, "findOne": 0, "insert": 0, "delete": 0, "update": 4521.00, "query": 0, - "command": 0, "findOnes": {"$numberLong": "0"}, "inserts": {"$numberLong": "0"}, "deletes": { - "$numberLong": "0" - }, "updates": {"$numberLong": "4521"}, "queries": {"$numberLong": "0"}, - "commands": {"$numberLong": "0"} -} - -_BM_REPORT_MULTI = { - "note": "values per second", "errCount": {"$numberLong": "0"}, - "trapped": "error: not implemented", "insertLatencyAverageMicros": 111.111, "totalOps": { - "$numberLong": "11532" - }, "totalOps/s": 5766.00, "findOne": 0, "insert": 2490.00, "delete": 0, "update": 9042.00, - "query": 0, "command": 0, "findOnes": {"$numberLong": "0"}, "inserts": { - "$numberLong": "2490.00" - }, "deletes": {"$numberLong": "0"}, "updates": {"$numberLong": "9042"}, - "queries": {"$numberLong": "0"}, "commands": {"$numberLong": "0"} -} - -_BM_ALL_REPORTS = [ - _BM_REPORT_INSERT_1, _BM_REPORT_INSERT_2, _BM_REPORT_DELETE, _BM_REPORT_UPDATE, _BM_REPORT_MULTI -] - -# 12/31/2999 @ 11:59pm (UTC) -_START_TIME = 32503679999 - -# 01/01/3000 @ 12:00am (UTC) -_END_TIME = 32503680000 - - -class CombineBenchrunEmbeddedResultsFixture(unittest.TestCase): - - # Mock the hook's parent class because we're testing only functionality of this hook and - # not anything related to or inherit from the parent class. - @mock.patch("buildscripts.resmokelib.testing.hooks.interface.Hook", autospec=True) - def setUp(self, MockHook): # pylint: disable=arguments-differ,unused-argument - self.cber_hook = cber.CombineBenchrunEmbeddedResults(None, None) - self.cber_hook.create_time = datetime.datetime.utcfromtimestamp(_START_TIME) - self.cber_hook.end_time = datetime.datetime.utcfromtimestamp(_END_TIME) - - -class TestCombineBenchmarkResults(CombineBenchrunEmbeddedResultsFixture): - def _setup_reports(self, reports, test_name, num_threads): - self.total_ops_per_sec = 0 - self.num_tests = len(reports) - self.cber_hook.benchmark_reports[test_name] = cber._BenchrunEmbeddedThreadsReport() - for rep in reports: - self.cber_hook.benchmark_reports[test_name].add_report(num_threads, rep) - self.total_ops_per_sec += rep["totalOps/s"] - self.ops_per_sec = self.total_ops_per_sec / self.num_tests - self.report = self.cber_hook._generate_perf_plugin_report() - - def test_generate_one_report(self): - test_name = "test_cber1" - num_threads = "2" - self._setup_reports([_BM_REPORT_MULTI], test_name, num_threads) - report_0 = self.report["results"][0] - self.assertEqual(report_0["name"], test_name) - self.assertEqual(report_0["results"][str(num_threads)]["ops_per_sec"], self.ops_per_sec) - - def test_generate_all_reports(self): - test_name = "test_cber2" - thread_num = "1" - self._setup_reports(_BM_ALL_REPORTS, test_name, thread_num) - self.assertEqual(len(self.report.keys()), 4) - report_0 = self.report["results"][0] - self.assertEqual(report_0["name"], test_name) - self.assertEqual(report_0["results"][thread_num]["ops_per_sec"], self.ops_per_sec) - self.assertEqual(self.report["start"], "2999-12-31T23:59:59Z") - self.assertEqual(self.report["end"], "3000-01-01T00:00:00Z") - - def test_parse_report_name(self): - self.cber_hook.report_root = os.path.join("benchrun_embedded", "results") - test_name = "test1" - thread_num = 3 - file_name = os.path.join(self.cber_hook.report_root, test_name, - "thread{}".format(thread_num), "mongoebench.0.json") - report_threads = self.cber_hook._parse_report_name(file_name) - self.assertEqual(thread_num, int(report_threads)) - - -class TestBenchrunEmbeddedThreadsReport(CombineBenchrunEmbeddedResultsFixture): - def test_generate_single_thread_perf_plugin_dict(self): - thread_report = cber._BenchrunEmbeddedThreadsReport() - thread_num = "1" - thread_report.add_report(thread_num, _BM_REPORT_INSERT_1) - perf_report = thread_report.generate_perf_plugin_dict() - self.assertEqual(len(perf_report.keys()), 1) - self.assertEqual(perf_report[thread_num]["ops_per_sec"], _BM_REPORT_INSERT_1["totalOps/s"]) - self.assertEqual(len(perf_report[thread_num]["ops_per_sec_values"]), 1) - - thread_report.add_report(thread_num, _BM_REPORT_INSERT_2) - perf_report = thread_report.generate_perf_plugin_dict() - self.assertEqual(len(perf_report.keys()), 1) - ops_per_sec = (_BM_REPORT_INSERT_1["totalOps/s"] + _BM_REPORT_INSERT_2["totalOps/s"]) / 2 - self.assertEqual(perf_report[thread_num]["ops_per_sec"], ops_per_sec) - self.assertEqual(len(perf_report[thread_num]["ops_per_sec_values"]), 2) - - def test_generate_multi_thread_perf_plugin_dict(self): - thread_report = cber._BenchrunEmbeddedThreadsReport() - thread_num = "1" - thread_report.add_report(thread_num, _BM_REPORT_INSERT_1) - perf_report = thread_report.generate_perf_plugin_dict() - self.assertEqual(len(perf_report.keys()), 1) - self.assertEqual(perf_report[thread_num]["ops_per_sec"], _BM_REPORT_INSERT_1["totalOps/s"]) - self.assertEqual(len(perf_report[thread_num]["ops_per_sec_values"]), 1) - - thread_num = "2" - thread_report.add_report(thread_num, _BM_REPORT_INSERT_2) - perf_report = thread_report.generate_perf_plugin_dict() - self.assertEqual(len(perf_report.keys()), 2) - self.assertEqual(perf_report["1"]["ops_per_sec"], _BM_REPORT_INSERT_1["totalOps/s"]) - self.assertEqual(len(perf_report["1"]["ops_per_sec_values"]), 1) - self.assertEqual(perf_report[thread_num]["ops_per_sec"], _BM_REPORT_INSERT_2["totalOps/s"]) - self.assertEqual(len(perf_report[thread_num]["ops_per_sec_values"]), 1) |
