summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXianyuan Jia <xianyuanjia@google.com>2020-09-21 23:33:34 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-09-21 23:33:34 +0000
commit0c116842e63386489df33f1a7effd9e214adb9a9 (patch)
tree828b504953765744843fcf2c62917677bb897077
parent1c67772fe901133cfbde69c0bf6f1bf19d12d186 (diff)
parent4a726f3bf999f35fd3e970acb23926bbc3cb9468 (diff)
downloadplatform_tools_test_connectivity-0c116842e63386489df33f1a7effd9e214adb9a9.tar.gz
platform_tools_test_connectivity-0c116842e63386489df33f1a7effd9e214adb9a9.tar.bz2
platform_tools_test_connectivity-0c116842e63386489df33f1a7effd9e214adb9a9.zip
Merge "[DO NOT MERGE] remove instrumentation framework and tests from AOSP"
-rw-r--r--acts/framework/acts/test_utils/instrumentation/config_wrapper.py81
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/apps/__init__.py0
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/apps/app_installer.py119
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/apps/dismiss_dialogs.py68
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/apps/hotword_model_extractor.py71
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/apps/permissions.py45
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/command/adb_command_types.py130
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/__init__.py0
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/common.py147
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/goog.py77
-rw-r--r--acts/framework/acts/test_utils/instrumentation/device/command/intent_builder.py83
-rw-r--r--acts/framework/acts/test_utils/instrumentation/instrumentation_base_test.py264
-rw-r--r--acts/framework/acts/test_utils/instrumentation/instrumentation_proto_parser.py124
-rw-r--r--acts/framework/acts/test_utils/instrumentation/power/__init__.py0
-rw-r--r--acts/framework/acts/test_utils/instrumentation/power/instrumentation_power_test.py486
-rw-r--r--acts/framework/acts/test_utils/instrumentation/power/power_metrics.py298
-rw-r--r--acts/framework/acts/test_utils/instrumentation/proto/gen/instrumentation_data_pb2.py345
-rw-r--r--acts/framework/acts/test_utils/instrumentation/proto/instrumentation_data.proto67
-rwxr-xr-xacts/framework/tests/test_utils/instrumentation/config_wrapper_test.py110
-rw-r--r--acts/framework/tests/test_utils/instrumentation/data/sample.instrumentation_data_proto6
-rw-r--r--acts/framework/tests/test_utils/instrumentation/data/sample_instrumentation_proto.txt17
-rw-r--r--acts/framework/tests/test_utils/instrumentation/data/sample_monsoon_data10
-rw-r--r--acts/framework/tests/test_utils/instrumentation/data/sample_timestamp.instrumentation_data_proto94
-rw-r--r--acts/framework/tests/test_utils/instrumentation/data/sample_timestamp_proto.txt110
-rw-r--r--acts/framework/tests/test_utils/instrumentation/device/apps/__init__.py0
-rw-r--r--acts/framework/tests/test_utils/instrumentation/device/apps/dismiss_dialogs_test.py72
-rw-r--r--acts/framework/tests/test_utils/instrumentation/device/apps/hotword_model_extractor_test.py73
-rw-r--r--acts/framework/tests/test_utils/instrumentation/device/apps/permissions_test.py48
-rwxr-xr-xacts/framework/tests/test_utils/instrumentation/device/command/adb_command_types_test.py152
-rw-r--r--acts/framework/tests/test_utils/instrumentation/device/command/intent_builder_test.py102
-rwxr-xr-xacts/framework/tests/test_utils/instrumentation/instrumentation_base_test_test.py80
-rw-r--r--acts/framework/tests/test_utils/instrumentation/instrumentation_proto_parser_test.py81
-rw-r--r--acts/framework/tests/test_utils/instrumentation/power/__init__.py0
-rw-r--r--acts/framework/tests/test_utils/instrumentation/power/instrumentation_power_test_test.py280
-rw-r--r--acts/framework/tests/test_utils/instrumentation/power/power_metrics_test.py159
-rwxr-xr-xacts/framework/tests/test_utils/instrumentation/unit_test_suite.py32
-rw-r--r--acts/tests/google/instrumentation/power/camera/CapturePhotosTest.py46
-rw-r--r--acts/tests/google/instrumentation/power/idle/DisplayAlwaysOnTest.py39
-rw-r--r--acts/tests/google/instrumentation/power/idle/PartialWakeLockTest.py32
-rw-r--r--acts/tests/google/instrumentation/power/idle/RockBottomTest.py32
-rw-r--r--acts/tests/google/instrumentation/power/media/VideoPlaybackTest.py43
41 files changed, 0 insertions, 4023 deletions
diff --git a/acts/framework/acts/test_utils/instrumentation/config_wrapper.py b/acts/framework/acts/test_utils/instrumentation/config_wrapper.py
deleted file mode 100644
index 4bd1aa37f2..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/config_wrapper.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import collections
-import os
-
-
-class InvalidParamError(Exception):
- pass
-
-
-class ConfigWrapper(collections.UserDict):
- """Class representing a test or preparer config."""
-
- def __init__(self, config=None):
- """Initialize a ConfigWrapper
-
- Args:
- config: A dict representing the preparer/test parameters
- """
- if config is None:
- config = {}
- super().__init__(
- {
- key: (ConfigWrapper(val) if isinstance(val, dict) else val)
- for key, val in config.items()
- }
- )
-
- def get(self, param_name, default=None, verify_fn=lambda _: True,
- failure_msg=''):
- """Get parameter from config, verifying that the value is valid
- with verify_fn.
-
- Args:
- param_name: Name of the param to fetch
- default: Default value of param.
- verify_fn: Callable to verify the param value. If it returns False,
- an exception will be raised.
- failure_msg: Exception message upon verify_fn failure.
- """
- result = self.data.get(param_name, default)
- if not verify_fn(result):
- raise InvalidParamError('Invalid value "%s" for param %s. %s'
- % (result, param_name, failure_msg))
- return result
-
- def get_config(self, param_name):
- """Get a sub-config from config. Returns an empty ConfigWrapper if no
- such sub-config is found.
- """
- return self.get(param_name, default=ConfigWrapper())
-
- def get_int(self, param_name, default=0):
- """Get integer parameter from config. Will raise an exception
- if result is not of type int.
- """
- return self.get(param_name, default=default,
- verify_fn=lambda val: type(val) is int,
- failure_msg='Param must be of type int.')
-
- def get_numeric(self, param_name, default=0):
- """Get int or float parameter from config. Will raise an exception if
- result is not of type int or float.
- """
- return self.get(param_name, default=default,
- verify_fn=lambda val: type(val) in (int, float),
- failure_msg='Param must be of type int or float.')
diff --git a/acts/framework/acts/test_utils/instrumentation/device/apps/__init__.py b/acts/framework/acts/test_utils/instrumentation/device/apps/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/apps/__init__.py
+++ /dev/null
diff --git a/acts/framework/acts/test_utils/instrumentation/device/apps/app_installer.py b/acts/framework/acts/test_utils/instrumentation/device/apps/app_installer.py
deleted file mode 100644
index 1688f0b7f0..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/apps/app_installer.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import re
-
-from acts.libs.proc import job
-
-PKG_NAME_PATTERN = r"^package:\s+name='(?P<pkg_name>.*?)'"
-PM_PATH_PATTERN = r"^package:(?P<apk_path>.*)"
-
-
-class AppInstaller(object):
- """Class that represents an app on an Android device. Includes methods
- for install, uninstall, and getting info.
- """
- def __init__(self, ad, apk_path):
- """Initializes an AppInstaller.
-
- Args:
- ad: device to install the apk
- apk_path: path to the apk
- """
- self._ad = ad
- self._apk_path = apk_path
- self._pkg_name = None
-
- @staticmethod
- def pull_from_device(ad, pkg_name, dest):
- """Initializes an AppInstaller by pulling the apk file from the device,
- given the package name
-
- Args:
- ad: device on which the apk is installed
- pkg_name: package name
- dest: destination directory
- (Note: If path represents a directory, it must already exist as
- a directory)
-
- Returns: AppInstaller object representing the pulled apk, or None if
- package not installed
- """
- if not ad.is_apk_installed(pkg_name):
- ad.log.warning('Unable to find package %s on device. Pull aborted.'
- % pkg_name)
- return None
- path_on_device = re.compile(PM_PATH_PATTERN).search(
- ad.adb.shell('pm path %s' % pkg_name)).group('apk_path')
- ad.pull_files(path_on_device, dest)
- if os.path.isdir(dest):
- dest = os.path.join(dest, os.path.basename(path_on_device))
- return AppInstaller(ad, dest)
-
- @property
- def apk_path(self):
- return self._apk_path
-
- @property
- def pkg_name(self):
- """Get the package name corresponding to the apk from aapt
-
- Returns: The package name, or empty string if not found.
- """
- if self._pkg_name is None:
- dump = job.run(
- 'aapt dump badging %s' % self.apk_path,
- ignore_status=True).stdout
- match = re.compile(PKG_NAME_PATTERN).search(dump)
- self._pkg_name = match.group('pkg_name') if match else ''
- return self._pkg_name
-
- def install(self, *extra_args):
- """Installs the apk on the device.
-
- Args:
- extra_args: Additional flags to the ADB install command.
- Note that '-r' is included by default.
- """
- self._ad.log.info('Installing app %s from %s' %
- (self.pkg_name, self.apk_path))
- args = '-r %s' % ' '.join(extra_args)
- self._ad.adb.install('%s %s' % (args, self.apk_path))
-
- def uninstall(self, *extra_args):
- """Uninstalls the apk from the device.
-
- Args:
- extra_args: Additional flags to the uninstall command.
- """
- self._ad.log.info('Uninstalling app %s' % self.pkg_name)
- if not self.is_installed():
- self._ad.log.warning('Unable to uninstall app %s. App is not '
- 'installed.' % self.pkg_name)
- return
- self._ad.adb.shell(
- 'pm uninstall %s %s' % (' '.join(extra_args), self.pkg_name))
-
- def is_installed(self):
- """Verifies that the apk is installed on the device.
-
- Returns: True if the apk is installed on the device.
- """
- if not self.pkg_name:
- self._ad.log.warning('No package name found for %s' % self.apk_path)
- return False
- return self._ad.is_apk_installed(self.pkg_name)
diff --git a/acts/framework/acts/test_utils/instrumentation/device/apps/dismiss_dialogs.py b/acts/framework/acts/test_utils/instrumentation/device/apps/dismiss_dialogs.py
deleted file mode 100644
index 909326abcd..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/apps/dismiss_dialogs.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-
-from acts.test_utils.instrumentation.device.apps.app_installer import \
- AppInstaller
-from acts.test_utils.instrumentation.device.command.instrumentation_command_builder \
- import InstrumentationCommandBuilder
-
-DISMISS_DIALOGS_RUNNER = '.DismissDialogsInstrumentation'
-SCREENSHOTS_DIR = 'dialog-dismissal'
-DISMISS_DIALOGS_TIMEOUT = 300
-
-
-class DialogDismissalUtil(object):
- """Utility for dismissing app dialogs."""
- def __init__(self, dut, util_apk):
- self._dut = dut
- self._dismiss_dialogs_apk = AppInstaller(dut, util_apk)
- self._dismiss_dialogs_apk.install('-g')
-
- def dismiss_dialogs(self, apps, screenshots=True, quit_on_error=True):
- """Dismiss dialogs for the given apps.
-
- Args:
- apps: List of apps to dismiss dialogs
- screenshots: Boolean to enable screenshots upon dialog dismissal
- quit_on_error: Boolean to indicate if tool should quit on failure
- """
- if not apps:
- return
- if not isinstance(apps, list):
- apps = [apps]
- self._dut.log.info('Dismissing app dialogs for %s' % apps)
- cmd_builder = InstrumentationCommandBuilder()
- cmd_builder.set_manifest_package(self._dismiss_dialogs_apk.pkg_name)
- cmd_builder.set_runner(DISMISS_DIALOGS_RUNNER)
- cmd_builder.add_flag('-w')
- cmd_builder.add_key_value_param('apps', ','.join(apps))
- cmd_builder.add_key_value_param('screenshots', screenshots)
- cmd_builder.add_key_value_param('quitOnError', quit_on_error)
- self._dut.adb.shell(cmd_builder.build(),
- timeout=DISMISS_DIALOGS_TIMEOUT)
-
- # Pull screenshots if screenshots=True
- if screenshots:
- self._dut.pull_files(
- os.path.join(self._dut.external_storage_path, SCREENSHOTS_DIR),
- self._dut.device_log_path
- )
-
- def close(self):
- """Clean up util by uninstalling the dialog dismissal APK."""
- self._dismiss_dialogs_apk.uninstall()
diff --git a/acts/framework/acts/test_utils/instrumentation/device/apps/hotword_model_extractor.py b/acts/framework/acts/test_utils/instrumentation/device/apps/hotword_model_extractor.py
deleted file mode 100644
index 57386b97ad..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/apps/hotword_model_extractor.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import tempfile
-import zipfile
-
-from acts.test_utils.instrumentation.device.apps.app_installer \
- import AppInstaller
-
-DEFAULT_MODEL_NAME = 'en_us.mmap'
-MODEL_DIR = 'res/raw'
-
-
-class HotwordModelExtractor(object):
- """
- Extracts a voice model data file from the Hotword APK and pushes it
- onto the device.
- """
- def __init__(self, dut):
- self._dut = dut
-
- def extract_to_dut(self, hotword_pkg, model_name=DEFAULT_MODEL_NAME):
- with tempfile.TemporaryDirectory() as tmp_dir:
- extracted_model = self._extract(hotword_pkg, model_name, tmp_dir)
- if not extracted_model:
- return
- device_dir = self._dut.adb.shell('echo $EXTERNAL_STORAGE')
- self._dut.adb.push(
- extracted_model, os.path.join(device_dir, model_name))
-
- def _extract(self, hotword_pkg, model_name, dest):
- """Extracts the model file from the given Hotword APK.
-
- Args:
- hotword_pkg: Package name of the Hotword APK
- model_name: File name of the model file.
- dest: Destination directory
-
- Returns: Full path to the extracted model file.
- """
- self._dut.log.info('Extracting voice model from Hotword APK.')
- hotword_apk = AppInstaller.pull_from_device(
- self._dut, hotword_pkg, dest)
- if not hotword_apk:
- self._dut.log.warning('Cannot extract Hotword voice model: '
- 'Hotword APK not installed.')
- return None
-
- model_rel_path = os.path.join(MODEL_DIR, model_name)
- with zipfile.ZipFile(hotword_apk.apk_path) as hotword_zip:
- try:
- return hotword_zip.extract(model_rel_path, dest)
- except KeyError:
- self._dut.log.warning(
- 'Cannot extract Hotword voice model: Model file %s not '
- 'found.' % model_rel_path)
- return None
diff --git a/acts/framework/acts/test_utils/instrumentation/device/apps/permissions.py b/acts/framework/acts/test_utils/instrumentation/device/apps/permissions.py
deleted file mode 100644
index 3973751573..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/apps/permissions.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.device.apps.app_installer import \
- AppInstaller
-from acts.test_utils.instrumentation.device.command.instrumentation_command_builder \
- import InstrumentationCommandBuilder
-
-PERMISSION_RUNNER = '.PermissionInstrumentation'
-
-
-class PermissionsUtil(object):
- """Utility for granting all revoked runtime permissions."""
- def __init__(self, dut, util_apk):
- self._dut = dut
- self._permissions_apk = AppInstaller(dut, util_apk)
- self._permissions_apk.install()
-
- def grant_all(self):
- """Grant all runtime permissions with PermissionUtils."""
- self._dut.log.info('Granting all revoked runtime permissions.')
- cmd_builder = InstrumentationCommandBuilder()
- cmd_builder.set_manifest_package(self._permissions_apk.pkg_name)
- cmd_builder.set_runner(PERMISSION_RUNNER)
- cmd_builder.add_flag('-w')
- cmd_builder.add_flag('-r')
- cmd_builder.add_key_value_param('command', 'grant-all')
- self._dut.adb.shell(cmd_builder.build())
-
- def close(self):
- """Clean up util by uninstalling the permissions APK."""
- self._permissions_apk.uninstall()
diff --git a/acts/framework/acts/test_utils/instrumentation/device/command/adb_command_types.py b/acts/framework/acts/test_utils/instrumentation/device/command/adb_command_types.py
deleted file mode 100644
index 072e1aecf7..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/command/adb_command_types.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.device.command.intent_builder import \
- IntentBuilder
-
-
-class DeviceState(object):
- """Class for adb commands for setting device properties to a value."""
-
- def __init__(self, base_cmd, on_val='1', off_val='0'):
- """Create a DeviceState.
-
- Args:
- base_cmd: The base adb command. Needs to accept an argument/value to
- generate the full command.
- on_val: Value used for the 'on' state
- off_val: Value used for the 'off' state
- """
- self._base_cmd = base_cmd
- self._on_val = on_val
- self._off_val = off_val
-
- def set_value(self, *values):
- """Returns the adb command with the given arguments/values.
-
- Args:
- values: The value(s) to run the command with
- """
- try:
- return self._base_cmd % values
- except TypeError:
- return str.strip(' '.join(
- [self._base_cmd] + [str(value) for value in values]))
-
- def toggle(self, enabled):
- """Returns the command corresponding to the desired state.
-
- Args:
- enabled: True for the 'on' state.
- """
- return self.set_value(self._on_val if enabled else self._off_val)
-
-
-class DeviceSetprop(DeviceState):
- """Class for setprop commands."""
-
- def __init__(self, prop, on_val='1', off_val='0'):
- """Create a DeviceSetprop.
-
- Args:
- prop: Property name
- on_val: Value used for the 'on' state
- off_val: Value used for the 'off' state
- """
- super().__init__('setprop %s' % prop, on_val, off_val)
-
-
-class DeviceSetting(DeviceState):
- """Class for commands to set a settings.db entry to a value."""
-
- def __init__(self, namespace, setting, on_val='1', off_val='0'):
- """Create a DeviceSetting.
-
- Args:
- namespace: Namespace of the setting
- setting: Setting name
- on_val: Value used for the 'on' state
- off_val: Value used for the 'off' state
- """
- super().__init__('settings put %s %s' % (namespace, setting),
- on_val, off_val)
-
-
-class DeviceGServices(DeviceState):
- """Class for overriding a GServices value."""
-
- OVERRIDE_GSERVICES_INTENT = ('com.google.gservices.intent.action.'
- 'GSERVICES_OVERRIDE')
-
- def __init__(self, setting, on_val='true', off_val='false'):
- """Create a DeviceGServices.
-
- Args:
- setting: Name of the GServices setting
- on_val: Value used for the 'on' state
- off_val: Value used for the 'off' state
- """
- super().__init__(None, on_val, off_val)
- self._intent_builder = IntentBuilder('am broadcast')
- self._intent_builder.set_action(self.OVERRIDE_GSERVICES_INTENT)
- self._setting = setting
-
- def set_value(self, value):
- """Returns the adb command with the given value."""
- self._intent_builder.add_key_value_param(self._setting, value)
- return self._intent_builder.build()
-
-
-class DeviceBinaryCommandSeries(object):
- """Class for toggling multiple settings at once."""
-
- def __init__(self, binary_commands):
- """Create a DeviceBinaryCommandSeries.
-
- Args:
- binary_commands: List of commands for setting toggleable options
- """
- self.cmd_list = binary_commands
-
- def toggle(self, enabled):
- """Returns the list of command corresponding to the desired state.
-
- Args:
- enabled: True for the 'on' state.
- """
- return [cmd.toggle(enabled) for cmd in self.cmd_list]
diff --git a/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/__init__.py b/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/__init__.py
+++ /dev/null
diff --git a/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/common.py b/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/common.py
deleted file mode 100644
index bf853dc118..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/common.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.device.command.adb_command_types \
- import DeviceBinaryCommandSeries
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceSetprop
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceSetting
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceState
-
-GLOBAL = 'global'
-SYSTEM = 'system'
-SECURE = 'secure'
-
-"""Common device settings for power testing."""
-
-# TODO: add descriptions to each setting
-
-# Network/Connectivity
-
-airplane_mode = DeviceBinaryCommandSeries(
- [
- DeviceSetting(GLOBAL, 'airplane_mode_on'),
- DeviceState(
- 'am broadcast -a android.intent.action.AIRPLANE_MODE --ez state',
- 'true', 'false')
- ]
-)
-
-mobile_data = DeviceBinaryCommandSeries(
- [
- DeviceSetting(GLOBAL, 'mobile_data'),
- DeviceState('svc data', 'enable', 'disable')
- ]
-)
-
-cellular = DeviceSetting(GLOBAL, 'cell_on')
-
-wifi = DeviceBinaryCommandSeries(
- [
- DeviceSetting(GLOBAL, 'wifi_on'),
- DeviceState('svc wifi', 'enable', 'disable')
- ]
-)
-
-ethernet = DeviceState('ifconfig eth0', 'up', 'down')
-
-bluetooth = DeviceState('service call bluetooth_manager', '6', '8')
-
-nfc = DeviceState('svc nfc', 'enable', 'disable')
-
-
-# Calling
-
-disable_dialing = DeviceSetprop('ro.telephony.disable-call', 'true', 'false')
-
-
-# Screen
-
-screen_adaptive_brightness = DeviceSetting(SYSTEM, 'screen_brightness_mode')
-
-screen_brightness = DeviceSetting(SYSTEM, 'screen_brightness')
-
-screen_always_on = DeviceState('svc power stayon', 'true', 'false')
-
-screen_timeout_ms = DeviceSetting(SYSTEM, 'screen_off_timeout')
-
-doze_mode = DeviceSetting(SECURE, 'doze_enabled')
-
-doze_always_on = DeviceSetting(SECURE, 'doze_always_on')
-
-wake_gesture = DeviceSetting(SECURE, 'wake_gesture_enabled')
-
-screensaver = DeviceSetting(SECURE, 'screensaver_enabled')
-
-notification_led = DeviceSetting(SYSTEM, 'notification_light_pulse')
-
-
-# Accelerometer
-
-auto_rotate = DeviceSetting(SYSTEM, 'accelerometer_rotation')
-
-
-# Time
-
-auto_time = DeviceSetting(GLOBAL, 'auto_time')
-
-auto_timezone = DeviceSetting(GLOBAL, 'auto_timezone')
-
-timezone = DeviceSetprop('persist.sys.timezone')
-
-
-# Location
-
-location_gps = DeviceSetting(SECURE, 'location_providers_allowed',
- '+gps', '-gps')
-
-location_network = DeviceSetting(SECURE, 'location_providers_allowed',
- '+network', '-network')
-
-
-# Power
-
-battery_saver_mode = DeviceSetting(GLOBAL, 'low_power')
-
-battery_saver_trigger = DeviceSetting(GLOBAL, 'low_power_trigger_level')
-
-enable_full_batterystats_history = 'dumpsys batterystats --enable full-history'
-
-disable_doze = 'dumpsys deviceidle disable'
-
-
-# Sensors
-
-disable_sensors = 'dumpsys sensorservice restrict blah'
-
-MOISTURE_DETECTION_SETTING_FILE = '/sys/class/power_supply/usb/moisture_detection_enabled'
-disable_moisture_detection = 'echo 0 > %s' % MOISTURE_DETECTION_SETTING_FILE
-
-## Ambient EQ: https://support.google.com/googlenest/answer/9137130?hl=en
-ambient_eq = DeviceSetting(SECURE, 'display_white_balance_enabled')
-
-# Miscellaneous
-
-test_harness = DeviceBinaryCommandSeries(
- [
- DeviceSetprop('ro.monkey'),
- DeviceSetprop('ro.test_harness')
- ]
-)
-
-dismiss_keyguard = 'wm dismiss-keyguard'
diff --git a/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/goog.py b/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/goog.py
deleted file mode 100644
index 48f6bf1bf1..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/command/adb_commands/goog.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.device.command.adb_command_types \
- import DeviceBinaryCommandSeries
-from acts.test_utils.instrumentation.device.command.adb_command_types \
- import DeviceGServices
-from acts.test_utils.instrumentation.device.command.adb_command_types \
- import DeviceState
-
-"""Google-internal device settings for power testing."""
-
-# TODO: add descriptions to each setting
-
-# Location
-
-location_collection = DeviceGServices(
- 'location:collection_enabled', on_val='1', off_val='0')
-
-location_opt_in = DeviceBinaryCommandSeries(
- [
- DeviceState('content insert --uri content://com.google.settings/'
- 'partner --bind name:s:use_location_for_services '
- '--bind value:s:%s'),
- DeviceState('content insert --uri content://com.google.settings/'
- 'partner --bind name:s:network_location_opt_in '
- '--bind value:s:%s')
- ]
-)
-
-# Cast
-
-cast_broadcast = DeviceGServices('gms:cast:mdns_device_scanner:is_enabled')
-
-
-# Apps
-
-disable_playstore = 'pm disable-user com.android.vending'
-
-
-# Volta
-
-disable_volta = 'pm disable-user com.google.android.volta'
-
-
-# CHRE
-
-disable_chre = 'setprop ctl.stop vendor.chre'
-
-
-# MusicIQ
-
-disable_musiciq = 'pm disable-user com.google.intelligence.sense'
-
-
-# Hotword
-
-disable_hotword = (
- 'am start -a com.android.intent.action.MANAGE_VOICE_KEYPHRASES '
- '--ei com.android.intent.extra.VOICE_KEYPHRASE_ACTION 2 '
- '--es com.android.intent.extra.VOICE_KEYPHRASE_HINT_TEXT "demo" '
- '--es com.android.intent.extra.VOICE_KEYPHRASE_LOCALE "en-US" '
- 'com.android.hotwordenrollment.okgoogle/'
- 'com.android.hotwordenrollment.okgoogle.EnrollmentActivity')
diff --git a/acts/framework/acts/test_utils/instrumentation/device/command/intent_builder.py b/acts/framework/acts/test_utils/instrumentation/device/command/intent_builder.py
deleted file mode 100644
index a1cc529f7a..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/device/command/intent_builder.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import collections
-
-TYPE_TO_FLAG = collections.defaultdict(lambda: '--es')
-TYPE_TO_FLAG.update({bool: '--ez', int: '--ei', float: '--ef', str: '--es'})
-
-
-class IntentBuilder(object):
- """Helper class to build am broadcast <INTENT> commands."""
-
- def __init__(self, base_cmd=''):
- """Initializes the intent command builder.
-
- Args:
- base_cmd: The base am command, e.g. am broadcast, am start
- """
- self._base_cmd = base_cmd
- self._action = None
- self._component = None
- self._data_uri = None
- self._flags = []
- self._key_value_params = collections.OrderedDict()
-
- def set_action(self, action):
- """Set the intent action, as marked by the -a flag"""
- self._action = action
-
- def set_component(self, package, component=None):
- """Set the package and/or component, as marked by the -n flag.
- Only the package name will be used if no component is specified.
- """
- if component:
- self._component = '%s/%s' % (package, component)
- else:
- self._component = package
-
- def set_data_uri(self, data_uri):
- """Set the data URI, as marked by the -d flag"""
- self._data_uri = data_uri
-
- def add_flag(self, flag):
- """Add any additional flags to the intent argument"""
- self._flags.append(flag)
-
- def add_key_value_param(self, key, value=None):
- """Add any extra data as a key-value pair"""
- self._key_value_params[key] = value
-
- def build(self):
- """Returns the full intent command string."""
- cmd = [self._base_cmd]
- if self._action:
- cmd.append('-a %s' % self._action)
- if self._component:
- cmd.append('-n %s' % self._component)
- if self._data_uri:
- cmd.append('-d %s' % self._data_uri)
- cmd += self._flags
- for key, value in self._key_value_params.items():
- if value is None:
- cmd.append('--esn %s' % key)
- else:
- str_value = str(value)
- if isinstance(value, bool):
- str_value = str_value.lower()
- cmd.append(' '.join((TYPE_TO_FLAG[type(value)], key,
- str_value)))
- return ' '.join(cmd).strip()
diff --git a/acts/framework/acts/test_utils/instrumentation/instrumentation_base_test.py b/acts/framework/acts/test_utils/instrumentation/instrumentation_base_test.py
deleted file mode 100644
index 5b9fda3b54..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/instrumentation_base_test.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-
-import yaml
-from acts.keys import Config
-from acts.test_utils.instrumentation import instrumentation_proto_parser \
- as proto_parser
-from acts.test_utils.instrumentation.config_wrapper import ConfigWrapper
-from acts.test_utils.instrumentation.device.command.adb_commands import common
-
-from acts import base_test
-from acts import context
-from acts import utils
-
-RESOLVE_FILE_MARKER = 'FILE'
-FILE_NOT_FOUND = 'File is missing from ACTS config'
-DEFAULT_INSTRUMENTATION_CONFIG_FILE = 'instrumentation_config.yaml'
-
-
-class InstrumentationTestError(Exception):
- pass
-
-
-class InstrumentationBaseTest(base_test.BaseTestClass):
- """Base class for tests based on am instrument."""
-
- def __init__(self, configs):
- """Initialize an InstrumentationBaseTest
-
- Args:
- configs: Dict representing the test configuration
- """
- super().__init__(configs)
- # Take instrumentation config path directly from ACTS config if found,
- # otherwise try to find the instrumentation config in the same directory
- # as the ACTS config
- instrumentation_config_path = ''
- if 'instrumentation_config' in self.user_params:
- instrumentation_config_path = (
- self.user_params['instrumentation_config'][0])
- elif Config.key_config_path.value in self.user_params:
- instrumentation_config_path = os.path.join(
- self.user_params[Config.key_config_path.value],
- DEFAULT_INSTRUMENTATION_CONFIG_FILE)
- self._instrumentation_config = ConfigWrapper()
- if os.path.exists(instrumentation_config_path):
- self._instrumentation_config = self._load_instrumentation_config(
- instrumentation_config_path)
- self._class_config = self._instrumentation_config.get_config(
- self.__class__.__name__)
- else:
- self.log.warning(
- 'Instrumentation config file %s does not exist' %
- instrumentation_config_path)
-
- def _load_instrumentation_config(self, path):
- """Load the instrumentation config file into an
- InstrumentationConfigWrapper object.
-
- Args:
- path: Path to the instrumentation config file.
-
- Returns: The loaded instrumentation config as an
- InstrumentationConfigWrapper
- """
- try:
- with open(path, mode='r', encoding='utf-8') as f:
- config_dict = yaml.safe_load(f)
- except Exception as e:
- raise InstrumentationTestError(
- 'Cannot open or parse instrumentation config file %s'
- % path) from e
-
- # Write out a copy of the instrumentation config
- with open(os.path.join(
- self.log_path, 'instrumentation_config.yaml'),
- mode='w', encoding='utf-8') as f:
- yaml.safe_dump(config_dict, f)
-
- return ConfigWrapper(config_dict)
-
- def setup_class(self):
- """Class setup"""
- self.ad_dut = self.android_devices[0]
-
- def teardown_test(self):
- """Test teardown. Takes bugreport and cleans up device."""
- self._ad_take_bugreport(self.ad_dut, 'teardown_class',
- utils.get_current_epoch_time())
- self._cleanup_device()
-
- def _prepare_device(self):
- """Prepares the device for testing."""
- pass
-
- def _cleanup_device(self):
- """Clean up device after test completion."""
- pass
-
- def _get_merged_config(self, config_name):
- """Takes the configs with config_name from the base, testclass, and
- testcase levels and merges them together. When the same parameter is
- defined in different contexts, the value from the most specific context
- is taken.
-
- Example:
- self._instrumentation_config = {
- 'sample_config': {
- 'val_a': 5,
- 'val_b': 7
- },
- 'ActsTestClass': {
- 'sample_config': {
- 'val_b': 3,
- 'val_c': 6
- },
- 'acts_test_case': {
- 'sample_config': {
- 'val_c': 10,
- 'val_d': 2
- }
- }
- }
- }
-
- self._get_merged_config('sample_config') returns
- {
- 'val_a': 5,
- 'val_b': 3,
- 'val_c': 10,
- 'val_d': 2
- }
-
- Args:
- config_name: Name of the config to fetch
- Returns: The merged config, as a ConfigWrapper
- """
- merged_config = self._instrumentation_config.get_config(
- config_name)
- merged_config.update(self._class_config.get_config(config_name))
- if self.current_test_name:
- case_config = self._class_config.get_config(self.current_test_name)
- merged_config.update(case_config.get_config(config_name))
- return merged_config
-
- def get_files_from_config(self, config_key):
- """Get a list of file paths on host from self.user_params with the
- given key. Verifies that each file exists.
-
- Args:
- config_key: Key in which the files are found.
-
- Returns: list of str file paths
- """
- if config_key not in self.user_params:
- raise InstrumentationTestError(
- 'Cannot get files for key "%s": Key missing from config.'
- % config_key)
- files = self.user_params[config_key]
- for f in files:
- if not os.path.exists(f):
- raise InstrumentationTestError(
- 'Cannot get files for key "%s": No file exists for %s.' %
- (config_key, f))
- return files
-
- def get_file_from_config(self, config_key):
- """Get a single file path on host from self.user_params with the given
- key. See get_files_from_config for details.
- """
- return self.get_files_from_config(config_key)[-1]
-
- def adb_run(self, cmds):
- """Run the specified command, or list of commands, with the ADB shell.
-
- Args:
- cmds: A string or list of strings representing ADB shell command(s)
-
- Returns: dict mapping command to resulting stdout
- """
- if isinstance(cmds, str):
- cmds = [cmds]
- out = {}
- for cmd in cmds:
- out[cmd] = self.ad_dut.adb.shell(cmd)
- return out
-
- def adb_run_async(self, cmds):
- """Run the specified command, or list of commands, with the ADB shell.
- (async)
-
- Args:
- cmds: A string or list of strings representing ADB shell command(s)
-
- Returns: dict mapping command to resulting subprocess.Popen object
- """
- if isinstance(cmds, str):
- cmds = [cmds]
- procs = {}
- for cmd in cmds:
- procs[cmd] = self.ad_dut.adb.shell_nb(cmd)
- return procs
-
- def dump_instrumentation_result_proto(self):
- """Dump the instrumentation result proto as a human-readable txt file
- in the log directory.
-
- Returns: The parsed instrumentation_data_pb2.Session
- """
- session = proto_parser.get_session_from_device(self.ad_dut)
- proto_txt_path = os.path.join(
- context.get_current_context().get_full_output_path(),
- 'instrumentation_proto.txt')
- with open(proto_txt_path, 'w') as f:
- f.write(str(session))
- return session
-
- # Basic setup methods
-
- def mode_airplane(self):
- """Mode for turning on airplane mode only."""
- self.log.info('Enabling airplane mode.')
- self.adb_run(common.airplane_mode.toggle(True))
- self.adb_run(common.auto_time.toggle(False))
- self.adb_run(common.auto_timezone.toggle(False))
- self.adb_run(common.location_gps.toggle(False))
- self.adb_run(common.location_network.toggle(False))
- self.adb_run(common.wifi.toggle(False))
- self.adb_run(common.bluetooth.toggle(False))
-
- def mode_wifi(self):
- """Mode for turning on airplane mode and wifi."""
- self.log.info('Enabling airplane mode and wifi.')
- self.adb_run(common.airplane_mode.toggle(True))
- self.adb_run(common.location_gps.toggle(False))
- self.adb_run(common.location_network.toggle(False))
- self.adb_run(common.wifi.toggle(True))
- self.adb_run(common.bluetooth.toggle(False))
-
- def mode_bluetooth(self):
- """Mode for turning on airplane mode and bluetooth."""
- self.log.info('Enabling airplane mode and bluetooth.')
- self.adb_run(common.airplane_mode.toggle(True))
- self.adb_run(common.auto_time.toggle(False))
- self.adb_run(common.auto_timezone.toggle(False))
- self.adb_run(common.location_gps.toggle(False))
- self.adb_run(common.location_network.toggle(False))
- self.adb_run(common.wifi.toggle(False))
- self.adb_run(common.bluetooth.toggle(True))
diff --git a/acts/framework/acts/test_utils/instrumentation/instrumentation_proto_parser.py b/acts/framework/acts/test_utils/instrumentation/instrumentation_proto_parser.py
deleted file mode 100644
index bdff9b4061..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/instrumentation_proto_parser.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import collections
-import os
-import tempfile
-
-from acts.test_utils.instrumentation.proto.gen import instrumentation_data_pb2
-
-DEFAULT_INST_LOG_DIR = 'instrument-logs'
-
-START_TIMESTAMP = 'start'
-END_TIMESTAMP = 'end'
-
-
-class ProtoParserError(Exception):
- """Class for exceptions raised by the proto parser."""
-
-
-def pull_proto(ad, dest_dir, source_path=None):
- """Pull latest instrumentation result proto from device.
-
- Args:
- ad: AndroidDevice object
- dest_dir: Directory on the host where the proto will be sent
- source_path: Path on the device where the proto is generated. If None,
- pull the latest proto from DEFAULT_INST_PROTO_DIR.
-
- Returns: Path to the retrieved proto file
- """
- if source_path:
- filename = os.path.basename(source_path)
- else:
- default_full_proto_dir = os.path.join(
- ad.external_storage_path, DEFAULT_INST_LOG_DIR)
- filename = ad.adb.shell('ls %s -t | head -n1' % default_full_proto_dir)
- if not filename:
- raise ProtoParserError(
- 'No instrumentation result protos found at default location.')
- source_path = os.path.join(default_full_proto_dir, filename)
- ad.pull_files(source_path, dest_dir)
- dest_path = os.path.join(dest_dir, filename)
- if not os.path.exists(dest_path):
- raise ProtoParserError(
- 'Failed to pull instrumentation result proto: %s -> %s'
- % (source_path, dest_path))
- return dest_path
-
-
-def get_session_from_local_file(proto_file):
- """Get a instrumentation_data_pb2.Session object from a proto file on the
- host.
-
- Args:
- proto_file: Path to the proto file (on host)
-
- Returns: A instrumentation_data_pb2.Session
- """
- with open(proto_file, 'rb') as f:
- return instrumentation_data_pb2.Session.FromString(f.read())
-
-
-def get_session_from_device(ad, proto_file=None):
- """Get a instrumentation_data_pb2.Session object from a proto file on
- device.
-
- Args:
- ad: AndroidDevice object
- proto_file: Path to the proto file (on device). If None, defaults to
- latest proto from DEFAULT_INST_PROTO_DIR.
-
- Returns: A instrumentation_data_pb2.Session
- """
- with tempfile.TemporaryDirectory() as tmp_dir:
- pulled_proto = pull_proto(ad, tmp_dir, proto_file)
- return get_session_from_local_file(pulled_proto)
-
-
-def get_test_timestamps(session):
- """Parse an instrumentation_data_pb2.Session to get the timestamps for each
- test.
-
- Args:
- session: an instrumentation_data.Session object
-
- Returns: a dict in the format
- {
- <test name> : (<begin_time>, <end_time>),
- ...
- }
- """
- timestamps = collections.defaultdict(dict)
- for test_status in session.test_status:
- entries = test_status.results.entries
- # Timestamp entries have the key 'timestamp-message'
- if any(entry.key == 'timestamps-message' for entry in entries):
- test_name = None
- timestamp = None
- timestamp_type = None
- for entry in entries:
- if entry.key == 'test':
- test_name = entry.value_string
- if entry.key == 'timestamp':
- timestamp = entry.value_long
- if entry.key == 'start-timestamp':
- timestamp_type = START_TIMESTAMP
- if entry.key == 'end-timestamp':
- timestamp_type = END_TIMESTAMP
- if test_name and timestamp and timestamp_type:
- timestamps[test_name][timestamp_type] = timestamp
- return timestamps
diff --git a/acts/framework/acts/test_utils/instrumentation/power/__init__.py b/acts/framework/acts/test_utils/instrumentation/power/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/power/__init__.py
+++ /dev/null
diff --git a/acts/framework/acts/test_utils/instrumentation/power/instrumentation_power_test.py b/acts/framework/acts/test_utils/instrumentation/power/instrumentation_power_test.py
deleted file mode 100644
index 92b9ad70e3..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/power/instrumentation_power_test.py
+++ /dev/null
@@ -1,486 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import shutil
-import tempfile
-import time
-
-import tzlocal
-from acts.controllers.android_device import SL4A_APK_NAME
-from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger
-from acts.test_utils.instrumentation import instrumentation_proto_parser \
- as proto_parser
-from acts.test_utils.instrumentation.device.apps.app_installer import \
- AppInstaller
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceGServices
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceSetprop
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceSetting
-from acts.test_utils.instrumentation.device.command.adb_commands import common
-from acts.test_utils.instrumentation.device.command.adb_commands import goog
-from acts.test_utils.instrumentation.device.command.instrumentation_command_builder \
- import DEFAULT_NOHUP_LOG
-from acts.test_utils.instrumentation.device.command.instrumentation_command_builder \
- import InstrumentationTestCommandBuilder
-from acts.test_utils.instrumentation.instrumentation_base_test \
- import InstrumentationBaseTest
-from acts.test_utils.instrumentation.instrumentation_base_test \
- import InstrumentationTestError
-from acts.test_utils.instrumentation.instrumentation_proto_parser import \
- DEFAULT_INST_LOG_DIR
-from acts.test_utils.instrumentation.power.power_metrics import Measurement
-from acts.test_utils.instrumentation.power.power_metrics import PowerMetrics
-from acts.test_utils.instrumentation.device.apps.permissions import PermissionsUtil
-
-from acts import asserts
-from acts import context
-
-ACCEPTANCE_THRESHOLD = 'acceptance_threshold'
-AUTOTESTER_LOG = 'autotester.log'
-DEFAULT_PUSH_FILE_TIMEOUT = 180
-DISCONNECT_USB_FILE = 'disconnectusb.log'
-POLLING_INTERVAL = 0.5
-
-
-class InstrumentationPowerTest(InstrumentationBaseTest):
- """Instrumentation test for measuring and validating power metrics.
-
- Params:
- metric_logger: Blackbox metric logger used to store test metrics.
- _instr_cmd_builder: Builder for the instrumentation command
- """
-
- def __init__(self, configs):
- super().__init__(configs)
-
- self.metric_logger = BlackboxMappedMetricLogger.for_test_case()
- self._test_apk = None
- self._sl4a_apk = None
- self._instr_cmd_builder = None
- self._power_metrics = None
-
- def setup_class(self):
- super().setup_class()
- self.monsoon = self.monsoons[0]
- self._setup_monsoon()
-
- def setup_test(self):
- """Test setup"""
- super().setup_test()
- self._prepare_device()
- self._instr_cmd_builder = self.power_instrumentation_command_builder()
- return True
-
- def _prepare_device(self):
- """Prepares the device for power testing."""
- super()._prepare_device()
- self._cleanup_test_files()
- self._permissions_util = PermissionsUtil(
- self.ad_dut,
- self.get_file_from_config('permissions_apk'))
- self._permissions_util.grant_all()
- self._install_test_apk()
-
- def _cleanup_device(self):
- """Clean up device after power testing."""
- if self._test_apk:
- self._test_apk.uninstall()
- self._permissions_util.close()
- self._cleanup_test_files()
-
- def base_device_configuration(self):
- """Run the base setup commands for power testing."""
- self.log.info('Running base device setup commands.')
-
- self.ad_dut.adb.ensure_root()
- self.adb_run(common.dismiss_keyguard)
- self.ad_dut.ensure_screen_on()
-
- # Test harness flag
- self.adb_run(common.test_harness.toggle(True))
-
- # Calling
- self.adb_run(common.disable_dialing.toggle(True))
-
- # Screen
- self.adb_run(common.screen_always_on.toggle(True))
- self.adb_run(common.screen_adaptive_brightness.toggle(False))
-
- brightness_level = None
- if 'brightness_level' in self._instrumentation_config:
- brightness_level = self._instrumentation_config['brightness_level']
-
- if brightness_level is None:
- raise ValueError('no brightness level defined (or left as None) '
- 'and it is needed.')
-
- self.adb_run(common.screen_brightness.set_value(brightness_level))
- self.adb_run(common.screen_timeout_ms.set_value(1800000))
- self.adb_run(common.notification_led.toggle(False))
- self.adb_run(common.screensaver.toggle(False))
- self.adb_run(common.wake_gesture.toggle(False))
- self.adb_run(common.doze_mode.toggle(False))
- self.adb_run(common.doze_always_on.toggle(False))
-
- # Sensors
- self.adb_run(common.auto_rotate.toggle(False))
- self.adb_run(common.disable_sensors)
- self.adb_run(common.ambient_eq.toggle(False))
-
- if self.file_exists(common.MOISTURE_DETECTION_SETTING_FILE):
- self.adb_run(common.disable_moisture_detection)
-
- # Time
- self.adb_run(common.auto_time.toggle(False))
- self.adb_run(common.auto_timezone.toggle(False))
- self.adb_run(common.timezone.set_value(str(tzlocal.get_localzone())))
-
- # Location
- self.adb_run(common.location_gps.toggle(False))
- self.adb_run(common.location_network.toggle(False))
-
- # Power
- self.adb_run(common.battery_saver_mode.toggle(False))
- self.adb_run(common.battery_saver_trigger.set_value(0))
- self.adb_run(common.enable_full_batterystats_history)
- self.adb_run(common.disable_doze)
-
- # Camera
- self.adb_run(DeviceSetprop(
- 'camera.optbar.hdr', 'true', 'false').toggle(True))
-
- # Gestures
- gestures = {
- 'doze_pulse_on_pick_up': False,
- 'doze_pulse_on_double_tap': False,
- 'camera_double_tap_power_gesture_disabled': True,
- 'camera_double_twist_to_flip_enabled': False,
- 'assist_gesture_enabled': False,
- 'assist_gesture_silence_alerts_enabled': False,
- 'assist_gesture_wake_enabled': False,
- 'system_navigation_keys_enabled': False,
- 'camera_lift_trigger_enabled': False,
- 'doze_always_on': False,
- 'aware_enabled': False,
- 'doze_wake_screen_gesture': False,
- 'skip_gesture': False,
- 'silence_gesture': False
- }
- self.adb_run(
- [DeviceSetting(common.SECURE, k).toggle(v)
- for k, v in gestures.items()])
-
- # GServices
- self.adb_run(goog.location_collection.toggle(False))
- self.adb_run(goog.cast_broadcast.toggle(False))
- self.adb_run(DeviceGServices(
- 'location:compact_log_enabled').toggle(True))
- self.adb_run(DeviceGServices('gms:magictether:enable').toggle(False))
- self.adb_run(DeviceGServices('ocr.cc_ocr_enabled').toggle(False))
- self.adb_run(DeviceGServices(
- 'gms:phenotype:phenotype_flag:debug_bypass_phenotype').toggle(True))
- self.adb_run(DeviceGServices(
- 'gms_icing_extension_download_enabled').toggle(False))
-
- # Comms
- self.adb_run(common.wifi.toggle(False))
- self.adb_run(common.bluetooth.toggle(False))
- self.adb_run(common.airplane_mode.toggle(True))
-
- # Misc. Google features
- self.adb_run(goog.disable_playstore)
- self.adb_run(goog.disable_volta)
- self.adb_run(goog.disable_chre)
- self.adb_run(goog.disable_musiciq)
- self.adb_run(goog.disable_hotword)
-
- # Enable clock dump info
- self.adb_run('echo 1 > /d/clk/debug_suspend')
-
- def _setup_monsoon(self):
- """Set up the Monsoon controller for this testclass/testcase."""
- self.log.info('Setting up Monsoon %s' % self.monsoon.serial)
- monsoon_config = self._get_merged_config('Monsoon')
- self._monsoon_voltage = monsoon_config.get_numeric('voltage', 4.2)
- self.monsoon.set_voltage_safe(self._monsoon_voltage)
- if 'max_current' in monsoon_config:
- self.monsoon.set_max_current(
- monsoon_config.get_numeric('max_current'))
-
- self.monsoon.usb('on')
- self.monsoon.set_on_disconnect(self._on_disconnect)
- self.monsoon.set_on_reconnect(self._on_reconnect)
-
- self._disconnect_usb_timeout = monsoon_config.get_numeric(
- 'usb_disconnection_timeout', 240)
-
- self._measurement_args = dict(
- duration=monsoon_config.get_numeric('duration'),
- hz=monsoon_config.get_numeric('frequency'),
- measure_after_seconds=monsoon_config.get_numeric('delay')
- )
-
- def _on_disconnect(self):
- """Callback invoked by device disconnection from the Monsoon."""
- self.ad_dut.log.info('Disconnecting device.')
- self.ad_dut.stop_services()
- # Uninstall SL4A
- self._sl4a_apk = AppInstaller.pull_from_device(
- self.ad_dut, SL4A_APK_NAME, tempfile.mkdtemp(prefix='sl4a'))
- self._sl4a_apk.uninstall()
- time.sleep(1)
-
- def _on_reconnect(self):
- """Callback invoked by device reconnection to the Monsoon"""
- # Reinstall SL4A
- if not self.ad_dut.is_sl4a_installed() and self._sl4a_apk:
- self._sl4a_apk.install()
- shutil.rmtree(os.path.dirname(self._sl4a_apk.apk_path))
- self._sl4a_apk = None
- self.ad_dut.start_services()
- # Release wake lock to put device into sleep.
- self.ad_dut.droid.goToSleepNow()
- self.ad_dut.log.info('Device reconnected.')
-
- def _install_test_apk(self):
- """Installs test apk on the device."""
- test_apk_file = self.get_file_from_config('test_apk')
- self._test_apk = AppInstaller(self.ad_dut, test_apk_file)
- self._test_apk.install('-g')
- if not self._test_apk.is_installed():
- raise InstrumentationTestError('Failed to install test APK.')
-
- def _cleanup_test_files(self):
- """Remove test-generated files from the device."""
- self.ad_dut.log.info('Cleaning up test generated files.')
- for file_name in [DISCONNECT_USB_FILE, DEFAULT_INST_LOG_DIR,
- DEFAULT_NOHUP_LOG, AUTOTESTER_LOG]:
- path = os.path.join(self.ad_dut.external_storage_path, file_name)
- self.adb_run('rm -rf %s' % path)
-
- def trigger_scan_on_external_storage(self):
- cmd = 'am broadcast -a android.intent.action.MEDIA_MOUNTED '
- cmd = cmd + '-d file://%s ' % self.ad_dut.external_storage_path
- cmd = cmd + '--receiver-include-background'
- return self.adb_run(cmd)
-
- def file_exists(self, file_path):
- cmd = '(test -f %s && echo yes) || echo no' % file_path
- result = self.adb_run(cmd)
- if result[cmd] == 'yes':
- return True
- elif result[cmd] == 'no':
- return False
- raise ValueError('Couldn\'t determine if %s exists. '
- 'Expected yes/no, got %s' % (file_path, result[cmd]))
-
- def push_to_external_storage(self, file_path, dest=None,
- timeout=DEFAULT_PUSH_FILE_TIMEOUT):
- """Pushes a file to {$EXTERNAL_STORAGE} and returns its final location.
-
- Args:
- file_path: The file to be pushed.
- dest: Where within {$EXTERNAL_STORAGE} it should be pushed.
- timeout: Float number of seconds to wait for the file to be pushed.
-
- Returns: The absolute path where the file was pushed.
- """
- if dest is None:
- dest = os.path.basename(file_path)
-
- dest_path = os.path.join(self.ad_dut.external_storage_path, dest)
- self.log.info('clearing %s before pushing %s' % (dest_path, file_path))
- self.ad_dut.adb.shell('rm -rf %s', dest_path)
- self.log.info('pushing file %s to %s' % (file_path, dest_path))
- self.ad_dut.adb.push(file_path, dest_path, timeout=timeout)
- return dest_path
-
- # Test runtime utils
-
- def power_instrumentation_command_builder(self):
- """Return the default command builder for power tests"""
- builder = InstrumentationTestCommandBuilder.default()
- builder.set_manifest_package(self._test_apk.pkg_name)
- builder.set_nohup()
- return builder
-
- def _wait_for_disconnect_signal(self):
- """Poll the device for a disconnect USB signal file. This will indicate
- to the Monsoon that the device is ready to be disconnected.
- """
- self.log.info('Waiting for USB disconnect signal')
- disconnect_file = os.path.join(
- self.ad_dut.external_storage_path, DISCONNECT_USB_FILE)
- start_time = time.time()
- while time.time() < start_time + self._disconnect_usb_timeout:
- if self.ad_dut.adb.shell('ls %s' % disconnect_file):
- return
- time.sleep(POLLING_INTERVAL)
- raise InstrumentationTestError('Timeout while waiting for USB '
- 'disconnect signal.')
-
- def measure_power(self):
- """Measures power consumption with the Monsoon. See monsoon_lib API for
- details.
- """
- if not hasattr(self, '_measurement_args'):
- raise InstrumentationTestError('Missing Monsoon measurement args.')
-
- # Start measurement after receiving disconnect signal
- self._wait_for_disconnect_signal()
- power_data_path = os.path.join(
- context.get_current_context().get_full_output_path(), 'power_data')
- self.log.info('Starting Monsoon measurement.')
- self.monsoon.usb('auto')
- measure_start_time = time.time()
- result = self.monsoon.measure_power(
- **self._measurement_args, output_path=power_data_path)
- self.monsoon.usb('on')
- self.log.info('Monsoon measurement complete.')
-
- # Gather relevant metrics from measurements
- session = self.dump_instrumentation_result_proto()
- self._power_metrics = PowerMetrics(self._monsoon_voltage,
- start_time=measure_start_time)
- self._power_metrics.generate_test_metrics(
- PowerMetrics.import_raw_data(power_data_path),
- proto_parser.get_test_timestamps(session))
- self._log_metrics()
- return result
-
- def run_and_measure(self, instr_class, instr_method=None, req_params=None,
- extra_params=None):
- """Convenience method for setting up the instrumentation test command,
- running it on the device, and starting the Monsoon measurement.
-
- Args:
- instr_class: Fully qualified name of the instrumentation test class
- instr_method: Name of the instrumentation test method
- req_params: List of required parameter names
- extra_params: List of ad-hoc parameters to be passed defined as
- tuples of size 2.
-
- Returns: summary of Monsoon measurement
- """
- if instr_method:
- self._instr_cmd_builder.add_test_method(instr_class, instr_method)
- else:
- self._instr_cmd_builder.add_test_class(instr_class)
- params = {}
- instr_call_config = self._get_merged_config('instrumentation_call')
- # Add required parameters
- for param_name in req_params or []:
- params[param_name] = instr_call_config.get(
- param_name, verify_fn=lambda x: x is not None,
- failure_msg='%s is a required parameter.' % param_name)
- # Add all other parameters
- params.update(instr_call_config)
- for name, value in params.items():
- self._instr_cmd_builder.add_key_value_param(name, value)
-
- if extra_params:
- for name, value in extra_params:
- self._instr_cmd_builder.add_key_value_param(name, value)
-
- instr_cmd = self._instr_cmd_builder.build()
- self.log.info('Running instrumentation call: %s' % instr_cmd)
- self.adb_run_async(instr_cmd)
- return self.measure_power()
-
- def _log_metrics(self):
- """Record the collected metrics with the metric logger."""
- self.log.info('Obtained metrics summaries:')
- for k, m in self._power_metrics.test_metrics.items():
- self.log.info('%s %s' % (k, str(m.summary)))
-
- for metric_name in PowerMetrics.ALL_METRICS:
- for instr_test_name in self._power_metrics.test_metrics:
- metric_value = getattr(
- self._power_metrics.test_metrics[instr_test_name],
- metric_name).value
- # TODO: Refactor this into instr_test_name.metric_name
- self.metric_logger.add_metric(
- '%s__%s' % (metric_name, instr_test_name), metric_value)
-
- def validate_power_results(self, *instr_test_names):
- """Compare power measurements with target values and set the test result
- accordingly.
-
- Args:
- instr_test_names: Name(s) of the instrumentation test method.
- If none specified, defaults to all test methods run.
-
- Raises:
- signals.TestFailure if one or more metrics do not satisfy threshold
- """
- summaries = {}
- failure = False
- all_thresholds = self._get_merged_config(ACCEPTANCE_THRESHOLD)
-
- if not instr_test_names:
- instr_test_names = all_thresholds.keys()
-
- for instr_test_name in instr_test_names:
- try:
- test_metrics = self._power_metrics.test_metrics[instr_test_name]
- except KeyError:
- raise InstrumentationTestError(
- 'Unable to find test method %s in instrumentation output. '
- 'Check instrumentation call results in '
- 'instrumentation_proto.txt.'
- % instr_test_name)
-
- summaries[instr_test_name] = {}
- test_thresholds = all_thresholds.get_config(instr_test_name)
- for metric_name, metric in test_thresholds.items():
- try:
- actual_result = getattr(test_metrics, metric_name)
- except AttributeError:
- continue
-
- if 'unit_type' not in metric or 'unit' not in metric:
- continue
- unit_type = metric['unit_type']
- unit = metric['unit']
-
- lower_value = metric.get_numeric('lower_limit', float('-inf'))
- upper_value = metric.get_numeric('upper_limit', float('inf'))
- if 'expected_value' in metric and 'percent_deviation' in metric:
- expected_value = metric.get_numeric('expected_value')
- percent_deviation = metric.get_numeric('percent_deviation')
- lower_value = expected_value * (1 - percent_deviation / 100)
- upper_value = expected_value * (1 + percent_deviation / 100)
-
- lower_bound = Measurement(lower_value, unit_type, unit)
- upper_bound = Measurement(upper_value, unit_type, unit)
- summary_entry = {
- 'expected': '[%s, %s]' % (lower_bound, upper_bound),
- 'actual': str(actual_result.to_unit(unit))
- }
- summaries[instr_test_name][metric_name] = summary_entry
- if not lower_bound <= actual_result <= upper_bound:
- failure = True
- self.log.info('Summary of measurements: %s' % summaries)
- asserts.assert_false(
- failure,
- msg='One or more measurements do not meet the specified criteria',
- extras=summaries)
- asserts.explicit_pass(
- msg='All measurements meet the criteria',
- extras=summaries)
diff --git a/acts/framework/acts/test_utils/instrumentation/power/power_metrics.py b/acts/framework/acts/test_utils/instrumentation/power/power_metrics.py
deleted file mode 100644
index b41ae61741..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/power/power_metrics.py
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import math
-
-from acts.test_utils.instrumentation import instrumentation_proto_parser \
- as parser
-from acts.test_utils.instrumentation.instrumentation_base_test \
- import InstrumentationTestError
-
-# Unit type constants
-CURRENT = 'current'
-POWER = 'power'
-TIME = 'time'
-
-# Unit constants
-MILLIAMP = 'mA'
-AMP = 'A'
-AMPERE = AMP
-MILLIWATT = 'mW'
-WATT = 'W'
-MILLISECOND = 'ms'
-SECOND = 's'
-MINUTE = 'm'
-HOUR = 'h'
-
-CONVERSION_TABLES = {
- CURRENT: {
- MILLIAMP: 0.001,
- AMP: 1
- },
- POWER: {
- MILLIWATT: 0.001,
- WATT: 1
- },
- TIME: {
- MILLISECOND: 0.001,
- SECOND: 1,
- MINUTE: 60,
- HOUR: 3600
- }
-}
-
-
-class Measurement(object):
- """Base class for describing power measurement values. Each object contains
- an value and a unit. Enables some basic arithmetic operations with other
- measurements of the same unit type.
-
- Attributes:
- _value: Numeric value of the measurement
- _unit_type: Unit type of the measurement (e.g. current, power)
- _unit: Unit of the measurement (e.g. W, mA)
- """
-
- def __init__(self, value, unit_type, unit):
- if unit_type not in CONVERSION_TABLES:
- raise TypeError('%s is not a valid unit type' % unit_type)
- self._value = value
- self._unit_type = unit_type
- self._unit = unit
-
- # Convenience constructor methods
- @staticmethod
- def amps(amps):
- """Create a new current measurement, in amps."""
- return Measurement(amps, CURRENT, AMP)
-
- @staticmethod
- def watts(watts):
- """Create a new power measurement, in watts."""
- return Measurement(watts, POWER, WATT)
-
- @staticmethod
- def seconds(seconds):
- """Create a new time measurement, in seconds."""
- return Measurement(seconds, TIME, SECOND)
-
- # Comparison methods
-
- def __eq__(self, other):
- return self.value == other.to_unit(self._unit).value
-
- def __lt__(self, other):
- return self.value < other.to_unit(self._unit).value
-
- def __le__(self, other):
- return self == other or self < other
-
- # Addition and subtraction with other measurements
-
- def __add__(self, other):
- """Adds measurements of compatible unit types. The result will be in the
- same units as self.
- """
- return Measurement(self.value + other.to_unit(self._unit).value,
- self._unit_type, self._unit)
-
- def __sub__(self, other):
- """Subtracts measurements of compatible unit types. The result will be
- in the same units as self.
- """
- return Measurement(self.value - other.to_unit(self._unit).value,
- self._unit_type, self._unit)
-
- # String representation
-
- def __str__(self):
- return '%g%s' % (self._value, self._unit)
-
- def __repr__(self):
- return str(self)
-
- @property
- def unit(self):
- return self._unit
-
- @property
- def value(self):
- return self._value
-
- def to_unit(self, new_unit):
- """Create an equivalent measurement under a different unit.
- e.g. 0.5W -> 500mW
-
- Args:
- new_unit: Target unit. Must be compatible with current unit.
-
- Returns: A new measurement with the converted value and unit.
- """
- try:
- new_value = self._value * (
- CONVERSION_TABLES[self._unit_type][self._unit] /
- CONVERSION_TABLES[self._unit_type][new_unit])
- except KeyError:
- raise TypeError('Incompatible units: %s, %s' %
- (self._unit, new_unit))
- return Measurement(new_value, self._unit_type, new_unit)
-
-
-class PowerMetrics(object):
- """Class for processing raw power metrics generated by Monsoon measurements.
- Provides useful metrics such as average current, max current, and average
- power. Can generate individual test metrics.
-
- See section "Numeric metrics" below for available metrics.
- """
-
- def __init__(self, voltage, start_time=0):
- """Create a PowerMetrics.
-
- Args:
- voltage: Voltage of the measurement
- start_time: Start time of the measurement. Used for generating
- test-specific metrics.
- """
- self._voltage = voltage
- self._start_time = start_time
- self._num_samples = 0
- self._sum_currents = 0
- self._sum_squares = 0
- self._max_current = None
- self._min_current = None
- self.test_metrics = {}
-
- @staticmethod
- def import_raw_data(path):
- """Create a generator from a Monsoon data file.
-
- Args:
- path: path to raw data file
-
- Returns: generator that yields (timestamp, sample) per line
- """
- with open(path, 'r') as f:
- for line in f:
- time, sample = line.split()
- yield float(time[:-1]), float(sample)
-
- def update_metrics(self, sample):
- """Update the running metrics with the current sample.
-
- Args:
- sample: A current sample in Amps.
- """
- self._num_samples += 1
- self._sum_currents += sample
- self._sum_squares += sample ** 2
- if self._max_current is None or sample > self._max_current:
- self._max_current = sample
- if self._min_current is None or sample < self._min_current:
- self._min_current = sample
-
- def generate_test_metrics(self, raw_data, test_timestamps=None):
- """Split the data into individual test metrics, based on the timestamps
- given as a dict.
-
- Args:
- raw_data: raw data as list or generator of (timestamp, sample)
- test_timestamps: dict following the output format of
- instrumentation_proto_parser.get_test_timestamps()
- """
-
- # Initialize metrics for each test
- if test_timestamps is None:
- test_timestamps = {}
- test_starts = {}
- test_ends = {}
- for test_name, times in test_timestamps.items():
- self.test_metrics[test_name] = PowerMetrics(
- self._voltage, self._start_time)
- try:
- test_starts[test_name] = Measurement(
- times[parser.START_TIMESTAMP], TIME, MILLISECOND) \
- .to_unit(SECOND).value - self._start_time
- except KeyError:
- raise InstrumentationTestError(
- 'Missing start timestamp for test scenario "%s". Refer to '
- 'instrumentation_proto.txt for details.' % test_name)
- try:
- test_ends[test_name] = Measurement(
- times[parser.END_TIMESTAMP], TIME, MILLISECOND) \
- .to_unit(SECOND).value - self._start_time
- except KeyError:
- raise InstrumentationTestError(
- 'Missing end timestamp for test scenario "%s". Test '
- 'scenario may have terminated with errors. Refer to '
- 'instrumentation_proto.txt for details.' % test_name)
-
- # Assign data to tests based on timestamps
- for timestamp, sample in raw_data:
- self.update_metrics(sample)
- for test_name in test_timestamps:
- if test_starts[test_name] <= timestamp <= test_ends[test_name]:
- self.test_metrics[test_name].update_metrics(sample)
-
- # Numeric metrics
-
- ALL_METRICS = ('avg_current', 'max_current', 'min_current', 'stdev_current',
- 'avg_power')
-
- @property
- def avg_current(self):
- """Average current, in milliamps."""
- if not self._num_samples:
- return Measurement.amps(0).to_unit(MILLIAMP)
- return (Measurement.amps(self._sum_currents / self._num_samples)
- .to_unit(MILLIAMP))
-
- @property
- def max_current(self):
- """Max current, in milliamps."""
- return Measurement.amps(self._max_current or 0).to_unit(MILLIAMP)
-
- @property
- def min_current(self):
- """Min current, in milliamps."""
- return Measurement.amps(self._min_current or 0).to_unit(MILLIAMP)
-
- @property
- def stdev_current(self):
- """Standard deviation of current values, in milliamps."""
- if self._num_samples < 2:
- return Measurement.amps(0).to_unit(MILLIAMP)
- stdev = math.sqrt(
- (self._sum_squares - (
- self._num_samples * self.avg_current.to_unit(AMP).value ** 2))
- / (self._num_samples - 1))
- return Measurement.amps(stdev).to_unit(MILLIAMP)
-
- def current_to_power(self, current):
- """Converts a current value to a power value."""
- return (Measurement.watts(current.to_unit(AMP).value * self._voltage))
-
- @property
- def avg_power(self):
- """Average power, in milliwatts."""
- return self.current_to_power(self.avg_current).to_unit(MILLIWATT)
-
- @property
- def summary(self):
- """A summary of test metrics"""
- return {'average_current': str(self.avg_current),
- 'max_current': str(self.max_current),
- 'average_power': str(self.avg_power)}
diff --git a/acts/framework/acts/test_utils/instrumentation/proto/gen/instrumentation_data_pb2.py b/acts/framework/acts/test_utils/instrumentation/proto/gen/instrumentation_data_pb2.py
deleted file mode 100644
index 783cd22b09..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/proto/gen/instrumentation_data_pb2.py
+++ /dev/null
@@ -1,345 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: instrumentation_data.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf.internal import enum_type_wrapper
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='instrumentation_data.proto',
- package='android.am',
- syntax='proto2',
- serialized_pb=_b('\n\x1ainstrumentation_data.proto\x12\nandroid.am\"\xcf\x01\n\x12ResultsBundleEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x14\n\x0cvalue_string\x18\x02 \x01(\t\x12\x11\n\tvalue_int\x18\x03 \x01(\x11\x12\x13\n\x0bvalue_float\x18\x04 \x01(\x02\x12\x14\n\x0cvalue_double\x18\x05 \x01(\x01\x12\x12\n\nvalue_long\x18\x06 \x01(\x12\x12/\n\x0cvalue_bundle\x18\x07 \x01(\x0b\x32\x19.android.am.ResultsBundle\x12\x13\n\x0bvalue_bytes\x18\x08 \x01(\x0c\"@\n\rResultsBundle\x12/\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1e.android.am.ResultsBundleEntry\"M\n\nTestStatus\x12\x13\n\x0bresult_code\x18\x03 \x01(\x11\x12*\n\x07results\x18\x04 \x01(\x0b\x32\x19.android.am.ResultsBundle\"\x98\x01\n\rSessionStatus\x12\x32\n\x0bstatus_code\x18\x01 \x01(\x0e\x32\x1d.android.am.SessionStatusCode\x12\x12\n\nerror_text\x18\x02 \x01(\t\x12\x13\n\x0bresult_code\x18\x03 \x01(\x11\x12*\n\x07results\x18\x04 \x01(\x0b\x32\x19.android.am.ResultsBundle\"i\n\x07Session\x12+\n\x0btest_status\x18\x01 \x03(\x0b\x32\x16.android.am.TestStatus\x12\x31\n\x0esession_status\x18\x02 \x01(\x0b\x32\x19.android.am.SessionStatus*>\n\x11SessionStatusCode\x12\x14\n\x10SESSION_FINISHED\x10\x00\x12\x13\n\x0fSESSION_ABORTED\x10\x01\x42\x19\n\x17\x63om.android.commands.am')
-)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-_SESSIONSTATUSCODE = _descriptor.EnumDescriptor(
- name='SessionStatusCode',
- full_name='android.am.SessionStatusCode',
- filename=None,
- file=DESCRIPTOR,
- values=[
- _descriptor.EnumValueDescriptor(
- name='SESSION_FINISHED', index=0, number=0,
- options=None,
- type=None),
- _descriptor.EnumValueDescriptor(
- name='SESSION_ABORTED', index=1, number=1,
- options=None,
- type=None),
- ],
- containing_type=None,
- options=None,
- serialized_start=659,
- serialized_end=721,
-)
-_sym_db.RegisterEnumDescriptor(_SESSIONSTATUSCODE)
-
-SessionStatusCode = enum_type_wrapper.EnumTypeWrapper(_SESSIONSTATUSCODE)
-SESSION_FINISHED = 0
-SESSION_ABORTED = 1
-
-
-
-_RESULTSBUNDLEENTRY = _descriptor.Descriptor(
- name='ResultsBundleEntry',
- full_name='android.am.ResultsBundleEntry',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='key', full_name='android.am.ResultsBundleEntry.key', index=0,
- number=1, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=_b("").decode('utf-8'),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_string', full_name='android.am.ResultsBundleEntry.value_string', index=1,
- number=2, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=_b("").decode('utf-8'),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_int', full_name='android.am.ResultsBundleEntry.value_int', index=2,
- number=3, type=17, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_float', full_name='android.am.ResultsBundleEntry.value_float', index=3,
- number=4, type=2, cpp_type=6, label=1,
- has_default_value=False, default_value=float(0),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_double', full_name='android.am.ResultsBundleEntry.value_double', index=4,
- number=5, type=1, cpp_type=5, label=1,
- has_default_value=False, default_value=float(0),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_long', full_name='android.am.ResultsBundleEntry.value_long', index=5,
- number=6, type=18, cpp_type=2, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_bundle', full_name='android.am.ResultsBundleEntry.value_bundle', index=6,
- number=7, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='value_bytes', full_name='android.am.ResultsBundleEntry.value_bytes', index=7,
- number=8, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value=_b(""),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=43,
- serialized_end=250,
-)
-
-
-_RESULTSBUNDLE = _descriptor.Descriptor(
- name='ResultsBundle',
- full_name='android.am.ResultsBundle',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='entries', full_name='android.am.ResultsBundle.entries', index=0,
- number=1, type=11, cpp_type=10, label=3,
- has_default_value=False, default_value=[],
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=252,
- serialized_end=316,
-)
-
-
-_TESTSTATUS = _descriptor.Descriptor(
- name='TestStatus',
- full_name='android.am.TestStatus',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='result_code', full_name='android.am.TestStatus.result_code', index=0,
- number=3, type=17, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='results', full_name='android.am.TestStatus.results', index=1,
- number=4, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=318,
- serialized_end=395,
-)
-
-
-_SESSIONSTATUS = _descriptor.Descriptor(
- name='SessionStatus',
- full_name='android.am.SessionStatus',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='status_code', full_name='android.am.SessionStatus.status_code', index=0,
- number=1, type=14, cpp_type=8, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='error_text', full_name='android.am.SessionStatus.error_text', index=1,
- number=2, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=_b("").decode('utf-8'),
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='result_code', full_name='android.am.SessionStatus.result_code', index=2,
- number=3, type=17, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='results', full_name='android.am.SessionStatus.results', index=3,
- number=4, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=398,
- serialized_end=550,
-)
-
-
-_SESSION = _descriptor.Descriptor(
- name='Session',
- full_name='android.am.Session',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='test_status', full_name='android.am.Session.test_status', index=0,
- number=1, type=11, cpp_type=10, label=3,
- has_default_value=False, default_value=[],
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='session_status', full_name='android.am.Session.session_status', index=1,
- number=2, type=11, cpp_type=10, label=1,
- has_default_value=False, default_value=None,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- syntax='proto2',
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=552,
- serialized_end=657,
-)
-
-_RESULTSBUNDLEENTRY.fields_by_name['value_bundle'].message_type = _RESULTSBUNDLE
-_RESULTSBUNDLE.fields_by_name['entries'].message_type = _RESULTSBUNDLEENTRY
-_TESTSTATUS.fields_by_name['results'].message_type = _RESULTSBUNDLE
-_SESSIONSTATUS.fields_by_name['status_code'].enum_type = _SESSIONSTATUSCODE
-_SESSIONSTATUS.fields_by_name['results'].message_type = _RESULTSBUNDLE
-_SESSION.fields_by_name['test_status'].message_type = _TESTSTATUS
-_SESSION.fields_by_name['session_status'].message_type = _SESSIONSTATUS
-DESCRIPTOR.message_types_by_name['ResultsBundleEntry'] = _RESULTSBUNDLEENTRY
-DESCRIPTOR.message_types_by_name['ResultsBundle'] = _RESULTSBUNDLE
-DESCRIPTOR.message_types_by_name['TestStatus'] = _TESTSTATUS
-DESCRIPTOR.message_types_by_name['SessionStatus'] = _SESSIONSTATUS
-DESCRIPTOR.message_types_by_name['Session'] = _SESSION
-DESCRIPTOR.enum_types_by_name['SessionStatusCode'] = _SESSIONSTATUSCODE
-
-ResultsBundleEntry = _reflection.GeneratedProtocolMessageType('ResultsBundleEntry', (_message.Message,), dict(
- DESCRIPTOR = _RESULTSBUNDLEENTRY,
- __module__ = 'instrumentation_data_pb2'
- # @@protoc_insertion_point(class_scope:android.am.ResultsBundleEntry)
- ))
-_sym_db.RegisterMessage(ResultsBundleEntry)
-
-ResultsBundle = _reflection.GeneratedProtocolMessageType('ResultsBundle', (_message.Message,), dict(
- DESCRIPTOR = _RESULTSBUNDLE,
- __module__ = 'instrumentation_data_pb2'
- # @@protoc_insertion_point(class_scope:android.am.ResultsBundle)
- ))
-_sym_db.RegisterMessage(ResultsBundle)
-
-TestStatus = _reflection.GeneratedProtocolMessageType('TestStatus', (_message.Message,), dict(
- DESCRIPTOR = _TESTSTATUS,
- __module__ = 'instrumentation_data_pb2'
- # @@protoc_insertion_point(class_scope:android.am.TestStatus)
- ))
-_sym_db.RegisterMessage(TestStatus)
-
-SessionStatus = _reflection.GeneratedProtocolMessageType('SessionStatus', (_message.Message,), dict(
- DESCRIPTOR = _SESSIONSTATUS,
- __module__ = 'instrumentation_data_pb2'
- # @@protoc_insertion_point(class_scope:android.am.SessionStatus)
- ))
-_sym_db.RegisterMessage(SessionStatus)
-
-Session = _reflection.GeneratedProtocolMessageType('Session', (_message.Message,), dict(
- DESCRIPTOR = _SESSION,
- __module__ = 'instrumentation_data_pb2'
- # @@protoc_insertion_point(class_scope:android.am.Session)
- ))
-_sym_db.RegisterMessage(Session)
-
-
-DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.android.commands.am'))
-# @@protoc_insertion_point(module_scope)
diff --git a/acts/framework/acts/test_utils/instrumentation/proto/instrumentation_data.proto b/acts/framework/acts/test_utils/instrumentation/proto/instrumentation_data.proto
deleted file mode 100644
index 8e29f96455..0000000000
--- a/acts/framework/acts/test_utils/instrumentation/proto/instrumentation_data.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.am;
-
-option java_package = "com.android.commands.am";
-
-message ResultsBundleEntry {
- optional string key = 1;
-
- optional string value_string = 2;
- optional sint32 value_int = 3;
- optional float value_float = 4;
- optional double value_double = 5;
- optional sint64 value_long = 6;
- optional ResultsBundle value_bundle = 7;
- optional bytes value_bytes = 8;
-}
-
-message ResultsBundle {
- repeated ResultsBundleEntry entries = 1;
-}
-
-message TestStatus {
- optional sint32 result_code = 3;
- optional ResultsBundle results = 4;
-}
-
-enum SessionStatusCode {
- /**
- * The command ran successfully. This does not imply that the tests passed.
- */
- SESSION_FINISHED = 0;
-
- /**
- * There was an unrecoverable error running the tests.
- */
- SESSION_ABORTED = 1;
-}
-
-message SessionStatus {
- optional SessionStatusCode status_code = 1;
- optional string error_text = 2;
- optional sint32 result_code = 3;
- optional ResultsBundle results = 4;
-}
-
-message Session {
- repeated TestStatus test_status = 1;
- optional SessionStatus session_status = 2;
-}
-
-
diff --git a/acts/framework/tests/test_utils/instrumentation/config_wrapper_test.py b/acts/framework/tests/test_utils/instrumentation/config_wrapper_test.py
deleted file mode 100755
index 18a420fed0..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/config_wrapper_test.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import mock
-import unittest
-
-from acts.test_utils.instrumentation.config_wrapper import ConfigWrapper
-from acts.test_utils.instrumentation.config_wrapper import InvalidParamError
-
-
-REAL_PATHS = ['realpath/1', 'realpath/2']
-MOCK_CONFIG = {
- 'big_int': 50000,
- 'small_int': 5,
- 'float': 7.77,
- 'string': 'insert text here',
- 'real_paths_only': REAL_PATHS,
- 'real_and_fake_paths': [
- 'realpath/1', 'fakepath/0'
- ],
- 'inner_config': {
- 'inner_val': 16
- }
-}
-
-
-class ConfigWrapperTest(unittest.TestCase):
- """Unit tests for the Config Wrapper."""
- def setUp(self):
- self.mock_config = ConfigWrapper(MOCK_CONFIG)
-
- def test_get_returns_correct_value(self):
- """Test that get() returns the correct param value."""
- self.assertEqual(self.mock_config.get('big_int'),
- MOCK_CONFIG['big_int'])
-
- def test_get_missing_param_returns_default(self):
- """Test that get() returns the default value if no param with the
- requested name is found.
- """
- default_val = 17
- self.assertEqual(self.mock_config.get('missing', default=default_val),
- default_val)
-
- def test_get_with_custom_verification_method(self):
- """Test that get() verifies the param with the user-provided test
- function.
- """
- verifier = lambda i: i > 100
- msg = 'Value too small'
- self.assertEqual(self.mock_config.get('big_int', verify_fn=verifier,
- failure_msg=msg),
- MOCK_CONFIG['big_int'])
- with self.assertRaisesRegex(InvalidParamError, msg):
- self.mock_config.get('small_int', verify_fn=verifier,
- failure_msg=msg)
-
- def test_get_config(self):
- """Test that get_config() returns an empty ConfigWrapper if no
- sub-config exists with the given name.
- """
- ret = self.mock_config.get_config('missing')
- self.assertIsInstance(ret, ConfigWrapper)
- self.assertFalse(ret)
-
- def test_get_int(self):
- """Test that get_int() returns the value if it is an int, and raises
- an exception if it isn't.
- """
- self.assertEqual(self.mock_config.get_int('small_int'),
- MOCK_CONFIG['small_int'])
- with self.assertRaisesRegex(InvalidParamError, 'of type int'):
- self.mock_config.get_int('float')
-
- def test_get_numeric(self):
- """Test that get_numeric() returns the value if it is an int or float,
- and raises an exception if it isn't.
- """
- self.assertEqual(self.mock_config.get_numeric('small_int'),
- MOCK_CONFIG['small_int'])
- self.assertEqual(self.mock_config.get_numeric('float'),
- MOCK_CONFIG['float'])
- with self.assertRaisesRegex(InvalidParamError, 'of type int or float'):
- self.mock_config.get_numeric('string')
-
- def test_config_wrapper_wraps_recursively(self):
- """Test that dict values within the input config get transformed into
- ConfigWrapper objects themselves.
- """
- self.assertTrue(
- isinstance(self.mock_config.get('inner_config'), ConfigWrapper))
- self.assertEqual(
- self.mock_config.get('inner_config').get_int('inner_val'), 16)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/data/sample.instrumentation_data_proto b/acts/framework/tests/test_utils/instrumentation/data/sample.instrumentation_data_proto
deleted file mode 100644
index 42892d5f08..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/data/sample.instrumentation_data_proto
+++ /dev/null
@@ -1,6 +0,0 @@
-a]INSTRUMENTATION_FAILED: com.google.android.powertests/androidx.test.runner.AndroidJUnitRunner
-¬"§
-†
-Error}Unable to find instrumentation info for: ComponentInfo{com.google.android.powertests/androidx.test.runner.AndroidJUnitRunner}
-
-idActivityManagerService \ No newline at end of file
diff --git a/acts/framework/tests/test_utils/instrumentation/data/sample_instrumentation_proto.txt b/acts/framework/tests/test_utils/instrumentation/data/sample_instrumentation_proto.txt
deleted file mode 100644
index 6de10d7e0e..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/data/sample_instrumentation_proto.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-test_status {
- result_code: -1
- results {
- entries {
- key: "Error"
- value_string: "Unable to find instrumentation info for: ComponentInfo{com.google.android.powertests/androidx.test.runner.AndroidJUnitRunner}"
- }
- entries {
- key: "id"
- value_string: "ActivityManagerService"
- }
- }
-}
-session_status {
- status_code: SESSION_ABORTED
- error_text: "INSTRUMENTATION_FAILED: com.google.android.powertests/androidx.test.runner.AndroidJUnitRunner"
-}
diff --git a/acts/framework/tests/test_utils/instrumentation/data/sample_monsoon_data b/acts/framework/tests/test_utils/instrumentation/data/sample_monsoon_data
deleted file mode 100644
index 2a70273694..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/data/sample_monsoon_data
+++ /dev/null
@@ -1,10 +0,0 @@
-0s 3.67
-1s 3.69
-2s 0.95
-3s 3.06
-4s 2.17
-5s 1.62
-6s 3.95
-7s 2.47
-8s 1.11
-9s 0.47
diff --git a/acts/framework/tests/test_utils/instrumentation/data/sample_timestamp.instrumentation_data_proto b/acts/framework/tests/test_utils/instrumentation/data/sample_timestamp.instrumentation_data_proto
deleted file mode 100644
index ecc75a50c7..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/data/sample_timestamp.instrumentation_data_proto
+++ /dev/null
@@ -1,94 +0,0 @@
-
-Æ"Á
-6
-class-com.google.android.powertests.PartialWakelock
-
-current
-
-idAndroidJUnitRunner
-
-numtests
-9
-stream/
-com.google.android.powertests.PartialWakelock:
-
-testpartialWakelock
-À#"Ž
-6
-class-com.google.android.powertests.PartialWakelock
-
-start-timestamp
-
-testpartialWakelock
-
- timestamp0Ôá—¤›[
-
-timestamps-message*¬"--------- beginning of main
-08-28 15:05:16.598 10178 7664 7664 I MonitoringInstr: Activities that are still in CREATED to STOPPED: 0
-08-28 15:05:16.601 10178 7664 7696 D com.google.android.powertests.PartialWakelock: fixture setup
-08-28 15:05:16.601 10178 7664 7696 I com.android.test.power.utils.Screen: Setting Screen Off
-08-28 15:05:16.684 10117 2426 7573 I ChromeSync: [Persistence,AffiliationManager] Fetching affiliations from the server.
-08-28 15:05:16.721 10117 2426 7573 E ChromeSync: [Sync,SyncIntentOperation] Error handling the intent: Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.google.android.powertests flg=0x4000010 cmp=com.google.android.gms/.chimera.GmsIntentOperationService (has extras) }.
-08-28 15:05:16.736 10117 2426 31227 I Icing : IndexChimeraService.getServiceInterface callingPackage=com.google.android.gms componentName=AppsCorpus serviceId=32
-08-28 15:05:16.737 10117 2426 16984 I Icing : IndexChimeraService.getServiceInterface callingPackage=com.google.android.gms componentName=AppsCorpus serviceId=36
---------- beginning of system
-08-28 15:05:16.774 1000 940 2043 W ProcessStats: Tracking association SourceState{7e3b0a1 com.google.android.gms.persistent/10117 ImpFg #71619} whose proc state 2 is better than process ProcessState{55175ae com.google.android.gms/10117 pkg=com.google.android.gms} proc state 3 (73 skipped)
-08-28 15:05:16.808 10117 2426 6018 I Icing : Usage reports ok 0, Failed Usage reports 0, indexed 0, rejected 0
-08-28 15:05:16.840 1000 940 2512 I ActivityManager: Force stopping com.googlecode.android_scripting appid=1000 user=0: from pid 7728
-08-28 15:05:16.841 1000 940 2512 I ActivityManager: Killing 6654:com.googlecode.android_scripting/1000 (adj 965): stop com.googlecode.android_scripting
-08-28 15:05:16.824 10117 2426 6018 I chatty : uid=10117(com.google.android.gms) lowpool[42] identical 1 line
-08-28 15:05:16.846 10117 2426 6018 I Icing : Usage reports ok 0, Failed Usage reports 0, indexed 0, rejected 0
-08-28 15:05:16.852 radio 1559 1559 E PhoneInterfaceManager: [PhoneIntfMgr] getCarrierPackageNamesForIntent: No UICC
-08-28 15:05:16.852 radio 1559 1559 D CarrierSvcBindHelper: No carrier app for: 0
-08-28 15:05:16.859 nfc 2452 2452 D RegisteredNfcFServicesCache: Service unchanged, not updating
-08-28 15:05:16.863 media 796 905 D NuPlayerDriver: reset(0xe199b100) at state 4
-08-28 15:05:16.865 root 629 629 I Zygote : Process 6654 exited due to signal 9 (Killed)
-08-28 15:05:16.865 media 796 6689 D NuPlayerDriver: notifyResetComplete(0xe199b100)
-08-28 15:05:16.873 10117 2426 6018 I Icing : Usage reports ok 0, Failed Usage reports 0, indexed 0, rejected 0
-08-28 15:05:16.887 1000 940 1069 I libprocessgroup: Successfully killed process cgroup uid 1000 pid 6654 in 44ms
-08-28 15:05:17.172 1000 647 647 I /vendor/bin/hw/android.hardware.health@2.0-service.marlin: SRAM data: 2812000
-08-28 15:05:17.668 1000 647 647 I chatty : uid=1000(system) health@2.0-serv identical 20 lines
-08-28 15:05:17.672 1000 647 647 I /vendor/bin/hw/android.hardware.health@2.0-service.marlin: SRAM data: 2812000
-08-28 15:05:17.697 10117 2426 28502 I Icing : Indexing com.google.android.gms-apps from com.google.android.gms
-08-28 15:05:17.717 1000 647 647 I /vendor/bin/hw/android.hardware.health@2.0-service.marlin: SRAM data: 2812000
-08-28 15:05:17.769 1000 647 647 I chatty : uid=1000(system) health@2.0-serv identical 2 lines
-08-28 15:05:17.773 1000 647 647 I /vendor/bin/hw/android.hardware.health@2.0-service.marlin: SRAM data: 2812000
-08-28 15:05:17.775 10117 2426 28502 I Icing : Indexing done com.google.android.gms-apps
-08-28 15:05:17.778 1000 647 647 I /vendor/bin/hw/android.hardware.health@2.0-service.marlin: SRAM data: 2812000
-08-28 15:05:17.786 1000 940 2043 I WindowManager: sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)
-08-28 15:05:17.787 1000 940 2043 I PowerManagerService: Going to sleep due to sleep_button (uid 1000)...
-08-28 15:05:17.788 1000 940 940 W UsageStatsService: Event reported without a package name, eventType:16
-08-28 15:05:17.802 10178 7664 7696 D com.google.android.powertests.PartialWakelock: before
-08-28 15:05:17.839 1000 940 1115 V DisplayPowerController: Brightness [131] reason changing to: 'manual', previous reason: 'manual [ dim ]'.
-
-"Œ
-6
-class-com.google.android.powertests.PartialWakelock
-
- end-timestamp
-
-testpartialWakelock
-
- timestamp0žÍ™¤›[
-
-timestamps-message
-–"“
-6
-class-com.google.android.powertests.PartialWakelock
-
-current
-
-idAndroidJUnitRunner
-
-numtests
-
-stream.
-
-testpartialWakelock-")
-'
-stream
-
-Time: 16.333
-
-OK (1 test)
-
diff --git a/acts/framework/tests/test_utils/instrumentation/data/sample_timestamp_proto.txt b/acts/framework/tests/test_utils/instrumentation/data/sample_timestamp_proto.txt
deleted file mode 100644
index 5ac75cd3aa..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/data/sample_timestamp_proto.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-test_status {
- result_code: 1
- results {
- entries {
- key: "class"
- value_string: "com.google.android.powertests.PartialWakelock"
- }
- entries {
- key: "current"
- value_int: 1
- }
- entries {
- key: "id"
- value_string: "AndroidJUnitRunner"
- }
- entries {
- key: "numtests"
- value_int: 1
- }
- entries {
- key: "stream"
- value_string: "\ncom.google.android.powertests.PartialWakelock:"
- }
- entries {
- key: "test"
- value_string: "partialWakelock"
- }
- }
-}
-test_status {
- results {
- entries {
- key: "class"
- value_string: "com.google.android.powertests.PartialWakelock"
- }
- entries {
- key: "start-timestamp"
- }
- entries {
- key: "test"
- value_string: "partialWakelock"
- }
- entries {
- key: "timestamp"
- value_long: 1567029917802
- }
- entries {
- key: "timestamps-message"
- }
- }
-}
-test_status {
- results {
- entries {
- key: "class"
- value_string: "com.google.android.powertests.PartialWakelock"
- }
- entries {
- key: "end-timestamp"
- }
- entries {
- key: "test"
- value_string: "partialWakelock"
- }
- entries {
- key: "timestamp"
- value_long: 1567029932879
- }
- entries {
- key: "timestamps-message"
- }
- }
-}
-test_status {
- results {
- entries {
- key: "class"
- value_string: "com.google.android.powertests.PartialWakelock"
- }
- entries {
- key: "current"
- value_int: 1
- }
- entries {
- key: "id"
- value_string: "AndroidJUnitRunner"
- }
- entries {
- key: "numtests"
- value_int: 1
- }
- entries {
- key: "stream"
- value_string: "."
- }
- entries {
- key: "test"
- value_string: "partialWakelock"
- }
- }
-}
-session_status {
- result_code: -1
- results {
- entries {
- key: "stream"
- value_string: "\n\nTime: 16.333\n\nOK (1 test)\n\n"
- }
- }
-}
diff --git a/acts/framework/tests/test_utils/instrumentation/device/apps/__init__.py b/acts/framework/tests/test_utils/instrumentation/device/apps/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/device/apps/__init__.py
+++ /dev/null
diff --git a/acts/framework/tests/test_utils/instrumentation/device/apps/dismiss_dialogs_test.py b/acts/framework/tests/test_utils/instrumentation/device/apps/dismiss_dialogs_test.py
deleted file mode 100644
index 3b362747a2..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/device/apps/dismiss_dialogs_test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-import mock
-from acts.test_utils.instrumentation.device.apps.dismiss_dialogs import \
- DialogDismissalUtil
-
-
-class MockDialogDismissalUtil(DialogDismissalUtil):
- """Mock DialogDismissalUtil for unit testing"""
- def __init__(self):
- self._dut = mock.MagicMock()
- self._dismiss_dialogs_apk = mock.MagicMock()
- self._dismiss_dialogs_apk.pkg_name = 'dismiss.dialogs'
-
-
-class DialogDismissalUtilTest(unittest.TestCase):
- def setUp(self):
- self._dismiss_dialogs_util = MockDialogDismissalUtil()
-
- def test_dismiss_dialog_zero_apps(self):
- """Test that no command is run if the apps arg is empty."""
- apps = []
- self._dismiss_dialogs_util.dismiss_dialogs(apps)
- self._dismiss_dialogs_util._dut.adb.shell.assert_not_called()
-
- def test_dismiss_dialog_single_app(self):
- """
- Test that the correct command is run when a single app is specified.
- """
- apps = ['sample.app.one']
- self._dismiss_dialogs_util.dismiss_dialogs(apps)
- expected_cmd = (
- 'am instrument -w -f -e apps sample.app.one '
- 'dismiss.dialogs/.DismissDialogsInstrumentation '
- '-e screenshots true -e quitOnError true'
- )
- self._dismiss_dialogs_util._dut.adb.shell.assert_called_with(
- expected_cmd)
-
- def test_dismiss_dialog_multiple_apps(self):
- """
- Test that the correct command is run when multiple apps are specified.
- """
- apps = ['sample.app.one', 'sample.app.two']
- self._dismiss_dialogs_util.dismiss_dialogs(apps)
- expected_cmd = (
- 'am instrument -w -f -e apps sample.app.one,sample.app.two '
- 'dismiss.dialogs/.DismissDialogsInstrumentation '
- '-e screenshots true -e quitOnError true'
- )
- self._dismiss_dialogs_util._dut.adb.shell.assert_called_with(
- expected_cmd)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/device/apps/hotword_model_extractor_test.py b/acts/framework/tests/test_utils/instrumentation/device/apps/hotword_model_extractor_test.py
deleted file mode 100644
index 053da31291..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/device/apps/hotword_model_extractor_test.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import unittest
-
-import mock
-from acts.test_utils.instrumentation.device.apps.hotword_model_extractor import \
- HotwordModelExtractor
-from acts.test_utils.instrumentation.device.apps.hotword_model_extractor import \
- MODEL_DIR
-
-GOOD_PACKAGE = 'good_package'
-GOOD_MODEL = 'good_model'
-BAD_PACKAGE = 'bad_package'
-BAD_MODEL = 'bad_model'
-
-
-def mock_pull_from_device(_, hotword_pkg, __):
- """Mocks the AppInstaller.pull_from_device method."""
- return mock.MagicMock() if hotword_pkg == GOOD_PACKAGE else None
-
-
-class MockZipFile(object):
- """Class for mocking zipfile.ZipFile"""
- def extract(self, path, _):
- if path == os.path.join(MODEL_DIR, GOOD_MODEL):
- return path
- raise KeyError
-
- def __enter__(self):
- return self
-
- def __exit__(self, *_):
- pass
-
-
-@mock.patch('acts.test_utils.instrumentation.device.apps.app_installer.'
- 'AppInstaller.pull_from_device', side_effect=mock_pull_from_device)
-@mock.patch('zipfile.ZipFile', return_value=MockZipFile())
-class HotwordModelExtractorTest(unittest.TestCase):
- """Unit tests for HotwordModelExtractor."""
- def setUp(self):
- self.extractor = HotwordModelExtractor(mock.MagicMock())
-
- def test_package_not_installed(self, *_):
- result = self.extractor._extract(BAD_PACKAGE, GOOD_MODEL, '')
- self.assertIsNone(result)
-
- def test_voice_model_not_found(self, *_):
- result = self.extractor._extract(GOOD_PACKAGE, BAD_MODEL, '')
- self.assertIsNone(result)
-
- def test_extract_model(self, *_):
- result = self.extractor._extract(GOOD_PACKAGE, GOOD_MODEL, '')
- self.assertEqual(result, 'res/raw/good_model')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/device/apps/permissions_test.py b/acts/framework/tests/test_utils/instrumentation/device/apps/permissions_test.py
deleted file mode 100644
index ec4ebc7b9c..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/device/apps/permissions_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-import mock
-from acts.test_utils.instrumentation.device.apps.permissions import \
- PermissionsUtil
-
-
-class MockPermissionsUtil(PermissionsUtil):
- """Mock PermissionsUtil for unit testing"""
- def __init__(self):
- self._dut = mock.MagicMock()
- self._permissions_apk = mock.MagicMock()
- self._permissions_apk.pkg_name = 'permissions.util'
-
-
-class PermissionsUtilTest(unittest.TestCase):
- def setUp(self):
- self._permissions_util = MockPermissionsUtil()
-
- def test_grant_all(self):
- """Test the grant-all command."""
- self._permissions_util.grant_all()
- expected_cmd = (
- 'am instrument -w -r -f -e command grant-all '
- 'permissions.util/.PermissionInstrumentation'
- )
- self._permissions_util._dut.adb.shell.assert_called_with(
- expected_cmd)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/device/command/adb_command_types_test.py b/acts/framework/tests/test_utils/instrumentation/device/command/adb_command_types_test.py
deleted file mode 100755
index 127575bd8d..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/device/command/adb_command_types_test.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceBinaryCommandSeries
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceGServices
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceSetprop
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceSetting
-from acts.test_utils.instrumentation.device.command.adb_command_types import \
- DeviceState
-
-
-class AdbCommandTypesTest(unittest.TestCase):
-
- def test_device_state(self):
- """Tests that DeviceState returns the correct ADB command with
- set_value.
- """
- base_cmd = 'run command with vals'
- val1 = 15
- val2 = 24
- device_state = DeviceState(base_cmd)
- self.assertEqual(device_state.set_value(val1, val2),
- 'run command with vals 15 24')
-
- def test_device_state_with_base_cmd_as_format_string(self):
- """Tests that DeviceState returns the correct ADB command if the base
- command is given as a format string.
- """
- base_cmd = 'echo %s > /test/data'
- val = 23
- device_state = DeviceState(base_cmd)
- self.assertEqual(device_state.set_value(val), 'echo 23 > /test/data')
-
- def test_device_binary_state(self):
- """Tests that DeviceState returns the correct ADB commands with toggle.
- """
- on_cmd = 'enable this service'
- off_cmd = 'disable the service'
- device_binary_state = DeviceState('', on_cmd, off_cmd)
- self.assertEqual(device_binary_state.toggle(True), on_cmd)
- self.assertEqual(device_binary_state.toggle(False), off_cmd)
-
- def test_device_setprop(self):
- """Tests that DeviceSetprop returns the correct ADB command with
- set_value.
- """
- prop = 'some.property'
- val = 3
- device_setprop = DeviceSetprop(prop)
- self.assertEqual(device_setprop.set_value(val),
- 'setprop some.property 3')
-
- def test_device_binary_setprop(self):
- """Tests that DeviceSetprop returns the correct ADB commands with
- toggle.
- """
- prop = 'some.other.property'
- on_val = True
- off_val = False
- device_binary_setprop = DeviceSetprop(prop, on_val, off_val)
- self.assertEqual(device_binary_setprop.toggle(True),
- 'setprop some.other.property True')
- self.assertEqual(device_binary_setprop.toggle(False),
- 'setprop some.other.property False')
-
- def test_device_setting(self):
- """Tests that DeviceSetting returns the correct ADB command with
- set_value.
- """
- namespace = 'global'
- setting = 'some_new_setting'
- val = 10
- device_setting = DeviceSetting(namespace, setting)
- self.assertEqual(device_setting.set_value(val),
- 'settings put global some_new_setting 10')
-
- def test_device_binary_setting(self):
- """Tests that DeviceSetting returns the correct ADB commands with
- toggle.
- """
- namespace = 'system'
- setting = 'some_other_setting'
- on_val = 'on'
- off_val = 'off'
- device_binary_setting = DeviceSetting(
- namespace, setting, on_val, off_val)
- self.assertEqual(
- device_binary_setting.toggle(True),
- 'settings put system some_other_setting on')
- self.assertEqual(
- device_binary_setting.toggle(False),
- 'settings put system some_other_setting off')
-
- def test_device_gservices(self):
- """Tests that DeviceGServices returns the correct ADB command with
- set_value.
- """
- setting = 'some_gservice'
- val = 22
- device_gservices = DeviceGServices(setting)
- self.assertEqual(
- device_gservices.set_value(val),
- 'am broadcast -a '
- 'com.google.gservices.intent.action.GSERVICES_OVERRIDE '
- '--ei some_gservice 22')
-
- def test_device_binary_command_series(self):
- """Tests that DeviceBinaryCommandSuite returns the correct ADB
- commands.
- """
- on_cmds = [
- 'settings put global test_setting on',
- 'setprop test.prop 1',
- 'svc test_svc enable'
- ]
- off_cmds = [
- 'settings put global test_setting off',
- 'setprop test.prop 0',
- 'svc test_svc disable'
- ]
- device_binary_command_series = DeviceBinaryCommandSeries(
- [
- DeviceSetting('global', 'test_setting', 'on', 'off'),
- DeviceSetprop('test.prop'),
- DeviceState('svc test_svc', 'enable', 'disable')
- ]
- )
- self.assertEqual(device_binary_command_series.toggle(True), on_cmds)
- self.assertEqual(device_binary_command_series.toggle(False), off_cmds)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/device/command/intent_builder_test.py b/acts/framework/tests/test_utils/instrumentation/device/command/intent_builder_test.py
deleted file mode 100644
index e69b1a237d..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/device/command/intent_builder_test.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-from acts.test_utils.instrumentation.device.command.intent_builder import \
- IntentBuilder
-
-
-class IntentBuilderTest(unittest.TestCase):
- """Unit tests for IntentBuilder"""
-
- def test_set_action(self):
- """Test that a set action yields the correct intent call"""
- builder = IntentBuilder('am start')
- builder.set_action('android.intent.action.SOME_ACTION')
- self.assertEqual(builder.build(),
- 'am start -a android.intent.action.SOME_ACTION')
-
- def test_set_component_with_package_only(self):
- """Test that the intent call is built properly with only the package
- name specified.
- """
- builder = IntentBuilder('am broadcast')
- builder.set_component('android.package.name')
- self.assertEqual(builder.build(),
- 'am broadcast -n android.package.name')
-
- def test_set_component_with_package_and_component(self):
- """Test that the intent call is built properly with both the package
- and component name specified.
- """
- builder = IntentBuilder('am start')
- builder.set_component('android.package.name', '.AndroidComponent')
- self.assertEqual(
- builder.build(),
- 'am start -n android.package.name/.AndroidComponent')
-
- def test_set_data_uri(self):
- """Test that a set data URI yields the correct intent call"""
- builder = IntentBuilder()
- builder.set_data_uri('file://path/to/file')
- self.assertEqual(builder.build(), '-d file://path/to/file')
-
- def test_add_flag(self):
- """Test that additional flags are added properly"""
- builder = IntentBuilder('am start')
- builder.add_flag('--flag-numero-uno')
- builder.add_flag('--flag-numero-dos')
- self.assertEqual(
- builder.build(), 'am start --flag-numero-uno --flag-numero-dos')
-
- def test_add_key_value_with_empty_value(self):
- """Test that a param with an empty value is added properly."""
- builder = IntentBuilder('am broadcast')
- builder.add_key_value_param('empty_param')
- self.assertEqual(builder.build(), 'am broadcast --esn empty_param')
-
- def test_add_key_value_with_nonempty_values(self):
- """Test that a param with various non-empty values is added properly."""
- builder = IntentBuilder('am start')
- builder.add_key_value_param('bool_param', False)
- builder.add_key_value_param('string_param', 'enabled')
- builder.add_key_value_param('int_param', 5)
- builder.add_key_value_param('float_param', 12.1)
- self.assertEqual(
- builder.build(),
- 'am start --ez bool_param false --es string_param enabled '
- '--ei int_param 5 --ef float_param 12.1')
-
- def test_full_intent_command(self):
- """Test a full intent command with all possible components."""
- builder = IntentBuilder('am broadcast')
- builder.set_action('android.intent.action.TEST_ACTION')
- builder.set_component('package.name', '.ComponentName')
- builder.set_data_uri('file://path/to/file')
- builder.add_key_value_param('empty')
- builder.add_key_value_param('numeric_param', 11.6)
- builder.add_key_value_param('bool_param', True)
- builder.add_flag('--unit-test')
- self.assertEqual(
- builder.build(),
- 'am broadcast -a android.intent.action.TEST_ACTION '
- '-n package.name/.ComponentName -d file://path/to/file --unit-test '
- '--esn empty --ef numeric_param 11.6 --ez bool_param true')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/instrumentation_base_test_test.py b/acts/framework/tests/test_utils/instrumentation/instrumentation_base_test_test.py
deleted file mode 100755
index ab982c1bd6..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/instrumentation_base_test_test.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import copy
-import unittest
-
-from acts.test_utils.instrumentation.config_wrapper import ConfigWrapper
-from acts.test_utils.instrumentation.instrumentation_base_test import \
- InstrumentationBaseTest
-
-MOCK_INSTRUMENTATION_CONFIG = {
- 'MockController': {
- 'param1': 1,
- 'param2': 4
- },
- 'MockInstrumentationBaseTest': {
- 'MockController': {
- 'param2': 2,
- 'param3': 5
- },
- 'test_case': {
- 'MockController': {
- 'param3': 3
- }
- }
- }
-}
-
-
-class MockInstrumentationBaseTest(InstrumentationBaseTest):
- """Mock test class to initialize required attributes."""
- def __init__(self):
- self.current_test_name = None
- self._instrumentation_config = ConfigWrapper(
- MOCK_INSTRUMENTATION_CONFIG)
- self._class_config = self._instrumentation_config.get_config(
- self.__class__.__name__)
-
-
-class InstrumentationBaseTestTest(unittest.TestCase):
- def setUp(self):
- self.instrumentation_test = MockInstrumentationBaseTest()
-
- def test_get_controller_config_for_test_case(self):
- """Test that _get_controller_config returns the corresponding
- controller config for the current test case.
- """
- self.instrumentation_test.current_test_name = 'test_case'
- config = self.instrumentation_test._get_merged_config(
- 'MockController')
- self.assertEqual(config.get('param1'), 1)
- self.assertEqual(config.get('param2'), 2)
- self.assertEqual(config.get('param3'), 3)
-
- def test_get_controller_config_for_test_class(self):
- """Test that _get_controller_config returns the controller config for
- the current test class (while no test case is running).
- """
- config = self.instrumentation_test._get_merged_config(
- 'MockController')
- self.assertEqual(config.get('param1'), 1)
- self.assertEqual(config.get('param2'), 2)
- self.assertEqual(config.get('param3'), 5)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/instrumentation_proto_parser_test.py b/acts/framework/tests/test_utils/instrumentation/instrumentation_proto_parser_test.py
deleted file mode 100644
index c276fc5c2d..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/instrumentation_proto_parser_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import unittest
-
-import mock
-from acts.test_utils.instrumentation import instrumentation_proto_parser \
- as parser
-from acts.test_utils.instrumentation.instrumentation_proto_parser import \
- ProtoParserError
-from acts.test_utils.instrumentation.proto.gen import instrumentation_data_pb2
-
-
-DEST_DIR = 'dest/proto_dir'
-SOURCE_PATH = 'source/proto/protofile'
-SAMPLE_PROTO = 'data/sample.instrumentation_data_proto'
-SAMPLE_TIMESTAMP_PROTO = 'data/sample_timestamp.instrumentation_data_proto'
-
-
-class InstrumentationProtoParserTest(unittest.TestCase):
- """Unit tests for instrumentation proto parser."""
-
- def setUp(self):
- self.ad = mock.MagicMock()
- self.ad.external_storage_path = ''
-
- @mock.patch('os.path.exists', return_value=True)
- def test_pull_proto_returns_correct_path_given_source(self, *_):
- self.assertEqual(parser.pull_proto(self.ad, DEST_DIR, SOURCE_PATH),
- 'dest/proto_dir/protofile')
-
- @mock.patch('os.path.exists', return_value=True)
- def test_pull_proto_returns_correct_path_from_default_location(self, *_):
- self.ad.adb.shell.return_value = 'default'
- self.assertEqual(parser.pull_proto(self.ad, DEST_DIR),
- 'dest/proto_dir/default')
-
- def test_pull_proto_fails_if_no_default_proto_found(self, *_):
- self.ad.adb.shell.return_value = None
- with self.assertRaisesRegex(
- ProtoParserError, 'No instrumentation result'):
- parser.pull_proto(self.ad, DEST_DIR)
-
- @mock.patch('os.path.exists', return_value=False)
- def test_pull_proto_fails_if_adb_pull_fails(self, *_):
- with self.assertRaisesRegex(ProtoParserError, 'Failed to pull'):
- parser.pull_proto(self.ad, DEST_DIR, SOURCE_PATH)
-
- def test_parser_converts_valid_proto(self):
- proto_file = os.path.join(os.path.dirname(__file__), SAMPLE_PROTO)
- self.assertIsInstance(parser.get_session_from_local_file(proto_file),
- instrumentation_data_pb2.Session)
-
- def test_get_test_timestamps(self):
- proto_file = os.path.join(os.path.dirname(__file__),
- SAMPLE_TIMESTAMP_PROTO)
- session = parser.get_session_from_local_file(proto_file)
- timestamps = parser.get_test_timestamps(session)
- self.assertEqual(
- timestamps['partialWakelock'][parser.START_TIMESTAMP],
- 1567029917802)
- self.assertEqual(
- timestamps['partialWakelock'][parser.END_TIMESTAMP], 1567029932879)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/power/__init__.py b/acts/framework/tests/test_utils/instrumentation/power/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/power/__init__.py
+++ /dev/null
diff --git a/acts/framework/tests/test_utils/instrumentation/power/instrumentation_power_test_test.py b/acts/framework/tests/test_utils/instrumentation/power/instrumentation_power_test_test.py
deleted file mode 100644
index 3a617e2bef..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/power/instrumentation_power_test_test.py
+++ /dev/null
@@ -1,280 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-import mock
-from acts.test_utils.instrumentation.config_wrapper import ConfigWrapper
-from acts.test_utils.instrumentation.power.instrumentation_power_test \
- import ACCEPTANCE_THRESHOLD
-from acts.test_utils.instrumentation.power.instrumentation_power_test \
- import InstrumentationPowerTest
-from acts.test_utils.instrumentation.power.power_metrics import PowerMetrics
-
-from acts import signals
-
-
-class MockInstrumentationPowerTest(InstrumentationPowerTest):
- """Mock test class to initialize required attributes."""
-
- # avg: 2.214, stdev: 1.358, max: 4.78, min: 0.61
- SAMPLE_DATA = [1.64, 2.98, 1.72, 3.45, 1.31, 4.78, 3.43, 0.61, 1.19, 1.03]
-
- def __init__(self):
- self.log = mock.Mock()
- self.metric_logger = mock.Mock()
- self.current_test_name = 'test_case'
- self._power_metrics = PowerMetrics(4.2)
- self._power_metrics.test_metrics = {
- 'instrTest1': PowerMetrics(4.2),
- 'instrTest2': PowerMetrics(4.2)
- }
- self._power_metrics.test_metrics['instrTest1'].generate_test_metrics(
- list(zip(range(10), self.SAMPLE_DATA))
- )
- self._power_metrics.test_metrics['instrTest2'].generate_test_metrics(
- list(zip(range(10), self.SAMPLE_DATA))
- )
- self._instrumentation_config = ConfigWrapper()
- self._class_config = ConfigWrapper(
- {
- self.current_test_name: {
- ACCEPTANCE_THRESHOLD: {}
- }
- }
- )
-
- def set_criteria(self, criteria):
- """Set the acceptance criteria for metrics validation."""
- test_config = self._class_config[self.current_test_name]
- test_config[ACCEPTANCE_THRESHOLD] = ConfigWrapper(criteria)
-
-
-class InstrumentationPowerTestTest(unittest.TestCase):
- """Unit tests for InstrumentationPowerTest."""
- def setUp(self):
- self.instrumentation_power_test = MockInstrumentationPowerTest()
-
- def test_validate_power_results_lower_and_upper_limit_accept(self):
- """Test that validate_power_results accept passing measurements
- given a lower and upper limit.
- """
- criteria_accept = {
- 'instrTest1': {
- 'avg_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'lower_limit': 1.5,
- 'upper_limit': 2.5
- },
- 'max_current': {
- 'unit_type': 'current',
- 'unit': 'mA',
- 'upper_limit': 5000
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_accept)
- with self.assertRaises(signals.TestPass):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_lower_and_upper_limit_reject(self):
- """Test that validate_power_results reject failing measurements
- given a lower and upper limit.
- """
- criteria_reject = {
- 'instrTest1': {
- 'avg_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'lower_limit': 1.5,
- 'upper_limit': 2
- },
- 'max_current': {
- 'unit_type': 'current',
- 'unit': 'mA',
- 'upper_limit': 4000
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_reject)
- with self.assertRaises(signals.TestFailure):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_expected_value_and_deviation_accept(self):
- """Test that validate_power_results accept passing measurements
- given an expected value and percent deviation.
- """
- criteria_accept = {
- 'instrTest1': {
- 'stdev_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'expected_value': 1.5,
- 'percent_deviation': 20
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_accept)
- with self.assertRaises(signals.TestPass):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_expected_value_and_deviation_reject(self):
- """Test that validate_power_results reject failing measurements
- given an expected value and percent deviation.
- """
- criteria_reject = {
- 'instrTest1': {
- 'min_current': {
- 'unit_type': 'current',
- 'unit': 'mA',
- 'expected_value': 500,
- 'percent_deviation': 10
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_reject)
- with self.assertRaises(signals.TestFailure):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_no_such_test(self):
- """Test that validate_power_results skip validation if there are no
- criteria matching the specified instrumentation test name.
- """
- criteria_wrong_test = {
- 'instrTest2': {
- 'min_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'expected_value': 2,
- 'percent_deviation': 20
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_wrong_test)
- with self.assertRaises(signals.TestPass):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_no_such_metric(self):
- """Test that validate_power_results skip validation if the specified
- metric is invalid.
- """
- criteria_invalid_metric = {
- 'instrTest1': {
- 'no_such_metric': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'lower_limit': 5,
- 'upper_limit': 7
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_invalid_metric)
- with self.assertRaises(signals.TestPass):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_criteria_missing_params(self):
- """Test that validate_power_results skip validation if the specified
- metric has missing parameters.
- """
- criteria_missing_params = {
- 'instrTest1': {
- 'avg_current': {
- 'unit': 'A',
- 'lower_limit': 1,
- 'upper_limit': 2
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_missing_params)
- with self.assertRaises(signals.TestPass):
- self.instrumentation_power_test.validate_power_results('instrTest1')
-
- def test_validate_power_results_pass_if_all_tests_accept(self):
- """Test that validate_power_results succeeds if it accepts the results
- of all instrumentation tests.
- """
- criteria_multi_test_accept = {
- 'instrTest1': {
- 'avg_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'lower_limit': 2
- },
- 'stdev_current': {
- 'unit_type': 'current',
- 'unit': 'mA',
- 'expected_value': 1250,
- 'percent_deviation': 30
- }
- },
- 'instrTest2': {
- 'max_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'upper_limit': 5
- },
- 'avg_power': {
- 'unit_type': 'power',
- 'unit': 'W',
- 'upper_limit': 10
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_multi_test_accept)
- with self.assertRaises(signals.TestPass):
- self.instrumentation_power_test.validate_power_results(
- 'instrTest1', 'instrTest2')
-
- def test_validate_power_results_fail_if_at_least_one_test_rejects(self):
- """Test that validate_power_results fails if it rejects the results
- of at least one instrumentation test.
- """
- criteria_multi_test_reject = {
- 'instrTest1': {
- 'avg_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'lower_limit': 2
- },
- 'stdev_current': {
- 'unit_type': 'current',
- 'unit': 'mA',
- 'expected_value': 1250,
- 'percent_deviation': 30
- }
- },
- 'instrTest2': {
- 'max_current': {
- 'unit_type': 'current',
- 'unit': 'A',
- 'upper_limit': 5
- },
- 'avg_power': {
- 'unit_type': 'power',
- 'unit': 'W',
- 'upper_limit': 8
- }
- }
- }
- self.instrumentation_power_test.set_criteria(criteria_multi_test_reject)
- with self.assertRaises(signals.TestFailure):
- self.instrumentation_power_test.validate_power_results(
- 'instrTest1', 'instrTest2')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/power/power_metrics_test.py b/acts/framework/tests/test_utils/instrumentation/power/power_metrics_test.py
deleted file mode 100644
index 38441d136d..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/power/power_metrics_test.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import statistics
-import unittest
-
-from acts.test_utils.instrumentation import instrumentation_proto_parser \
- as parser
-from acts.test_utils.instrumentation.power.power_metrics import CURRENT
-from acts.test_utils.instrumentation.power.power_metrics import HOUR
-from acts.test_utils.instrumentation.power.power_metrics import MILLIAMP
-from acts.test_utils.instrumentation.power.power_metrics import MINUTE
-from acts.test_utils.instrumentation.power.power_metrics import Measurement
-from acts.test_utils.instrumentation.power.power_metrics import PowerMetrics
-from acts.test_utils.instrumentation.power.power_metrics import TIME
-from acts.test_utils.instrumentation.power.power_metrics import WATT
-
-FAKE_UNIT_TYPE = 'fake_unit'
-FAKE_UNIT = 'F'
-
-
-class MeasurementTest(unittest.TestCase):
- """Unit tests for the Measurement class."""
-
- def test_init_with_valid_unit_type(self):
- """Test that a Measurement is properly initialized given a valid unit
- type.
- """
- measurement = Measurement(2, CURRENT, MILLIAMP)
- self.assertEqual(measurement.value, 2)
- self.assertEqual(measurement._unit, MILLIAMP)
-
- def test_init_with_invalid_unit_type(self):
- """Test that __init__ raises an error if given an invalid unit type."""
- with self.assertRaisesRegex(TypeError, 'valid unit type'):
- measurement = Measurement(2, FAKE_UNIT_TYPE, FAKE_UNIT)
-
- def test_unit_conversion(self):
- """Test that to_unit correctly converts value and unit."""
- ratio = 1000
- current_amps = Measurement.amps(15)
- current_milliamps = current_amps.to_unit(MILLIAMP)
- self.assertEqual(current_milliamps.value / current_amps.value, ratio)
-
- def test_unit_conversion_with_wrong_type(self):
- """Test that to_unit raises and error if incompatible unit type is
- specified.
- """
- current_amps = Measurement.amps(3.4)
- with self.assertRaisesRegex(TypeError, 'Incompatible units'):
- power_watts = current_amps.to_unit(WATT)
-
- def test_comparison_operators(self):
- """Test that the comparison operators work as intended."""
- # time_a == time_b < time_c
- time_a = Measurement.seconds(120)
- time_b = Measurement(2, TIME, MINUTE)
- time_c = Measurement(0.1, TIME, HOUR)
-
- self.assertEqual(time_a, time_b)
- self.assertEqual(time_b, time_a)
- self.assertLessEqual(time_a, time_b)
- self.assertGreaterEqual(time_a, time_b)
-
- self.assertNotEqual(time_a, time_c)
- self.assertNotEqual(time_c, time_a)
- self.assertLess(time_a, time_c)
- self.assertLessEqual(time_a, time_c)
- self.assertGreater(time_c, time_a)
- self.assertGreaterEqual(time_c, time_a)
-
- def test_arithmetic_operators(self):
- """Test that the addition and subtraction operators work as intended"""
- time_a = Measurement(3, TIME, HOUR)
- time_b = Measurement(90, TIME, MINUTE)
-
- sum_ = time_a + time_b
- self.assertEqual(sum_.value, 4.5)
- self.assertEqual(sum_._unit, HOUR)
-
- sum_reversed = time_b + time_a
- self.assertEqual(sum_reversed.value, 270)
- self.assertEqual(sum_reversed._unit, MINUTE)
-
- diff = time_a - time_b
- self.assertEqual(diff.value, 1.5)
- self.assertEqual(diff._unit, HOUR)
-
- diff_reversed = time_b - time_a
- self.assertEqual(diff_reversed.value, -90)
- self.assertEqual(diff_reversed._unit, MINUTE)
-
-
-class PowerMetricsTest(unittest.TestCase):
- """Unit tests for the PowerMetrics class."""
-
- SAMPLES = [0.13, 0.95, 0.32, 4.84, 2.48, 4.11, 4.85, 4.88, 4.22, 2.2]
- RAW_DATA = list(zip(range(10), SAMPLES))
- VOLTAGE = 4.2
- START_TIME = 5
-
- def setUp(self):
- self.power_metrics = PowerMetrics(self.VOLTAGE, self.START_TIME)
-
- def test_import_raw_data(self):
- """Test that power metrics can be loaded from file. Simply ensure that
- the number of samples is correct."""
-
- imported_data = PowerMetrics.import_raw_data(
- os.path.join(os.path.dirname(__file__),
- '../data/sample_monsoon_data')
- )
- self.power_metrics.generate_test_metrics(imported_data)
- self.assertEqual(self.power_metrics._num_samples, 10)
-
- def test_split_by_test_with_timestamps(self):
- """Test that given test timestamps, a power metric is generated from
- a subset of samples corresponding to the test."""
- sample_test = 'sample_test'
- test_start = 8500
- test_end = 13500
- test_timestamps = {sample_test: {parser.START_TIMESTAMP: test_start,
- parser.END_TIMESTAMP: test_end}}
- self.power_metrics.generate_test_metrics(self.RAW_DATA, test_timestamps)
- test_metrics = self.power_metrics.test_metrics[sample_test]
- self.assertEqual(test_metrics._num_samples, 5)
-
- def test_numeric_metrics(self):
- """Test that the numeric metrics have correct values."""
- self.power_metrics.generate_test_metrics(self.RAW_DATA)
- self.assertAlmostEqual(self.power_metrics.avg_current.value,
- statistics.mean(self.SAMPLES) * 1000)
- self.assertAlmostEqual(self.power_metrics.max_current.value,
- max(self.SAMPLES) * 1000)
- self.assertAlmostEqual(self.power_metrics.min_current.value,
- min(self.SAMPLES) * 1000)
- self.assertAlmostEqual(self.power_metrics.stdev_current.value,
- statistics.stdev(self.SAMPLES) * 1000)
- self.assertAlmostEqual(
- self.power_metrics.avg_power.value,
- self.power_metrics.avg_current.value * self.VOLTAGE)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/acts/framework/tests/test_utils/instrumentation/unit_test_suite.py b/acts/framework/tests/test_utils/instrumentation/unit_test_suite.py
deleted file mode 100755
index d253cb33ad..0000000000
--- a/acts/framework/tests/test_utils/instrumentation/unit_test_suite.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import sys
-import unittest
-
-
-def main():
- suite = unittest.TestLoader().discover(
- start_dir=os.path.dirname(__file__), pattern='*_test.py')
- return suite
-
-
-if __name__ == '__main__':
- test_suite = main()
- runner = unittest.TextTestRunner()
- test_run = runner.run(test_suite)
- sys.exit(not test_run.wasSuccessful())
diff --git a/acts/tests/google/instrumentation/power/camera/CapturePhotosTest.py b/acts/tests/google/instrumentation/power/camera/CapturePhotosTest.py
deleted file mode 100644
index a99fd5d539..0000000000
--- a/acts/tests/google/instrumentation/power/camera/CapturePhotosTest.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.power import instrumentation_power_test
-from acts.test_utils.instrumentation.device.apps.dismiss_dialogs import \
- DialogDismissalUtil
-
-
-class ImageCaptureTest(instrumentation_power_test.InstrumentationPowerTest):
- """
- Test class for running instrumentation test CameraTests#testImageCapture.
- """
-
- def _prepare_device(self):
- super()._prepare_device()
- self.mode_airplane()
- self.base_device_configuration()
- self._dialog_util = DialogDismissalUtil(
- self.ad_dut,
- self.get_file_from_config('dismiss_dialogs_apk')
- )
- self._dialog_util.dismiss_dialogs('GoogleCamera')
-
- def _cleanup_device(self):
- self._dialog_util.close()
- super()._cleanup_device()
-
- def test_capture_photos(self):
- """Measures power during photo capture."""
- self.run_and_measure(
- 'com.google.android.platform.powertests.CameraTests',
- 'testImageCapture', req_params=['hdr_mode'])
- self.validate_power_results()
diff --git a/acts/tests/google/instrumentation/power/idle/DisplayAlwaysOnTest.py b/acts/tests/google/instrumentation/power/idle/DisplayAlwaysOnTest.py
deleted file mode 100644
index b891b0cc45..0000000000
--- a/acts/tests/google/instrumentation/power/idle/DisplayAlwaysOnTest.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.power import instrumentation_power_test
-from acts.test_utils.instrumentation.device.command.adb_commands import common
-
-
-class DisplayAlwaysOnTest(instrumentation_power_test.InstrumentationPowerTest):
- """Test class for running instrumentation test DisplayAlwaysOn."""
-
- def _prepare_device(self):
- super()._prepare_device()
- self.base_device_configuration()
- self.adb_run(common.doze_mode.toggle(True))
- self.adb_run(common.doze_always_on.toggle(True))
- self.adb_run(common.disable_sensors)
-
- def test_display_always_on(self):
- """Measures power when the device is rock bottom state plus display
- always on (known as doze mode)."""
-
- self.run_and_measure(
- 'com.google.android.platform.powertests.IdleTestCase',
- 'testIdleScreenOff')
-
- self.validate_power_results()
diff --git a/acts/tests/google/instrumentation/power/idle/PartialWakeLockTest.py b/acts/tests/google/instrumentation/power/idle/PartialWakeLockTest.py
deleted file mode 100644
index 973c0f9828..0000000000
--- a/acts/tests/google/instrumentation/power/idle/PartialWakeLockTest.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.power import instrumentation_power_test
-
-
-class PartialWakeLockTest(instrumentation_power_test.InstrumentationPowerTest):
- """Test class for running instrumentation test PartialWakeLock."""
-
- def _prepare_device(self):
- super()._prepare_device()
- self.base_device_configuration()
-
- def test_partial_wake_lock(self):
- """Measures power when the device is idle with a partial wake lock."""
- self.run_and_measure(
- 'com.google.android.platform.powertests.IdleTestCase',
- 'testPartialWakelock')
- self.validate_power_results()
diff --git a/acts/tests/google/instrumentation/power/idle/RockBottomTest.py b/acts/tests/google/instrumentation/power/idle/RockBottomTest.py
deleted file mode 100644
index 43dd9f1a4c..0000000000
--- a/acts/tests/google/instrumentation/power/idle/RockBottomTest.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.power import instrumentation_power_test
-
-
-class RockBottomTest(instrumentation_power_test.InstrumentationPowerTest):
- """Test class for running instrumentation test RockBottom."""
-
- def _prepare_device(self):
- super()._prepare_device()
- self.base_device_configuration()
-
- def test_rock_bottom(self):
- """Measures power when the device is in a rock bottom state."""
- self.run_and_measure(
- 'com.google.android.platform.powertests.IdleTestCase',
- 'testIdleScreenOff')
- self.validate_power_results()
diff --git a/acts/tests/google/instrumentation/power/media/VideoPlaybackTest.py b/acts/tests/google/instrumentation/power/media/VideoPlaybackTest.py
deleted file mode 100644
index 9541f460d0..0000000000
--- a/acts/tests/google/instrumentation/power/media/VideoPlaybackTest.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2020 - The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from acts.test_utils.instrumentation.power import instrumentation_power_test
-
-BIG_FILE_PUSH_TIMEOUT = 600
-
-
-class VideoPlaybackTest(
- instrumentation_power_test.InstrumentationPowerTest):
- """Test class for running instrumentation tests
- VideoPlaybackHighBitRateTest."""
-
- def _prepare_device(self):
- super()._prepare_device()
- self.base_device_configuration()
-
- def test_playback_high_bit_rate(self):
- """Measures power when the device is in a rock bottom state."""
- video_location = self.push_to_external_storage(
- self.get_file_from_config('high_bit_rate_video'),
- timeout=BIG_FILE_PUSH_TIMEOUT)
- self.trigger_scan_on_external_storage()
-
- self.run_and_measure(
- 'com.google.android.platform.powertests.PhotosTests',
- 'testVideoPlaybackThroughIntent',
- extra_params=[('video_file_path', video_location)])
-
- self.validate_power_results()