Upgrade mobly to 161ff47b51c5fa836bf7a14fbdc69587682018b3 am: 51b0b7394a

Original change: https://android-review.googlesource.com/c/platform/external/python/mobly/+/3031248

Change-Id: Idb764ab6fb79c35eca72dcd89d3fb24d336c86ea
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b788662..a24efc3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-name: CI tests for google/mobly
+name: CI
 
 on: [push, pull_request]
 
@@ -8,7 +8,7 @@
     strategy:
       matrix:
         os: [ubuntu-latest, macos-latest, windows-latest]
-        python-version: [3.7, 3.8]
+        python-version: ["3.11", "3.12"]
     steps:
     - name: Checkout repo
       uses: actions/checkout@v2
@@ -27,3 +27,8 @@
       run: |
         tox
 
+    - name: Check formatting
+      run: |
+        python -m pip install pyink
+        pyink --check .
+
diff --git a/.gitignore b/.gitignore
index 9c7984a..06591ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@
 .sass-cache
 _site
 .tox/
+venv/
diff --git a/.style.yapf b/.style.yapf
deleted file mode 100644
index 38ecc35..0000000
--- a/.style.yapf
+++ /dev/null
@@ -1,5 +0,0 @@
-[style]
-based_on_style = google
-indent_width: 2
-spaces_before_comment = 2
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42c8df7..424dc64 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,26 @@
 # Mobly Release History
 
 
+## Mobly Release 1.12.3: Proper Repeat and Retry Reporting
+Bumping min Python version requirement to 3.11.
+Modernized the repo's packaging mechanism.
+Removed legacy code and dependencies.
+
+### New
+* Support am instrument options in snippet client.
+* Support adb reverse in `AdbProxy`.
+* Improved mechanism for tracking repeat and retry records in test report.
+
+### Breaking Changes
+* [Deprecation] `get_available_host_port` is now deprecated and will be removed
+  in the next major release. Please rely on the OS to allocate ports.
+
+### Fixes
+* Eliminated redundant `fastboot` calls.
+
+[Full list of changes](https://github.com/google/mobly/milestone/30?closed=1)
+
+
 ## Mobly Release 1.12.2: Improve Support for Custom Suites
 
 Bug fixes and improvements to better support users who construct their own
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d9bdd95..bca38c3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -43,16 +43,16 @@
 ```
 
 ### Code style
-Before pushing your changes, you need to lint the code style via `yapf`
+Before pushing your changes, you need to lint the code style via `pyink`
 
-To install `yapf`:
+To install `pyink`:
 
 ```sh
-$ pip3 install yapf
+$ pip3 install pyink
 ```
 
 To lint the code:
 
 ```sh
-mobly $ yapf -i {files you modified}
+mobly $ pyink .
 ```
diff --git a/METADATA b/METADATA
index 2d088a5..57b7b7e 100644
--- a/METADATA
+++ b/METADATA
@@ -1,20 +1,20 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update external/python/mobly
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
 name: "mobly"
-description:
-    "Mobly is a Python-based test framework that specializes in supporting test "
-    "cases that require multiple devices, complex environments, or custom "
-    "hardware setups."
-
+description: "Mobly is a Python-based test framework that specializes in supporting test cases that require multiple devices, complex environments, or custom hardware setups."
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://github.com/google/mobly"
-  }
-  url {
-    type: GIT
-    value: "https://github.com/google/mobly"
-  }
-  version: "1.11"
-  last_upgrade_date { year: 2021 month: 12 day: 16 }
   license_type: NOTICE
+  last_upgrade_date {
+    year: 2024
+    month: 4
+    day: 9
+  }
+  homepage: "https://github.com/google/mobly"
+  identifier {
+    type: "Git"
+    value: "https://github.com/google/mobly"
+    version: "161ff47b51c5fa836bf7a14fbdc69587682018b3"
+  }
 }
-
diff --git a/README.md b/README.md
index 290a5b1..a9cd38f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
 # Welcome to Mobly
 
+[![Latest release](https://img.shields.io/github/release/google/mobly.svg)](https://github.com/google/mobly/releases/latest)
+[![Build Status](https://github.com/google/mobly/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/google/mobly/actions)
+
 **Mobly** is a Python-based test framework that specializes in supporting test
 cases that require multiple devices, complex environments, or custom hardware
 setups.
@@ -21,24 +24,16 @@
 
 ## Compatibility
 
-Mobly requires *python 3.6* or newer.
+Mobly requires *python 3.11* or newer.
 
 Mobly tests could run on the following platforms:
   - Ubuntu 14.04+
   - MacOS 10.6+
   - Windows 7+
 
-| Platform | Build Status |
-|----------|--------------|
-| Linux    | [![Linux Build Status](https://travis-ci.org/google/mobly.svg?branch=master)](https://travis-ci.org/google/mobly) |
-| Windows  | [![Windows Build Status](https://storage.googleapis.com/mobly-kokoro-build-badges/mobly-windows.svg)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod%3Amobly%2Fgcp_windows%2Fcontinuous) |
-
 ## System dependencies
   - adb (1.0.40+ recommended)
-  - python3.7+
-  - python-setuptools
-
-*To use Python3, use `pip3` and `python3` (or python3.x) accordingly.*
+  - python3.11+
 
 ## Installation
 You can install the released package from pip
@@ -47,12 +42,12 @@
 pip install mobly
 ```
 
-or download the source then run `setup.py` to use the bleeding edge:
+or install from the source to use the bleeding edge:
 
 ```sh
 git clone https://github.com/google/mobly.git
 cd mobly
-python setup.py install
+pip install -e .
 ```
 
 You may need `sudo` for the above commands if your system has certain permission
diff --git a/docs/conf.py b/docs/conf.py
index d08be89..2a7e6a9 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -18,6 +18,7 @@
 #
 import os
 import sys
+
 sys.path.insert(0, os.path.abspath(os.path.pardir))
 
 # -- General configuration ------------------------------------------------
@@ -30,8 +31,10 @@
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
 extensions = [
-    'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.todo',
-    'sphinx.ext.viewcode'
+    'sphinx.ext.autodoc',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.todo',
+    'sphinx.ext.viewcode',
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -54,18 +57,18 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'Mobly'
-copyright = u'Copyright 2016 Google Inc.'
-author = u'Ang Li'
+project = 'Mobly'
+copyright = 'Copyright 2016 Google Inc.'
+author = 'Ang Li'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = u''
+version = ''
 # The full version, including alpha/beta/rc tags.
-release = u''
+release = ''
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -78,8 +81,12 @@
 # directories to ignore when looking for source files.
 # This patterns also effect to html_static_path and html_extra_path
 exclude_patterns = [
-    '_build', 'Thumbs.db', '.DS_Store', 'tutorial.md',
-    'instrumentation_tutorial.md', 'android_device_service.md'
+    '_build',
+    'Thumbs.db',
+    '.DS_Store',
+    'tutorial.md',
+    'instrumentation_tutorial.md',
+    'android_device_service.md',
 ]
 
 # The name of the Pygments (syntax highlighting) style to use.
@@ -117,15 +124,12 @@
     # The paper size ('letterpaper' or 'a4paper').
     #
     # 'papersize': 'letterpaper',
-
     # The font size ('10pt', '11pt' or '12pt').
     #
     # 'pointsize': '10pt',
-
     # Additional stuff for the LaTeX preamble.
     #
     # 'preamble': '',
-
     # Latex figure (float) alignment
     #
     # 'figure_align': 'htbp',
@@ -135,14 +139,14 @@
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'Mobly.tex', u'Mobly Documentation', u'Ang Li', 'manual'),
+    (master_doc, 'Mobly.tex', 'Mobly Documentation', 'Ang Li', 'manual'),
 ]
 
 # -- Options for manual page output ---------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [(master_doc, 'mobly', u'Mobly Documentation', [author], 1)]
+man_pages = [(master_doc, 'mobly', 'Mobly Documentation', [author], 1)]
 
 # -- Options for Texinfo output -------------------------------------------
 
@@ -150,9 +154,19 @@
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'Mobly', u'Mobly Documentation', author, 'Mobly',
-     'Mobly is a Python-based test framework that specializes in supporting tests that require multiple devices, complex environments, or custom hardware setups.',
-     'Miscellaneous'),
+    (
+        master_doc,
+        'Mobly',
+        'Mobly Documentation',
+        author,
+        'Mobly',
+        (
+            'Mobly is a Python-based test framework that specializes in'
+            ' supporting tests that require multiple devices, complex'
+            ' environments, or custom hardware setups.'
+        ),
+        'Miscellaneous',
+    ),
 ]
 
 # -- Options for Epub output ----------------------------------------------
diff --git a/mobly/asserts.py b/mobly/asserts.py
index 70e1256..e877e05 100644
--- a/mobly/asserts.py
+++ b/mobly/asserts.py
@@ -23,11 +23,9 @@
 _pyunit_proxy.maxDiff = None
 
 
-def _call_unittest_assertion(assertion_method,
-                             *args,
-                             msg=None,
-                             extras=None,
-                             **kwargs):
+def _call_unittest_assertion(
+    assertion_method, *args, msg=None, extras=None, **kwargs
+):
   """Wrapper for converting a unittest assertion into a Mobly one.
 
   Args:
@@ -65,28 +63,21 @@
     extras: An optional field for extra information to be included in
       test result.
   """
-  _call_unittest_assertion(_pyunit_proxy.assertEqual,
-                           first,
-                           second,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertEqual, first, second, msg=msg, extras=extras
+  )
 
 
 def assert_not_equal(first, second, msg=None, extras=None):
   """Asserts that first is not equal (!=) to second."""
-  _call_unittest_assertion(_pyunit_proxy.assertNotEqual,
-                           first,
-                           second,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertNotEqual, first, second, msg=msg, extras=extras
+  )
 
 
-def assert_almost_equal(first,
-                        second,
-                        places=None,
-                        msg=None,
-                        delta=None,
-                        extras=None):
+def assert_almost_equal(
+    first, second, places=None, msg=None, delta=None, extras=None
+):
   """Asserts that first is almost equal to second.
 
   Fails if the two objects are unequal as determined by their difference
@@ -107,21 +98,20 @@
     extras: An optional field for extra information to be included in
       test result.
   """
-  _call_unittest_assertion(_pyunit_proxy.assertAlmostEqual,
-                           first,
-                           second,
-                           places=places,
-                           msg=msg,
-                           delta=delta,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertAlmostEqual,
+      first,
+      second,
+      places=places,
+      msg=msg,
+      delta=delta,
+      extras=extras,
+  )
 
 
-def assert_not_almost_equal(first,
-                            second,
-                            places=None,
-                            msg=None,
-                            delta=None,
-                            extras=None):
+def assert_not_almost_equal(
+    first, second, places=None, msg=None, delta=None, extras=None
+):
   """Asserts that first is not almost equal to second.
 
   Args:
@@ -135,49 +125,43 @@
     extras: An optional field for extra information to be included in
       test result.
   """
-  _call_unittest_assertion(_pyunit_proxy.assertNotAlmostEqual,
-                           first,
-                           second,
-                           places=places,
-                           msg=msg,
-                           delta=delta,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertNotAlmostEqual,
+      first,
+      second,
+      places=places,
+      msg=msg,
+      delta=delta,
+      extras=extras,
+  )
 
 
 def assert_in(member, container, msg=None, extras=None):
   """Asserts that member is in container."""
-  _call_unittest_assertion(_pyunit_proxy.assertIn,
-                           member,
-                           container,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertIn, member, container, msg=msg, extras=extras
+  )
 
 
 def assert_not_in(member, container, msg=None, extras=None):
   """Asserts that member is not in container."""
-  _call_unittest_assertion(_pyunit_proxy.assertNotIn,
-                           member,
-                           container,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertNotIn, member, container, msg=msg, extras=extras
+  )
 
 
 def assert_is(expr1, expr2, msg=None, extras=None):
   """Asserts that expr1 is expr2."""
-  _call_unittest_assertion(_pyunit_proxy.assertIs,
-                           expr1,
-                           expr2,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertIs, expr1, expr2, msg=msg, extras=extras
+  )
 
 
 def assert_is_not(expr1, expr2, msg=None, extras=None):
   """Asserts that expr1 is not expr2."""
-  _call_unittest_assertion(_pyunit_proxy.assertIsNot,
-                           expr1,
-                           expr2,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertIsNot, expr1, expr2, msg=msg, extras=extras
+  )
 
 
 def assert_count_equal(first, second, msg=None, extras=None):
@@ -197,99 +181,83 @@
     assert_count_equal([0, 1, 1], [1, 0, 1]) passes the assertion.
     assert_count_equal([0, 0, 1], [0, 1]) raises an assertion error.
   """
-  _call_unittest_assertion(_pyunit_proxy.assertCountEqual,
-                           first,
-                           second,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertCountEqual, first, second, msg=msg, extras=extras
+  )
 
 
 def assert_less(a, b, msg=None, extras=None):
   """Asserts that a < b."""
-  _call_unittest_assertion(_pyunit_proxy.assertLess,
-                           a,
-                           b,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertLess, a, b, msg=msg, extras=extras
+  )
 
 
 def assert_less_equal(a, b, msg=None, extras=None):
   """Asserts that a <= b."""
-  _call_unittest_assertion(_pyunit_proxy.assertLessEqual,
-                           a,
-                           b,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertLessEqual, a, b, msg=msg, extras=extras
+  )
 
 
 def assert_greater(a, b, msg=None, extras=None):
   """Asserts that a > b."""
-  _call_unittest_assertion(_pyunit_proxy.assertGreater,
-                           a,
-                           b,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertGreater, a, b, msg=msg, extras=extras
+  )
 
 
 def assert_greater_equal(a, b, msg=None, extras=None):
   """Asserts that a >= b."""
-  _call_unittest_assertion(_pyunit_proxy.assertGreaterEqual,
-                           a,
-                           b,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertGreaterEqual, a, b, msg=msg, extras=extras
+  )
 
 
 def assert_is_none(obj, msg=None, extras=None):
   """Asserts that obj is None."""
-  _call_unittest_assertion(_pyunit_proxy.assertIsNone,
-                           obj,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertIsNone, obj, msg=msg, extras=extras
+  )
 
 
 def assert_is_not_none(obj, msg=None, extras=None):
   """Asserts that obj is not None."""
-  _call_unittest_assertion(_pyunit_proxy.assertIsNotNone,
-                           obj,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertIsNotNone, obj, msg=msg, extras=extras
+  )
 
 
 def assert_is_instance(obj, cls, msg=None, extras=None):
   """Asserts that obj is an instance of cls."""
-  _call_unittest_assertion(_pyunit_proxy.assertIsInstance,
-                           obj,
-                           cls,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertIsInstance, obj, cls, msg=msg, extras=extras
+  )
 
 
 def assert_not_is_instance(obj, cls, msg=None, extras=None):
   """Asserts that obj is not an instance of cls."""
-  _call_unittest_assertion(_pyunit_proxy.assertNotIsInstance,
-                           obj,
-                           cls,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertNotIsInstance, obj, cls, msg=msg, extras=extras
+  )
 
 
 def assert_regex(text, expected_regex, msg=None, extras=None):
   """Fails the test unless the text matches the regular expression."""
-  _call_unittest_assertion(_pyunit_proxy.assertRegex,
-                           text,
-                           expected_regex,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertRegex, text, expected_regex, msg=msg, extras=extras
+  )
 
 
 def assert_not_regex(text, unexpected_regex, msg=None, extras=None):
   """Fails the test if the text matches the regular expression."""
-  _call_unittest_assertion(_pyunit_proxy.assertNotRegex,
-                           text,
-                           unexpected_regex,
-                           msg=msg,
-                           extras=extras)
+  _call_unittest_assertion(
+      _pyunit_proxy.assertNotRegex,
+      text,
+      unexpected_regex,
+      msg=msg,
+      extras=extras,
+  )
 
 
 def assert_raises(expected_exception, extras=None, *args, **kwargs):
@@ -312,11 +280,9 @@
   return context
 
 
-def assert_raises_regex(expected_exception,
-                        expected_regex,
-                        extras=None,
-                        *args,
-                        **kwargs):
+def assert_raises_regex(
+    expected_exception, expected_regex, extras=None, *args, **kwargs
+):
   """Assert that an exception is raised when a function is called.
 
   If no exception is raised, test fail. If an exception is raised but not
@@ -334,9 +300,9 @@
     extras: An optional field for extra information to be included in
       test result.
   """
-  context = _AssertRaisesContext(expected_exception,
-                                 expected_regex,
-                                 extras=extras)
+  context = _AssertRaisesContext(
+      expected_exception, expected_regex, extras=extras
+  )
   return context
 
 
@@ -526,7 +492,9 @@
     if isinstance(expected_regexp, str):
       expected_regexp = re.compile(expected_regexp)
     if not expected_regexp.search(str(exc_value)):
-      raise signals.TestFailure('"%s" does not match "%s"' %
-                                (expected_regexp.pattern, str(exc_value)),
-                                extras=self.extras)
+      raise signals.TestFailure(
+          '"%s" does not match "%s"'
+          % (expected_regexp.pattern, str(exc_value)),
+          extras=self.extras,
+      )
     return True
diff --git a/mobly/base_instrumentation_test.py b/mobly/base_instrumentation_test.py
index 9c24386..f41a500 100644
--- a/mobly/base_instrumentation_test.py
+++ b/mobly/base_instrumentation_test.py
@@ -302,10 +302,12 @@
     unknown_keys: dict, arbitrary keys that are handled generically.
   """
 
-  def __init__(self,
-               state=_InstrumentationBlockStates.UNKNOWN,
-               prefix=None,
-               previous_instrumentation_block=None):
+  def __init__(
+      self,
+      state=_InstrumentationBlockStates.UNKNOWN,
+      prefix=None,
+      previous_instrumentation_block=None,
+  ):
     self.state = state
     self.prefix = prefix
     self.previous_instrumentation_block = previous_instrumentation_block
@@ -369,7 +371,7 @@
       A string containing a key value pair descripting some property
       of the current instrumentation test method.
     """
-    return line[len(prefix):].strip()
+    return line[len(prefix) :].strip()
 
   def set_status_code(self, status_code_line):
     """Sets the status code for the instrumentation test method, used in
@@ -480,10 +482,12 @@
     self._unknown_keys = {}
     for key, value in instrumentation_block.known_keys.items():
       self._known_keys[key] = '\n'.join(
-          instrumentation_block.known_keys[key]).rstrip()
+          instrumentation_block.known_keys[key]
+      ).rstrip()
     for key, value in instrumentation_block.unknown_keys.items():
       self._unknown_keys[key] = '\n'.join(
-          instrumentation_block.unknown_keys[key]).rstrip()
+          instrumentation_block.unknown_keys[key]
+      ).rstrip()
     self._begin_time = instrumentation_block.begin_time
 
   def _get_name(self):
@@ -510,7 +514,8 @@
       name.
     """
     class_parts = [
-        self._prefix, self._known_keys[_InstrumentationKnownStatusKeys.CLASS]
+        self._prefix,
+        self._known_keys[_InstrumentationKnownStatusKeys.CLASS],
     ]
     return '.'.join(filter(None, class_parts))
 
@@ -549,16 +554,20 @@
 
     extra_parts.append(self._known_keys[_InstrumentationKnownStatusKeys.STREAM])
     extra_parts.append(
-        self._known_keys[_InstrumentationKnownResultKeys.SHORTMSG])
+        self._known_keys[_InstrumentationKnownResultKeys.SHORTMSG]
+    )
     extra_parts.append(
-        self._known_keys[_InstrumentationKnownResultKeys.LONGMSG])
+        self._known_keys[_InstrumentationKnownResultKeys.LONGMSG]
+    )
     extra_parts.append(self._known_keys[_InstrumentationKnownStatusKeys.ERROR])
 
-    if self._known_keys[
-        _InstrumentationKnownStatusKeys.STACK] not in self._known_keys[
-            _InstrumentationKnownStatusKeys.STREAM]:
+    if (
+        self._known_keys[_InstrumentationKnownStatusKeys.STACK]
+        not in self._known_keys[_InstrumentationKnownStatusKeys.STREAM]
+    ):
       extra_parts.append(
-          self._known_keys[_InstrumentationKnownStatusKeys.STACK])
+          self._known_keys[_InstrumentationKnownStatusKeys.STACK]
+      )
 
     return '\n'.join(filter(None, extra_parts))
 
@@ -574,8 +583,10 @@
     """
     if self._status_code in _InstrumentationStatusCodeCategories.FAIL:
       return True
-    elif (self._known_keys[_InstrumentationKnownStatusKeys.STACK] and
-          self._status_code != _InstrumentationStatusCodes.ASSUMPTION_FAILURE):
+    elif (
+        self._known_keys[_InstrumentationKnownStatusKeys.STACK]
+        and self._status_code != _InstrumentationStatusCodes.ASSUMPTION_FAILURE
+    ):
       return True
     elif self._known_keys[_InstrumentationKnownStatusKeys.ERROR]:
       return True
@@ -616,14 +627,16 @@
     elif self._status_code in _InstrumentationStatusCodeCategories.TIMING:
       if self._error_message:
         tr_record.test_error(
-            e=signals.TestError(details=details, extras=extras))
+            e=signals.TestError(details=details, extras=extras)
+        )
       else:
         tr_record = None
     else:
       tr_record.test_error(e=signals.TestError(details=details, extras=extras))
     if self._known_keys[_InstrumentationKnownStatusKeys.STACK]:
       tr_record.termination_signal.stacktrace = self._known_keys[
-          _InstrumentationKnownStatusKeys.STACK]
+          _InstrumentationKnownStatusKeys.STACK
+      ]
     return tr_record
 
   def has_completed_result_block_format(self, error_message):
@@ -669,11 +682,13 @@
   """
 
   DEFAULT_INSTRUMENTATION_OPTION_PREFIX = 'instrumentation_option_'
-  DEFAULT_INSTRUMENTATION_ERROR_MESSAGE = ('instrumentation run exited '
-                                           'unexpectedly')
+  DEFAULT_INSTRUMENTATION_ERROR_MESSAGE = (
+      'instrumentation run exited unexpectedly'
+  )
 
-  def _previous_block_never_completed(self, current_block, previous_block,
-                                      new_state):
+  def _previous_block_never_completed(
+      self, current_block, previous_block, new_state
+  ):
     """Checks if the previous instrumentation method block completed.
 
     Args:
@@ -691,11 +706,14 @@
       completed executing.
     """
     if previous_block:
-      previously_timing_block = (previous_block.status_code
-                                 in _InstrumentationStatusCodeCategories.TIMING)
-      currently_new_block = (current_block.status_code
-                             == _InstrumentationStatusCodes.START or
-                             new_state == _InstrumentationBlockStates.RESULT)
+      previously_timing_block = (
+          previous_block.status_code
+          in _InstrumentationStatusCodeCategories.TIMING
+      )
+      currently_new_block = (
+          current_block.status_code == _InstrumentationStatusCodes.START
+          or new_state == _InstrumentationBlockStates.RESULT
+      )
       return all([previously_timing_block, currently_new_block])
     else:
       return False
@@ -718,21 +736,24 @@
     if self._previous_block_never_completed(
         current_block=instrumentation_block,
         previous_block=instrumentation_block.previous_instrumentation_block,
-        new_state=new_state):
+        new_state=new_state,
+    ):
       instrumentation_block.previous_instrumentation_block.set_error_message(
-          self.DEFAULT_INSTRUMENTATION_ERROR_MESSAGE)
+          self.DEFAULT_INSTRUMENTATION_ERROR_MESSAGE
+      )
       formatters.append(
           _InstrumentationBlockFormatter(
-              instrumentation_block.previous_instrumentation_block))
+              instrumentation_block.previous_instrumentation_block
+          )
+      )
 
     if not instrumentation_block.is_empty:
       formatters.append(_InstrumentationBlockFormatter(instrumentation_block))
     return formatters
 
   def _transition_instrumentation_block(
-      self,
-      instrumentation_block,
-      new_state=_InstrumentationBlockStates.UNKNOWN):
+      self, instrumentation_block, new_state=_InstrumentationBlockStates.UNKNOWN
+  ):
     """Transitions and finishes the current instrumentation block.
 
     Args:
@@ -750,8 +771,9 @@
       test_record = formatter.create_test_record(self.TAG)
       if test_record:
         self.results.add_record(test_record)
-        self.summary_writer.dump(test_record.to_dict(),
-                                 records.TestSummaryEntryType.RECORD)
+        self.summary_writer.dump(
+            test_record.to_dict(), records.TestSummaryEntryType.RECORD
+        )
     return instrumentation_block.transition_state(new_state=new_state)
 
   def _parse_method_block_line(self, instrumentation_block, line):
@@ -767,16 +789,18 @@
       parsing instrumentation output.
     """
     if line.startswith(_InstrumentationStructurePrefixes.STATUS):
-      instrumentation_block.set_key(_InstrumentationStructurePrefixes.STATUS,
-                                    line)
+      instrumentation_block.set_key(
+          _InstrumentationStructurePrefixes.STATUS, line
+      )
       return instrumentation_block
     elif line.startswith(_InstrumentationStructurePrefixes.STATUS_CODE):
       instrumentation_block.set_status_code(line)
       return self._transition_instrumentation_block(instrumentation_block)
     elif line.startswith(_InstrumentationStructurePrefixes.RESULT):
       # Unexpected transition from method block -> result block
-      instrumentation_block.set_key(_InstrumentationStructurePrefixes.RESULT,
-                                    line)
+      instrumentation_block.set_key(
+          _InstrumentationStructurePrefixes.RESULT, line
+      )
       return self._parse_result_line(
           self._transition_instrumentation_block(
               instrumentation_block,
@@ -828,8 +852,10 @@
           ),
           line,
       )
-    elif (line.startswith(_InstrumentationStructurePrefixes.RESULT) or
-          _InstrumentationStructurePrefixes.FAILED in line):
+    elif (
+        line.startswith(_InstrumentationStructurePrefixes.RESULT)
+        or _InstrumentationStructurePrefixes.FAILED in line
+    ):
       return self._parse_result_block_line(
           self._transition_instrumentation_block(
               instrumentation_block,
@@ -882,7 +908,8 @@
     """
     formatter = _InstrumentationBlockFormatter(instrumentation_block)
     return formatter.has_completed_result_block_format(
-        self.DEFAULT_INSTRUMENTATION_ERROR_MESSAGE)
+        self.DEFAULT_INSTRUMENTATION_ERROR_MESSAGE
+    )
 
   def parse_instrumentation_options(self, parameters=None):
     """Returns the options for the instrumentation test from user_params.
@@ -904,17 +931,15 @@
     filtered_parameters = {}
     for parameter_key, parameter_value in parameters.items():
       if parameter_key.startswith(self.DEFAULT_INSTRUMENTATION_OPTION_PREFIX):
-        option_key = parameter_key[len(self.
-                                       DEFAULT_INSTRUMENTATION_OPTION_PREFIX):]
+        option_key = parameter_key[
+            len(self.DEFAULT_INSTRUMENTATION_OPTION_PREFIX) :
+        ]
         filtered_parameters[option_key] = parameter_value
     return filtered_parameters
 
-  def run_instrumentation_test(self,
-                               device,
-                               package,
-                               options=None,
-                               prefix=None,
-                               runner=None):
+  def run_instrumentation_test(
+      self, device, package, options=None, prefix=None, runner=None
+  ):
     """Runs instrumentation tests on a device and creates test records.
 
     Args:
@@ -942,19 +967,23 @@
     def parse_instrumentation(raw_line):
       line = raw_line.rstrip().decode('utf-8')
       logging.info(line)
-      instrumentation_block[0] = self._parse_line(instrumentation_block[0],
-                                                  line)
+      instrumentation_block[0] = self._parse_line(
+          instrumentation_block[0], line
+      )
 
-    device.adb.instrument(package=package,
-                          options=options,
-                          runner=runner,
-                          handler=parse_instrumentation)
+    device.adb.instrument(
+        package=package,
+        options=options,
+        runner=runner,
+        handler=parse_instrumentation,
+    )
 
     return self._finish_parsing(instrumentation_block[0])
 
 
-class BaseInstrumentationTestClass(InstrumentationTestMixin,
-                                   base_test.BaseTestClass):
+class BaseInstrumentationTestClass(
+    InstrumentationTestMixin, base_test.BaseTestClass
+):
   """Base class for all instrumentation test classes to inherit from.
 
   This class extends the BaseTestClass to add functionality to run and parse
diff --git a/mobly/base_suite.py b/mobly/base_suite.py
index 6febcd8..06cdeed 100644
--- a/mobly/base_suite.py
+++ b/mobly/base_suite.py
@@ -14,6 +14,7 @@
 
 import abc
 
+
 class BaseSuite(abc.ABC):
   """Class used to define a Mobly suite.
 
diff --git a/mobly/base_test.py b/mobly/base_test.py
index 9bf4fcc..e5060af 100644
--- a/mobly/base_test.py
+++ b/mobly/base_test.py
@@ -78,12 +78,14 @@
   """
   if count <= 1:
     raise ValueError(
-        f'The `count` for `repeat` must be larger than 1, got "{count}".')
+        f'The `count` for `repeat` must be larger than 1, got "{count}".'
+    )
 
   if max_consecutive_error is not None and max_consecutive_error > count:
     raise ValueError(
         f'The `max_consecutive_error` ({max_consecutive_error}) for `repeat` '
-        f'must be smaller than `count` ({count}).')
+        f'must be smaller than `count` ({count}).'
+    )
 
   def _outer_decorator(func):
     setattr(func, ATTR_REPEAT_CNT, count)
@@ -192,8 +194,10 @@
     self.tests = []
     class_identifier = self.__class__.__name__
     if configs.test_class_name_suffix:
-      class_identifier = '%s_%s' % (class_identifier,
-                                    configs.test_class_name_suffix)
+      class_identifier = '%s_%s' % (
+          class_identifier,
+          configs.test_class_name_suffix,
+      )
     if self.TAG is None:
       self.TAG = class_identifier
     # Set params.
@@ -208,13 +212,13 @@
     self.summary_writer = configs.summary_writer
     self._generated_test_table = collections.OrderedDict()
     self._controller_manager = controller_manager.ControllerManager(
-        class_name=self.TAG, controller_configs=configs.controller_configs)
+        class_name=self.TAG, controller_configs=configs.controller_configs
+    )
     self.controller_configs = self._controller_manager.controller_configs
 
-  def unpack_userparams(self,
-                        req_param_names=None,
-                        opt_param_names=None,
-                        **kwargs):
+  def unpack_userparams(
+      self, req_param_names=None, opt_param_names=None, **kwargs
+  ):
     """An optional function that unpacks user defined parameters into
     individual variables.
 
@@ -251,8 +255,9 @@
       if hasattr(self, name):
         continue
       if name not in self.user_params:
-        raise Error('Missing required user param "%s" in test '
-                    'configuration.' % name)
+        raise Error(
+            'Missing required user param "%s" in test configuration.' % name
+        )
       setattr(self, name, self.user_params[name])
     for name in opt_param_names:
       if hasattr(self, name):
@@ -261,8 +266,8 @@
         setattr(self, name, self.user_params[name])
       else:
         logging.warning(
-            'Missing optional user param "%s" in '
-            'configuration, continue.', name)
+            'Missing optional user param "%s" in configuration, continue.', name
+        )
 
   def register_controller(self, module, required=True, min_number=1):
     """Loads a controller module and returns its loaded devices.
@@ -337,15 +342,17 @@
         * `required` is True and no corresponding config can be found.
         * Any other error occurred in the registration process.
     """
-    return self._controller_manager.register_controller(module, required,
-                                                        min_number)
+    return self._controller_manager.register_controller(
+        module, required, min_number
+    )
 
   def _record_controller_info(self):
     # Collect controller information and write to test result.
     for record in self._controller_manager.get_controller_info_records():
       self.results.add_controller_info_record(record)
-      self.summary_writer.dump(record.to_dict(),
-                               records.TestSummaryEntryType.CONTROLLER_INFO)
+      self.summary_writer.dump(
+          record.to_dict(), records.TestSummaryEntryType.CONTROLLER_INFO
+      )
 
   def _pre_run(self):
     """Proxy function to guarantee the base implementation of `pre_run` is
@@ -358,7 +365,8 @@
     record = records.TestResultRecord(stage_name, self.TAG)
     record.test_begin()
     self.current_test_info = runtime_test_info.RuntimeTestInfo(
-        stage_name, self.log_path, record)
+        stage_name, self.log_path, record
+    )
     try:
       with self._log_test_stage(stage_name):
         self.pre_run()
@@ -371,8 +379,9 @@
       logging.exception('%s failed for %s.', stage_name, self.TAG)
       record.test_error(e)
       self.results.add_class_error(record)
-      self.summary_writer.dump(record.to_dict(),
-                               records.TestSummaryEntryType.RECORD)
+      self.summary_writer.dump(
+          record.to_dict(), records.TestSummaryEntryType.RECORD
+      )
       return False
 
   def pre_run(self):
@@ -411,7 +420,8 @@
     class_record = records.TestResultRecord(STAGE_NAME_SETUP_CLASS, self.TAG)
     class_record.test_begin()
     self.current_test_info = runtime_test_info.RuntimeTestInfo(
-        STAGE_NAME_SETUP_CLASS, self.log_path, class_record)
+        STAGE_NAME_SETUP_CLASS, self.log_path, class_record
+    )
     expects.recorder.reset_internal_states(class_record)
     try:
       with self._log_test_stage(STAGE_NAME_SETUP_CLASS):
@@ -427,16 +437,18 @@
       self.results.add_class_error(class_record)
       self._exec_procedure_func(self._on_fail, class_record)
       class_record.update_record()
-      self.summary_writer.dump(class_record.to_dict(),
-                               records.TestSummaryEntryType.RECORD)
+      self.summary_writer.dump(
+          class_record.to_dict(), records.TestSummaryEntryType.RECORD
+      )
       self._skip_remaining_tests(e)
       return self.results
     if expects.recorder.has_error:
       self._exec_procedure_func(self._on_fail, class_record)
       class_record.test_error()
       class_record.update_record()
-      self.summary_writer.dump(class_record.to_dict(),
-                               records.TestSummaryEntryType.RECORD)
+      self.summary_writer.dump(
+          class_record.to_dict(), records.TestSummaryEntryType.RECORD
+      )
       self.results.add_class_error(class_record)
       self._skip_remaining_tests(class_record.termination_signal.exception)
       return self.results
@@ -460,7 +472,8 @@
     record = records.TestResultRecord(stage_name, self.TAG)
     record.test_begin()
     self.current_test_info = runtime_test_info.RuntimeTestInfo(
-        stage_name, self.log_path, record)
+        stage_name, self.log_path, record
+    )
     expects.recorder.reset_internal_states(record)
     try:
       with self._log_test_stage(stage_name):
@@ -473,15 +486,17 @@
       record.test_error(e)
       record.update_record()
       self.results.add_class_error(record)
-      self.summary_writer.dump(record.to_dict(),
-                               records.TestSummaryEntryType.RECORD)
+      self.summary_writer.dump(
+          record.to_dict(), records.TestSummaryEntryType.RECORD
+      )
     else:
       if expects.recorder.has_error:
         record.test_error()
         record.update_record()
         self.results.add_class_error(record)
-        self.summary_writer.dump(record.to_dict(),
-                                 records.TestSummaryEntryType.RECORD)
+        self.summary_writer.dump(
+            record.to_dict(), records.TestSummaryEntryType.RECORD
+        )
     finally:
       self._clean_up()
 
@@ -511,14 +526,18 @@
     if parent_token == stage_name:
       parent_token = self.TAG
     logging.debug(
-        TEST_STAGE_BEGIN_LOG_TEMPLATE.format(parent_token=parent_token,
-                                             child_token=stage_name))
+        TEST_STAGE_BEGIN_LOG_TEMPLATE.format(
+            parent_token=parent_token, child_token=stage_name
+        )
+    )
     try:
       yield
     finally:
       logging.debug(
-          TEST_STAGE_END_LOG_TEMPLATE.format(parent_token=parent_token,
-                                             child_token=stage_name))
+          TEST_STAGE_END_LOG_TEMPLATE.format(
+              parent_token=parent_token, child_token=stage_name
+          )
+      )
 
   def _setup_test(self, test_name):
     """Proxy function to guarantee the base implementation of setup_test is
@@ -647,8 +666,11 @@
       except signals.TestAbortSignal:
         raise
       except Exception as e:
-        logging.exception('Exception happened when executing %s for %s.',
-                          procedure_name, self.current_test_info.name)
+        logging.exception(
+            'Exception happened when executing %s for %s.',
+            procedure_name,
+            self.current_test_info.name,
+        )
         tr_record.add_error(procedure_name, e)
 
   def record_data(self, content):
@@ -698,12 +720,14 @@
       retry_name = f'{test_name}_retry_{i+1}'
       new_record = records.TestResultRecord(retry_name, self.TAG)
       new_record.retry_parent = previous_record
+      new_record.parent = (previous_record, records.TestParentType.RETRY)
       previous_record = self.exec_one_test(retry_name, test_method, new_record)
       if not should_retry(previous_record):
         break
 
-  def _exec_one_test_with_repeat(self, test_name, test_method, repeat_count,
-                                 max_consecutive_error):
+  def _exec_one_test_with_repeat(
+      self, test_name, test_method, repeat_count, max_consecutive_error
+  ):
     """Repeatedly execute a test case.
 
     This method performs the action defined by the `repeat` decorator.
@@ -726,21 +750,31 @@
     if max_consecutive_error == 0:
       max_consecutive_error = repeat_count
 
+    previous_record = None
     for i in range(repeat_count):
       new_test_name = f'{test_name}_{i}'
-      record = self.exec_one_test(new_test_name, test_method)
-      if record.result in [
+      new_record = records.TestResultRecord(new_test_name, self.TAG)
+      if i > 0:
+        new_record.parent = (previous_record, records.TestParentType.REPEAT)
+      previous_record = self.exec_one_test(
+          new_test_name, test_method, new_record
+      )
+      if previous_record.result in [
           records.TestResultEnums.TEST_RESULT_FAIL,
           records.TestResultEnums.TEST_RESULT_ERROR,
       ]:
         consecutive_error_count += 1
       else:
         consecutive_error_count = 0
+
       if consecutive_error_count == max_consecutive_error:
         logging.error(
             'Repeated test case "%s" has consecutively failed %d iterations, '
-            'aborting the remaining %d iterations.', test_name,
-            consecutive_error_count, repeat_count - 1 - i)
+            'aborting the remaining %d iterations.',
+            test_name,
+            consecutive_error_count,
+            repeat_count - 1 - i,
+        )
         return
 
   def exec_one_test(self, test_name, test_method, record=None):
@@ -768,7 +802,8 @@
     tr_record.uid = getattr(test_method, 'uid', None)
     tr_record.test_begin()
     self.current_test_info = runtime_test_info.RuntimeTestInfo(
-        test_name, self.log_path, tr_record)
+        test_name, self.log_path, tr_record
+    )
     expects.recorder.reset_internal_states(tr_record)
     logging.info('%s %s', TEST_CASE_TOKEN, test_name)
     # Did teardown_test throw an error.
@@ -784,8 +819,9 @@
       except (signals.TestPass, signals.TestAbortSignal, signals.TestSkip):
         raise
       except Exception:
-        logging.exception('Exception occurred in %s.',
-                          self.current_test_info.name)
+        logging.exception(
+            'Exception occurred in %s.', self.current_test_info.name
+        )
         raise
       finally:
         before_count = expects.recorder.error_count
@@ -794,9 +830,11 @@
         except signals.TestAbortSignal:
           raise
         except Exception as e:
-          logging.exception('Exception occurred in %s of %s.',
-                            STAGE_NAME_TEARDOWN_TEST,
-                            self.current_test_info.name)
+          logging.exception(
+              'Exception occurred in %s of %s.',
+              STAGE_NAME_TEARDOWN_TEST,
+              self.current_test_info.name,
+          )
           tr_record.test_error()
           tr_record.add_error(STAGE_NAME_TEARDOWN_TEST, e)
           teardown_test_failed = True
@@ -831,32 +869,37 @@
     finally:
       tr_record.update_record()
       try:
-        if tr_record.result in (records.TestResultEnums.TEST_RESULT_ERROR,
-                                records.TestResultEnums.TEST_RESULT_FAIL):
+        if tr_record.result in (
+            records.TestResultEnums.TEST_RESULT_ERROR,
+            records.TestResultEnums.TEST_RESULT_FAIL,
+        ):
           self._exec_procedure_func(self._on_fail, tr_record)
         elif tr_record.result == records.TestResultEnums.TEST_RESULT_PASS:
           self._exec_procedure_func(self._on_pass, tr_record)
         elif tr_record.result == records.TestResultEnums.TEST_RESULT_SKIP:
           self._exec_procedure_func(self._on_skip, tr_record)
       finally:
-        logging.info(RESULT_LINE_TEMPLATE, tr_record.test_name,
-                     tr_record.result)
+        logging.info(
+            RESULT_LINE_TEMPLATE, tr_record.test_name, tr_record.result
+        )
         self.results.add_record(tr_record)
-        self.summary_writer.dump(tr_record.to_dict(),
-                                 records.TestSummaryEntryType.RECORD)
+        self.summary_writer.dump(
+            tr_record.to_dict(), records.TestSummaryEntryType.RECORD
+        )
         self.current_test_info = None
     return tr_record
 
   def _assert_function_names_in_stack(self, expected_func_names):
-    """Asserts that the current stack contains any of the given function names.
-    """
+    """Asserts that the current stack contains any of the given function names."""
     current_frame = inspect.currentframe()
     caller_frames = inspect.getouterframes(current_frame, 2)
     for caller_frame in caller_frames[2:]:
       if caller_frame[3] in expected_func_names:
         return
-    raise Error(f"'{caller_frames[1][3]}' cannot be called outside of the "
-                f"following functions: {expected_func_names}.")
+    raise Error(
+        f"'{caller_frames[1][3]}' cannot be called outside of the "
+        f'following functions: {expected_func_names}.'
+    )
 
   def generate_tests(self, test_logic, name_func, arg_sets, uid_func=None):
     """Generates tests in the test class.
@@ -884,20 +927,26 @@
         is the corresponding UID.
     """
     self._assert_function_names_in_stack(
-        [STAGE_NAME_PRE_RUN, STAGE_NAME_SETUP_GENERATED_TESTS])
+        [STAGE_NAME_PRE_RUN, STAGE_NAME_SETUP_GENERATED_TESTS]
+    )
     root_msg = 'During test generation of "%s":' % test_logic.__name__
     for args in arg_sets:
       test_name = name_func(*args)
       if test_name in self.get_existing_test_names():
-        raise Error('%s Test name "%s" already exists, cannot be duplicated!' %
-                    (root_msg, test_name))
+        raise Error(
+            '%s Test name "%s" already exists, cannot be duplicated!'
+            % (root_msg, test_name)
+        )
       test_func = functools.partial(test_logic, *args)
       # If the `test_logic` method is decorated by `retry` or `repeat`
       # decorators, copy the attributes added by the decorators to the
       # generated test methods as well, so the generated test methods
       # also have the retry/repeat behavior.
-      for attr_name in (ATTR_MAX_RETRY_CNT, ATTR_MAX_CONSEC_ERROR,
-                        ATTR_REPEAT_CNT):
+      for attr_name in (
+          ATTR_MAX_RETRY_CNT,
+          ATTR_MAX_CONSEC_ERROR,
+          ATTR_REPEAT_CNT,
+      ):
         attr = getattr(test_logic, attr_name, None)
         if attr is not None:
           setattr(test_func, attr_name, attr)
@@ -927,8 +976,9 @@
     except signals.TestAbortAll:
       raise
     except Exception:
-      logging.exception('Exception happened when executing %s in %s.',
-                        func.__name__, self.TAG)
+      logging.exception(
+          'Exception happened when executing %s in %s.', func.__name__, self.TAG
+      )
 
   def get_existing_test_names(self):
     """Gets the names of existing tests in the class.
@@ -966,8 +1016,10 @@
     test_methods = []
     for test_name in test_names:
       if not test_name.startswith('test_'):
-        raise Error('Test method name %s does not follow naming '
-                    'convention test_*, abort.' % test_name)
+        raise Error(
+            'Test method name %s does not follow naming '
+            'convention test_*, abort.' % test_name
+        )
       if hasattr(self, test_name):
         test_method = getattr(self, test_name)
       elif test_name in self._generated_test_table:
@@ -992,8 +1044,9 @@
         test_record = records.TestResultRecord(test_name, self.TAG)
         test_record.test_skip(exception)
         self.results.add_record(test_record)
-        self.summary_writer.dump(test_record.to_dict(),
-                                 records.TestSummaryEntryType.RECORD)
+        self.summary_writer.dump(
+            test_record.to_dict(), records.TestSummaryEntryType.RECORD
+        )
 
   def run(self, test_names=None):
     """Runs tests within a test class.
@@ -1029,8 +1082,10 @@
         # No test method specified by user, execute all in test class.
         test_names = self.get_existing_test_names()
     self.results.requested = test_names
-    self.summary_writer.dump(self.results.requested_test_names_dict(),
-                             records.TestSummaryEntryType.TEST_NAME_LIST)
+    self.summary_writer.dump(
+        self.results.requested_test_names_dict(),
+        records.TestSummaryEntryType.TEST_NAME_LIST,
+    )
     tests = self._get_test_methods(test_names)
     try:
       setup_class_result = self._setup_class()
@@ -1042,11 +1097,13 @@
         repeat_count = getattr(test_method, ATTR_REPEAT_CNT, 0)
         max_retry_count = getattr(test_method, ATTR_MAX_RETRY_CNT, 0)
         if max_retry_count:
-          self._exec_one_test_with_retry(test_name, test_method,
-                                         max_retry_count)
+          self._exec_one_test_with_retry(
+              test_name, test_method, max_retry_count
+          )
         elif repeat_count:
-          self._exec_one_test_with_repeat(test_name, test_method, repeat_count,
-                                          max_consecutive_error)
+          self._exec_one_test_with_repeat(
+              test_name, test_method, repeat_count, max_consecutive_error
+          )
         else:
           self.exec_one_test(test_name, test_method)
       return self.results
@@ -1063,8 +1120,9 @@
       raise e
     finally:
       self._teardown_class()
-      logging.info('Summary for test class %s: %s', self.TAG,
-                   self.results.summary_str())
+      logging.info(
+          'Summary for test class %s: %s', self.TAG, self.results.summary_str()
+      )
 
   def _clean_up(self):
     """The final stage of a test class execution."""
@@ -1072,7 +1130,8 @@
     record = records.TestResultRecord(stage_name, self.TAG)
     record.test_begin()
     self.current_test_info = runtime_test_info.RuntimeTestInfo(
-        stage_name, self.log_path, record)
+        stage_name, self.log_path, record
+    )
     expects.recorder.reset_internal_states(record)
     with self._log_test_stage(stage_name):
       # Write controller info and summary to summary file.
@@ -1082,5 +1141,6 @@
         record.test_error()
         record.update_record()
         self.results.add_class_error(record)
-        self.summary_writer.dump(record.to_dict(),
-                                 records.TestSummaryEntryType.RECORD)
+        self.summary_writer.dump(
+            record.to_dict(), records.TestSummaryEntryType.RECORD
+        )
diff --git a/mobly/config_parser.py b/mobly/config_parser.py
index 2f2da91..a9aae59 100644
--- a/mobly/config_parser.py
+++ b/mobly/config_parser.py
@@ -39,8 +39,9 @@
   """
   required_key = keys.Config.key_testbed.value
   if required_key not in test_config:
-    raise MoblyConfigError('Required key %s missing in test config.' %
-                           required_key)
+    raise MoblyConfigError(
+        'Required key %s missing in test config.' % required_key
+    )
 
 
 def _validate_testbed_name(name):
@@ -60,8 +61,9 @@
   name = str(name)
   for char in name:
     if char not in utils.valid_filename_chars:
-      raise MoblyConfigError('Char "%s" is not allowed in test bed names.' %
-                             char)
+      raise MoblyConfigError(
+          'Char "%s" is not allowed in test bed names.' % char
+      )
 
 
 def _validate_testbed_configs(testbed_configs):
@@ -111,7 +113,8 @@
     if len(tbs) != len(tb_filters):
       raise MoblyConfigError(
           'Expect to find %d test bed configs, found %d. Check if'
-          ' you have the correct test bed names.' % (len(tb_filters), len(tbs)))
+          ' you have the correct test bed names.' % (len(tb_filters), len(tbs))
+      )
     configs[keys.Config.key_testbed.value] = tbs
   mobly_params = configs.get(keys.Config.key_mobly_params.value, {})
   # Decide log path.
@@ -127,14 +130,17 @@
   for original_bed_config in configs[keys.Config.key_testbed.value]:
     test_run_config = TestRunConfig()
     test_run_config.testbed_name = original_bed_config[
-        keys.Config.key_testbed_name.value]
+        keys.Config.key_testbed_name.value
+    ]
     # Deprecated, use testbed_name
     test_run_config.test_bed_name = test_run_config.testbed_name
     test_run_config.log_path = log_path
     test_run_config.controller_configs = original_bed_config.get(
-        keys.Config.key_testbed_controllers.value, {})
+        keys.Config.key_testbed_controllers.value, {}
+    )
     test_run_config.user_params = original_bed_config.get(
-        keys.Config.key_testbed_test_params.value, {})
+        keys.Config.key_testbed_test_params.value, {}
+    )
     test_configs.append(test_run_config)
   return test_configs
 
@@ -186,8 +192,7 @@
     self.test_class_name_suffix = None
 
   def copy(self):
-    """Returns a deep copy of the current config.
-    """
+    """Returns a deep copy of the current config."""
     return copy.deepcopy(self)
 
   def __str__(self):
diff --git a/mobly/controller_manager.py b/mobly/controller_manager.py
index f19da27..c4633e7 100644
--- a/mobly/controller_manager.py
+++ b/mobly/controller_manager.py
@@ -11,7 +11,7 @@
 # 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.
-""" Module for Mobly controller management."""
+"""Module for Mobly controller management."""
 import collections
 import copy
 import logging
@@ -41,12 +41,14 @@
   for attr in required_attributes:
     if not hasattr(module, attr):
       raise signals.ControllerError(
-          'Module %s missing required controller module attribute'
-          ' %s.' % (module.__name__, attr))
+          'Module %s missing required controller module attribute %s.'
+          % (module.__name__, attr)
+      )
     if not getattr(module, attr):
       raise signals.ControllerError(
-          'Controller interface %s in %s cannot be null.' %
-          (attr, module.__name__))
+          'Controller interface %s in %s cannot be null.'
+          % (attr, module.__name__)
+      )
 
 
 class ControllerManager:
@@ -62,7 +64,8 @@
 
   def __init__(self, class_name, controller_configs):
     # Controller object management.
-    self._controller_objects = collections.OrderedDict(
+    self._controller_objects = (
+        collections.OrderedDict()
     )  # controller_name: objects
     self._controller_modules = {}  # controller_name: module
     self._class_name = class_name
@@ -102,16 +105,19 @@
     if module_ref_name in self._controller_objects:
       raise signals.ControllerError(
           'Controller module %s has already been registered. It cannot '
-          'be registered again.' % module_ref_name)
+          'be registered again.' % module_ref_name
+      )
     # Create controller objects.
     module_config_name = module.MOBLY_CONTROLLER_CONFIG_NAME
     if module_config_name not in self.controller_configs:
       if required:
-        raise signals.ControllerError('No corresponding config found for %s' %
-                                      module_config_name)
+        raise signals.ControllerError(
+            'No corresponding config found for %s' % module_config_name
+        )
       logging.warning(
           'No corresponding config found for optional controller %s',
-          module_config_name)
+          module_config_name,
+      )
       return None
     try:
       # Make a deep copy of the config to pass to the controller module,
@@ -122,24 +128,28 @@
     except Exception:
       logging.exception(
           'Failed to initialize objects for controller %s, abort!',
-          module_config_name)
+          module_config_name,
+      )
       raise
     if not isinstance(objects, list):
       raise signals.ControllerError(
-          'Controller module %s did not return a list of objects, abort.' %
-          module_ref_name)
+          'Controller module %s did not return a list of objects, abort.'
+          % module_ref_name
+      )
     # Check we got enough controller objects to continue.
     actual_number = len(objects)
     if actual_number < min_number:
       module.destroy(objects)
       raise signals.ControllerError(
-          'Expected to get at least %d controller objects, got %d.' %
-          (min_number, actual_number))
+          'Expected to get at least %d controller objects, got %d.'
+          % (min_number, actual_number)
+      )
     # Save a shallow copy of the list for internal usage, so tests can't
     # affect internal registry by manipulating the object list.
     self._controller_objects[module_ref_name] = copy.copy(objects)
-    logging.debug('Found %d objects for controller %s', len(objects),
-                  module_config_name)
+    logging.debug(
+        'Found %d objects for controller %s', len(objects), module_config_name
+    )
     self._controller_modules[module_ref_name] = module
     return objects
 
@@ -174,22 +184,27 @@
     controller_info = None
     try:
       controller_info = module.get_info(
-          copy.copy(self._controller_objects[controller_module_name]))
+          copy.copy(self._controller_objects[controller_module_name])
+      )
     except AttributeError:
       logging.warning(
           'No optional debug info found for controller '
-          '%s. To provide it, implement `get_info`.', controller_module_name)
+          '%s. To provide it, implement `get_info`.',
+          controller_module_name,
+      )
     try:
       yaml.dump(controller_info)
     except TypeError:
       logging.warning(
           'The info of controller %s in class "%s" is not '
-          'YAML serializable! Coercing it to string.', controller_module_name,
-          self._class_name)
+          'YAML serializable! Coercing it to string.',
+          controller_module_name,
+          self._class_name,
+      )
       controller_info = str(controller_info)
-    return records.ControllerInfoRecord(self._class_name,
-                                        module.MOBLY_CONTROLLER_CONFIG_NAME,
-                                        controller_info)
+    return records.ControllerInfoRecord(
+        self._class_name, module.MOBLY_CONTROLLER_CONFIG_NAME, controller_info
+    )
 
   def get_controller_info_records(self):
     """Get the info records for all the controller objects in the manager.
@@ -204,7 +219,8 @@
     info_records = []
     for controller_module_name in self._controller_objects.keys():
       with expects.expect_no_raises(
-          'Failed to collect controller info from %s' % controller_module_name):
+          'Failed to collect controller info from %s' % controller_module_name
+      ):
         record = self._create_controller_info_record(controller_module_name)
         if record:
           info_records.append(record)
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
index c093e3c..20c5762 100644
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -14,6 +14,7 @@
 
 import contextlib
 import enum
+import functools
 import logging
 import os
 import re
@@ -149,12 +150,17 @@
     serials: list of strings, the serials of all the devices that are expected
       to exist.
   """
-  valid_ad_identifiers = (list_adb_devices() + list_adb_devices_by_usb_id() +
-                          list_fastboot_devices())
+  valid_ad_identifiers = (
+      list_adb_devices()
+      + list_adb_devices_by_usb_id()
+      + list_fastboot_devices()
+  )
   for serial in serials:
     if serial not in valid_ad_identifiers:
-      raise Error(f'Android device serial "{serial}" is specified in '
-                  'config but is not reachable.')
+      raise Error(
+          f'Android device serial "{serial}" is specified in '
+          'config but is not reachable.'
+      )
 
 
 def _start_services_on_ads(ads):
@@ -172,15 +178,18 @@
       if start_logcat:
         ad.services.logcat.start()
     except Exception:
-      is_required = getattr(ad, KEY_DEVICE_REQUIRED,
-                            DEFAULT_VALUE_DEVICE_REQUIRED)
+      is_required = getattr(
+          ad, KEY_DEVICE_REQUIRED, DEFAULT_VALUE_DEVICE_REQUIRED
+      )
       if is_required:
         ad.log.exception('Failed to start some services, abort!')
         destroy(ads)
         raise
       else:
-        ad.log.exception('Skipping this optional device because some '
-                         'services failed to start.')
+        ad.log.exception(
+            'Skipping this optional device because some '
+            'services failed to start.'
+        )
 
 
 def parse_device_list(device_list_str, key=None):
@@ -201,7 +210,7 @@
   try:
     clean_lines = str(device_list_str, 'utf-8').strip().split('\n')
   except UnicodeDecodeError:
-    logging.warning("unicode decode error, origin str: %s", device_list_str)
+    logging.warning('unicode decode error, origin str: %s', device_list_str)
     raise
   results = []
   for line in clean_lines:
@@ -291,7 +300,8 @@
       serials.append(c['serial'])
     except KeyError:
       raise Error(
-          'Required value "serial" is missing in AndroidDevice config %s.' % c)
+          'Required value "serial" is missing in AndroidDevice config %s.' % c
+      )
   _validate_device_existence(serials)
   results = []
   for c in configs:
@@ -373,8 +383,9 @@
 
   filtered = filter_devices(ads, _get_device_filter)
   if not filtered:
-    raise Error('Could not find a target device that matches condition: %s.' %
-                kwargs)
+    raise Error(
+        'Could not find a target device that matches condition: %s.' % kwargs
+    )
   else:
     return filtered
 
@@ -429,9 +440,9 @@
     begin_time = mobly_logger.sanitize_filename(str(begin_time))
 
   def take_br(test_name, begin_time, ad, destination):
-    ad.take_bug_report(test_name=test_name,
-                       begin_time=begin_time,
-                       destination=destination)
+    ad.take_bug_report(
+        test_name=test_name, begin_time=begin_time, destination=destination
+    )
 
   args = [(test_name, begin_time, ad, destination) for ad in ads]
   utils.concurrent_exec(take_br, args)
@@ -450,7 +461,10 @@
   BUILD_TYPE = 'build_type', 'ro.build.type'
   BUILD_FINGERPRINT = 'build_fingerprint', 'ro.build.fingerprint'
   BUILD_VERSION_CODENAME = 'build_version_codename', 'ro.build.version.codename'
-  BUILD_VERSION_INCREMENTAL = 'build_version_incremental', 'ro.build.version.incremental'
+  BUILD_VERSION_INCREMENTAL = (
+      'build_version_incremental',
+      'ro.build.version.incremental',
+  )
   BUILD_VERSION_SDK = 'build_version_sdk', 'ro.build.version.sdk'
   BUILD_PRODUCT = 'build_product', 'ro.build.product'
   BUILD_CHARACTERISTICS = 'build_characteristics', 'ro.build.characteristics'
@@ -494,11 +508,13 @@
     self._serial = str(serial)
     # logging.log_path only exists when this is used in an Mobly test run.
     _log_path_base = utils.abs_path(getattr(logging, 'log_path', '/tmp/logs'))
-    self._log_path = os.path.join(_log_path_base,
-                                  'AndroidDevice%s' % self._normalized_serial)
+    self._log_path = os.path.join(
+        _log_path_base, 'AndroidDevice%s' % self._normalized_serial
+    )
     self._debug_tag = self._serial
-    self.log = AndroidDeviceLoggerAdapter(logging.getLogger(),
-                                          {'tag': self.debug_tag})
+    self.log = AndroidDeviceLoggerAdapter(
+        logging.getLogger(), {'tag': self.debug_tag}
+    )
     self._build_info = None
     self._is_rebooting = False
     self.adb = adb.AdbProxy(serial)
@@ -506,11 +522,12 @@
     if self.is_rootable:
       self.root_adb()
     self.services = service_manager.ServiceManager(self)
-    self.services.register(SERVICE_NAME_LOGCAT,
-                           logcat.Logcat,
-                           start_service=False)
-    self.services.register('snippets',
-                           snippet_management_service.SnippetManagementService)
+    self.services.register(
+        SERVICE_NAME_LOGCAT, logcat.Logcat, start_service=False
+    )
+    self.services.register(
+        'snippets', snippet_management_service.SnippetManagementService
+    )
     # Device info cache.
     self._user_added_device_info = {}
 
@@ -544,7 +561,7 @@
         'serial': self.serial,
         'model': self.model,
         'build_info': self.build_info,
-        'user_added_info': self._user_added_device_info
+        'user_added_info': self._user_added_device_info,
     }
     return info
 
@@ -621,8 +638,7 @@
 
   @property
   def log_path(self):
-    """A string that is the path for all logs collected from this device.
-    """
+    """A string that is the path for all logs collected from this device."""
     if not os.path.exists(self._log_path):
       utils.create_dir(self._log_path)
     return self._log_path
@@ -632,13 +648,15 @@
     """Setter for `log_path`, use with caution."""
     if self.has_active_service:
       raise DeviceError(
-          self, 'Cannot change `log_path` when there is service running.')
+          self, 'Cannot change `log_path` when there is service running.'
+      )
     old_path = self._log_path
     if new_path == old_path:
       return
     if os.listdir(new_path):
-      raise DeviceError(self,
-                        'Logs already exist at %s, cannot override.' % new_path)
+      raise DeviceError(
+          self, 'Logs already exist at %s, cannot override.' % new_path
+      )
     if os.path.exists(old_path):
       # Remove new path so copytree doesn't complain.
       shutil.rmtree(new_path, ignore_errors=True)
@@ -682,7 +700,8 @@
     if self.has_active_service:
       raise DeviceError(
           self,
-          'Cannot change device serial number when there is service running.')
+          'Cannot change device serial number when there is service running.',
+      )
     if self._debug_tag == self.serial:
       self._debug_tag = new_serial
     self._serial = new_serial
@@ -802,21 +821,20 @@
       build_info = self.adb.getprops(CACHED_SYSTEM_PROPS)
       for build_info_constant in BuildInfoConstants:
         info[build_info_constant.build_info_key] = build_info.get(
-            build_info_constant.system_prop_key, '')
+            build_info_constant.system_prop_key, ''
+        )
       self._build_info = info
       return info
     return self._build_info
 
   @property
   def is_bootloader(self):
-    """True if the device is in bootloader mode.
-    """
+    """True if the device is in bootloader mode."""
     return self.serial in list_fastboot_devices()
 
   @property
   def is_adb_root(self):
-    """True if adb is running as root for this device.
-    """
+    """True if adb is running as root for this device."""
     try:
       return '0' == self.adb.shell('id -u').decode('utf-8').strip()
     except adb.AdbError:
@@ -828,10 +846,9 @@
   def is_rootable(self):
     return not self.is_bootloader and self.build_info['debuggable'] == '1'
 
-  @property
+  @functools.cached_property
   def model(self):
-    """The Android code name for the device.
-    """
+    """The Android code name for the device."""
     # If device is in bootloader mode, get mode name from fastboot.
     if self.is_bootloader:
       out = self.fastboot.getvar('product').strip()
@@ -886,8 +903,10 @@
     for k, v in config.items():
       if hasattr(self, k) and k not in _ANDROID_DEVICE_SETTABLE_PROPS:
         raise DeviceError(
-            self, ('Attribute %s already exists with value %s, cannot set '
-                   'again.') % (k, getattr(self, k)))
+            self,
+            'Attribute %s already exists with value %s, cannot set again.'
+            % (k, getattr(self, k)),
+        )
       setattr(self, k, v)
 
   def root_adb(self):
@@ -928,10 +947,9 @@
     if hasattr(self, name):
       raise SnippetError(
           self,
-          'Attribute "%s" already exists, please use a different name.' % name)
-    self.services.snippets.add_snippet_client(
-        name, package, config=config
-    )
+          'Attribute "%s" already exists, please use a different name.' % name,
+      )
+    self.services.snippets.add_snippet_client(name, package, config=config)
 
   def unload_snippet(self, name):
     """Stops a snippet apk.
@@ -944,10 +962,9 @@
     """
     self.services.snippets.remove_snippet_client(name)
 
-  def generate_filename(self,
-                        file_type,
-                        time_identifier=None,
-                        extension_name=None):
+  def generate_filename(
+      self, file_type, time_identifier=None, extension_name=None
+  ):
     """Generates a name for an output file related to this device.
 
     The name follows the pattern:
@@ -984,11 +1001,9 @@
     self.log.debug('Generated filename: %s', filename_str)
     return filename_str
 
-  def take_bug_report(self,
-                      test_name=None,
-                      begin_time=None,
-                      timeout=300,
-                      destination=None):
+  def take_bug_report(
+      self, test_name=None, begin_time=None, timeout=300, destination=None
+  ):
     """Takes a bug report on the device and stores it in a file.
 
     Args:
@@ -1056,8 +1071,9 @@
     """
     filename = self.generate_filename(prefix, extension_name='png')
     device_path = os.path.join('/storage/emulated/0/', filename)
-    self.adb.shell(['screencap', '-p', device_path],
-                   timeout=TAKE_SCREENSHOT_TIMEOUT_SECOND)
+    self.adb.shell(
+        ['screencap', '-p', device_path], timeout=TAKE_SCREENSHOT_TIMEOUT_SECOND
+    )
     utils.create_dir(destination)
     self.adb.pull([device_path, destination])
     pic_path = os.path.join(destination, filename)
@@ -1086,8 +1102,9 @@
       return False, clean_out
     return True, clean_out
 
-  def wait_for_boot_completion(self,
-                               timeout=DEFAULT_TIMEOUT_BOOT_COMPLETION_SECOND):
+  def wait_for_boot_completion(
+      self, timeout=DEFAULT_TIMEOUT_BOOT_COMPLETION_SECOND
+  ):
     """Waits for Android framework to broadcast ACTION_BOOT_COMPLETED.
 
     This function times out after 15 minutes.
diff --git a/mobly/controllers/android_device_lib/adb.py b/mobly/controllers/android_device_lib/adb.py
index 8b55b65..721dcc7 100644
--- a/mobly/controllers/android_device_lib/adb.py
+++ b/mobly/controllers/android_device_lib/adb.py
@@ -33,7 +33,9 @@
 ADB_ROOT_RETRY_ATTEMPT_INTERVAL_SEC = 10
 
 # Qualified class name of the default instrumentation test runner.
-DEFAULT_INSTRUMENTATION_RUNNER = 'com.android.common.support.test.runner.AndroidJUnitRunner'
+DEFAULT_INSTRUMENTATION_RUNNER = (
+    'com.android.common.support.test.runner.AndroidJUnitRunner'
+)
 
 # `adb shell getprop` can take surprisingly long, when the device is a
 # networked virtual device.
@@ -43,7 +45,8 @@
 
 # The regex pattern indicating the `adb connect` command did not fail.
 PATTERN_ADB_CONNECT_SUCCESS = re.compile(
-    r'^connected to .*|^already connected to .*')
+    r'^connected to .*|^already connected to .*'
+)
 
 
 class Error(Exception):
@@ -72,9 +75,12 @@
     self.serial = serial
 
   def __str__(self):
-    return ('Error executing adb cmd "%s". ret: %d, stdout: %s, stderr: %s') % (
-        utils.cli_cmd_to_string(
-            self.cmd), self.ret_code, self.stdout, self.stderr)
+    return 'Error executing adb cmd "%s". ret: %d, stdout: %s, stderr: %s' % (
+        utils.cli_cmd_to_string(self.cmd),
+        self.ret_code,
+        self.stdout,
+        self.stderr,
+    )
 
 
 class AdbTimeoutError(Error):
@@ -96,7 +102,9 @@
 
   def __str__(self):
     return 'Timed out executing command "%s" after %ss.' % (
-        utils.cli_cmd_to_string(self.cmd), self.timeout)
+        utils.cli_cmd_to_string(self.cmd),
+        self.timeout,
+    )
 
 
 def is_adb_available():
@@ -190,16 +198,19 @@
 
     if stderr:
       stderr.write(err)
-    logging.debug('cmd: %s, stdout: %s, stderr: %s, ret: %s',
-                  utils.cli_cmd_to_string(args), out, err, ret)
+    logging.debug(
+        'cmd: %s, stdout: %s, stderr: %s, ret: %s',
+        utils.cli_cmd_to_string(args),
+        out,
+        err,
+        ret,
+    )
     if ret == 0:
       return out
     else:
-      raise AdbError(cmd=args,
-                     stdout=out,
-                     stderr=err,
-                     ret_code=ret,
-                     serial=self.serial)
+      raise AdbError(
+          cmd=args, stdout=out, stderr=err, ret_code=ret, serial=self.serial
+      )
 
   def _execute_and_process_stdout(self, args, shell, handler) -> bytes:
     """Executes adb commands and processes the stdout with a handler.
@@ -217,11 +228,13 @@
     Raises:
       AdbError: The adb command exit code is not 0.
     """
-    proc = subprocess.Popen(args,
-                            stdout=subprocess.PIPE,
-                            stderr=subprocess.PIPE,
-                            shell=shell,
-                            bufsize=1)
+    proc = subprocess.Popen(
+        args,
+        stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE,
+        shell=shell,
+        bufsize=1,
+    )
     out = '[elided, processed via handler]'
     try:
       # Even if the process dies, stdout.readline still works
@@ -241,8 +254,13 @@
           handler(line)
 
     ret = proc.returncode
-    logging.debug('cmd: %s, stdout: %s, stderr: %s, ret: %s',
-                  utils.cli_cmd_to_string(args), out, err, ret)
+    logging.debug(
+        'cmd: %s, stdout: %s, stderr: %s, ret: %s',
+        utils.cli_cmd_to_string(args),
+        out,
+        err,
+        ret,
+    )
     if ret == 0:
       return err
     else:
@@ -291,12 +309,13 @@
     out = self._exec_cmd(adb_cmd, shell=shell, timeout=timeout, stderr=stderr)
     return out
 
-  def _execute_adb_and_process_stdout(self, name, args, shell,
-                                      handler) -> bytes:
+  def _execute_adb_and_process_stdout(
+      self, name, args, shell, handler
+  ) -> bytes:
     adb_cmd = self._construct_adb_cmd(name, args, shell=shell)
-    err = self._execute_and_process_stdout(adb_cmd,
-                                           shell=shell,
-                                           handler=handler)
+    err = self._execute_and_process_stdout(
+        adb_cmd, shell=shell, handler=handler
+    )
     return err
 
   def _parse_getprop_output(self, output):
@@ -357,16 +376,13 @@
     Raises:
       AdbError: if the connection failed.
     """
-    stdout = self._exec_adb_cmd('connect',
-                                address,
-                                shell=False,
-                                timeout=None,
-                                stderr=None)
+    stdout = self._exec_adb_cmd(
+        'connect', address, shell=False, timeout=None, stderr=None
+    )
     if PATTERN_ADB_CONNECT_SUCCESS.match(stdout.decode('utf-8')) is None:
-      raise AdbError(cmd=f'connect {address}',
-                     stdout=stdout,
-                     stderr='',
-                     ret_code=0)
+      raise AdbError(
+          cmd=f'connect {address}', stdout=stdout, stderr='', ret_code=0
+      )
     return stdout
 
   def getprop(self, prop_name, timeout=DEFAULT_GETPROP_TIMEOUT_SEC):
@@ -383,8 +399,11 @@
       A string that is the value of the property, or None if the property
       doesn't exist.
     """
-    return self.shell(['getprop', prop_name],
-                      timeout=timeout).decode('utf-8').strip()
+    return (
+        self.shell(['getprop', prop_name], timeout=timeout)
+        .decode('utf-8')
+        .strip()
+    )
 
   def getprops(self, prop_names):
     """Get multiple properties of the device.
@@ -436,17 +455,19 @@
 
   def forward(self, args=None, shell=False) -> bytes:
     with ADB_PORT_LOCK:
-      return self._exec_adb_cmd('forward',
-                                args,
-                                shell,
-                                timeout=None,
-                                stderr=None)
+      return self._exec_adb_cmd(
+          'forward', args, shell, timeout=None, stderr=None
+      )
 
-  def instrument(self,
-                 package,
-                 options=None,
-                 runner=None,
-                 handler=None) -> bytes:
+  def reverse(self, args=None, shell=False) -> bytes:
+    with ADB_PORT_LOCK:
+      return self._exec_adb_cmd(
+          'reverse', args, shell, timeout=None, stderr=None
+      )
+
+  def instrument(
+      self, package, options=None, runner=None, handler=None
+  ) -> bytes:
     """Runs an instrumentation command on the device.
 
     This is a convenience wrapper to avoid parameter formatting.
@@ -487,21 +508,28 @@
       options_list.append('-e %s %s' % (option_key, option_value))
     options_string = ' '.join(options_list)
 
-    instrumentation_command = 'am instrument -r -w %s %s/%s' % (options_string,
-                                                                package, runner)
-    logging.info('AndroidDevice|%s: Executing adb shell %s', self.serial,
-                 instrumentation_command)
+    instrumentation_command = 'am instrument -r -w %s %s/%s' % (
+        options_string,
+        package,
+        runner,
+    )
+    logging.info(
+        'AndroidDevice|%s: Executing adb shell %s',
+        self.serial,
+        instrumentation_command,
+    )
     if handler is None:
-      return self._exec_adb_cmd('shell',
-                                instrumentation_command,
-                                shell=False,
-                                timeout=None,
-                                stderr=None)
+      return self._exec_adb_cmd(
+          'shell',
+          instrumentation_command,
+          shell=False,
+          timeout=None,
+          stderr=None,
+      )
     else:
-      return self._execute_adb_and_process_stdout('shell',
-                                                  instrumentation_command,
-                                                  shell=False,
-                                                  handler=handler)
+      return self._execute_adb_and_process_stdout(
+          'shell', instrumentation_command, shell=False, handler=handler
+      )
 
   def root(self) -> bytes:
     """Enables ADB root mode on the device.
@@ -520,16 +548,18 @@
     retry_interval = ADB_ROOT_RETRY_ATTEMPT_INTERVAL_SEC
     for attempt in range(ADB_ROOT_RETRY_ATTEMPTS):
       try:
-        return self._exec_adb_cmd('root',
-                                  args=None,
-                                  shell=False,
-                                  timeout=None,
-                                  stderr=None)
+        return self._exec_adb_cmd(
+            'root', args=None, shell=False, timeout=None, stderr=None
+        )
       except AdbError as e:
         if attempt + 1 < ADB_ROOT_RETRY_ATTEMPTS:
-          logging.debug('Retry the command "%s" since Error "%s" occurred.' %
-                        (utils.cli_cmd_to_string(
-                            e.cmd), e.stderr.decode('utf-8').strip()))
+          logging.debug(
+              'Retry the command "%s" since Error "%s" occurred.'
+              % (
+                  utils.cli_cmd_to_string(e.cmd),
+                  e.stderr.decode('utf-8').strip(),
+              )
+          )
           # Buffer between "adb root" commands.
           time.sleep(retry_interval)
           retry_interval *= 2
@@ -537,7 +567,6 @@
           raise e
 
   def __getattr__(self, name):
-
     def adb_call(args=None, shell=False, timeout=None, stderr=None) -> bytes:
       """Wrapper for an ADB command.
 
@@ -554,10 +583,8 @@
       Returns:
         The output of the adb command run if exit code is 0.
       """
-      return self._exec_adb_cmd(name,
-                                args,
-                                shell=shell,
-                                timeout=timeout,
-                                stderr=stderr)
+      return self._exec_adb_cmd(
+          name, args, shell=shell, timeout=timeout, stderr=stderr
+      )
 
     return adb_call
diff --git a/mobly/controllers/android_device_lib/callback_handler.py b/mobly/controllers/android_device_lib/callback_handler.py
index c783b71..711c92a 100644
--- a/mobly/controllers/android_device_lib/callback_handler.py
+++ b/mobly/controllers/android_device_lib/callback_handler.py
@@ -21,7 +21,8 @@
 logging.warning(
     'The module mobly.controllers.android_device_lib.callback_handler is '
     'deprecated and will be removed in a future version. Use module '
-    'mobly.controllers.android_device_lib.callback_handler_v2 instead.')
+    'mobly.controllers.android_device_lib.callback_handler_v2 instead.'
+)
 
 # The max timeout cannot be larger than the max time the socket waits for a
 # response message. Otherwise, the socket would timeout before the Rpc call
@@ -91,8 +92,9 @@
     """
     # Convert to milliseconds for Java side.
     timeout_ms = int(timeout * 1000)
-    return self._event_client.eventWaitAndGet(callback_id, event_name,
-                                              timeout_ms)
+    return self._event_client.eventWaitAndGet(
+        callback_id, event_name, timeout_ms
+    )
 
   def _callEventGetAll(self, callback_id, event_name):
     """Calls snippet lib's eventGetAll.
@@ -128,15 +130,19 @@
     if timeout:
       if timeout > MAX_TIMEOUT:
         raise Error(
-            self._ad, 'Specified timeout %s is longer than max timeout %s.' %
-            (timeout, MAX_TIMEOUT))
+            self._ad,
+            'Specified timeout %s is longer than max timeout %s.'
+            % (timeout, MAX_TIMEOUT),
+        )
     try:
       raw_event = self._callEventWaitAndGet(self._id, event_name, timeout)
     except Exception as e:
       if 'EventSnippetException: timeout.' in str(e):
         raise TimeoutError(
-            self._ad, 'Timed out after waiting %ss for event "%s" triggered by'
-            ' %s (%s).' % (timeout, event_name, self._method_name, self._id))
+            self._ad,
+            'Timed out after waiting %ss for event "%s" triggered by %s (%s).'
+            % (timeout, event_name, self._method_name, self._id),
+        )
       raise
     return snippet_event.from_dict(raw_event)
 
@@ -186,7 +192,8 @@
     raise TimeoutError(
         self._ad,
         'Timed out after %ss waiting for an "%s" event that satisfies the '
-        'predicate "%s".' % (timeout, event_name, predicate.__name__))
+        'predicate "%s".' % (timeout, event_name, predicate.__name__),
+    )
 
   def getAll(self, event_name):
     """Gets all the events of a certain name that have been received so
diff --git a/mobly/controllers/android_device_lib/callback_handler_v2.py b/mobly/controllers/android_device_lib/callback_handler_v2.py
index 5675f7a..d1f9e8f 100644
--- a/mobly/controllers/android_device_lib/callback_handler_v2.py
+++ b/mobly/controllers/android_device_lib/callback_handler_v2.py
@@ -42,14 +42,19 @@
     """
     timeout_ms = int(timeout_sec * 1000)
     try:
-      return self._event_client.eventWaitAndGet(callback_id, event_name,
-                                                timeout_ms)
+      return self._event_client.eventWaitAndGet(
+          callback_id, event_name, timeout_ms
+      )
     except Exception as e:
       if TIMEOUT_ERROR_MESSAGE in str(e):
         raise errors.CallbackHandlerTimeoutError(
-            self._device, (f'Timed out after waiting {timeout_sec}s for event '
-                           f'"{event_name}" triggered by {self._method_name} '
-                           f'({self.callback_id}).')) from e
+            self._device,
+            (
+                f'Timed out after waiting {timeout_sec}s for event '
+                f'"{event_name}" triggered by {self._method_name} '
+                f'({self.callback_id}).'
+            ),
+        ) from e
       raise
 
   def callEventGetAllRpc(self, callback_id, event_name):
diff --git a/mobly/controllers/android_device_lib/errors.py b/mobly/controllers/android_device_lib/errors.py
index 9434cbc..1f9156e 100644
--- a/mobly/controllers/android_device_lib/errors.py
+++ b/mobly/controllers/android_device_lib/errors.py
@@ -42,6 +42,7 @@
   A service is inherently associated with a device instance, so the service
   error type is a subtype of `DeviceError`.
   """
+
   SERVICE_TYPE = None
 
   def __init__(self, device, msg):
diff --git a/mobly/controllers/android_device_lib/event_dispatcher.py b/mobly/controllers/android_device_lib/event_dispatcher.py
index 26db911..80610ef 100644
--- a/mobly/controllers/android_device_lib/event_dispatcher.py
+++ b/mobly/controllers/android_device_lib/event_dispatcher.py
@@ -25,18 +25,15 @@
 
 
 class IllegalStateError(EventDispatcherError):
-  """Raise when user tries to put event_dispatcher into an illegal state.
-  """
+  """Raise when user tries to put event_dispatcher into an illegal state."""
 
 
 class DuplicateError(EventDispatcherError):
-  """Raise when a duplicate is being created and it shouldn't.
-  """
+  """Raise when a duplicate is being created and it shouldn't."""
 
 
 class EventDispatcher:
-  """Class managing events for an sl4a connection.
-  """
+  """Class managing events for an sl4a connection."""
 
   DEFAULT_TIMEOUT = 60
 
@@ -69,11 +66,11 @@
           raise
       if not event_obj:
         continue
-      elif 'name' not in event_obj:
+      elif "name" not in event_obj:
         print("Received Malformed event {}".format(event_obj))
         continue
       else:
-        event_name = event_obj['name']
+        event_name = event_obj["name"]
       # if handler registered, process event
       if event_name in self.handlers:
         self.handle_subscribed_event(event_obj, event_name)
@@ -107,13 +104,13 @@
         handler for one type of event.
     """
     if self.started:
-      raise IllegalStateError(("Can't register service after polling is"
-                               " started"))
+      raise IllegalStateError("Can't register service after polling is started")
     self.lock.acquire()
     try:
       if event_name in self.handlers:
         raise DuplicateError(
-            'A handler for {} already exists'.format(event_name))
+            "A handler for {} already exists".format(event_name)
+        )
       self.handlers[event_name] = (handler, args)
     finally:
       self.lock.release()
@@ -194,15 +191,13 @@
         # Block forever on event wait
         return e_queue.get(True)
     except queue.Empty:
-      raise queue.Empty('Timeout after {}s waiting for event: {}'.format(
-          timeout, event_name))
+      raise queue.Empty(
+          "Timeout after {}s waiting for event: {}".format(timeout, event_name)
+      )
 
-  def wait_for_event(self,
-                     event_name,
-                     predicate,
-                     timeout=DEFAULT_TIMEOUT,
-                     *args,
-                     **kwargs):
+  def wait_for_event(
+      self, event_name, predicate, timeout=DEFAULT_TIMEOUT, *args, **kwargs
+  ):
     """Wait for an event that satisfies a predicate to appear.
 
     Continuously pop events of a particular name and check against the
@@ -238,8 +233,11 @@
         return event
 
       if time.perf_counter() > deadline:
-        raise queue.Empty('Timeout after {}s waiting for event: {}'.format(
-            timeout, event_name))
+        raise queue.Empty(
+            "Timeout after {}s waiting for event: {}".format(
+                timeout, event_name
+            )
+        )
 
   def pop_events(self, regex_pattern, timeout):
     """Pop events whose names match a regex pattern.
@@ -275,10 +273,13 @@
         break
       time.sleep(1)
     if len(results) == 0:
-      raise queue.Empty('Timeout after {}s waiting for event: {}'.format(
-          timeout, regex_pattern))
+      raise queue.Empty(
+          "Timeout after {}s waiting for event: {}".format(
+              timeout, regex_pattern
+          )
+      )
 
-    return sorted(results, key=lambda event: event['time'])
+    return sorted(results, key=lambda event: event["time"])
 
   def _match_and_pop(self, regex_pattern):
     """Pop one event from each of the event queues whose names
@@ -331,8 +332,15 @@
     handler, args = self.handlers[event_name]
     self.executor.submit(handler, event_obj, *args)
 
-  def _handle(self, event_handler, event_name, user_args, event_timeout, cond,
-              cond_timeout):
+  def _handle(
+      self,
+      event_handler,
+      event_name,
+      user_args,
+      event_timeout,
+      cond,
+      cond_timeout,
+  ):
     """Pop an event of specified type and calls its handler on it. If
     condition is not None, block until condition is met or timeout.
     """
@@ -341,13 +349,15 @@
     event = self.pop_event(event_name, event_timeout)
     return event_handler(event, *user_args)
 
-  def handle_event(self,
-                   event_handler,
-                   event_name,
-                   user_args,
-                   event_timeout=None,
-                   cond=None,
-                   cond_timeout=None):
+  def handle_event(
+      self,
+      event_handler,
+      event_name,
+      user_args,
+      event_timeout=None,
+      cond=None,
+      cond_timeout=None,
+  ):
     """Handle events that don't have registered handlers
 
     In a new thread, poll one event of specified type from its queue and
@@ -371,8 +381,15 @@
       If blocking call worker.result() is triggered, the handler
       needs to return something to unblock.
     """
-    worker = self.executor.submit(self._handle, event_handler, event_name,
-                                  user_args, event_timeout, cond, cond_timeout)
+    worker = self.executor.submit(
+        self._handle,
+        event_handler,
+        event_name,
+        user_args,
+        event_timeout,
+        cond,
+        cond_timeout,
+    )
     return worker
 
   def pop_all(self, event_name):
@@ -392,8 +409,7 @@
         starts polling.
     """
     if not self.started:
-      raise IllegalStateError(("Dispatcher needs to be started before "
-                               "popping."))
+      raise IllegalStateError("Dispatcher needs to be started before popping.")
     results = []
     try:
       self.lock.acquire()
diff --git a/mobly/controllers/android_device_lib/fastboot.py b/mobly/controllers/android_device_lib/fastboot.py
index 1ef4969..cac08f1 100644
--- a/mobly/controllers/android_device_lib/fastboot.py
+++ b/mobly/controllers/android_device_lib/fastboot.py
@@ -37,14 +37,19 @@
   proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
   (out, err) = proc.communicate()
   ret = proc.returncode
-  logging.debug('cmd: %s, stdout: %s, stderr: %s, ret: %s',
-                utils.cli_cmd_to_string(cmds), out, err, ret)
+  logging.debug(
+      'cmd: %s, stdout: %s, stderr: %s, ret: %s',
+      utils.cli_cmd_to_string(cmds),
+      out,
+      err,
+      ret,
+  )
   if not err:
     return out
   return err
 
 
-class FastbootProxy():
+class FastbootProxy:
   """Proxy class for fastboot.
 
   For syntactic reasons, the '-' in fastboot commands need to be replaced
@@ -53,12 +58,12 @@
   >> fb.devices() # will return the console output of "fastboot devices".
   """
 
-  def __init__(self, serial=""):
+  def __init__(self, serial=''):
     self.serial = serial
     if serial:
-      self.fastboot_str = "fastboot -s {}".format(serial)
+      self.fastboot_str = 'fastboot -s {}'.format(serial)
     else:
-      self.fastboot_str = "fastboot"
+      self.fastboot_str = 'fastboot'
 
   def _exec_fastboot_cmd(self, name, arg_str):
     return exe_cmd(' '.join((self.fastboot_str, name, arg_str)))
@@ -67,7 +72,6 @@
     return exe_cmd(' '.join((self.fastboot_str,) + args))
 
   def __getattr__(self, name):
-
     def fastboot_call(*args):
       clean_name = name.replace('_', '-')
       arg_str = ' '.join(str(elem) for elem in args)
diff --git a/mobly/controllers/android_device_lib/jsonrpc_client_base.py b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
index 7f27fa5..d272782 100644
--- a/mobly/controllers/android_device_lib/jsonrpc_client_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
@@ -86,6 +86,7 @@
   INIT: Initializes a new session.
   CONTINUE: Creates a connection.
   """
+
   INIT = 'initiate'
   CONTINUE = 'continue'
 
@@ -203,16 +204,20 @@
     """
     self._counter = self._id_counter()
     try:
-      self._conn = socket.create_connection(('localhost', self.host_port),
-                                            _SOCKET_CONNECTION_TIMEOUT)
+      self._conn = socket.create_connection(
+          ('localhost', self.host_port), _SOCKET_CONNECTION_TIMEOUT
+      )
     except ConnectionRefusedError as err:
       # Retry using '127.0.0.1' for IPv4 enabled machines that only resolve
       # 'localhost' to '[::1]'.
       self.log.debug(
           'Failed to connect to localhost, trying 127.0.0.1: {}'.format(
-              str(err)))
-      self._conn = socket.create_connection(('127.0.0.1', self.host_port),
-                                            _SOCKET_CONNECTION_TIMEOUT)
+              str(err)
+          )
+      )
+      self._conn = socket.create_connection(
+          ('127.0.0.1', self.host_port), _SOCKET_CONNECTION_TIMEOUT
+      )
 
     self._conn.settimeout(_SOCKET_READ_TIMEOUT)
     self._client = self._conn.makefile(mode='brw')
@@ -248,8 +253,7 @@
       self._conn = None
 
   def clear_host_port(self):
-    """Stops the adb port forwarding of the host port used by this client.
-    """
+    """Stops the adb port forwarding of the host port used by this client."""
     if self.host_port:
       self._ad.adb.forward(['--remove', 'tcp:%d' % self.host_port])
       self.host_port = None
@@ -264,13 +268,14 @@
       Error: a socket error occurred during the send.
     """
     try:
-      self._client.write(msg.encode("utf8") + b'\n')
+      self._client.write(msg.encode('utf8') + b'\n')
       self._client.flush()
       self.log.debug('Snippet sent %s.', msg)
     except socket.error as e:
       raise Error(
           self._ad,
-          'Encountered socket error "%s" sending RPC message "%s"' % (e, msg))
+          'Encountered socket error "%s" sending RPC message "%s"' % (e, msg),
+      )
 
   def _client_receive(self):
     """Receives the server's response of an Rpc message.
@@ -289,13 +294,16 @@
         if _MAX_RPC_RESP_LOGGING_LENGTH >= len(response):
           self.log.debug('Snippet received: %s', response)
         else:
-          self.log.debug('Snippet received: %s... %d chars are truncated',
-                         response[:_MAX_RPC_RESP_LOGGING_LENGTH],
-                         len(response) - _MAX_RPC_RESP_LOGGING_LENGTH)
+          self.log.debug(
+              'Snippet received: %s... %d chars are truncated',
+              response[:_MAX_RPC_RESP_LOGGING_LENGTH],
+              len(response) - _MAX_RPC_RESP_LOGGING_LENGTH,
+          )
       return response
     except socket.error as e:
-      raise Error(self._ad,
-                  'Encountered socket error reading RPC response "%s"' % e)
+      raise Error(
+          self._ad, 'Encountered socket error reading RPC response "%s"' % e
+      )
 
   def _cmd(self, command, uid=None):
     """Send a command to the server.
@@ -342,11 +350,13 @@
     if result.get('callback') is not None:
       if self._event_client is None:
         self._event_client = self._start_event_client()
-      return callback_handler.CallbackHandler(callback_id=result['callback'],
-                                              event_client=self._event_client,
-                                              ret_value=result['result'],
-                                              method_name=method,
-                                              ad=self._ad)
+      return callback_handler.CallbackHandler(
+          callback_id=result['callback'],
+          event_client=self._event_client,
+          ret_value=result['result'],
+          method_name=method,
+          ad=self._ad,
+      )
     return result['result']
 
   def disable_hidden_api_blacklist(self):
@@ -357,7 +367,8 @@
     # in development report sdk_version 27, but still enforce the blacklist.
     if self._ad.is_rootable and (sdk_version >= 28 or version_codename == 'P'):
       self._ad.adb.shell(
-          'settings put global hidden_api_blacklist_exemptions "*"')
+          'settings put global hidden_api_blacklist_exemptions "*"'
+      )
 
   def __getattr__(self, name):
     """Wrapper for python magic to turn method calls into RPC calls."""
diff --git a/mobly/controllers/android_device_lib/jsonrpc_shell_base.py b/mobly/controllers/android_device_lib/jsonrpc_shell_base.py
index 3129f59..c6d395b 100755
--- a/mobly/controllers/android_device_lib/jsonrpc_shell_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_shell_base.py
@@ -59,8 +59,11 @@
       elif len(serials) == 1:
         serial = serials[0]
       else:
-        raise Error('Expected one phone, but %d found. Use the -s flag or '
-                    'specify ANDROID_SERIAL.' % len(serials))
+        raise Error(
+            'Expected one phone, but %d found. Use the -s flag or '
+            'specify ANDROID_SERIAL.'
+            % len(serials)
+        )
     if serial not in serials:
       raise Error('Device "%s" is not found by adb.' % serial)
     ads = android_device.get_instances([serial])
diff --git a/mobly/controllers/android_device_lib/service_manager.py b/mobly/controllers/android_device_lib/service_manager.py
index 983cff7..17d5a1f 100644
--- a/mobly/controllers/android_device_lib/service_manager.py
+++ b/mobly/controllers/android_device_lib/service_manager.py
@@ -74,11 +74,15 @@
     if not inspect.isclass(service_class):
       raise Error(self._device, '"%s" is not a class!' % service_class)
     if not issubclass(service_class, base_service.BaseService):
-      raise Error(self._device,
-                  'Class %s is not a subclass of BaseService!' % service_class)
+      raise Error(
+          self._device,
+          'Class %s is not a subclass of BaseService!' % service_class,
+      )
     if alias in self._service_objects:
-      raise Error(self._device,
-                  'A service is already registered with alias "%s".' % alias)
+      raise Error(
+          self._device,
+          'A service is already registered with alias "%s".' % alias,
+      )
     service_obj = service_class(self._device, configs)
     service_obj.alias = alias
     if start_service:
@@ -94,12 +98,14 @@
       alias: string, the alias of the service instance to unregister.
     """
     if alias not in self._service_objects:
-      raise Error(self._device,
-                  'No service is registered with alias "%s".' % alias)
+      raise Error(
+          self._device, 'No service is registered with alias "%s".' % alias
+      )
     service_obj = self._service_objects.pop(alias)
     if service_obj.is_alive:
-      with expects.expect_no_raises('Failed to stop service instance "%s".' %
-                                    alias):
+      with expects.expect_no_raises(
+          'Failed to stop service instance "%s".' % alias
+      ):
         service_obj.stop()
 
   def for_each(self, func):
@@ -111,8 +117,9 @@
     """
     aliases = list(self._service_objects.keys())
     for alias in aliases:
-      with expects.expect_no_raises('Failed to execute "%s" for service "%s".' %
-                                    (func.__name__, alias)):
+      with expects.expect_no_raises(
+          'Failed to execute "%s" for service "%s".' % (func.__name__, alias)
+      ):
         func(self._service_objects[alias])
 
   def list_live_services(self):
@@ -125,8 +132,11 @@
       list of strings, the aliases of the services that are running.
     """
     aliases = []
-    self.for_each(lambda service: aliases.append(service.alias)
-                  if service.is_alive else None)
+    self.for_each(
+        lambda service: aliases.append(service.alias)
+        if service.is_alive
+        else None
+    )
     return aliases
 
   def create_output_excerpts_all(self, test_info):
@@ -185,8 +195,9 @@
       if name not in self._service_objects:
         raise Error(
             self._device,
-            'No service is registered under the name "%s", cannot start.' %
-            name)
+            'No service is registered under the name "%s", cannot start.'
+            % name,
+        )
       service = self._service_objects[name]
       if not service.is_alive:
         service.start()
@@ -235,8 +246,9 @@
       if name not in self._service_objects:
         raise Error(
             self._device,
-            'No service is registered under the name "%s", cannot resume.' %
-            name)
+            'No service is registered under the name "%s", cannot resume.'
+            % name,
+        )
       service = self._service_objects[name]
       service.resume()
 
diff --git a/mobly/controllers/android_device_lib/services/base_service.py b/mobly/controllers/android_device_lib/services/base_service.py
index 4739797..8706bf0 100644
--- a/mobly/controllers/android_device_lib/services/base_service.py
+++ b/mobly/controllers/android_device_lib/services/base_service.py
@@ -21,6 +21,7 @@
 
   This class defines the interface for Mobly's AndroidDevice service.
   """
+
   _alias = None
 
   def __init__(self, device, configs=None):
diff --git a/mobly/controllers/android_device_lib/services/logcat.py b/mobly/controllers/android_device_lib/services/logcat.py
index 37a8454..04dcf9d 100644
--- a/mobly/controllers/android_device_lib/services/logcat.py
+++ b/mobly/controllers/android_device_lib/services/logcat.py
@@ -27,6 +27,7 @@
 
 class Error(errors.ServiceError):
   """Root error type for logcat service."""
+
   SERVICE_TYPE = 'Logcat'
 
 
@@ -54,6 +55,7 @@
     adb_logcat_file_path: string, path to the file that the service writes
       adb logcat to by default.
   """
+
   OUTPUT_FILE_TYPE = 'logcat'
 
   def __init__(self, android_device, configs=None):
@@ -73,8 +75,10 @@
     if not self._ad.is_rootable:
       return
 
-    logpersist_warning = ('%s encountered an error enabling persistent'
-                          ' logs, logs may not get saved.')
+    logpersist_warning = (
+        '%s encountered an error enabling persistent'
+        ' logs, logs may not get saved.'
+    )
     # Android L and older versions do not have logpersist installed,
     # so check that the logpersist scripts exists before trying to use
     # them.
@@ -113,11 +117,13 @@
     """
     dest_path = test_info.output_path
     utils.create_dir(dest_path)
-    filename = self._ad.generate_filename(self.OUTPUT_FILE_TYPE, test_info,
-                                          'txt')
+    filename = self._ad.generate_filename(
+        self.OUTPUT_FILE_TYPE, test_info, 'txt'
+    )
     excerpt_file_path = os.path.join(dest_path, filename)
-    with io.open(excerpt_file_path, 'w', encoding='utf-8',
-                 errors='replace') as out:
+    with io.open(
+        excerpt_file_path, 'w', encoding='utf-8', errors='replace'
+    ) as out:
       # Devices may accidentally go offline during test,
       # check not None before readline().
       while self._adb_logcat_file_obj:
@@ -153,7 +159,8 @@
     if self.is_alive:
       raise Error(
           self._ad,
-          'Logcat thread is already running, cannot start another one.')
+          'Logcat thread is already running, cannot start another one.',
+      )
 
   def update_config(self, new_config):
     """Updates the configuration for the service.
@@ -168,8 +175,11 @@
       new_config: Config, the new config to use.
     """
     self._assert_not_running()
-    self._ad.log.info('[LogcatService] Changing config from %s to %s',
-                      self._config, new_config)
+    self._ad.log.info(
+        '[LogcatService] Changing config from %s to %s',
+        self._config,
+        new_config,
+    )
     self._config = new_config
 
   def _open_logcat_file(self):
@@ -181,13 +191,13 @@
       deadline = time.perf_counter() + CREATE_LOGCAT_FILE_TIMEOUT_SEC
       while not os.path.exists(self.adb_logcat_file_path):
         if time.perf_counter() > deadline:
-          raise Error(self._ad,
-                      'Timeout while waiting for logcat file to be created.')
+          raise Error(
+              self._ad, 'Timeout while waiting for logcat file to be created.'
+          )
         time.sleep(1)
-      self._adb_logcat_file_obj = io.open(self.adb_logcat_file_path,
-                                          'r',
-                                          encoding='utf-8',
-                                          errors='replace')
+      self._adb_logcat_file_obj = io.open(
+          self.adb_logcat_file_path, 'r', encoding='utf-8', errors='replace'
+      )
       self._adb_logcat_file_obj.seek(0, os.SEEK_END)
 
   def _close_logcat_file(self):
@@ -203,7 +213,8 @@
     """
     if self._ad.is_bootloader:
       self._ad.log.warning(
-          'Skip starting logcat because the device is in fastboot mode.')
+          'Skip starting logcat because the device is in fastboot mode.'
+      )
       return
     self._assert_not_running()
     if self._config.clear_log:
@@ -218,8 +229,9 @@
       self._close_logcat_file()
       self.adb_logcat_file_path = self._config.output_file_path
     if not self.adb_logcat_file_path:
-      f_name = self._ad.generate_filename(self.OUTPUT_FILE_TYPE,
-                                          extension_name='txt')
+      f_name = self._ad.generate_filename(
+          self.OUTPUT_FILE_TYPE, extension_name='txt'
+      )
       logcat_file_path = os.path.join(self._ad.log_path, f_name)
       self.adb_logcat_file_path = logcat_file_path
     utils.create_dir(os.path.dirname(self.adb_logcat_file_path))
@@ -227,8 +239,11 @@
     # double quotes in args if starting and ending with it.
     # Add spaces at beginning and at last to fix this issue.
     cmd = ' "%s" -s %s logcat -v threadtime -T 1 %s >> "%s" ' % (
-        adb.ADB, self._ad.serial, self._config.logcat_params,
-        self.adb_logcat_file_path)
+        adb.ADB,
+        self._ad.serial,
+        self._config.logcat_params,
+        self.adb_logcat_file_path,
+    )
     process = utils.start_standing_subprocess(cmd, shell=True)
     self._adb_logcat_process = process
 
diff --git a/mobly/controllers/android_device_lib/services/snippet_management_service.py b/mobly/controllers/android_device_lib/services/snippet_management_service.py
index 05e8cda..7da1b23 100644
--- a/mobly/controllers/android_device_lib/services/snippet_management_service.py
+++ b/mobly/controllers/android_device_lib/services/snippet_management_service.py
@@ -21,6 +21,7 @@
 
 class Error(errors.ServiceError):
   """Root error type for snippet management service."""
+
   SERVICE_TYPE = 'SnippetManagementService'
 
 
@@ -73,17 +74,23 @@
     # Should not load snippet with the same name more than once.
     if name in self._snippet_clients:
       raise Error(
-          self, 'Name "%s" is already registered with package "%s", it cannot '
-          'be used again.' % (name, self._snippet_clients[name].client.package))
+          self,
+          'Name "%s" is already registered with package "%s", it cannot '
+          'be used again.' % (name, self._snippet_clients[name].client.package),
+      )
     # Should not load the same snippet package more than once.
     for snippet_name, client in self._snippet_clients.items():
       if package == client.package:
         raise Error(
-            self, 'Snippet package "%s" has already been loaded under name'
-            ' "%s".' % (package, snippet_name))
+            self,
+            'Snippet package "%s" has already been loaded under name "%s".'
+            % (package, snippet_name),
+        )
 
     client = snippet_client_v2.SnippetClientV2(
-        package=package, ad=self._device, config=config,
+        package=package,
+        ad=self._device,
+        config=config,
     )
     client.initialize()
     self._snippet_clients[name] = client
@@ -111,7 +118,8 @@
       else:
         self._device.log.debug(
             'Not startng SnippetClient<%s> because it is already alive.',
-            client.package)
+            client.package,
+        )
 
   def stop(self):
     """Stops all the snippet clients under management."""
@@ -122,7 +130,8 @@
       else:
         self._device.log.debug(
             'Not stopping SnippetClient<%s> because it is not alive.',
-            client.package)
+            client.package,
+        )
 
   def pause(self):
     """Pauses all the snippet clients under management.
@@ -141,8 +150,9 @@
         self._device.log.debug('Resuming SnippetClient<%s>.', client.package)
         client.restore_server_connection()
       else:
-        self._device.log.debug('Not resuming SnippetClient<%s>.',
-                               client.package)
+        self._device.log.debug(
+            'Not resuming SnippetClient<%s>.', client.package
+        )
 
   def __getattr__(self, name):
     client = self.get_snippet_client(name)
diff --git a/mobly/controllers/android_device_lib/sl4a_client.py b/mobly/controllers/android_device_lib/sl4a_client.py
index 725a61c..ac59f5b 100644
--- a/mobly/controllers/android_device_lib/sl4a_client.py
+++ b/mobly/controllers/android_device_lib/sl4a_client.py
@@ -24,7 +24,8 @@
 _LAUNCH_CMD = (
     'am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER '
     '--ei com.googlecode.android_scripting.extra.USE_SERVICE_PORT %s '
-    'com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher')
+    'com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher'
+)
 # Maximum time to wait for the app to start on the device (10 minutes).
 # TODO: This timeout is set high in order to allow for retries in
 # start_app_and_connect. Decrease it when the call to connect() has the option
@@ -59,7 +60,8 @@
     out = self._adb.shell('pm list package')
     if not utils.grep('com.googlecode.android_scripting', out):
       raise jsonrpc_client_base.AppStartError(
-          self._ad, '%s is not installed on %s' % (_APP_NAME, self._adb.serial))
+          self._ad, '%s is not installed on %s' % (_APP_NAME, self._adb.serial)
+      )
     self.disable_hidden_api_blacklist()
 
     # sl4a has problems connecting after disconnection, so kill the apk and
@@ -108,8 +110,9 @@
         try:
           self.closeSl4aSession()
         except Exception:
-          self.log.exception('Failed to gracefully shut down %s.',
-                             self.app_name)
+          self.log.exception(
+              'Failed to gracefully shut down %s.', self.app_name
+          )
 
         # Close the socket connection.
         self.disconnect()
@@ -141,23 +144,25 @@
         started = True
         break
       except Exception:
-        self.log.debug('%s is not yet running, retrying',
-                       self.app_name,
-                       exc_info=True)
+        self.log.debug(
+            '%s is not yet running, retrying', self.app_name, exc_info=True
+        )
       time.sleep(1)
     if not started:
       raise jsonrpc_client_base.AppRestoreConnectionError(
-          self._ad, '%s failed to connect for %s at host port %s, '
-          'device port %s' %
-          (self.app_name, self._adb.serial, self.host_port, self.device_port))
+          self._ad,
+          '%s failed to connect for %s at host port %s, device port %s'
+          % (self.app_name, self._adb.serial, self.host_port, self.device_port),
+      )
 
   def _start_event_client(self):
     # Start an EventDispatcher for the current sl4a session
     event_client = Sl4aClient(self._ad)
     event_client.host_port = self.host_port
     event_client.device_port = self.device_port
-    event_client.connect(uid=self.uid,
-                         cmd=jsonrpc_client_base.JsonRpcCommand.CONTINUE)
+    event_client.connect(
+        uid=self.uid, cmd=jsonrpc_client_base.JsonRpcCommand.CONTINUE
+    )
     ed = event_dispatcher.EventDispatcher(event_client)
     ed.start()
     return ed
diff --git a/mobly/controllers/android_device_lib/snippet_client.py b/mobly/controllers/android_device_lib/snippet_client.py
index 42ae122..099f9c7 100644
--- a/mobly/controllers/android_device_lib/snippet_client.py
+++ b/mobly/controllers/android_device_lib/snippet_client.py
@@ -23,13 +23,16 @@
 from mobly.controllers.android_device_lib import jsonrpc_client_base
 from mobly.snippet import errors as snippet_errors
 
-logging.warning('The module mobly.controllers.android_device_lib.snippet_client'
-                ' is deprecated and will be removed in a future version. Use'
-                ' module mobly.controllers.android_device_lib.snippet_client_v2'
-                ' instead.')
+logging.warning(
+    'The module mobly.controllers.android_device_lib.snippet_client'
+    ' is deprecated and will be removed in a future version. Use'
+    ' module mobly.controllers.android_device_lib.snippet_client_v2'
+    ' instead.'
+)
 
 _INSTRUMENTATION_RUNNER_PACKAGE = (
-    'com.google.android.mobly.snippet.SnippetRunner')
+    'com.google.android.mobly.snippet.SnippetRunner'
+)
 
 # Major version of the launch and communication protocol being used by this
 # client.
@@ -45,11 +48,14 @@
 _PROTOCOL_MINOR_VERSION = 0
 
 _LAUNCH_CMD = (
-    '{shell_cmd} am instrument {user} -w -e action start {snippet_package}/' +
-    _INSTRUMENTATION_RUNNER_PACKAGE)
+    '{shell_cmd} am instrument {user} -w -e action start {snippet_package}/'
+    + _INSTRUMENTATION_RUNNER_PACKAGE
+)
 
-_STOP_CMD = ('am instrument {user} -w -e action stop {snippet_package}/' +
-             _INSTRUMENTATION_RUNNER_PACKAGE)
+_STOP_CMD = (
+    'am instrument {user} -w -e action stop {snippet_package}/'
+    + _INSTRUMENTATION_RUNNER_PACKAGE
+)
 
 # Test that uses UiAutomation requires the shell session to be maintained while
 # test is in progress. However, this requirement does not hold for the test that
@@ -154,7 +160,8 @@
         self.stop_app()
       except Exception:
         self._ad.log.exception(
-            'Failed to stop app after failure to start and connect.')
+            'Failed to stop app after failure to start and connect.'
+        )
       # Explicitly raise the original error from starting app.
       raise e
 
@@ -177,11 +184,17 @@
     # process. Starting snippets can be slow, especially if there are
     # multiple, and this avoids the perception that the framework is hanging
     # for a long time doing nothing.
-    self.log.info('Launching snippet apk %s with protocol %d.%d', self.package,
-                  _PROTOCOL_MAJOR_VERSION, _PROTOCOL_MINOR_VERSION)
-    cmd = _LAUNCH_CMD.format(shell_cmd=persists_shell_cmd,
-                             user=self._get_user_command_string(),
-                             snippet_package=self.package)
+    self.log.info(
+        'Launching snippet apk %s with protocol %d.%d',
+        self.package,
+        _PROTOCOL_MAJOR_VERSION,
+        _PROTOCOL_MINOR_VERSION,
+    )
+    cmd = _LAUNCH_CMD.format(
+        shell_cmd=persists_shell_cmd,
+        user=self._get_user_command_string(),
+        snippet_package=self.package,
+    )
     start_time = time.perf_counter()
     self._proc = self._do_start_app(cmd)
 
@@ -203,9 +216,12 @@
     self.connect()
 
     # Yaaay! We're done!
-    self.log.debug('Snippet %s started after %.1fs on host port %s',
-                   self.package,
-                   time.perf_counter() - start_time, self.host_port)
+    self.log.debug(
+        'Snippet %s started after %.1fs on host port %s',
+        self.package,
+        time.perf_counter() - start_time,
+        self.host_port,
+    )
 
   def restore_app_connection(self, port=None):
     """Restores the app after device got reconnected.
@@ -232,8 +248,12 @@
       self.log.exception('Failed to re-connect to app.')
       raise jsonrpc_client_base.AppRestoreConnectionError(
           self._ad,
-          ('Failed to restore app connection for %s at host port %s, '
-           'device port %s') % (self.package, self.host_port, self.device_port))
+          (
+              'Failed to restore app connection for %s at host port %s, '
+              'device port %s'
+          )
+          % (self.package, self.host_port, self.device_port),
+      )
 
     # Because the previous connection was lost, update self._proc
     self._proc = None
@@ -252,11 +272,14 @@
       utils.stop_standing_subprocess(self._proc)
       self._proc = None
     out = self._adb.shell(
-        _STOP_CMD.format(snippet_package=self.package,
-                         user=self._get_user_command_string())).decode('utf-8')
+        _STOP_CMD.format(
+            snippet_package=self.package, user=self._get_user_command_string()
+        )
+    ).decode('utf-8')
     if 'OK (0 tests)' not in out:
       raise errors.DeviceError(
-          self._ad, 'Failed to stop existing apk. Unexpected output: %s' % out)
+          self._ad, 'Failed to stop existing apk. Unexpected output: %s' % out
+      )
 
     self._stop_event_client()
 
@@ -293,17 +316,21 @@
     out = self._adb.shell(f'pm list package --user {self.user_id}')
     if not utils.grep('^package:%s$' % self.package, out):
       raise AppStartPreCheckError(
-          self._ad, f'{self.package} is not installed for user {self.user_id}.')
+          self._ad, f'{self.package} is not installed for user {self.user_id}.'
+      )
     # Check that the app is instrumented.
     out = self._adb.shell('pm list instrumentation')
     matched_out = utils.grep(
         f'^instrumentation:{self.package}/{_INSTRUMENTATION_RUNNER_PACKAGE}',
-        out)
+        out,
+    )
     if not matched_out:
       raise AppStartPreCheckError(
-          self._ad, f'{self.package} is installed, but it is not instrumented.')
-    match = re.search(r'^instrumentation:(.*)\/(.*) \(target=(.*)\)$',
-                      matched_out[0])
+          self._ad, f'{self.package} is installed, but it is not instrumented.'
+      )
+    match = re.search(
+        r'^instrumentation:(.*)\/(.*) \(target=(.*)\)$', matched_out[0]
+    )
     target_name = match.group(3)
     # Check that the instrumentation target is installed if it's not the
     # same as the snippet package.
@@ -313,7 +340,8 @@
         raise AppStartPreCheckError(
             self._ad,
             f'Instrumentation target {target_name} is not installed for user '
-            f'{self.user_id}.')
+            f'{self.user_id}.',
+        )
 
   def _do_start_app(self, launch_cmd):
     adb_cmd = [adb.ADB]
@@ -339,14 +367,16 @@
       line = self._proc.stdout.readline().decode('utf-8')
       if not line:
         raise jsonrpc_client_base.AppStartError(
-            self._ad, 'Unexpected EOF waiting for app to start')
+            self._ad, 'Unexpected EOF waiting for app to start'
+        )
       # readline() uses an empty string to mark EOF, and a single newline
       # to mark regular empty lines in the output. Don't move the strip()
       # call above the truthiness check, or this method will start
       # considering any blank output line to be EOF.
       line = line.strip()
-      if (line.startswith('INSTRUMENTATION_RESULT:') or
-          line.startswith('SNIPPET ')):
+      if line.startswith('INSTRUMENTATION_RESULT:') or line.startswith(
+          'SNIPPET '
+      ):
         self.log.debug('Accepted line from instrumentation output: "%s"', line)
         return line
       self.log.debug('Discarded line from instrumentation output: "%s"', line)
@@ -362,8 +392,10 @@
     self.log.warning(
         'No %s and %s commands available to launch instrument '
         'persistently, tests that depend on UiAutomator and '
-        'at the same time performs USB disconnection may fail', _SETSID_COMMAND,
-        _NOHUP_COMMAND)
+        'at the same time performs USB disconnection may fail',
+        _SETSID_COMMAND,
+        _NOHUP_COMMAND,
+    )
     return ''
 
   def help(self, print_output=True):
diff --git a/mobly/controllers/android_device_lib/snippet_client_v2.py b/mobly/controllers/android_device_lib/snippet_client_v2.py
index f7494c2..41376fb 100644
--- a/mobly/controllers/android_device_lib/snippet_client_v2.py
+++ b/mobly/controllers/android_device_lib/snippet_client_v2.py
@@ -18,7 +18,7 @@
 import json
 import re
 import socket
-from typing import Dict
+from typing import Dict, Union
 
 from mobly import utils
 from mobly.controllers.android_device_lib import adb
@@ -28,16 +28,22 @@
 from mobly.snippet import errors
 
 # The package of the instrumentation runner used for mobly snippet
-_INSTRUMENTATION_RUNNER_PACKAGE = 'com.google.android.mobly.snippet.SnippetRunner'
+_INSTRUMENTATION_RUNNER_PACKAGE = (
+    'com.google.android.mobly.snippet.SnippetRunner'
+)
 
 # The command template to start the snippet server
 _LAUNCH_CMD = (
-    '{shell_cmd} am instrument {user} -w -e action start {instrument_options} '
-    f'{{snippet_package}}/{_INSTRUMENTATION_RUNNER_PACKAGE}')
+    '{shell_cmd} am instrument {user} -w -e action start'
+    ' {instrument_options}'
+    f' {{snippet_package}}/{_INSTRUMENTATION_RUNNER_PACKAGE}'
+)
 
 # The command template to stop the snippet server
-_STOP_CMD = ('am instrument {user} -w -e action stop {snippet_package}/'
-             f'{_INSTRUMENTATION_RUNNER_PACKAGE}')
+_STOP_CMD = (
+    'am instrument {user} -w -e action stop {snippet_package}/'
+    f'{_INSTRUMENTATION_RUNNER_PACKAGE}'
+)
 
 # Major version of the launch and communication protocol being used by this
 # client.
@@ -89,10 +95,13 @@
       other purposes may not take effect and you should use snippet RPCs. This
       is because Mobly snippet runner changes the subsequent instrumentation
       process.
+    user_id: The user id under which to launch the snippet process.
   """
 
   am_instrument_options: Dict[str, str] = dataclasses.field(
-      default_factory=dict)
+      default_factory=dict
+  )
+  user_id: Union[int, None] = None
 
 
 class ConnectionHandshakeCommand(enum.Enum):
@@ -106,6 +115,7 @@
   INIT: Initiates a new session and makes a connection with this session.
   CONTINUE: Makes a connection with the current session.
   """
+
   INIT = 'initiate'
   CONTINUE = 'continue'
 
@@ -142,7 +152,7 @@
     self.device_port = None
     self.uid = UNKNOWN_UID
     self._adb = ad.adb
-    self._user_id = None
+    self._user_id = None if config is None else config.user_id
     self._proc = None
     self._client = None  # keep it to prevent close errors on connect failure
     self._conn = None
@@ -205,19 +215,23 @@
     if not utils.grep(f'^package:{self.package}$', out):
       raise errors.ServerStartPreCheckError(
           self._device,
-          f'{self.package} is not installed for user {self.user_id}.')
+          f'{self.package} is not installed for user {self.user_id}.',
+      )
 
     # Validate that the app is instrumented.
     out = self._adb.shell('pm list instrumentation')
     matched_out = utils.grep(
         f'^instrumentation:{self.package}/{_INSTRUMENTATION_RUNNER_PACKAGE}',
-        out)
+        out,
+    )
     if not matched_out:
       raise errors.ServerStartPreCheckError(
           self._device,
-          f'{self.package} is installed, but it is not instrumented.')
-    match = re.search(r'^instrumentation:(.*)\/(.*) \(target=(.*)\)$',
-                      matched_out[0])
+          f'{self.package} is installed, but it is not instrumented.',
+      )
+    match = re.search(
+        r'^instrumentation:(.*)\/(.*) \(target=(.*)\)$', matched_out[0]
+    )
     target_name = match.group(3)
     # Validate that the instrumentation target is installed if it's not the
     # same as the snippet package.
@@ -227,14 +241,16 @@
         raise errors.ServerStartPreCheckError(
             self._device,
             f'Instrumentation target {target_name} is not installed for user '
-            f'{self.user_id}.')
+            f'{self.user_id}.',
+        )
 
   def _disable_hidden_api_blocklist(self):
     """If necessary and possible, disables hidden api blocklist."""
     sdk_version = int(self._device.build_info['build_version_sdk'])
     if self._device.is_rootable and sdk_version >= 28:
       self._device.adb.shell(
-          'settings put global hidden_api_blacklist_exemptions "*"')
+          'settings put global hidden_api_blacklist_exemptions "*"'
+      )
 
   def start_server(self):
     """Starts the server on the remote device.
@@ -250,14 +266,19 @@
         server output.
     """
     persists_shell_cmd = self._get_persisting_command()
-    self.log.debug('Snippet server for package %s is using protocol %d.%d',
-                   self.package, _PROTOCOL_MAJOR_VERSION,
-                   _PROTOCOL_MINOR_VERSION)
+    self.log.debug(
+        'Snippet server for package %s is using protocol %d.%d',
+        self.package,
+        _PROTOCOL_MAJOR_VERSION,
+        _PROTOCOL_MINOR_VERSION,
+    )
     option_str = self._get_instrument_options_str()
-    cmd = _LAUNCH_CMD.format(shell_cmd=persists_shell_cmd,
-                             user=self._get_user_command_string(),
-                             snippet_package=self.package,
-                             instrument_options=option_str)
+    cmd = _LAUNCH_CMD.format(
+        shell_cmd=persists_shell_cmd,
+        user=self._get_user_command_string(),
+        snippet_package=self.package,
+        instrument_options=option_str,
+    )
     self._proc = self._run_adb_cmd(cmd)
 
     # Check protocol version and get the device port
@@ -293,7 +314,9 @@
         'No %s and %s commands available to launch instrument '
         'persistently, tests that depend on UiAutomator and '
         'at the same time perform USB disconnections may fail.',
-        _SETSID_COMMAND, _NOHUP_COMMAND)
+        _SETSID_COMMAND,
+        _NOHUP_COMMAND,
+    )
     return ''
 
   def _get_instrument_options_str(self):
@@ -343,15 +366,17 @@
       line = self._proc.stdout.readline().decode('utf-8')
       if not line:
         raise errors.ServerStartError(
-            self._device, 'Unexpected EOF when waiting for server to start.')
+            self._device, 'Unexpected EOF when waiting for server to start.'
+        )
 
       # readline() uses an empty string to mark EOF, and a single newline
       # to mark regular empty lines in the output. Don't move the strip()
       # call above the truthiness check, or this method will start
       # considering any blank output line to be EOF.
       line = line.strip()
-      if (line.startswith('INSTRUMENTATION_RESULT:') or
-          line.startswith('SNIPPET ')):
+      if line.startswith('INSTRUMENTATION_RESULT:') or line.startswith(
+          'SNIPPET '
+      ):
         self.log.debug('Accepted line from instrumentation output: "%s"', line)
         return line
 
@@ -378,9 +403,17 @@
 
   def _forward_device_port(self):
     """Forwards the device port to a host port."""
-    if not self.host_port:
-      self.host_port = utils.get_available_host_port()
-    self._adb.forward([f'tcp:{self.host_port}', f'tcp:{self.device_port}'])
+    if self.host_port and self.host_port in adb.list_occupied_adb_ports():
+      raise errors.Error(
+          self._device,
+          f'Cannot forward to host port {self.host_port} because adb has'
+          ' forwarded another device port to it.',
+      )
+
+    host_port = self.host_port or 0
+    # Example stdout: b'12345\n'
+    stdout = self._adb.forward([f'tcp:{host_port}', f'tcp:{self.device_port}'])
+    self.host_port = int(stdout.strip())
 
   def create_socket_connection(self):
     """Creates a socket connection to the server.
@@ -397,23 +430,29 @@
     try:
       self.log.debug(
           'Snippet client is creating socket connection to the snippet server '
-          'of %s through host port %d.', self.package, self.host_port)
-      self._conn = socket.create_connection(('localhost', self.host_port),
-                                            _SOCKET_CONNECTION_TIMEOUT)
+          'of %s through host port %d.',
+          self.package,
+          self.host_port,
+      )
+      self._conn = socket.create_connection(
+          ('localhost', self.host_port), _SOCKET_CONNECTION_TIMEOUT
+      )
     except ConnectionRefusedError as err:
       # Retry using '127.0.0.1' for IPv4 enabled machines that only resolve
       # 'localhost' to '[::1]'.
-      self.log.debug('Failed to connect to localhost, trying 127.0.0.1: %s',
-                     str(err))
-      self._conn = socket.create_connection(('127.0.0.1', self.host_port),
-                                            _SOCKET_CONNECTION_TIMEOUT)
+      self.log.debug(
+          'Failed to connect to localhost, trying 127.0.0.1: %s', str(err)
+      )
+      self._conn = socket.create_connection(
+          ('127.0.0.1', self.host_port), _SOCKET_CONNECTION_TIMEOUT
+      )
 
     self._conn.settimeout(_SOCKET_READ_TIMEOUT)
     self._client = self._conn.makefile(mode='brw')
 
-  def send_handshake_request(self,
-                             uid=UNKNOWN_UID,
-                             cmd=ConnectionHandshakeCommand.INIT):
+  def send_handshake_request(
+      self, uid=UNKNOWN_UID, cmd=ConnectionHandshakeCommand.INIT
+  ):
     """Sends a handshake request to the server to prepare for the communication.
 
     Through the handshake response, this function checks whether the server
@@ -438,7 +477,8 @@
 
     if not response:
       raise errors.ProtocolError(
-          self._device, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE)
+          self._device, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE
+      )
 
     response = self._decode_socket_response_bytes(response)
 
@@ -471,8 +511,9 @@
     self._client_send(request)
     response = self._client_receive()
     if not response:
-      raise errors.ProtocolError(self._device,
-                                 errors.ProtocolError.NO_RESPONSE_FROM_SERVER)
+      raise errors.ProtocolError(
+          self._device, errors.ProtocolError.NO_RESPONSE_FROM_SERVER
+      )
     return self._decode_socket_response_bytes(response)
 
   def _client_send(self, message):
@@ -490,7 +531,7 @@
     except socket.error as e:
       raise errors.Error(
           self._device,
-          f'Encountered socket error "{e}" sending RPC message "{message}"'
+          f'Encountered socket error "{e}" sending RPC message "{message}"',
       ) from e
 
   def _client_receive(self):
@@ -506,8 +547,8 @@
       return self._client.readline()
     except socket.error as e:
       raise errors.Error(
-          self._device,
-          f'Encountered socket error "{e}" reading RPC response') from e
+          self._device, f'Encountered socket error "{e}" reading RPC response'
+      ) from e
 
   def _decode_socket_response_bytes(self, response):
     """Returns a string decoded from the socket response bytes.
@@ -525,8 +566,9 @@
       return str(response, encoding='utf8')
     except UnicodeError:
       self.log.error(
-          'Failed to decode socket response bytes using encoding '
-          'utf8: %s', response)
+          'Failed to decode socket response bytes using encoding utf8: %s',
+          response,
+      )
       raise
 
   def handle_callback(self, callback_id, ret_value, rpc_func_name):
@@ -552,7 +594,8 @@
         method_name=rpc_func_name,
         device=self._device,
         rpc_max_timeout_sec=_SOCKET_READ_TIMEOUT,
-        default_timeout_sec=_CALLBACK_DEFAULT_TIMEOUT_SEC)
+        default_timeout_sec=_CALLBACK_DEFAULT_TIMEOUT_SEC,
+    )
 
   def _create_event_client(self):
     """Creates a separate client to the same session for propagating events.
@@ -563,14 +606,19 @@
     """
     self._event_client = SnippetClientV2(package=self.package, ad=self._device)
     self._event_client.make_connection_with_forwarded_port(
-        self.host_port, self.device_port, self.uid,
-        ConnectionHandshakeCommand.CONTINUE)
+        self.host_port,
+        self.device_port,
+        self.uid,
+        ConnectionHandshakeCommand.CONTINUE,
+    )
 
-  def make_connection_with_forwarded_port(self,
-                                          host_port,
-                                          device_port,
-                                          uid=UNKNOWN_UID,
-                                          cmd=ConnectionHandshakeCommand.INIT):
+  def make_connection_with_forwarded_port(
+      self,
+      host_port,
+      device_port,
+      uid=UNKNOWN_UID,
+      cmd=ConnectionHandshakeCommand.INIT,
+  ):
     """Makes a connection to the server with the given forwarded port.
 
     This process assumes that a device port has already been forwarded to a
@@ -653,13 +701,16 @@
 
     # Send the stop signal to the server running on the device side.
     out = self._adb.shell(
-        _STOP_CMD.format(snippet_package=self.package,
-                         user=self._get_user_command_string())).decode('utf-8')
+        _STOP_CMD.format(
+            snippet_package=self.package, user=self._get_user_command_string()
+        )
+    ).decode('utf-8')
 
     if 'OK (0 tests)' not in out:
       raise android_device_lib_errors.DeviceError(
           self._device,
-          f'Failed to stop existing apk. Unexpected output: {out}.')
+          f'Failed to stop existing apk. Unexpected output: {out}.',
+      )
 
   def _destroy_event_client(self):
     """Releases all the resources acquired in `_create_event_client`."""
@@ -699,9 +750,11 @@
       self.log.error('Failed to re-connect to the server.')
       raise errors.ServerRestoreConnectionError(
           self._device,
-          (f'Failed to restore server connection for {self.package} at '
-           f'host port {self.host_port}, device port {self.device_port}.'
-          )) from e
+          (
+              f'Failed to restore server connection for {self.package} at '
+              f'host port {self.host_port}, device port {self.device_port}.'
+          ),
+      ) from e
 
     # Because the previous connection was lost, update self._proc
     self._proc = None
@@ -719,7 +772,8 @@
     """
     if self._event_client:
       self._event_client.make_connection_with_forwarded_port(
-          self.host_port, self.device_port)
+          self.host_port, self.device_port
+      )
 
   def help(self, print_output=True):
     """Calls the help RPC, which returns the list of RPC calls available.
diff --git a/mobly/controllers/android_device_lib/snippet_event.py b/mobly/controllers/android_device_lib/snippet_event.py
index 7ef75c1..860335b 100644
--- a/mobly/controllers/android_device_lib/snippet_event.py
+++ b/mobly/controllers/android_device_lib/snippet_event.py
@@ -13,9 +13,11 @@
 # limitations under the License.
 import logging
 
-logging.warning('The module mobly.controllers.android_device_lib.snippet_event '
-                'is deprecated and will be removed in a future version. Use '
-                'module mobly.snippet.callback_event instead.')
+logging.warning(
+    'The module mobly.controllers.android_device_lib.snippet_event '
+    'is deprecated and will be removed in a future version. Use '
+    'module mobly.snippet.callback_event instead.'
+)
 
 
 def from_dict(event_dict):
@@ -29,10 +31,12 @@
   Returns:
     A SnippetEvent object.
   """
-  return SnippetEvent(callback_id=event_dict['callbackId'],
-                      name=event_dict['name'],
-                      creation_time=event_dict['time'],
-                      data=event_dict['data'])
+  return SnippetEvent(
+      callback_id=event_dict['callbackId'],
+      name=event_dict['name'],
+      creation_time=event_dict['time'],
+      data=event_dict['data'],
+  )
 
 
 class SnippetEvent:
@@ -55,6 +59,6 @@
     self.data = data
 
   def __repr__(self):
-    return ('SnippetEvent(callback_id: %s, name: %s, creation_time: %s, '
-            'data: %s)') % (self.callback_id, self.name, self.creation_time,
-                            self.data)
+    return (
+        'SnippetEvent(callback_id: %s, name: %s, creation_time: %s, data: %s)'
+    ) % (self.callback_id, self.name, self.creation_time, self.data)
diff --git a/mobly/controllers/attenuator.py b/mobly/controllers/attenuator.py
index eebc0e4..70f1faa 100644
--- a/mobly/controllers/attenuator.py
+++ b/mobly/controllers/attenuator.py
@@ -33,7 +33,6 @@
     ]
 """
 import importlib
-import logging
 
 MOBLY_CONTROLLER_CONFIG_NAME = "Attenuator"
 # Keys used inside a config dict for attenuator.
@@ -62,7 +61,8 @@
     module = importlib.import_module(module_name)
     # Create each
     attenuation_device = module.AttenuatorDevice(
-        path_count=len(config[KEY_PATHS]))
+        path_count=len(config[KEY_PATHS])
+    )
     attenuation_device.model = attenuator_model
     instances = attenuation_device.open(config[KEY_ADDRESS], config[KEY_PORT])
     for idx, path_name in enumerate(config[KEY_PATHS]):
@@ -78,19 +78,19 @@
 
 class Error(Exception):
   """This is the Exception class defined for all errors generated by
-    Attenuator-related modules.
-    """
+  Attenuator-related modules.
+  """
 
 
 def _validate_config(config):
   """Verifies that a config dict for an attenuator device is valid.
 
-    Args:
-        config: A dict that is the configuration for an attenuator device.
+  Args:
+      config: A dict that is the configuration for an attenuator device.
 
-    Raises:
-        attenuator.Error: A config is not valid.
-    """
+  Raises:
+      attenuator.Error: A config is not valid.
+  """
   required_keys = [KEY_ADDRESS, KEY_MODEL, KEY_PORT, KEY_PATHS]
   for key in required_keys:
     if key not in config:
@@ -99,62 +99,62 @@
 
 class AttenuatorPath:
   """A convenience class that allows users to control each attenuator path
-    separately as different objects, as opposed to passing in an index number
-    to the functions of an attenuator device object.
+  separately as different objects, as opposed to passing in an index number
+  to the functions of an attenuator device object.
 
-    This decouples the test code from the actual attenuator device used in the
-    physical test bed.
+  This decouples the test code from the actual attenuator device used in the
+  physical test bed.
 
-    For example, if a test needs to attenuate four signal paths, this allows the
-    test to do:
+  For example, if a test needs to attenuate four signal paths, this allows the
+  test to do:
 
-    .. code-block:: python
+  .. code-block:: python
 
-        self.attenuation_paths[0].set_atten(50)
-        self.attenuation_paths[1].set_atten(40)
+      self.attenuation_paths[0].set_atten(50)
+      self.attenuation_paths[1].set_atten(40)
 
-    instead of:
+  instead of:
 
-    .. code-block:: python
+  .. code-block:: python
 
-        self.attenuators[0].set_atten(0, 50)
-        self.attenuators[0].set_atten(1, 40)
+      self.attenuators[0].set_atten(0, 50)
+      self.attenuators[0].set_atten(1, 40)
 
-    The benefit the former is that the physical test bed can use either four
-    single-channel attenuators, or one four-channel attenuators. Whereas the
-    latter forces the test bed to use a four-channel attenuator.
-    """
+  The benefit the former is that the physical test bed can use either four
+  single-channel attenuators, or one four-channel attenuators. Whereas the
+  latter forces the test bed to use a four-channel attenuator.
+  """
 
   def __init__(self, attenuation_device, idx=0, name=None):
     self.model = attenuation_device.model
     self.attenuation_device = attenuation_device
     self.idx = idx
     self.name = name
-    if (self.idx >= attenuation_device.path_count):
+    if self.idx >= attenuation_device.path_count:
       raise IndexError("Attenuator index out of range!")
 
   def set_atten(self, value):
     """This function sets the attenuation of Attenuator.
 
-        Args:
-            value: This is a floating point value for nominal attenuation to be
-                set. Unit is db.
-        """
+    Args:
+        value: This is a floating point value for nominal attenuation to be
+            set. Unit is db.
+    """
     self.attenuation_device.set_atten(self.idx, value)
 
   def get_atten(self):
     """Gets the current attenuation setting of Attenuator.
 
-        Returns:
-            A float that is the current attenuation value. Unit is db.
-        """
+    Returns:
+        A float that is the current attenuation value. Unit is db.
+    """
 
     return self.attenuation_device.get_atten(self.idx)
 
   def get_max_atten(self):
     """Gets the max attenuation supported by the Attenuator.
 
-        Returns:
-            A float that is the max attenuation value.
-        """
+    Returns:
+        A float that is the max attenuation value.
+    """
     return self.attenuation_device.max_atten
diff --git a/mobly/controllers/attenuator_lib/minicircuits.py b/mobly/controllers/attenuator_lib/minicircuits.py
index f33a5d1..7234015 100644
--- a/mobly/controllers/attenuator_lib/minicircuits.py
+++ b/mobly/controllers/attenuator_lib/minicircuits.py
@@ -24,75 +24,79 @@
 
 class AttenuatorDevice:
   """This provides a specific telnet-controlled implementation of
-    AttenuatorDevice for Mini-Circuits RC-DAT attenuators.
+  AttenuatorDevice for Mini-Circuits RC-DAT attenuators.
 
-    Attributes:
-        path_count: The number of signal attenuation path this device has.
-    """
+  Attributes:
+      path_count: The number of signal attenuation path this device has.
+  """
 
   def __init__(self, path_count=1):
     self.path_count = path_count
     # The telnet client used to communicate with the attenuator device.
     self._telnet_client = telnet_scpi_client.TelnetScpiClient(
-        tx_cmd_separator="\r\n", rx_cmd_separator="\r\n", prompt="")
+        tx_cmd_separator="\r\n", rx_cmd_separator="\r\n", prompt=""
+    )
 
   @property
   def is_open(self):
     """This function returns the state of the telnet connection to the
-        underlying AttenuatorDevice.
+    underlying AttenuatorDevice.
 
-        Returns:
-            True if there is a successfully open connection to the
-            AttenuatorDevice.
-        """
+    Returns:
+        True if there is a successfully open connection to the
+        AttenuatorDevice.
+    """
     return bool(self._telnet_client.is_open)
 
   def open(self, host, port=23):
     """Opens a telnet connection to the desired AttenuatorDevice and
-        queries basic information.
+    queries basic information.
 
-        Args:
-            host: A valid hostname (IP address or DNS-resolvable name) to an
-                MC-DAT attenuator instrument.
-            port: An optional port number (defaults to telnet default 23)
-        """
+    Args:
+        host: A valid hostname (IP address or DNS-resolvable name) to an
+            MC-DAT attenuator instrument.
+        port: An optional port number (defaults to telnet default 23)
+    """
     self._telnet_client.open(host, port)
     config_str = self._telnet_client.cmd("MN?")
     if config_str.startswith("MN="):
-      config_str = config_str[len("MN="):]
+      config_str = config_str[len("MN=") :]
     self.properties = dict(
-        zip(['model', 'max_freq', 'max_atten'], config_str.split("-", 2)))
-    self.max_atten = float(self.properties['max_atten'])
+        zip(["model", "max_freq", "max_atten"], config_str.split("-", 2))
+    )
+    self.max_atten = float(self.properties["max_atten"])
 
   def close(self):
     """Closes a telnet connection to the desired attenuator device.
 
-        This should be called as part of any teardown procedure prior to the
-        attenuator instrument leaving scope.
-        """
+    This should be called as part of any teardown procedure prior to the
+    attenuator instrument leaving scope.
+    """
     if self.is_open:
       self._telnet_client.close()
 
   def set_atten(self, idx, value):
     """Sets the attenuation value for a particular signal path.
 
-        Args:
-            idx: Zero-based index int which is the identifier for a particular
-                signal path in an instrument. For instruments that only has one
-                channel, this is ignored by the device.
-            value: A float that is the attenuation value to set.
+    Args:
+        idx: Zero-based index int which is the identifier for a particular
+            signal path in an instrument. For instruments that only has one
+            channel, this is ignored by the device.
+        value: A float that is the attenuation value to set.
 
-        Raises:
-            Error: The underlying telnet connection to the instrument is not
-                open.
-            IndexError: The index of the attenuator is greater than the maximum
-                index of the underlying instrument.
-            ValueError: The requested set value is greater than the maximum
-                attenuation value.
-        """
+    Raises:
+        Error: The underlying telnet connection to the instrument is not
+            open.
+        IndexError: The index of the attenuator is greater than the maximum
+            index of the underlying instrument.
+        ValueError: The requested set value is greater than the maximum
+            attenuation value.
+    """
     if not self.is_open:
-      raise attenuator.Error("Connection to attenuator at %s is not open!" %
-                             self._telnet_client.host)
+      raise attenuator.Error(
+          "Connection to attenuator at %s is not open!"
+          % self._telnet_client.host
+      )
     if idx + 1 > self.path_count:
       raise IndexError("Attenuator index out of range!", self.path_count, idx)
     if value > self.max_atten:
@@ -102,22 +106,24 @@
 
   def get_atten(self, idx=0):
     """This function returns the current attenuation from an attenuator at a
-        given index in the instrument.
+    given index in the instrument.
 
-        Args:
-            idx: This zero-based index is the identifier for a particular
-                attenuator in an instrument.
+    Args:
+        idx: This zero-based index is the identifier for a particular
+            attenuator in an instrument.
 
-        Raises:
-            Error: The underlying telnet connection to the instrument is not
-                open.
+    Raises:
+        Error: The underlying telnet connection to the instrument is not
+            open.
 
-        Returns:
-            A float that is the current attenuation value.
-        """
+    Returns:
+        A float that is the current attenuation value.
+    """
     if not self.is_open:
-      raise attenuator.Error("Connection to attenuator at %s is not open!" %
-                             self._telnet_client.host)
+      raise attenuator.Error(
+          "Connection to attenuator at %s is not open!"
+          % self._telnet_client.host
+      )
     if idx + 1 > self.path_count or idx < 0:
       raise IndexError("Attenuator index out of range!", self.path_count, idx)
     telnet_cmd = ":ATT?" if self.path_count == 1 else "CHAN:%s:ATT?" % (idx + 1)
diff --git a/mobly/controllers/attenuator_lib/telnet_scpi_client.py b/mobly/controllers/attenuator_lib/telnet_scpi_client.py
index 4dde387..98cccca 100644
--- a/mobly/controllers/attenuator_lib/telnet_scpi_client.py
+++ b/mobly/controllers/attenuator_lib/telnet_scpi_client.py
@@ -23,14 +23,14 @@
 
 
 def _ascii_string(uc_string):
-  return str(uc_string).encode('ASCII')
+  return str(uc_string).encode("ASCII")
 
 
 class TelnetScpiClient:
   """This is an internal helper class for Telnet+SCPI command-based
-    instruments. It should only be used by those implemention control libraries
-    and not by any user code directly.
-    """
+  instruments. It should only be used by those implemention control libraries
+  and not by any user code directly.
+  """
 
   def __init__(self, tx_cmd_separator="\n", rx_cmd_separator="\n", prompt=""):
     self._tn = None
@@ -70,13 +70,15 @@
       return None
 
     match_idx, match_val, ret_text = self._tn.expect(
-        [_ascii_string("\S+" + self.rx_cmd_separator)], 1)
+        [_ascii_string("\S+" + self.rx_cmd_separator)], 1
+    )
 
     if match_idx == -1:
       raise attenuator.Error("Telnet command failed to return valid data")
 
     ret_text = ret_text.decode()
-    ret_text = ret_text.strip(self.tx_cmd_separator + self.rx_cmd_separator +
-                              self.prompt)
+    ret_text = ret_text.strip(
+        self.tx_cmd_separator + self.rx_cmd_separator + self.prompt
+    )
 
     return ret_text
diff --git a/mobly/controllers/iperf_server.py b/mobly/controllers/iperf_server.py
index e4dcb81..e99b298 100644
--- a/mobly/controllers/iperf_server.py
+++ b/mobly/controllers/iperf_server.py
@@ -16,11 +16,10 @@
 import json
 import logging
 import os
-import subprocess
 
 from mobly import utils
 
-MOBLY_CONTROLLER_CONFIG_NAME = "IPerfServer"
+MOBLY_CONTROLLER_CONFIG_NAME = 'IPerfServer'
 
 
 def create(configs):
@@ -57,16 +56,16 @@
   def _has_data(self):
     """Checks if the iperf result has valid throughput data.
 
-        Returns:
-            True if the result contains throughput data. False otherwise.
-        """
-    return ('end' in self.result) and ('sum' in self.result["end"])
+    Returns:
+        True if the result contains throughput data. False otherwise.
+    """
+    return ('end' in self.result) and ('sum' in self.result['end'])
 
   def get_json(self):
     """
-        Returns:
-            The raw json output from iPerf.
-        """
+    Returns:
+        The raw json output from iPerf.
+    """
     return self.result
 
   @property
@@ -79,8 +78,8 @@
   def avg_rate(self):
     """Average receiving rate in MB/s over the entire run.
 
-        If the result is not from a success run, this property is None.
-        """
+    If the result is not from a success run, this property is None.
+    """
     if not self._has_data or 'sum' not in self.result['end']:
       return None
     bps = self.result['end']['sum']['bits_per_second']
@@ -89,10 +88,10 @@
   @property
   def avg_receive_rate(self):
     """Average receiving rate in MB/s over the entire run. This data may
-        not exist if iperf was interrupted.
+    not exist if iperf was interrupted.
 
-        If the result is not from a success run, this property is None.
-        """
+    If the result is not from a success run, this property is None.
+    """
     if not self._has_data or 'sum_received' not in self.result['end']:
       return None
     bps = self.result['end']['sum_received']['bits_per_second']
@@ -101,44 +100,44 @@
   @property
   def avg_send_rate(self):
     """Average sending rate in MB/s over the entire run. This data may
-        not exist if iperf was interrupted.
+    not exist if iperf was interrupted.
 
-        If the result is not from a success run, this property is None.
-        """
+    If the result is not from a success run, this property is None.
+    """
     if not self._has_data or 'sum_sent' not in self.result['end']:
       return None
     bps = self.result['end']['sum_sent']['bits_per_second']
     return bps / 8 / 1024 / 1024
 
 
-class IPerfServer():
-  """Class that handles iperf3 operations.
-    """
+class IPerfServer:
+  """Class that handles iperf3 operations."""
 
   def __init__(self, port, log_path):
     self.port = port
-    self.log_path = os.path.join(log_path, "iPerf{}".format(self.port))
-    self.iperf_str = "iperf3 -s -J -p {}".format(port)
+    self.log_path = os.path.join(log_path, 'iPerf{}'.format(self.port))
+    self.iperf_str = 'iperf3 -s -J -p {}'.format(port)
     self.iperf_process = None
     self.log_files = []
     self.started = False
 
-  def start(self, extra_args="", tag=""):
+  def start(self, extra_args='', tag=''):
     """Starts iperf server on specified port.
 
-        Args:
-            extra_args: A string representing extra arguments to start iperf
-                server with.
-            tag: Appended to log file name to identify logs from different
-                iperf runs.
-        """
+    Args:
+        extra_args: A string representing extra arguments to start iperf
+            server with.
+        tag: Appended to log file name to identify logs from different
+            iperf runs.
+    """
     if self.started:
       return
     utils.create_dir(self.log_path)
     if tag:
       tag = tag + ','
-    out_file_name = "IPerfServer,{},{}{}.log".format(self.port, tag,
-                                                     len(self.log_files))
+    out_file_name = 'IPerfServer,{},{}{}.log'.format(
+        self.port, tag, len(self.log_files)
+    )
     full_out_path = os.path.join(self.log_path, out_file_name)
     cmd = '%s %s > %s' % (self.iperf_str, extra_args, full_out_path)
     self.iperf_process = utils.start_standing_subprocess(cmd, shell=True)
diff --git a/mobly/controllers/sniffer.py b/mobly/controllers/sniffer.py
index 91293b4..e1f3460 100644
--- a/mobly/controllers/sniffer.py
+++ b/mobly/controllers/sniffer.py
@@ -20,18 +20,18 @@
 
 def create(configs):
   """Initializes the sniffer structures based on the JSON configuration. The
-    expected keys are:
+  expected keys are:
 
-        * Type: A first-level type of sniffer. Planned to be 'local' for
-            sniffers running on the local machine, or 'remote' for sniffers
-            running remotely.
-        * SubType: The specific sniffer type to be used.
-        * Interface: The WLAN interface used to configure the sniffer.
-        * BaseConfigs: A dictionary specifying baseline configurations of
-            the sniffer. Configurations can be overridden when starting a
-            capture. The keys must be one of the Sniffer.CONFIG_KEY_*
-            values.
-    """
+      * Type: A first-level type of sniffer. Planned to be 'local' for
+          sniffers running on the local machine, or 'remote' for sniffers
+          running remotely.
+      * SubType: The specific sniffer type to be used.
+      * Interface: The WLAN interface used to configure the sniffer.
+      * BaseConfigs: A dictionary specifying baseline configurations of
+          the sniffer. Configurations can be overridden when starting a
+          capture. The keys must be one of the Sniffer.CONFIG_KEY_*
+          values.
+  """
   objs = []
   for c in configs:
     sniffer_type = c["Type"]
@@ -39,18 +39,19 @@
     interface = c["Interface"]
     base_configs = c["BaseConfigs"]
     module_name = "mobly.controllers.sniffer_lib.{}.{}".format(
-        sniffer_type, sniffer_subtype)
+        sniffer_type, sniffer_subtype
+    )
     module = importlib.import_module(module_name)
     objs.append(
-        module.Sniffer(interface,
-                       logging.getLogger(),
-                       base_configs=base_configs))
+        module.Sniffer(
+            interface, logging.getLogger(), base_configs=base_configs
+        )
+    )
   return objs
 
 
 def destroy(objs):
-  """Destroys the sniffers and terminates any ongoing capture sessions.
-    """
+  """Destroys the sniffers and terminates any ongoing capture sessions."""
   for sniffer in objs:
     try:
       sniffer.stop_capture()
@@ -60,221 +61,227 @@
 
 class SnifferError(Exception):
   """This is the Exception class defined for all errors generated by
-    Sniffer-related modules.
-    """
+  Sniffer-related modules.
+  """
+
   pass
 
 
 class InvalidDataError(Exception):
   """This exception is thrown when invalid configuration data is passed
-    to a method.
-    """
+  to a method.
+  """
+
   pass
 
 
 class ExecutionError(SnifferError):
   """This exception is thrown when trying to configure the capture device
-    or when trying to execute the capture operation.
+  or when trying to execute the capture operation.
 
-    When this exception is seen, it is possible that the sniffer module is run
-    without sudo (for local sniffers) or keys are out-of-date (for remote
-    sniffers).
-    """
+  When this exception is seen, it is possible that the sniffer module is run
+  without sudo (for local sniffers) or keys are out-of-date (for remote
+  sniffers).
+  """
+
   pass
 
 
 class InvalidOperationError(SnifferError):
   """Certain methods may only be accessed when the instance upon which they
-    are invoked is in a certain state. This indicates that the object is not
-    in the correct state for a method to be called.
-    """
+  are invoked is in a certain state. This indicates that the object is not
+  in the correct state for a method to be called.
+  """
+
   pass
 
 
 class Sniffer:
   """This class defines an object representing a sniffer.
 
-    The object defines the generic behavior of sniffers - irrespective of how
-    they are implemented, or where they are located: on the local machine or on
-    the remote machine.
-    """
+  The object defines the generic behavior of sniffers - irrespective of how
+  they are implemented, or where they are located: on the local machine or on
+  the remote machine.
+  """
 
   CONFIG_KEY_CHANNEL = "channel"
 
   def __init__(self, interface, logger, base_configs=None):
     """The constructor for the Sniffer. It constructs a sniffer and
-        configures it to be ready for capture.
+    configures it to be ready for capture.
 
-        Args:
-            interface: A string specifying the interface used to configure the
-                sniffer.
-            logger: Mobly logger object.
-            base_configs: A dictionary containing baseline configurations of the
-                sniffer. These can be overridden when staring a capture. The
-                keys are specified by Sniffer.CONFIG_KEY_*.
+    Args:
+        interface: A string specifying the interface used to configure the
+            sniffer.
+        logger: Mobly logger object.
+        base_configs: A dictionary containing baseline configurations of the
+            sniffer. These can be overridden when staring a capture. The
+            keys are specified by Sniffer.CONFIG_KEY_*.
 
-        Returns:
-            self: A configured sniffer.
+    Returns:
+        self: A configured sniffer.
 
-        Raises:
-            InvalidDataError: if the config_path is invalid.
-            NoPermissionError: if an error occurs while configuring the
-                sniffer.
-        """
+    Raises:
+        InvalidDataError: if the config_path is invalid.
+        NoPermissionError: if an error occurs while configuring the
+            sniffer.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def get_descriptor(self):
     """This function returns a string describing the sniffer. The specific
-        string (and its format) is up to each derived sniffer type.
+    string (and its format) is up to each derived sniffer type.
 
-        Returns:
-            A string describing the sniffer.
-        """
+    Returns:
+        A string describing the sniffer.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def get_type(self):
     """This function returns the type of the sniffer.
 
-        Returns:
-            The type (string) of the sniffer. Corresponds to the 'Type' key of
-            the sniffer configuration.
-        """
+    Returns:
+        The type (string) of the sniffer. Corresponds to the 'Type' key of
+        the sniffer configuration.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def get_subtype(self):
     """This function returns the sub-type of the sniffer.
 
-        Returns:
-            The sub-type (string) of the sniffer. Corresponds to the 'SubType'
-            key of the sniffer configuration.
-        """
+    Returns:
+        The sub-type (string) of the sniffer. Corresponds to the 'SubType'
+        key of the sniffer configuration.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def get_interface(self):
     """This function returns The interface used to configure the sniffer,
-        e.g. 'wlan0'.
+    e.g. 'wlan0'.
 
-        Returns:
-            The interface (string) used to configure the sniffer. Corresponds to
-            the 'Interface' key of the sniffer configuration.
-        """
+    Returns:
+        The interface (string) used to configure the sniffer. Corresponds to
+        the 'Interface' key of the sniffer configuration.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def get_capture_file(self):
     """The sniffer places a capture in the logger directory. This function
-        enables the caller to obtain the path of that capture.
+    enables the caller to obtain the path of that capture.
 
-        Returns:
-            The full path of the current or last capture.
-        """
+    Returns:
+        The full path of the current or last capture.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
-  def start_capture(self,
-                    override_configs=None,
-                    additional_args=None,
-                    duration=None,
-                    packet_count=None):
+  def start_capture(
+      self,
+      override_configs=None,
+      additional_args=None,
+      duration=None,
+      packet_count=None,
+  ):
     """This function starts a capture which is saved to the specified file
-        path.
+    path.
 
-        Depending on the type/subtype and configuration of the sniffer the
-        capture may terminate on its own or may require an explicit call to the
-        stop_capture() function.
+    Depending on the type/subtype and configuration of the sniffer the
+    capture may terminate on its own or may require an explicit call to the
+    stop_capture() function.
 
-        This is a non-blocking function so a terminating function must be
-        called either explicitly or implicitly:
+    This is a non-blocking function so a terminating function must be
+    called either explicitly or implicitly:
 
-            * Explicitly: call either stop_capture() or wait_for_capture()
-            * Implicitly: use with a with clause. The wait_for_capture()
-                function will be called if a duration is specified (i.e.
-                is not None), otherwise a stop_capture() will be called.
+        * Explicitly: call either stop_capture() or wait_for_capture()
+        * Implicitly: use with a with clause. The wait_for_capture()
+            function will be called if a duration is specified (i.e.
+            is not None), otherwise a stop_capture() will be called.
 
-        The capture is saved to a file in the log path of the logger. Use
-        the get_capture_file() to get the full path to the current or most
-        recent capture.
+    The capture is saved to a file in the log path of the logger. Use
+    the get_capture_file() to get the full path to the current or most
+    recent capture.
 
-        Args:
-            override_configs: A dictionary which is combined with the
-                base_configs ("BaseConfigs" in the sniffer configuration). The
-                keys (specified by Sniffer.CONFIG_KEY_*) determine the
-                configuration of the sniffer for this specific capture.
-            additional_args: A string specifying additional raw
-                command-line arguments to pass to the underlying sniffer. The
-                interpretation of these flags is sniffer-dependent.
-            duration: An integer specifying the number of seconds over which to
-                capture packets. The sniffer will be terminated after this
-                duration. Used in implicit mode when using a 'with' clause. In
-                explicit control cases may have to be performed using a
-                sleep+stop or as the timeout argument to the wait function.
-            packet_count: An integer specifying the number of packets to capture
-                before terminating. Should be used with duration to guarantee
-                that capture terminates at some point (even if did not capture
-                the specified number of packets).
+    Args:
+        override_configs: A dictionary which is combined with the
+            base_configs ("BaseConfigs" in the sniffer configuration). The
+            keys (specified by Sniffer.CONFIG_KEY_*) determine the
+            configuration of the sniffer for this specific capture.
+        additional_args: A string specifying additional raw
+            command-line arguments to pass to the underlying sniffer. The
+            interpretation of these flags is sniffer-dependent.
+        duration: An integer specifying the number of seconds over which to
+            capture packets. The sniffer will be terminated after this
+            duration. Used in implicit mode when using a 'with' clause. In
+            explicit control cases may have to be performed using a
+            sleep+stop or as the timeout argument to the wait function.
+        packet_count: An integer specifying the number of packets to capture
+            before terminating. Should be used with duration to guarantee
+            that capture terminates at some point (even if did not capture
+            the specified number of packets).
 
-        Returns:
-            An ActiveCaptureContext process which can be used with a 'with'
-            clause.
+    Returns:
+        An ActiveCaptureContext process which can be used with a 'with'
+        clause.
 
-        Raises:
-            InvalidDataError: for invalid configurations
-            NoPermissionError: if an error occurs while configuring and running
-                the sniffer.
-        """
+    Raises:
+        InvalidDataError: for invalid configurations
+        NoPermissionError: if an error occurs while configuring and running
+            the sniffer.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def stop_capture(self):
     """This function stops a capture and guarantees that the capture is
-        saved to the capture file configured during the start_capture() method.
-        Depending on the type of the sniffer the file may previously contain
-        partial results (e.g. for a local sniffer) or may not exist until the
-        stop_capture() method is executed (e.g. for a remote sniffer).
+    saved to the capture file configured during the start_capture() method.
+    Depending on the type of the sniffer the file may previously contain
+    partial results (e.g. for a local sniffer) or may not exist until the
+    stop_capture() method is executed (e.g. for a remote sniffer).
 
-        Depending on the type/subtype and configuration of the sniffer the
-        capture may terminate on its own without requiring a call to this
-        function. In such a case it is still necessary to call either this
-        function or the wait_for_capture() function to make sure that the
-        capture file is moved to the correct location.
+    Depending on the type/subtype and configuration of the sniffer the
+    capture may terminate on its own without requiring a call to this
+    function. In such a case it is still necessary to call either this
+    function or the wait_for_capture() function to make sure that the
+    capture file is moved to the correct location.
 
-        Raises:
-            NoPermissionError: No permission when trying to stop a capture
-                and save the capture file.
-        """
+    Raises:
+        NoPermissionError: No permission when trying to stop a capture
+            and save the capture file.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def wait_for_capture(self, timeout=None):
     """This function waits for a capture to terminate and guarantees that
-        the capture is saved to the capture file configured during the
-        start_capture() method. Depending on the type of the sniffer the file
-        may previously contain partial results (e.g. for a local sniffer) or
-        may not exist until the stop_capture() method is executed (e.g. for a
-        remote sniffer).
+    the capture is saved to the capture file configured during the
+    start_capture() method. Depending on the type of the sniffer the file
+    may previously contain partial results (e.g. for a local sniffer) or
+    may not exist until the stop_capture() method is executed (e.g. for a
+    remote sniffer).
 
-        Depending on the type/subtype and configuration of the sniffer the
-        capture may terminate on its own without requiring a call to this
-        function. In such a case it is still necessary to call either this
-        function or the stop_capture() function to make sure that the capture
-        file is moved to the correct location.
+    Depending on the type/subtype and configuration of the sniffer the
+    capture may terminate on its own without requiring a call to this
+    function. In such a case it is still necessary to call either this
+    function or the stop_capture() function to make sure that the capture
+    file is moved to the correct location.
 
-        Args:
-            timeout: An integer specifying the number of seconds to wait for
-                the capture to terminate on its own. On expiration of the
-                timeout the sniffer is stopped explicitly using the
-                stop_capture() function.
+    Args:
+        timeout: An integer specifying the number of seconds to wait for
+            the capture to terminate on its own. On expiration of the
+            timeout the sniffer is stopped explicitly using the
+            stop_capture() function.
 
-        Raises:
-            NoPermissionError: No permission when trying to stop a capture and
-                save the capture file.
-        """
+    Raises:
+        NoPermissionError: No permission when trying to stop a capture and
+            save the capture file.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
 
 class ActiveCaptureContext:
   """This class defines an object representing an active sniffer capture.
 
-    The object is returned by a Sniffer.start_capture() command and terminates
-    the capture when the 'with' clause exits. It is syntactic sugar for
-    try/finally.
-    """
+  The object is returned by a Sniffer.start_capture() command and terminates
+  the capture when the 'with' clause exits. It is syntactic sugar for
+  try/finally.
+  """
 
   _sniffer = None
   _timeout = None
diff --git a/mobly/controllers/sniffer_lib/local/local_base.py b/mobly/controllers/sniffer_lib/local/local_base.py
index a9fb673..c81b108 100644
--- a/mobly/controllers/sniffer_lib/local/local_base.py
+++ b/mobly/controllers/sniffer_lib/local/local_base.py
@@ -20,7 +20,6 @@
 
 import os
 import shutil
-import signal
 import subprocess
 import tempfile
 from mobly import logger
@@ -30,15 +29,14 @@
 
 class SnifferLocalBase(sniffer.Sniffer):
   """This class defines the common behaviors of WLAN sniffers running on
-    WLAN interfaces of the local machine.
+  WLAN interfaces of the local machine.
 
-    Specific mechanisms to capture packets over the local WLAN interfaces are
-    implemented by sub-classes of this class - i.e. it is not a final class.
-    """
+  Specific mechanisms to capture packets over the local WLAN interfaces are
+  implemented by sub-classes of this class - i.e. it is not a final class.
+  """
 
   def __init__(self, interface, logger, base_configs=None):
-    """See base class documentation
-        """
+    """See base class documentation"""
     self._base_configs = None
     self._capture_file_path = ""
     self._interface = ""
@@ -52,20 +50,18 @@
     self._base_configs = base_configs
 
     try:
-      subprocess.check_call(['ifconfig', self._interface, 'down'])
-      subprocess.check_call(['iwconfig', self._interface, 'mode', 'monitor'])
-      subprocess.check_call(['ifconfig', self._interface, 'up'])
+      subprocess.check_call(["ifconfig", self._interface, "down"])
+      subprocess.check_call(["iwconfig", self._interface, "mode", "monitor"])
+      subprocess.check_call(["ifconfig", self._interface, "up"])
     except Exception as err:
       raise sniffer.ExecutionError(err)
 
   def get_interface(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     return self._interface
 
   def get_type(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     return "local"
 
   def get_capture_file(self):
@@ -73,10 +69,10 @@
 
   def _pre_capture_config(self, override_configs=None):
     """Utility function which configures the wireless interface per the
-        specified configurations. Operation is performed before every capture
-        start using baseline configurations (specified when sniffer initialized)
-        and override configurations specified here.
-        """
+    specified configurations. Operation is performed before every capture
+    start using baseline configurations (specified when sniffer initialized)
+    and override configurations specified here.
+    """
     final_configs = {}
     if self._base_configs:
       final_configs.update(self._base_configs)
@@ -86,71 +82,78 @@
     if sniffer.Sniffer.CONFIG_KEY_CHANNEL in final_configs:
       try:
         subprocess.check_call([
-            'iwconfig', self._interface, 'channel',
-            str(final_configs[sniffer.Sniffer.CONFIG_KEY_CHANNEL])
+            "iwconfig",
+            self._interface,
+            "channel",
+            str(final_configs[sniffer.Sniffer.CONFIG_KEY_CHANNEL]),
         ])
       except Exception as err:
         raise sniffer.ExecutionError(err)
 
-  def _get_command_line(self,
-                        additional_args=None,
-                        duration=None,
-                        packet_count=None):
+  def _get_command_line(
+      self, additional_args=None, duration=None, packet_count=None
+  ):
     """Utility function to be implemented by every child class - which
-        are the concrete sniffer classes. Each sniffer-specific class should
-        derive the command line to execute its sniffer based on the specified
-        arguments.
-        """
+    are the concrete sniffer classes. Each sniffer-specific class should
+    derive the command line to execute its sniffer based on the specified
+    arguments.
+    """
     raise NotImplementedError("Base class should not be called directly!")
 
   def _post_process(self):
     """Utility function which is executed after a capture is done. It
-        moves the capture file to the requested location.
-        """
+    moves the capture file to the requested location.
+    """
     self._process = None
     shutil.move(self._temp_capture_file_path, self._capture_file_path)
 
-  def start_capture(self,
-                    override_configs=None,
-                    additional_args=None,
-                    duration=None,
-                    packet_count=None):
-    """See base class documentation
-        """
+  def start_capture(
+      self,
+      override_configs=None,
+      additional_args=None,
+      duration=None,
+      packet_count=None,
+  ):
+    """See base class documentation"""
     if self._process is not None:
       raise sniffer.InvalidOperationError(
-          "Trying to start a sniff while another is still running!")
-    capture_dir = os.path.join(self._logger.log_path,
-                               "Sniffer-{}".format(self._interface))
+          "Trying to start a sniff while another is still running!"
+      )
+    capture_dir = os.path.join(
+        self._logger.log_path, "Sniffer-{}".format(self._interface)
+    )
     os.makedirs(capture_dir, exist_ok=True)
     self._capture_file_path = os.path.join(
-        capture_dir, "capture_{}.pcap".format(logger.get_log_file_timestamp()))
+        capture_dir, "capture_{}.pcap".format(logger.get_log_file_timestamp())
+    )
 
     self._pre_capture_config(override_configs)
     _, self._temp_capture_file_path = tempfile.mkstemp(suffix=".pcap")
 
-    cmd = self._get_command_line(additional_args=additional_args,
-                                 duration=duration,
-                                 packet_count=packet_count)
+    cmd = self._get_command_line(
+        additional_args=additional_args,
+        duration=duration,
+        packet_count=packet_count,
+    )
 
     self._process = utils.start_standing_subprocess(cmd)
     return sniffer.ActiveCaptureContext(self, duration)
 
   def stop_capture(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     if self._process is None:
       raise sniffer.InvalidOperationError(
-          "Trying to stop a non-started process")
+          "Trying to stop a non-started process"
+      )
     utils.stop_standing_subprocess(self._process)
     self._post_process()
 
   def wait_for_capture(self, timeout=None):
-    """See base class documentation
-        """
+    """See base class documentation"""
     if self._process is None:
       raise sniffer.InvalidOperationError(
-          "Trying to wait on a non-started process")
+          "Trying to wait on a non-started process"
+      )
     try:
       utils.wait_for_standing_subprocess(self._process, timeout)
       self._post_process()
diff --git a/mobly/controllers/sniffer_lib/local/tcpdump.py b/mobly/controllers/sniffer_lib/local/tcpdump.py
index 053d4eb..4f54cdb 100644
--- a/mobly/controllers/sniffer_lib/local/tcpdump.py
+++ b/mobly/controllers/sniffer_lib/local/tcpdump.py
@@ -18,12 +18,10 @@
 
 
 class Sniffer(local_base.SnifferLocalBase):
-  """This class defines a sniffer which uses tcpdump as its back-end
-    """
+  """This class defines a sniffer which uses tcpdump as its back-end"""
 
   def __init__(self, config_path, logger, base_configs=None):
-    """See base class documentation
-        """
+    """See base class documentation"""
     self._executable_path = None
 
     super().__init__(config_path, logger, base_configs=base_configs)
@@ -31,24 +29,23 @@
     self._executable_path = shutil.which("tcpdump")
     if self._executable_path is None:
       raise sniffer.SnifferError(
-          "Cannot find a path to the 'tcpdump' executable")
+          "Cannot find a path to the 'tcpdump' executable"
+      )
 
   def get_descriptor(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     return "local-tcpdump-{}".format(self._interface)
 
   def get_subtype(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     return "tcpdump"
 
-  def _get_command_line(self,
-                        additional_args=None,
-                        duration=None,
-                        packet_count=None):
-    cmd = "{} -i {} -w {}".format(self._executable_path, self._interface,
-                                  self._temp_capture_file_path)
+  def _get_command_line(
+      self, additional_args=None, duration=None, packet_count=None
+  ):
+    cmd = "{} -i {} -w {}".format(
+        self._executable_path, self._interface, self._temp_capture_file_path
+    )
     if packet_count is not None:
       cmd = "{} -c {}".format(cmd, packet_count)
     if additional_args is not None:
diff --git a/mobly/controllers/sniffer_lib/local/tshark.py b/mobly/controllers/sniffer_lib/local/tshark.py
index a22d5f0..e48b1c6 100644
--- a/mobly/controllers/sniffer_lib/local/tshark.py
+++ b/mobly/controllers/sniffer_lib/local/tshark.py
@@ -18,38 +18,37 @@
 
 
 class Sniffer(local_base.SnifferLocalBase):
-  """This class defines a sniffer which uses tshark as its back-end
-    """
+  """This class defines a sniffer which uses tshark as its back-end"""
 
   def __init__(self, config_path, logger, base_configs=None):
-    """See base class documentation
-        """
+    """See base class documentation"""
     self._executable_path = None
 
     super().__init__(config_path, logger, base_configs=base_configs)
 
-    self._executable_path = (shutil.which("tshark") or
-                             shutil.which("/usr/local/bin/tshark"))
+    self._executable_path = shutil.which("tshark") or shutil.which(
+        "/usr/local/bin/tshark"
+    )
     if self._executable_path is None:
-      raise sniffer.SnifferError("Cannot find a path to the 'tshark' "
-                                 "executable (or to '/usr/local/bin/tshark')")
+      raise sniffer.SnifferError(
+          "Cannot find a path to the 'tshark' "
+          "executable (or to '/usr/local/bin/tshark')"
+      )
 
   def get_descriptor(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     return "local-tshark-{}-ch{}".format(self._interface)
 
   def get_subtype(self):
-    """See base class documentation
-        """
+    """See base class documentation"""
     return "tshark"
 
-  def _get_command_line(self,
-                        additional_args=None,
-                        duration=None,
-                        packet_count=None):
-    cmd = "{} -i {} -w {}".format(self._executable_path, self._interface,
-                                  self._temp_capture_file_path)
+  def _get_command_line(
+      self, additional_args=None, duration=None, packet_count=None
+  ):
+    cmd = "{} -i {} -w {}".format(
+        self._executable_path, self._interface, self._temp_capture_file_path
+    )
     if duration is not None:
       cmd = "{} -a duration:{}".format(cmd, duration)
     if packet_count is not None:
diff --git a/mobly/expects.py b/mobly/expects.py
index 9475758..ad7cb8a 100644
--- a/mobly/expects.py
+++ b/mobly/expects.py
@@ -129,8 +129,9 @@
   try:
     asserts.assert_equal(first, second, msg, extras)
   except signals.TestSignal as e:
-    logging.exception('Expected %s equals to %s, but they are not.', first,
-                      second)
+    logging.exception(
+        'Expected %s equals to %s, but they are not.', first, second
+    )
     recorder.add_error(e)
 
 
diff --git a/mobly/keys.py b/mobly/keys.py
index b561734..1987cdc 100644
--- a/mobly/keys.py
+++ b/mobly/keys.py
@@ -17,6 +17,7 @@
 
 class Config(enum.Enum):
   """The reserved keywordss used in configurations."""
+
   # Keywords for params consumed by Mobly itself.
   key_mobly_params = 'MoblyParams'
   key_log_path = 'LogPath'
diff --git a/mobly/logger.py b/mobly/logger.py
index ea1de12..b792cae 100644
--- a/mobly/logger.py
+++ b/mobly/logger.py
@@ -30,34 +30,25 @@
 # length seems to be lower.
 WINDOWS_MAX_FILENAME_LENGTH = 237
 WINDOWS_RESERVED_CHARACTERS_REPLACEMENTS = {
-    '<':
-        '-',
-    '>':
-        '-',
-    ':':
-        '-',
-    '"':
-        '_',
-    '/':
-        '_',
-    '\\':
-        '_',
-    '|':
-        ',',
-    '?':
-        ',',
-    '*':
-        ',',
+    '<': '-',
+    '>': '-',
+    ':': '-',
+    '"': '_',
+    '/': '_',
+    '\\': '_',
+    '|': ',',
+    '?': ',',
+    '*': ',',
     # Integer zero (i.e. NUL) is not a valid character.
     # While integers 1-31 are also usually valid, they aren't sanitized because
     # they are situationally valid.
-    chr(0):
-        '0',
+    chr(0): '0',
 }
 # Note, although the documentation does not specify as such, COM0 and LPT0 are
 # also invalid/reserved filenames.
 WINDOWS_RESERVED_FILENAME_REGEX = re.compile(
-    r'^(CON|PRN|AUX|NUL|(COM|LPT)[0-9])(\.[^.]*)?$', re.IGNORECASE)
+    r'^(CON|PRN|AUX|NUL|(COM|LPT)[0-9])(\.[^.]*)?$', re.IGNORECASE
+)
 WINDOWS_RESERVED_FILENAME_PREFIX = 'mobly_'
 
 log_line_format = '%(asctime)s.%(msecs).03d %(levelname)s %(message)s'
@@ -201,11 +192,13 @@
   f_formatter = logging.Formatter(log_line_format, log_line_time_format)
   # Write logger output to files
   fh_info = logging.FileHandler(
-      os.path.join(log_path, records.OUTPUT_FILE_INFO_LOG))
+      os.path.join(log_path, records.OUTPUT_FILE_INFO_LOG)
+  )
   fh_info.setFormatter(f_formatter)
   fh_info.setLevel(logging.INFO)
   fh_debug = logging.FileHandler(
-      os.path.join(log_path, records.OUTPUT_FILE_DEBUG_LOG))
+      os.path.join(log_path, records.OUTPUT_FILE_DEBUG_LOG)
+  )
   fh_debug.setFormatter(f_formatter)
   fh_debug.setLevel(logging.DEBUG)
   log.addHandler(ch)
@@ -241,10 +234,9 @@
   utils.create_alias(actual_path, alias_path)
 
 
-def setup_test_logger(log_path,
-                      prefix=None,
-                      alias='latest',
-                      console_level=logging.INFO):
+def setup_test_logger(
+    log_path, prefix=None, alias='latest', console_level=logging.INFO
+):
   """Customizes the root logger for a test run.
 
   In addition to configuring the Mobly logging handlers, this also sets two
@@ -294,7 +286,7 @@
       # This is kind of a degrenerate case where the extension is
       # extremely long, in which case, just return the truncated filename.
       return filename[:max_length]
-    return '.'.join([filename[:max_length - len(extension) - 1], extension])
+    return '.'.join([filename[: max_length - len(extension) - 1], extension])
   else:
     return filename[:max_length]
 
diff --git a/mobly/records.py b/mobly/records.py
index 08ebe8e..10d3063 100644
--- a/mobly/records.py
+++ b/mobly/records.py
@@ -11,8 +11,7 @@
 # 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.
-"""This module has classes for test result collection, and test result output.
-"""
+"""This module has classes for test result collection, and test result output."""
 
 import collections
 import copy
@@ -38,6 +37,13 @@
   """Raised for errors in record module members."""
 
 
+class TestParentType(enum.Enum):
+  """The type of parent in a chain of executions of the same test."""
+
+  REPEAT = 'repeat'
+  RETRY = 'retry'
+
+
 def uid(uid):
   """Decorator specifying the unique identifier (UID) of a test case.
 
@@ -56,7 +62,6 @@
     raise ValueError('UID cannot be None.')
 
   def decorate(test_func):
-
     @functools.wraps(test_func)
     def wrapper(*args, **kwargs):
       return test_func(*args, **kwargs)
@@ -77,6 +82,7 @@
   The idea is similar to how `TestResult.json_str` categorizes different
   sections of a `TestResult` object in the serialized format.
   """
+
   # A list of all the tests requested for a test run.
   # This is dumped at the beginning of a summary file so we know what was
   # requested in case the test is interrupted and the final summary is not
@@ -153,12 +159,14 @@
       with io.open(self._path, 'a', encoding='utf-8') as f:
         # Use safe_dump here to avoid language-specific tags in final
         # output.
-        yaml.safe_dump(new_content,
-                       f,
-                       explicit_start=True,
-                       explicit_end=True,
-                       allow_unicode=True,
-                       indent=4)
+        yaml.safe_dump(
+            new_content,
+            f,
+            explicit_start=True,
+            explicit_end=True,
+            allow_unicode=True,
+            indent=4,
+        )
 
 
 class TestResultEnums:
@@ -181,6 +189,7 @@
   RECORD_STACKTRACE = 'Stacktrace'
   RECORD_SIGNATURE = 'Signature'
   RECORD_RETRY_PARENT = 'Retry Parent'
+  RECORD_PARENT = 'Parent'
   RECORD_POSITION = 'Position'
   TEST_RESULT_PASS = 'PASS'
   TEST_RESULT_FAIL = 'FAIL'
@@ -240,7 +249,8 @@
     exc_traceback = e.__traceback__
     if exc_traceback:
       self.stacktrace = ''.join(
-          traceback.format_exception(e.__class__, e, exc_traceback))
+          traceback.format_exception(e.__class__, e, exc_traceback)
+      )
     # Populate fields based on the type of the termination signal.
     if self.is_test_signal:
       self._set_details(e.details)
@@ -315,9 +325,10 @@
     uid: User-defined unique identifier of the test.
     signature: string, unique identifier of a test record, the value is
       generated by Mobly.
-    retry_parent: TestResultRecord, only set for retry iterations. This is the
-      test result record of the previous retry iteration. Parsers can use this
-      field to construct the chain of execution for each retried test.
+    retry_parent: [DEPRECATED] Use the `parent` field instead.
+    parent: tuple[TestResultRecord, TestParentType], set for multiple iterations
+      of a test. This is the test result record of the previous iteration.
+      Parsers can use this field to construct the chain of execution for each test.
     termination_signal: ExceptionRecord, the main exception of the test.
     extra_errors: OrderedDict, all exceptions occurred during the entire
       test lifecycle. The order of occurrence is preserved.
@@ -332,6 +343,7 @@
     self.uid = None
     self.signature = None
     self.retry_parent = None
+    self.parent = None
     self.termination_signal = None
     self.extra_errors = collections.OrderedDict()
     self.result = None
@@ -358,8 +370,7 @@
 
   @property
   def stacktrace(self):
-    """The stacktrace string for the exception that terminated the test.
-    """
+    """The stacktrace string for the exception that terminated the test."""
     if self.termination_signal:
       return self.termination_signal.stacktrace
 
@@ -468,8 +479,10 @@
     if self.result != TestResultEnums.TEST_RESULT_FAIL:
       self.result = TestResultEnums.TEST_RESULT_ERROR
     if position in self.extra_errors:
-      raise Error('An exception is already recorded with position "%s",'
-                  ' cannot reuse.' % position)
+      raise Error(
+          'An exception is already recorded with position "%s", cannot reuse.'
+          % position
+      )
     if isinstance(e, ExceptionRecord):
       self.extra_errors[position] = e
     else:
@@ -500,12 +513,22 @@
     d[TestResultEnums.RECORD_RESULT] = self.result
     d[TestResultEnums.RECORD_UID] = self.uid
     d[TestResultEnums.RECORD_SIGNATURE] = self.signature
-    d[TestResultEnums.
-      RECORD_RETRY_PARENT] = self.retry_parent.signature if self.retry_parent else None
+    d[TestResultEnums.RECORD_RETRY_PARENT] = (
+        self.retry_parent.signature if self.retry_parent else None
+    )
+    d[TestResultEnums.RECORD_PARENT] = (
+        {
+            'parent': self.parent[0].signature,
+            'type': self.parent[1].value,
+        }
+        if self.parent
+        else None
+    )
     d[TestResultEnums.RECORD_EXTRAS] = self.extras
     d[TestResultEnums.RECORD_DETAILS] = self.details
-    d[TestResultEnums.
-      RECORD_TERMINATION_SIGNAL_TYPE] = self.termination_signal_type
+    d[TestResultEnums.RECORD_TERMINATION_SIGNAL_TYPE] = (
+        self.termination_signal_type
+    )
     d[TestResultEnums.RECORD_EXTRA_ERRORS] = {
         key: value.to_dict() for (key, value) in self.extra_errors.items()
     }
@@ -551,8 +574,9 @@
       A TestResult instance that's the sum of two TestResult instances.
     """
     if not isinstance(r, TestResult):
-      raise TypeError('Operand %s of type %s is not a TestResult.' %
-                      (r, type(r)))
+      raise TypeError(
+          'Operand %s of type %s is not a TestResult.' % (r, type(r))
+      )
     sum_result = TestResult()
     for name in sum_result.__dict__:
       r_value = getattr(r, name)
@@ -638,16 +662,19 @@
     count = 0
     for record in self.passed:
       r = record
-      while r.retry_parent:
+      while r.parent is not None and r.parent[1] == TestParentType.RETRY:
         count += 1
-        r = r.retry_parent
+        r = r.parent[0]
     return count
 
   @property
   def is_all_pass(self):
     """True if no tests failed or threw errors, False otherwise."""
-    num_of_result_altering_errors = (len(self.failed) + len(self.error) -
-                                     self._count_eventually_passing_retries())
+    num_of_result_altering_errors = (
+        len(self.failed)
+        + len(self.error)
+        - self._count_eventually_passing_retries()
+    )
     if num_of_result_altering_errors == 0:
       return True
     return False
diff --git a/mobly/runtime_test_info.py b/mobly/runtime_test_info.py
index ed691bc..ca0eafd 100644
--- a/mobly/runtime_test_info.py
+++ b/mobly/runtime_test_info.py
@@ -40,7 +40,8 @@
     self._name = test_name
     self._record = record
     self._output_dir_path = utils.abs_path(
-        os.path.join(log_path, self._record.signature))
+        os.path.join(log_path, self._record.signature)
+    )
 
   @property
   def name(self):
diff --git a/mobly/signals.py b/mobly/signals.py
index ef777d9..dc020f9 100644
--- a/mobly/signals.py
+++ b/mobly/signals.py
@@ -11,8 +11,7 @@
 # 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.
-"""This module is where all the test signal classes and related utilities live.
-"""
+"""This module is where all the test signal classes and related utilities live."""
 
 import json
 
@@ -38,8 +37,9 @@
       json.dumps(extras)
       self.extras = extras
     except TypeError:
-      raise TestSignalError('Extras must be json serializable. %s '
-                            'is not.' % extras)
+      raise TestSignalError(
+          'Extras must be json serializable. %s is not.' % extras
+      )
 
   def __str__(self):
     return 'Details=%s, Extras=%s' % (self.details, self.extras)
@@ -62,8 +62,7 @@
 
 
 class TestAbortSignal(TestSignal):
-  """Base class for abort signals.
-  """
+  """Base class for abort signals."""
 
 
 class TestAbortClass(TestAbortSignal):
diff --git a/mobly/snippet/callback_event.py b/mobly/snippet/callback_event.py
index 55471c7..ea8ee38 100644
--- a/mobly/snippet/callback_event.py
+++ b/mobly/snippet/callback_event.py
@@ -23,10 +23,12 @@
   Returns:
     A CallbackEvent object.
   """
-  return CallbackEvent(callback_id=event_dict['callbackId'],
-                       name=event_dict['name'],
-                       creation_time=event_dict['time'],
-                       data=event_dict['data'])
+  return CallbackEvent(
+      callback_id=event_dict['callbackId'],
+      name=event_dict['name'],
+      creation_time=event_dict['time'],
+      data=event_dict['data'],
+  )
 
 
 class CallbackEvent:
@@ -49,4 +51,5 @@
   def __repr__(self):
     return (
         f'CallbackEvent(callback_id: {self.callback_id}, name: {self.name}, '
-        f'creation_time: {self.creation_time}, data: {self.data})')
+        f'creation_time: {self.creation_time}, data: {self.data})'
+    )
diff --git a/mobly/snippet/callback_handler_base.py b/mobly/snippet/callback_handler_base.py
index 50465d1..95b5a4b 100644
--- a/mobly/snippet/callback_handler_base.py
+++ b/mobly/snippet/callback_handler_base.py
@@ -45,14 +45,16 @@
     ret_value: any, the direct return value of the async RPC call.
   """
 
-  def __init__(self,
-               callback_id,
-               event_client,
-               ret_value,
-               method_name,
-               device,
-               rpc_max_timeout_sec,
-               default_timeout_sec=120):
+  def __init__(
+      self,
+      callback_id,
+      event_client,
+      ret_value,
+      method_name,
+      device,
+      rpc_max_timeout_sec,
+      default_timeout_sec=120,
+  ):
     """Initializes a callback handler base object.
 
     Args:
@@ -74,10 +76,12 @@
     self._method_name = method_name
 
     if rpc_max_timeout_sec < default_timeout_sec:
-      raise ValueError('The max timeout of a single RPC must be no smaller '
-                       'than the default timeout of the callback handler. '
-                       f'Got rpc_max_timeout_sec={rpc_max_timeout_sec}, '
-                       f'default_timeout_sec={default_timeout_sec}.')
+      raise ValueError(
+          'The max timeout of a single RPC must be no smaller '
+          'than the default timeout of the callback handler. '
+          f'Got rpc_max_timeout_sec={rpc_max_timeout_sec}, '
+          f'default_timeout_sec={default_timeout_sec}.'
+      )
     self._rpc_max_timeout_sec = rpc_max_timeout_sec
     self._default_timeout_sec = default_timeout_sec
 
@@ -168,7 +172,8 @@
         raise errors.CallbackHandlerBaseError(
             self._device,
             f'Specified timeout {timeout} is longer than max timeout '
-            f'{self.rpc_max_timeout_sec}.')
+            f'{self.rpc_max_timeout_sec}.',
+        )
 
     raw_event = self.callEventWaitAndGetRpc(self._id, event_name, timeout)
     return callback_event.from_dict(raw_event)
@@ -223,7 +228,8 @@
     raise errors.CallbackHandlerTimeoutError(
         self._device,
         f'Timed out after {timeout}s waiting for an "{event_name}" event that '
-        f'satisfies the predicate "{predicate.__name__}".')
+        f'satisfies the predicate "{predicate.__name__}".',
+    )
 
   def getAll(self, event_name):
     """Gets all existing events in the server with the specified identifier.
diff --git a/mobly/snippet/client_base.py b/mobly/snippet/client_base.py
index 3e046df..3a24a20 100644
--- a/mobly/snippet/client_base.py
+++ b/mobly/snippet/client_base.py
@@ -127,26 +127,34 @@
       self.log.debug('Starting the snippet server of %s.', self.package)
       self.start_server()
 
-      self.log.debug('Making a connection to the snippet server of %s.',
-                     self.package)
+      self.log.debug(
+          'Making a connection to the snippet server of %s.', self.package
+      )
       self._make_connection()
 
     except Exception:
       self.log.error(
           'Error occurred trying to start and connect to the snippet server '
-          'of %s.', self.package)
+          'of %s.',
+          self.package,
+      )
       try:
         self.stop()
       except Exception:  # pylint: disable=broad-except
         # Only prints this exception and re-raises the original exception
         self.log.exception(
             'Failed to stop the snippet package %s after failure to start '
-            'and connect.', self.package)
+            'and connect.',
+            self.package,
+        )
 
       raise
 
-    self.log.debug('Snippet package %s initialized after %.1fs.', self.package,
-                   time.perf_counter() - start_time)
+    self.log.debug(
+        'Snippet package %s initialized after %.1fs.',
+        self.package,
+        time.perf_counter() - start_time,
+    )
 
   @abc.abstractmethod
   def before_starting_server(self):
@@ -271,7 +279,8 @@
     except Exception:
       self.log.error(
           'Server process running check failed, skip sending RPC method(%s).',
-          rpc_func_name)
+          rpc_func_name,
+      )
       raise
 
     with self._lock:
@@ -285,12 +294,15 @@
       if self.verbose_logging or _MAX_RPC_RESP_LOGGING_LENGTH >= len(response):
         self.log.debug('Snippet received: %s', response)
       else:
-        self.log.debug('Snippet received: %s... %d chars are truncated',
-                       response[:_MAX_RPC_RESP_LOGGING_LENGTH],
-                       len(response) - _MAX_RPC_RESP_LOGGING_LENGTH)
+        self.log.debug(
+            'Snippet received: %s... %d chars are truncated',
+            response[:_MAX_RPC_RESP_LOGGING_LENGTH],
+            len(response) - _MAX_RPC_RESP_LOGGING_LENGTH,
+        )
 
     response_decoded = self._decode_response_string_and_validate_format(
-        rpc_id, response)
+        rpc_id, response
+    )
     return self._handle_rpc_response(rpc_func_name, response_decoded)
 
   @abc.abstractmethod
@@ -360,19 +372,22 @@
       errors.ProtocolError: if the response format is invalid.
     """
     if not response:
-      raise errors.ProtocolError(self._device,
-                                 errors.ProtocolError.NO_RESPONSE_FROM_SERVER)
+      raise errors.ProtocolError(
+          self._device, errors.ProtocolError.NO_RESPONSE_FROM_SERVER
+      )
 
     result = json.loads(response)
     for field_name in RPC_RESPONSE_REQUIRED_FIELDS:
       if field_name not in result:
         raise errors.ProtocolError(
             self._device,
-            errors.ProtocolError.RESPONSE_MISSING_FIELD % field_name)
+            errors.ProtocolError.RESPONSE_MISSING_FIELD % field_name,
+        )
 
     if result['id'] != rpc_id:
-      raise errors.ProtocolError(self._device,
-                                 errors.ProtocolError.MISMATCHED_API_ID)
+      raise errors.ProtocolError(
+          self._device, errors.ProtocolError.MISMATCHED_API_ID
+      )
 
     return result
 
@@ -399,8 +414,9 @@
     if response['error']:
       raise errors.ApiError(self._device, response['error'])
     if response['callback'] is not None:
-      return self.handle_callback(response['callback'], response['result'],
-                                  rpc_func_name)
+      return self.handle_callback(
+          response['callback'], response['result'], rpc_func_name
+      )
     return response['result']
 
   @abc.abstractmethod
diff --git a/mobly/snippet/errors.py b/mobly/snippet/errors.py
index 4d41adb..6ca7197 100644
--- a/mobly/snippet/errors.py
+++ b/mobly/snippet/errors.py
@@ -51,9 +51,11 @@
 
 class ProtocolError(Error):
   """Raised when there was an error in exchanging data with server."""
+
   NO_RESPONSE_FROM_HANDSHAKE = 'No response from handshake.'
-  NO_RESPONSE_FROM_SERVER = ('No response from server. '
-                             'Check the device logcat for crashes.')
+  NO_RESPONSE_FROM_SERVER = (
+      'No response from server. Check the device logcat for crashes.'
+  )
   MISMATCHED_API_ID = 'RPC request-response ID mismatch.'
   RESPONSE_MISSING_FIELD = 'Missing required field in the RPC response: %s.'
 
diff --git a/mobly/suite_runner.py b/mobly/suite_runner.py
index b2b2579..b0b064c 100644
--- a/mobly/suite_runner.py
+++ b/mobly/suite_runner.py
@@ -93,34 +93,45 @@
   """
   parser = argparse.ArgumentParser(description='Mobly Suite Executable.')
   group = parser.add_mutually_exclusive_group(required=True)
-  group.add_argument('-c',
-                     '--config',
-                     type=str,
-                     metavar='<PATH>',
-                     help='Path to the test configuration file.')
+  group.add_argument(
+      '-c',
+      '--config',
+      type=str,
+      metavar='<PATH>',
+      help='Path to the test configuration file.',
+  )
   group.add_argument(
       '-l',
       '--list_tests',
       action='store_true',
-      help='Print the names of the tests defined in a script without '
-      'executing them.')
-  parser.add_argument('--tests',
-                      '--test_case',
-                      nargs='+',
-                      type=str,
-                      metavar='[ClassA[.test_a] ClassB[.test_b] ...]',
-                      help='A list of test classes and optional tests to execute.')
-  parser.add_argument('-tb',
-                      '--test_bed',
-                      nargs='+',
-                      type=str,
-                      metavar='[<TEST BED NAME1> <TEST BED NAME2> ...]',
-                      help='Specify which test beds to run tests on.')
+      help=(
+          'Print the names of the tests defined in a script without '
+          'executing them.'
+      ),
+  )
+  parser.add_argument(
+      '--tests',
+      '--test_case',
+      nargs='+',
+      type=str,
+      metavar='[ClassA[.test_a] ClassB[.test_b] ...]',
+      help='A list of test classes and optional tests to execute.',
+  )
+  parser.add_argument(
+      '-tb',
+      '--test_bed',
+      nargs='+',
+      type=str,
+      metavar='[<TEST BED NAME1> <TEST BED NAME2> ...]',
+      help='Specify which test beds to run tests on.',
+  )
 
-  parser.add_argument('-v',
-                      '--verbose',
-                      action='store_true',
-                      help='Set console logger level to DEBUG')
+  parser.add_argument(
+      '-v',
+      '--verbose',
+      action='store_true',
+      help='Set console logger level to DEBUG',
+  )
   if not argv:
     argv = sys.argv[1:]
   return parser.parse_known_args(argv)[0]
@@ -142,8 +153,10 @@
       if issubclass(module_member, base_suite.BaseSuite):
         test_suites.append(module_member)
   if len(test_suites) != 1:
-    logging.error('Expected 1 test class per file, found %s.',
-                  [t.__name__ for t in test_suites])
+    logging.error(
+        'Expected 1 test class per file, found %s.',
+        [t.__name__ for t in test_suites],
+    )
     sys.exit(1)
   return test_suites[0]
 
@@ -172,7 +185,7 @@
       cls._clean_up()
     print('==========> %s <==========' % cls.TAG)
     for name in test_names:
-      print(f"{cls.TAG}.{name}")
+      print(f'{cls.TAG}.{name}')
 
 
 def run_suite_class(argv=None):
@@ -186,14 +199,16 @@
   if cli_args.list_tests:
     _print_test_names([suite_class])
     sys.exit(0)
-  test_configs = config_parser.load_test_config_file(cli_args.config,
-                                                     cli_args.test_bed)
+  test_configs = config_parser.load_test_config_file(
+      cli_args.config, cli_args.test_bed
+  )
   config_count = len(test_configs)
   if config_count != 1:
     logging.error('Expect exactly one test config, found %d', config_count)
   config = test_configs[0]
   runner = test_runner.TestRunner(
-      log_dir=config.log_path, testbed_name=config.testbed_name)
+      log_dir=config.log_path, testbed_name=config.testbed_name
+  )
   suite = suite_class(runner, config)
   console_level = logging.DEBUG if cli_args.verbose else logging.INFO
   ok = False
@@ -229,8 +244,9 @@
   for test_class in test_classes:
     if not issubclass(test_class, base_test.BaseTestClass):
       logging.error(
-          'Test class %s does not extend '
-          'mobly.base_test.BaseTestClass', test_class)
+          'Test class %s does not extend mobly.base_test.BaseTestClass',
+          test_class,
+      )
       sys.exit(1)
 
   if args.list_tests:
@@ -238,8 +254,7 @@
     sys.exit(0)
 
   # Load test config file.
-  test_configs = config_parser.load_test_config_file(args.config,
-                                                     args.test_bed)
+  test_configs = config_parser.load_test_config_file(args.config, args.test_bed)
   # Find the full list of tests to execute
   selected_tests = compute_selected_tests(test_classes, args.tests)
 
@@ -249,7 +264,7 @@
   for config in test_configs:
     runner = test_runner.TestRunner(config.log_path, config.testbed_name)
     with runner.mobly_logger(console_level=console_level):
-      for (test_class, tests) in selected_tests.items():
+      for test_class, tests in selected_tests.items():
         runner.add_test_class(config, test_class, tests)
       try:
         runner.run()
diff --git a/mobly/test_runner.py b/mobly/test_runner.py
index 529035f..5c97113 100644
--- a/mobly/test_runner.py
+++ b/mobly/test_runner.py
@@ -70,8 +70,9 @@
   # Execute the test class with configs.
   ok = True
   for config in test_configs:
-    runner = TestRunner(log_dir=config.log_path,
-                        testbed_name=config.testbed_name)
+    runner = TestRunner(
+        log_dir=config.log_path, testbed_name=config.testbed_name
+    )
     with runner.mobly_logger(console_level=console_level):
       runner.add_test_class(config, test_class, tests)
       try:
@@ -104,34 +105,45 @@
   """
   parser = argparse.ArgumentParser(description='Mobly Test Executable.')
   group = parser.add_mutually_exclusive_group(required=True)
-  group.add_argument('-c',
-                     '--config',
-                     type=str,
-                     metavar='<PATH>',
-                     help='Path to the test configuration file.')
+  group.add_argument(
+      '-c',
+      '--config',
+      type=str,
+      metavar='<PATH>',
+      help='Path to the test configuration file.',
+  )
   group.add_argument(
       '-l',
       '--list_tests',
       action='store_true',
-      help='Print the names of the tests defined in a script without '
-      'executing them.')
-  parser.add_argument('--tests',
-                      '--test_case',
-                      nargs='+',
-                      type=str,
-                      metavar='[test_a test_b...]',
-                      help='A list of tests in the test class to execute.')
-  parser.add_argument('-tb',
-                      '--test_bed',
-                      nargs='+',
-                      type=str,
-                      metavar='[<TEST BED NAME1> <TEST BED NAME2> ...]',
-                      help='Specify which test beds to run tests on.')
+      help=(
+          'Print the names of the tests defined in a script without '
+          'executing them.'
+      ),
+  )
+  parser.add_argument(
+      '--tests',
+      '--test_case',
+      nargs='+',
+      type=str,
+      metavar='[test_a test_b...]',
+      help='A list of tests in the test class to execute.',
+  )
+  parser.add_argument(
+      '-tb',
+      '--test_bed',
+      nargs='+',
+      type=str,
+      metavar='[<TEST BED NAME1> <TEST BED NAME2> ...]',
+      help='Specify which test beds to run tests on.',
+  )
 
-  parser.add_argument('-v',
-                      '--verbose',
-                      action='store_true',
-                      help='Set console logger level to DEBUG')
+  parser.add_argument(
+      '-v',
+      '--verbose',
+      action='store_true',
+      help='Set console logger level to DEBUG',
+  )
   if not argv:
     argv = sys.argv[1:]
   return parser.parse_known_args(argv)[0]
@@ -150,11 +162,14 @@
     SystemExit: Raised if the number of test classes is not exactly one.
   """
   try:
-    return utils.find_subclass_in_module(base_test.BaseTestClass,
-                                         sys.modules['__main__'])
+    return utils.find_subclass_in_module(
+        base_test.BaseTestClass, sys.modules['__main__']
+    )
   except ValueError:
-    logging.exception('Exactly one subclass of `base_test.BaseTestClass`'
-                      ' should be in the main file.')
+    logging.exception(
+        'Exactly one subclass of `base_test.BaseTestClass`'
+        ' should be in the main file.'
+    )
     sys.exit(1)
 
 
@@ -206,11 +221,9 @@
     run it with.
     """
 
-    def __init__(self,
-                 config,
-                 test_class,
-                 tests=None,
-                 test_class_name_suffix=None):
+    def __init__(
+        self, config, test_class, tests=None, test_class_name_suffix=None
+    ):
       self.config = config
       self.test_class = test_class
       self.test_class_name_suffix = test_class_name_suffix
@@ -255,8 +268,9 @@
         String, the generated log path.
       """
       self._logger_start_time = logger.get_log_file_timestamp()
-      self.root_output_path = os.path.join(self._log_dir, self._testbed_name,
-                                           self._logger_start_time)
+      self.root_output_path = os.path.join(
+          self._log_dir, self._testbed_name, self._logger_start_time
+      )
       return self.root_output_path
 
     @property
@@ -323,10 +337,12 @@
     """
     # Refresh the log path at the beginning of the logger context.
     root_output_path = self._test_run_metadata.generate_test_run_log_path()
-    logger.setup_test_logger(root_output_path,
-                             self._testbed_name,
-                             alias=alias,
-                             console_level=console_level)
+    logger.setup_test_logger(
+        root_output_path,
+        self._testbed_name,
+        alias=alias,
+        console_level=console_level,
+    )
     try:
       yield self._test_run_metadata.root_output_path
     finally:
@@ -351,18 +367,25 @@
         constructor.
     """
     if self._log_dir != config.log_path:
-      raise Error('TestRunner\'s log folder is "%s", but a test config with a '
-                  'different log folder ("%s") was added.' %
-                  (self._log_dir, config.log_path))
+      raise Error(
+          'TestRunner\'s log folder is "%s", but a test config with a '
+          'different log folder ("%s") was added.'
+          % (self._log_dir, config.log_path)
+      )
     if self._testbed_name != config.testbed_name:
-      raise Error('TestRunner\'s test bed is "%s", but a test config with a '
-                  'different test bed ("%s") was added.' %
-                  (self._testbed_name, config.testbed_name))
+      raise Error(
+          'TestRunner\'s test bed is "%s", but a test config with a '
+          'different test bed ("%s") was added.'
+          % (self._testbed_name, config.testbed_name)
+      )
     self._test_run_infos.append(
-        TestRunner._TestRunInfo(config=config,
-                                test_class=test_class,
-                                tests=tests,
-                                test_class_name_suffix=name_suffix))
+        TestRunner._TestRunInfo(
+            config=config,
+            test_class=test_class,
+            tests=tests,
+            test_class_name_suffix=name_suffix,
+        )
+    )
 
   def _run_test_class(self, config, test_class, tests=None):
     """Instantiates and executes a test class.
@@ -377,8 +400,9 @@
       tests: Optional list of test names within the class to execute.
     """
     test_instance = test_class(config)
-    logging.debug('Executing test class "%s" with config: %s',
-                  test_class.__name__, config)
+    logging.debug(
+        'Executing test class "%s" with config: %s', test_class.__name__, config
+    )
     try:
       cls_result = test_instance.run(tests)
       self.results += cls_result
@@ -412,7 +436,8 @@
     utils.create_dir(self._test_run_metadata.root_output_path)
 
     summary_writer = records.TestSummaryWriter(
-        self._test_run_metadata.summary_file_path)
+        self._test_run_metadata.summary_file_path
+    )
 
     # When a SIGTERM is received during the execution of a test, the Mobly test
     # immediately terminates without executing any of the finally blocks. This
@@ -432,24 +457,35 @@
         test_config = test_run_info.config.copy()
         test_config.log_path = self._test_run_metadata.root_output_path
         test_config.summary_writer = summary_writer
-        test_config.test_class_name_suffix = test_run_info.test_class_name_suffix
+        test_config.test_class_name_suffix = (
+            test_run_info.test_class_name_suffix
+        )
         try:
-          self._run_test_class(config=test_config,
-                               test_class=test_run_info.test_class,
-                               tests=test_run_info.tests)
+          self._run_test_class(
+              config=test_config,
+              test_class=test_run_info.test_class,
+              tests=test_run_info.tests,
+          )
         except signals.TestAbortAll as e:
           logging.warning('Abort all subsequent test classes. Reason: %s', e)
           raise
     finally:
-      summary_writer.dump(self.results.summary_dict(),
-                          records.TestSummaryEntryType.SUMMARY)
+      summary_writer.dump(
+          self.results.summary_dict(), records.TestSummaryEntryType.SUMMARY
+      )
       self._test_run_metadata.set_end_point()
       # Show the test run summary.
       summary_lines = [
           f'Summary for test run {self._test_run_metadata.run_id}:',
           f'Total time elapsed {self._test_run_metadata.time_elapsed_sec}s',
-          f'Artifacts are saved in "{self._test_run_metadata.root_output_path}"',
-          f'Test summary saved in "{self._test_run_metadata.summary_file_path}"',
-          f'Test results: {self.results.summary_str()}'
+          (
+              'Artifacts are saved in'
+              f' "{self._test_run_metadata.root_output_path}"'
+          ),
+          (
+              'Test summary saved in'
+              f' "{self._test_run_metadata.summary_file_path}"'
+          ),
+          f'Test results: {self.results.summary_str()}',
       ]
       logging.info('\n'.join(summary_lines))
diff --git a/mobly/utils.py b/mobly/utils.py
index 7d26496..02125ed 100644
--- a/mobly/utils.py
+++ b/mobly/utils.py
@@ -20,27 +20,20 @@
 import io
 import logging
 import os
-import pipes
 import platform
 import random
 import re
+import shlex
 import signal
 import string
 import subprocess
 import threading
 import time
 import traceback
-from typing import Tuple, overload
+from typing import Literal, Tuple, overload
 
 import portpicker
 
-# TODO(#851): Remove this try/except statement and typing_extensions from
-# install_requires when Python 3.8 is the minimum version we support.
-try:
-    from typing import Literal
-except ImportError:
-    from typing_extensions import Literal
-
 # File name length is limited to 255 chars on some OS, so we need to make sure
 # the file names we output fits within the limit.
 MAX_FILENAME_LEN = 255
@@ -75,7 +68,7 @@
     'GMT+12': 'Pacific/Fiji',
     'GMT+13': 'Pacific/Tongatapu',
     'GMT-11': 'Pacific/Midway',
-    'GMT-10': 'Pacific/Honolulu'
+    'GMT-10': 'Pacific/Honolulu',
 }
 
 
@@ -127,6 +120,7 @@
     os.remove(alias_path)
   if platform.system() == 'Windows':
     from win32com import client
+
     shell = client.Dispatch('WScript.Shell')
     shortcut = shell.CreateShortCut(alias_path)
     shortcut.Targetpath = target_path
@@ -280,19 +274,23 @@
   while stack:
     pid = stack.pop()
     try:
-      ps_results = subprocess.check_output([
-          'ps',
-          '-o',
-          'pid',
-          '--ppid',
-          str(pid),
-          '--noheaders',
-      ]).decode().strip()
+      ps_results = (
+          subprocess.check_output([
+              'ps',
+              '-o',
+              'pid',
+              '--ppid',
+              str(pid),
+              '--noheaders',
+          ])
+          .decode()
+          .strip()
+      )
     except subprocess.CalledProcessError:
       # Ignore if there is not child process.
       continue
 
-    children_pid_list = list(map(int, ps_results.split('\n ')))
+    children_pid_list = [int(p.strip()) for p in ps_results.split('\n')]
     stack.extend(children_pid_list)
     ret.extend(children_pid_list)
 
@@ -358,7 +356,8 @@
       `raise_on_exception` is True.
   """
   with concurrent.futures.ThreadPoolExecutor(
-      max_workers=max_workers) as executor:
+      max_workers=max_workers
+  ) as executor:
     # Start the load operations and mark each future with its params
     future_to_params = {executor.submit(func, *p): p for p in param_list}
     return_vals = []
@@ -368,55 +367,64 @@
       try:
         return_vals.append(future.result())
       except Exception as exc:  # pylint: disable=broad-except
-        logging.exception('%s generated an exception: %s', params,
-                          traceback.format_exc())
+        logging.exception(
+            '%s generated an exception: %s', params, traceback.format_exc()
+        )
         return_vals.append(exc)
         exceptions.append(exc)
     if raise_on_exception and exceptions:
       error_messages = []
       for exception in exceptions:
-        error_messages.append(''.join(
-            traceback.format_exception(exception.__class__, exception,
-                                       exception.__traceback__)))
+        error_messages.append(
+            ''.join(
+                traceback.format_exception(
+                    exception.__class__, exception, exception.__traceback__
+                )
+            )
+        )
       raise RuntimeError('\n\n'.join(error_messages))
     return return_vals
 
 
 # Provide hint for pytype checker to avoid the Union[bytes, str] case.
 @overload
-def run_command(cmd,
-                stdout=...,
-                stderr=...,
-                shell=...,
-                timeout=...,
-                cwd=...,
-                env=...,
-                universal_newlines: Literal[False] = ...
-               ) -> Tuple[int, bytes, bytes]:
+def run_command(
+    cmd,
+    stdout=...,
+    stderr=...,
+    shell=...,
+    timeout=...,
+    cwd=...,
+    env=...,
+    universal_newlines: Literal[False] = ...,
+) -> Tuple[int, bytes, bytes]:
   ...
 
 
 @overload
-def run_command(cmd,
-                stdout=...,
-                stderr=...,
-                shell=...,
-                timeout=...,
-                cwd=...,
-                env=...,
-                universal_newlines: Literal[True] = ...
-               ) -> Tuple[int, str, str]:
+def run_command(
+    cmd,
+    stdout=...,
+    stderr=...,
+    shell=...,
+    timeout=...,
+    cwd=...,
+    env=...,
+    universal_newlines: Literal[True] = ...,
+) -> Tuple[int, str, str]:
   ...
 
 
-def run_command(cmd,
-                stdout=None,
-                stderr=None,
-                shell=False,
-                timeout=None,
-                cwd=None,
-                env=None,
-                universal_newlines=False):
+def run_command(
+    cmd,
+    stdout=None,
+    stderr=None,
+    shell=False,
+    timeout=None,
+    cwd=None,
+    env=None,
+    universal_newlines=False,
+):
   """Runs a command in a subprocess.
 
   This function is very similar to subprocess.check_output. The main
@@ -457,13 +465,15 @@
     stdout = subprocess.PIPE
   if stderr is None:
     stderr = subprocess.PIPE
-  process = subprocess.Popen(cmd,
-                             stdout=stdout,
-                             stderr=stderr,
-                             shell=shell,
-                             cwd=cwd,
-                             env=env,
-                             universal_newlines=universal_newlines)
+  process = subprocess.Popen(
+      cmd,
+      stdout=stdout,
+      stderr=stderr,
+      shell=shell,
+      cwd=cwd,
+      env=env,
+      universal_newlines=universal_newlines,
+  )
   timer = None
   timer_triggered = threading.Event()
   if timeout and timeout > 0:
@@ -482,10 +492,9 @@
   if timer is not None:
     timer.cancel()
   if timer_triggered.is_set():
-    raise subprocess.TimeoutExpired(cmd=cmd,
-                                    timeout=timeout,
-                                    output=out,
-                                    stderr=err)
+    raise subprocess.TimeoutExpired(
+        cmd=cmd, timeout=timeout, output=out, stderr=err
+    )
   return process.returncode, out, err
 
 
@@ -510,12 +519,14 @@
     The subprocess that was started.
   """
   logging.debug('Starting standing subprocess with: %s', cmd)
-  proc = subprocess.Popen(cmd,
-                          stdin=subprocess.PIPE,
-                          stdout=subprocess.PIPE,
-                          stderr=subprocess.PIPE,
-                          shell=shell,
-                          env=env)
+  proc = subprocess.Popen(
+      cmd,
+      stdin=subprocess.PIPE,
+      stdout=subprocess.PIPE,
+      stderr=subprocess.PIPE,
+      shell=shell,
+      env=env,
+  )
   # Leaving stdin open causes problems for input, e.g. breaking the
   # code.inspect() shell (http://stackoverflow.com/a/25512460/1612937), so
   # explicitly close it assuming it is not needed for standing subprocesses.
@@ -585,6 +596,8 @@
 def get_available_host_port():
   """Gets a host port number available for adb forward.
 
+  DEPRECATED: This method is unreliable. Pass `tcp:0` to adb forward instead.
+
   Returns:
     An integer representing a port number on the host available for adb
     forward.
@@ -592,8 +605,14 @@
   Raises:
     Error: when no port is found after MAX_PORT_ALLOCATION_RETRY times.
   """
+  logging.warning(
+      'The method mobly.utils.get_available_host_port is deprecated because it '
+      'is unreliable. Pass "tcp:0" to adb forward instead.'
+  )
+
   # Only import adb module if needed.
   from mobly.controllers.android_device_lib import adb
+
   port = portpicker.pick_unused_port()
   if not adb.is_adb_available():
     return port
@@ -603,8 +622,11 @@
     if port not in adb.list_occupied_adb_ports():
       return port
     port = portpicker.pick_unused_port()
-  raise Error('Failed to find available port after {} retries'.format(
-      MAX_PORT_ALLOCATION_RETRY))
+  raise Error(
+      'Failed to find available port after {} retries'.format(
+          MAX_PORT_ALLOCATION_RETRY
+      )
+  )
 
 
 def grep(regex, output):
@@ -642,7 +664,7 @@
   if isinstance(args, str):
     # Return directly if it's already a string.
     return args
-  return ' '.join([pipes.quote(arg) for arg in args])
+  return ' '.join([shlex.quote(arg) for arg in args])
 
 
 def get_settable_properties(cls):
@@ -696,6 +718,7 @@
   subclasses = find_subclasses_in_module([base_class], module)
   if len(subclasses) != 1:
     raise ValueError(
-        'Expected 1 subclass of %s per module, found %s.' %
-        (base_class.__name__, [subclass.__name__ for subclass in subclasses]))
+        'Expected 1 subclass of %s per module, found %s.'
+        % (base_class.__name__, [subclass.__name__ for subclass in subclasses])
+    )
   return subclasses[0]
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..47bbbfc
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,44 @@
+[build-system]
+requires = [ "setuptools>=61.2",]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "mobly"
+version = "1.12.3"
+description = "Automation framework for special end-to-end test cases"
+requires-python = ">=3.11"
+dependencies = [ "portpicker", "pywin32; platform_system == \"Windows\"", "pyyaml",]
+
+[[project.maintainers]]
+name = "Ang Li"
+email = "[email protected]"
+
+[project.license]
+text = "Apache2.0"
+
+[project.urls]
+Homepage = "https://github.com/google/mobly"
+Download = "https://github.com/google/mobly/tarball/1.12.3"
+
+[project.optional-dependencies]
+testing = [ "mock", "pytest", "pytz",]
+
+[tool.setuptools]
+include-package-data = false
+script-files = [ "tools/sl4a_shell.py", "tools/snippet_shell.py",]
+
+[tool.pyink]
+line-length = 80
+preview = true
+pyink-indentation = 2
+pyink-use-majority-quotes = true
+extend-exclude = '.*\/venv/.*|.*\/\.tox\/.*'
+
+[tool.pytest.ini_options]
+python_classes = [ "*Test",]
+python_files = [ "*_test.py",]
+testpaths = [ "tests/mobly",]
+
+[tool.setuptools.packages.find]
+exclude = [ "tests",]
+namespaces = false
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 3b9eef9..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,6 +0,0 @@
-[metadata]
-description_file = README.md
-[tool:pytest]
-python_classes = *Test
-python_files = *_test.py
-testpaths = tests/mobly
diff --git a/setup.py b/setup.py
deleted file mode 100755
index e99a054..0000000
--- a/setup.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright 2016 Google Inc.
-#
-# 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 platform
-import setuptools
-from setuptools.command import test
-import sys
-
-install_requires = [
-    'portpicker',
-    'pyyaml',
-    'typing_extensions>=4.1.1; python_version<"3.8"',
-]
-
-if platform.system() == 'Windows':
-  install_requires.append('pywin32')
-
-
-class PyTest(test.test):
-  """Class used to execute unit tests using PyTest. This allows us to execute
-  unit tests without having to install the package.
-  """
-
-  def finalize_options(self):
-    test.test.finalize_options(self)
-    self.test_args = ['-x', "tests/mobly"]
-    self.test_suite = True
-
-  def run_tests(self):
-    import pytest
-    errno = pytest.main(self.test_args)
-    sys.exit(errno)
-
-
-def main():
-  setuptools.setup(
-      name='mobly',
-      version='1.12.2',
-      maintainer='Ang Li',
-      maintainer_email='[email protected]',
-      description='Automation framework for special end-to-end test cases',
-      license='Apache2.0',
-      url='https://github.com/google/mobly',
-      download_url='https://github.com/google/mobly/tarball/1.12.2',
-      packages=setuptools.find_packages(exclude=['tests']),
-      include_package_data=False,
-      scripts=['tools/sl4a_shell.py', 'tools/snippet_shell.py'],
-      tests_require=[
-          'mock',
-          'pytest',
-          'pytz',
-      ],
-      install_requires=install_requires,
-      cmdclass={'test': PyTest},
-  )
-
-
-if __name__ == '__main__':
-  main()
diff --git a/tests/lib/integration_test.py b/tests/lib/integration_test.py
index 0a1cf87..905caa6 100755
--- a/tests/lib/integration_test.py
+++ b/tests/lib/integration_test.py
@@ -28,13 +28,16 @@
   def test_hello_world(self):
     asserts.assert_equal(self.user_params['icecream'], 42)
     asserts.assert_equal(self.user_params['extra_param'], 'haha')
-    logging.info('This is a bare minimal test to make sure the basic MOBLY'
-                 ' test flow works.')
+    logging.info(
+        'This is a bare minimal test to make sure the basic MOBLY'
+        ' test flow works.'
+    )
     asserts.explicit_pass(
         'Hello World',
         # Use a unicode string here to make sure the full log pipeline
         # works with unicode.
-        extras=u'\u2022')
+        extras='\u2022',
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/lib/jsonrpc_client_test_base.py b/tests/lib/jsonrpc_client_test_base.py
index 3124630..7ea0eeb 100755
--- a/tests/lib/jsonrpc_client_test_base.py
+++ b/tests/lib/jsonrpc_client_test_base.py
@@ -26,21 +26,26 @@
 
   MOCK_RESP = (
       b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1, '
-      b'"callback": null}')
+      b'"callback": null}'
+  )
   MOCK_RESP_WITHOUT_CALLBACK = (
-      b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1}')
+      b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1}'
+  )
   MOCK_RESP_TEMPLATE = (
       '{"id": %d, "result": 123, "error": null, "status": 1, "uid": 1, '
-      '"callback": null}')
+      '"callback": null}'
+  )
   MOCK_RESP_UNKNOWN_STATUS = (
-      b'{"id": 0, "result": 123, "error": null, "status": 0, '
-      b'"callback": null}')
+      b'{"id": 0, "result": 123, "error": null, "status": 0, "callback": null}'
+  )
   MOCK_RESP_WITH_CALLBACK = (
       b'{"id": 0, "result": 123, "error": null, "status": 1, "uid": 1, '
-      b'"callback": "1-0"}')
+      b'"callback": "1-0"}'
+  )
   MOCK_RESP_WITH_ERROR = b'{"id": 0, "error": 1, "status": 1, "uid": 1}'
   MOCK_RESP_FLEXIABLE_RESULT_LENGTH = (
-      '{"id": 0, "result": "%s", "error": null, "status": 0, "callback": null}')
+      '{"id": 0, "result": "%s", "error": null, "status": 0, "callback": null}'
+  )
 
   class MockSocketFile:
 
diff --git a/tests/lib/mock_android_device.py b/tests/lib/mock_android_device.py
index 9d14991..cbc61f8 100755
--- a/tests/lib/mock_android_device.py
+++ b/tests/lib/mock_android_device.py
@@ -29,7 +29,7 @@
     'ro.build.version.sdk': '28',
     'ro.product.name': 'FakeModel',
     'ro.debuggable': '1',
-    'sys.boot_completed': "1",
+    'sys.boot_completed': '1',
     'ro.build.characteristics': 'emulator,phone',
     'ro.hardware': 'marlin',
 }
@@ -50,7 +50,7 @@
   """
   ads = []
   for i in range(num):
-    ad = mock.MagicMock(name="AndroidDevice", serial=str(i), h_port=None)
+    ad = mock.MagicMock(name='AndroidDevice', serial=str(i), h_port=None)
     ad.skip_logcat = False
     ads.append(ad)
   return ads
@@ -63,7 +63,7 @@
 def get_instances(serials):
   ads = []
   for serial in serials:
-    ad = mock.MagicMock(name="AndroidDevice", serial=serial, h_port=None)
+    ad = mock.MagicMock(name='AndroidDevice', serial=serial, h_port=None)
     ads.append(ad)
   return ads
 
@@ -79,13 +79,15 @@
 class MockAdbProxy:
   """Mock class that swaps out calls to adb with mock calls."""
 
-  def __init__(self,
-               serial='',
-               fail_br=False,
-               fail_br_before_N=False,
-               mock_properties=None,
-               installed_packages=None,
-               instrumented_packages=None):
+  def __init__(
+      self,
+      serial='',
+      fail_br=False,
+      fail_br_before_N=False,
+      mock_properties=None,
+      installed_packages=None,
+      instrumented_packages=None,
+  ):
     self.serial = serial
     self.fail_br = fail_br
     self.fail_br_before_N = fail_br_before_N
@@ -103,28 +105,31 @@
     self.instrumented_packages = instrumented_packages
 
   def shell(self, params, timeout=None):
-    if params == "id -u":
-      return b"root"
-    elif params == "bugreportz":
+    if params == 'id -u':
+      return b'root'
+    elif params == 'bugreportz':
       if self.fail_br:
-        return b"OMG I died!\n"
+        return b'OMG I died!\n'
       return b'OK:/path/bugreport.zip\n'
-    elif params == "bugreportz -v":
+    elif params == 'bugreportz -v':
       if self.fail_br_before_N:
-        return b"/system/bin/sh: bugreportz: not found"
+        return b'/system/bin/sh: bugreportz: not found'
       return b'1.1'
     elif 'pm list package' in params:
       packages = self.installed_packages + [
           package for package, _, _ in self.instrumented_packages
       ]
-      return bytes('\n'.join(['package:%s' % package for package in packages]),
-                   'utf-8')
+      return bytes(
+          '\n'.join(['package:%s' % package for package in packages]), 'utf-8'
+      )
     elif 'pm list instrumentation' in params:
       return bytes(
           '\n'.join([
               'instrumentation:%s/%s (target=%s)' % (package, runner, target)
               for package, runner, target in self.instrumented_packages
-          ]), 'utf-8')
+          ]),
+          'utf-8',
+      )
     elif 'which' in params:
       return b''
 
@@ -138,8 +143,11 @@
 
   def bugreport(self, args, shell=False, timeout=None):
     expected = os.path.join(
-        logging.log_path, 'AndroidDevice%s' % self.serial, 'BugReports',
-        'bugreport,test_something,%s,fakemodel,sometime' % self.serial)
+        logging.log_path,
+        'AndroidDevice%s' % self.serial,
+        'BugReports',
+        'bugreport,test_something,%s,fakemodel,sometime' % self.serial,
+    )
     if expected not in args:
       raise Error('"Expected "%s", got "%s"' % (expected, args))
 
@@ -162,10 +170,9 @@
     self.serial = serial
 
   def devices(self):
-    return b"xxxx device\nyyyy device"
+    return b'xxxx device\nyyyy device'
 
   def __getattr__(self, name):
-
     def fastboot_call(*args):
       arg_str = ' '.join(str(elem) for elem in args)
       return arg_str
diff --git a/tests/lib/mock_instrumentation_test.py b/tests/lib/mock_instrumentation_test.py
index be3d90e..ee1ee6a 100644
--- a/tests/lib/mock_instrumentation_test.py
+++ b/tests/lib/mock_instrumentation_test.py
@@ -24,7 +24,8 @@
 
 
 class MockInstrumentationTest(
-    base_instrumentation_test.BaseInstrumentationTestClass):
+    base_instrumentation_test.BaseInstrumentationTestClass
+):
 
   def __init__(self, tmp_dir, user_params={}):
     mock_test_run_configs = config_parser.TestRunConfig()
@@ -35,7 +36,6 @@
     super().__init__(mock_test_run_configs)
 
   def run_mock_instrumentation_test(self, instrumentation_output, prefix):
-
     def fake_instrument(package, options=None, runner=None, handler=None):
       for line in instrumentation_output.splitlines():
         handler(line)
@@ -44,6 +44,6 @@
     mock_device = mock.Mock(spec=android_device.AndroidDevice)
     mock_device.adb = mock.Mock(spec=adb.AdbProxy)
     mock_device.adb.instrument = fake_instrument
-    return self.run_instrumentation_test(mock_device,
-                                         MOCK_TEST_PACKAGE,
-                                         prefix=prefix)
+    return self.run_instrumentation_test(
+        mock_device, MOCK_TEST_PACKAGE, prefix=prefix
+    )
diff --git a/tests/lib/mock_second_controller.py b/tests/lib/mock_second_controller.py
index 3f32349..aef70b3 100644
--- a/tests/lib/mock_second_controller.py
+++ b/tests/lib/mock_second_controller.py
@@ -54,7 +54,7 @@
     return self.magic
 
   def set_magic(self, extra_magic):
-    self.magic['extra_magic'] = extra_magic
+    self.magic["extra_magic"] = extra_magic
 
   def who_am_i(self):
     return {"MyOtherMagic": self.magic}
diff --git a/tests/lib/utils.py b/tests/lib/utils.py
index 904459c..3bbe43c 100644
--- a/tests/lib/utils.py
+++ b/tests/lib/utils.py
@@ -34,5 +34,6 @@
   for bucket_list, expected_enum in buckets:
     for record in bucket_list:
       if record.result != expected_enum:
-        raise AssertionError('Expected result %s, got %s.' %
-                             (expected_enum, record.result))
+        raise AssertionError(
+            'Expected result %s, got %s.' % (expected_enum, record.result)
+        )
diff --git a/tests/mobly/asserts_test.py b/tests/mobly/asserts_test.py
index 662173f..3713185 100755
--- a/tests/mobly/asserts_test.py
+++ b/tests/mobly/asserts_test.py
@@ -58,11 +58,9 @@
 
   def test_assert_almost_equal_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
-      asserts.assert_almost_equal(1,
-                                  2,
-                                  delta=0.1,
-                                  msg='Message',
-                                  extras='Extras')
+      asserts.assert_almost_equal(
+          1, 2, delta=0.1, msg='Message', extras='Extras'
+      )
     self.assertRegex(cm.exception.details, r'1 != 2 within 0\.1 delta.*Message')
     self.assertEqual(cm.exception.extras, 'Extras')
 
@@ -77,11 +75,9 @@
 
   def test_assert_not_almost_equal_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
-      asserts.assert_not_almost_equal(1,
-                                      2,
-                                      delta=1,
-                                      msg='Message',
-                                      extras='Extras')
+      asserts.assert_not_almost_equal(
+          1, 2, delta=1, msg='Message', extras='Extras'
+      )
     self.assertRegex(cm.exception.details, r'1 == 2 within 1 delta.*Message')
     self.assertEqual(cm.exception.extras, 'Extras')
 
@@ -116,8 +112,9 @@
   def test_assert_not_in_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_not_in(1, [1, 2, 3], msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     '1 unexpectedly found in [1, 2, 3] Message')
+    self.assertEqual(
+        cm.exception.details, '1 unexpectedly found in [1, 2, 3] Message'
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_is_pass(self):
@@ -131,8 +128,9 @@
   def test_assert_is_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_is(_OBJECT_1, _OBJECT_2, msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     f'{_OBJECT_1} is not {_OBJECT_2} Message')
+    self.assertEqual(
+        cm.exception.details, f'{_OBJECT_1} is not {_OBJECT_2} Message'
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_is_not_pass(self):
@@ -141,17 +139,18 @@
   def test_assert_is_not_fail(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_is_not(_OBJECT_1, _OBJECT_1)
-    self.assertEqual(cm.exception.details,
-                     f'unexpectedly identical: {_OBJECT_1}')
+    self.assertEqual(
+        cm.exception.details, f'unexpectedly identical: {_OBJECT_1}'
+    )
 
   def test_assert_is_not_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
-      asserts.assert_is_not(_OBJECT_1,
-                            _OBJECT_1,
-                            msg='Message',
-                            extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     f'unexpectedly identical: {_OBJECT_1} Message')
+      asserts.assert_is_not(
+          _OBJECT_1, _OBJECT_1, msg='Message', extras='Extras'
+      )
+    self.assertEqual(
+        cm.exception.details, f'unexpectedly identical: {_OBJECT_1} Message'
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_count_equal_pass(self):
@@ -162,15 +161,20 @@
       asserts.assert_count_equal([3, 3], [3])
     self.assertEqual(
         cm.exception.details,
-        'Element counts were not equal:\nFirst has 2, Second has 1:  3')
+        'Element counts were not equal:\nFirst has 2, Second has 1:  3',
+    )
 
   def test_assert_count_equal_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_count_equal((3, 3), (4, 4), msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     ('Element counts were not equal:\n'
-                      'First has 2, Second has 0:  3\n'
-                      'First has 0, Second has 2:  4 Message'))
+    self.assertEqual(
+        cm.exception.details,
+        (
+            'Element counts were not equal:\n'
+            'First has 2, Second has 0:  3\n'
+            'First has 0, Second has 2:  4 Message'
+        ),
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_less_pass(self):
@@ -199,8 +203,9 @@
   def test_assert_less_equal_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_less_equal(2, 1, msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     '2 not less than or equal to 1 Message')
+    self.assertEqual(
+        cm.exception.details, '2 not less than or equal to 1 Message'
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_greater_pass(self):
@@ -229,8 +234,9 @@
   def test_assert_greater_equal_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_greater_equal(1, 2, msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     '1 not greater than or equal to 2 Message')
+    self.assertEqual(
+        cm.exception.details, '1 not greater than or equal to 2 Message'
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_is_none_pass(self):
@@ -274,8 +280,9 @@
   def test_assert_is_instance_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_is_instance(1.0, int, msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     f'1.0 is not an instance of {int} Message')
+    self.assertEqual(
+        cm.exception.details, f'1.0 is not an instance of {int} Message'
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_not_is_instance_pass(self):
@@ -291,8 +298,9 @@
   def test_assert_not_is_instance_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
       asserts.assert_not_is_instance('foo', str, msg='Message', extras='Extras')
-    self.assertEqual(cm.exception.details,
-                     f"'foo' is an instance of {str} Message")
+    self.assertEqual(
+        cm.exception.details, f"'foo' is an instance of {str} Message"
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_regex_pass(self):
@@ -303,18 +311,18 @@
       asserts.assert_regex('Big socks', r'(r|m)ocks')
     self.assertEqual(
         cm.exception.details,
-        "Regex didn't match: '(r|m)ocks' not found in 'Big socks'")
+        "Regex didn't match: '(r|m)ocks' not found in 'Big socks'",
+    )
 
   def test_assert_regex_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
-      asserts.assert_regex('Big socks',
-                           r'(r|m)ocks',
-                           msg='Message',
-                           extras='Extras')
+      asserts.assert_regex(
+          'Big socks', r'(r|m)ocks', msg='Message', extras='Extras'
+      )
     self.assertEqual(
         cm.exception.details,
-        ("Regex didn't match: '(r|m)ocks' not found in 'Big socks' "
-         'Message'))
+        "Regex didn't match: '(r|m)ocks' not found in 'Big socks' Message",
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
   def test_assert_not_regex_pass(self):
@@ -325,18 +333,18 @@
       asserts.assert_not_regex('Big rocks', r'(r|m)ocks')
     self.assertEqual(
         cm.exception.details,
-        "Regex matched: 'rocks' matches '(r|m)ocks' in 'Big rocks'")
+        "Regex matched: 'rocks' matches '(r|m)ocks' in 'Big rocks'",
+    )
 
   def test_assert_not_regex_fail_with_msg_and_extras(self):
     with self.assertRaises(signals.TestFailure) as cm:
-      asserts.assert_not_regex('Big mocks',
-                               r'(r|m)ocks',
-                               msg='Message',
-                               extras='Extras')
+      asserts.assert_not_regex(
+          'Big mocks', r'(r|m)ocks', msg='Message', extras='Extras'
+      )
     self.assertEqual(
         cm.exception.details,
-        ("Regex matched: 'mocks' matches '(r|m)ocks' in 'Big mocks' "
-         'Message'))
+        "Regex matched: 'mocks' matches '(r|m)ocks' in 'Big mocks' Message",
+    )
     self.assertEqual(cm.exception.extras, 'Extras')
 
 
diff --git a/tests/mobly/base_instrumentation_test_test.py b/tests/mobly/base_instrumentation_test_test.py
index c336b90..fcf52fb 100755
--- a/tests/mobly/base_instrumentation_test_test.py
+++ b/tests/mobly/base_instrumentation_test_test.py
@@ -57,10 +57,12 @@
   def tearDown(self):
     shutil.rmtree(self.tmp_dir)
 
-  def assert_parse_instrumentation_options(self, user_params,
-                                           expected_instrumentation_options):
+  def assert_parse_instrumentation_options(
+      self, user_params, expected_instrumentation_options
+  ):
     mit = mock_instrumentation_test.MockInstrumentationTest(
-        self.tmp_dir, user_params)
+        self.tmp_dir, user_params
+    )
     instrumentation_options = mit.parse_instrumentation_options(mit.user_params)
     self.assertEqual(instrumentation_options, expected_instrumentation_options)
 
@@ -82,10 +84,7 @@
             'instrumentation_option_key1': 'value1',
             'instrumentation_option_key2': 'value2',
         },
-        {
-            'key1': 'value1',
-            'key2': 'value2'
-        },
+        {'key1': 'value1', 'key2': 'value2'},
     )
 
   def test_parse_instrumentation_options_with_mixed_user_params(self):
@@ -96,10 +95,7 @@
             'instrumentation_option_key1': 'value1',
             'instrumentation_option_key2': 'value2',
         },
-        {
-            'key1': 'value1',
-            'key2': 'value2'
-        },
+        {'key1': 'value1', 'key2': 'value2'},
     )
 
   def run_instrumentation_test(self, instrumentation_output, prefix=None):
@@ -107,7 +103,8 @@
     result = InstrumentationResult()
     try:
       result.completed_and_passed = mit.run_mock_instrumentation_test(
-          instrumentation_output, prefix=prefix)
+          instrumentation_output, prefix=prefix
+      )
     except signals.TestError as e:
       result.error = e
     result.executed = mit.results.executed
@@ -116,29 +113,34 @@
 
   def assert_equal_test(self, actual_test, expected_test):
     (expected_test_name, expected_signal) = expected_test
-    self.assertEqual(actual_test.test_class,
-                     MOCK_INSTRUMENTATION_TEST_CLASS_NAME)
+    self.assertEqual(
+        actual_test.test_class, MOCK_INSTRUMENTATION_TEST_CLASS_NAME
+    )
     self.assertEqual(actual_test.test_name, expected_test_name)
-    self.assertIsInstance(actual_test.termination_signal.exception,
-                          expected_signal)
+    self.assertIsInstance(
+        actual_test.termination_signal.exception, expected_signal
+    )
 
-  def assert_run_instrumentation_test(self,
-                                      instrumentation_output,
-                                      expected_executed=[],
-                                      expected_skipped=[],
-                                      expected_completed_and_passed=False,
-                                      expected_has_error=False,
-                                      prefix=None,
-                                      expected_executed_times=[]):
-    result = self.run_instrumentation_test(bytes(instrumentation_output,
-                                                 'utf-8'),
-                                           prefix=prefix)
+  def assert_run_instrumentation_test(
+      self,
+      instrumentation_output,
+      expected_executed=[],
+      expected_skipped=[],
+      expected_completed_and_passed=False,
+      expected_has_error=False,
+      prefix=None,
+      expected_executed_times=[],
+  ):
+    result = self.run_instrumentation_test(
+        bytes(instrumentation_output, 'utf-8'), prefix=prefix
+    )
     if expected_has_error:
       self.assertIsInstance(result.error, signals.TestError)
     else:
       self.assertIsNone(result.error)
-      self.assertEqual(result.completed_and_passed,
-                       expected_completed_and_passed)
+      self.assertEqual(
+          result.completed_and_passed, expected_completed_and_passed
+      )
     self.assertEqual(len(result.executed), len(expected_executed))
     for actual_test, expected_test in zip(result.executed, expected_executed):
       self.assert_equal_test(actual_test, expected_test)
@@ -146,8 +148,9 @@
     for actual_test, expected_test in zip(result.skipped, expected_skipped):
       self.assert_equal_test(actual_test, expected_test)
     if expected_executed_times:
-      for actual_test, expected_time in zip(result.executed,
-                                            expected_executed_times):
+      for actual_test, expected_time in zip(
+          result.executed, expected_executed_times
+      ):
         (expected_begin_time, expected_end_time) = expected_time
         self.assertEqual(actual_test.begin_time, expected_begin_time)
         self.assertEqual(actual_test.end_time, expected_end_time)
@@ -173,14 +176,16 @@
 
 Error: Bad component name: /
 """
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_has_error=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_has_error=True
+    )
 
   def test_run_instrumentation_test_with_no_output(self):
     instrumentation_output = """\
 """
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_has_error=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_has_error=True
+    )
 
   def test_run_instrumentation_test_with_missing_test_package(self):
     instrumentation_output = """\
@@ -194,8 +199,9 @@
 INSTRUMENTATION_STATUS: id=ActivityManagerService
 INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.my.package.test/com.my.package.test.runner.MyRunner}
 INSTRUMENTATION_STATUS_CODE: -1"""
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_has_error=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_has_error=True
+    )
 
   def test_run_instrumentation_test_with_missing_runner(self):
     instrumentation_output = """\
@@ -209,19 +215,22 @@
   at com.android.commands.am.Am.main(Am.java:124)
   at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
   at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:262)"""
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_has_error=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_has_error=True
+    )
 
   def test_run_instrumentation_test_with_no_tests(self):
     instrumentation_output = MOCK_EMPTY_INSTRUMENTATION_TEST
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_completed_and_passed=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_completed_and_passed=True
+    )
 
   @mock.patch('logging.info')
   def test_run_instrumentation_test_logs_correctly(self, mock_info_logger):
     instrumentation_output = MOCK_EMPTY_INSTRUMENTATION_TEST
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_completed_and_passed=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_completed_and_passed=True
+    )
     for mock_call in mock_info_logger.mock_calls:
       logged_format = mock_call[1][0]
       self.assertIsInstance(logged_format, str)
@@ -257,10 +266,12 @@
         ('com.my.package.test.BasicTest#basicTest', signals.TestPass),
     ]
     mock_get_time.side_effect = [13, 51]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_completed_and_passed=True,
-                                         expected_executed_times=[(13, 51)])
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_completed_and_passed=True,
+        expected_executed_times=[(13, 51)],
+    )
 
   def test_run_instrumentation_test_with_random_whitespace(self):
     instrumentation_output = """\
@@ -312,9 +323,11 @@
     expected_executed = [
         ('com.my.package.test.BasicTest#basicTest', signals.TestPass),
     ]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_completed_and_passed=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_completed_and_passed=True,
+    )
 
   def test_run_instrumentation_test_with_prefix_test(self):
     instrumentation_output = """\
@@ -343,13 +356,17 @@
 INSTRUMENTATION_CODE: -1
 """
     expected_executed = [
-        ('%s.com.my.package.test.BasicTest#basicTest' % MOCK_PREFIX,
-         signals.TestPass),
+        (
+            '%s.com.my.package.test.BasicTest#basicTest' % MOCK_PREFIX,
+            signals.TestPass,
+        ),
     ]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_completed_and_passed=True,
-                                         prefix=MOCK_PREFIX)
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_completed_and_passed=True,
+        prefix=MOCK_PREFIX,
+    )
 
   def test_run_instrumentation_test_with_failing_test(self):
     instrumentation_output = """\
@@ -535,8 +552,9 @@
     expected_executed = [
         ('com.my.package.test.BasicTest#failingTest', signals.TestFailure),
     ]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_executed=expected_executed
+    )
 
   def test_run_instrumentation_test_with_assumption_failure_test(self):
     instrumentation_output = """\
@@ -618,12 +636,16 @@
 
 INSTRUMENTATION_CODE: -1"""
     expected_skipped = [
-        ('com.my.package.test.BasicTest#assumptionFailureTest',
-         signals.TestSkip),
+        (
+            'com.my.package.test.BasicTest#assumptionFailureTest',
+            signals.TestSkip,
+        ),
     ]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_skipped=expected_skipped,
-                                         expected_completed_and_passed=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_skipped=expected_skipped,
+        expected_completed_and_passed=True,
+    )
 
   def test_run_instrumentation_test_with_ignored_test(self):
     instrumentation_output = """\
@@ -654,9 +676,11 @@
     expected_skipped = [
         ('com.my.package.test.BasicTest#ignoredTest', signals.TestSkip),
     ]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_skipped=expected_skipped,
-                                         expected_completed_and_passed=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_skipped=expected_skipped,
+        expected_completed_and_passed=True,
+    )
 
   @mock.patch('mobly.utils.get_current_epoch_time')
   def test_run_instrumentation_test_with_crashed_test(self, mock_get_time):
@@ -675,10 +699,12 @@
         ('com.my.package.test.BasicTest#crashTest', signals.TestError),
     ]
     mock_get_time.side_effect = [67, 942]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_has_error=True,
-                                         expected_executed_times=[(67, 942)])
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_has_error=True,
+        expected_executed_times=[(67, 942)],
+    )
 
   @mock.patch('mobly.utils.get_current_epoch_time')
   def test_run_instrumentation_test_with_crashing_test(self, mock_get_time):
@@ -708,25 +734,31 @@
 
 INSTRUMENTATION_CODE: -1"""
     expected_executed = [
-        ('com.my.package.test.BasicTest#crashAndRecover1Test',
-         signals.TestError),
-        ('com.my.package.test.BasicTest#crashAndRecover2Test',
-         signals.TestError),
+        (
+            'com.my.package.test.BasicTest#crashAndRecover1Test',
+            signals.TestError,
+        ),
+        (
+            'com.my.package.test.BasicTest#crashAndRecover2Test',
+            signals.TestError,
+        ),
     ]
     mock_get_time.side_effect = [16, 412, 4143, 6547]
     # TODO(winterfrosts): Fix this issue with overlapping timing
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_completed_and_passed=True,
-                                         expected_executed_times=[(16, 4143),
-                                                                  (412, 6547)])
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_completed_and_passed=True,
+        expected_executed_times=[(16, 4143), (412, 6547)],
+    )
 
   def test_run_instrumentation_test_with_runner_setup_crash(self):
     instrumentation_output = """\
 INSTRUMENTATION_RESULT: shortMsg=Process crashed.
 INSTRUMENTATION_CODE: 0"""
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_has_error=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output, expected_has_error=True
+    )
 
   def test_run_instrumentation_test_with_runner_teardown_crash(self):
     instrumentation_output = """\
@@ -751,9 +783,11 @@
     expected_executed = [
         ('com.my.package.test.BasicTest#basicTest', signals.TestPass),
     ]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_has_error=True)
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_has_error=True,
+    )
 
   @mock.patch('mobly.utils.get_current_epoch_time')
   def test_run_instrumentation_test_with_multiple_tests(self, mock_get_time):
@@ -1036,24 +1070,28 @@
         ('com.my.package.test.BasicTest#passingTest', signals.TestPass),
     ]
     expected_skipped = [
-        ('com.my.package.test.BasicTest#assumptionFailureTest',
-         signals.TestSkip),
+        (
+            'com.my.package.test.BasicTest#assumptionFailureTest',
+            signals.TestSkip,
+        ),
         ('com.my.package.test.BasicTest#ignoredTest', signals.TestSkip),
     ]
     mock_get_time.side_effect = [54, 64, -1, -1, -1, -1, 89, 94]
-    self.assert_run_instrumentation_test(instrumentation_output,
-                                         expected_executed=expected_executed,
-                                         expected_skipped=expected_skipped,
-                                         expected_executed_times=[(54, 64),
-                                                                  (89, 94)])
+    self.assert_run_instrumentation_test(
+        instrumentation_output,
+        expected_executed=expected_executed,
+        expected_skipped=expected_skipped,
+        expected_executed_times=[(54, 64), (89, 94)],
+    )
 
   def test__Instrumentation_block_set_key_on_multiple_equals_sign(self):
-    value = "blah=blah, blah2=blah2, blah=2=1=2"
-    parsed_line = "INSTRUMENTATION_STATUS: stack=%s" % value
+    value = 'blah=blah, blah2=blah2, blah=2=1=2'
+    parsed_line = 'INSTRUMENTATION_STATUS: stack=%s' % value
     block = _InstrumentationBlock()
     block.set_key(_InstrumentationStructurePrefixes.STATUS, parsed_line)
-    self.assertIn(value,
-                  block.known_keys[_InstrumentationKnownStatusKeys.STACK])
+    self.assertIn(
+        value, block.known_keys[_InstrumentationKnownStatusKeys.STACK]
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/base_test_test.py b/tests/mobly/base_test_test.py
index b166357..bfc7b75 100755
--- a/tests/mobly/base_test_test.py
+++ b/tests/mobly/base_test_test.py
@@ -33,11 +33,11 @@
 from tests.lib import mock_second_controller
 import yaml
 
-MSG_EXPECTED_EXCEPTION = "This is an expected exception."
-MSG_EXPECTED_TEST_FAILURE = "This is an expected test failure."
-MSG_UNEXPECTED_EXCEPTION = "Unexpected exception!"
+MSG_EXPECTED_EXCEPTION = 'This is an expected exception.'
+MSG_EXPECTED_TEST_FAILURE = 'This is an expected test failure.'
+MSG_UNEXPECTED_EXCEPTION = 'Unexpected exception!'
 
-MOCK_EXTRA = {"key": "value", "answer_to_everything": 42}
+MOCK_EXTRA = {'key': 'value', 'answer_to_everything': 42}
 
 
 def never_call():
@@ -55,18 +55,19 @@
     self.mock_test_cls_configs = config_parser.TestRunConfig()
     self.summary_file = os.path.join(self.tmp_dir, 'summary.yaml')
     self.mock_test_cls_configs.summary_writer = records.TestSummaryWriter(
-        self.summary_file)
+        self.summary_file
+    )
     self.mock_test_cls_configs.controller_configs = {}
     self.mock_test_cls_configs.log_path = self.tmp_dir
-    self.mock_test_cls_configs.user_params = {"some_param": "hahaha"}
+    self.mock_test_cls_configs.user_params = {'some_param': 'hahaha'}
     self.mock_test_cls_configs.reporter = mock.MagicMock()
-    self.mock_test_name = "test_something"
+    self.mock_test_name = 'test_something'
 
   def tearDown(self):
     shutil.rmtree(self.tmp_dir)
 
   def test_paths(self):
-    '''Checks the output paths set in `BaseTestClass`.'''
+    """Checks the output paths set in `BaseTestClass`."""
     path_checker = mock.MagicMock()
 
     class MockBaseTest(base_test.BaseTestClass):
@@ -76,7 +77,7 @@
         path_checker.root_output_path = self.root_output_path
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     self.assertEqual(path_checker.root_output_path, self.tmp_dir)
     self.assertTrue(os.path.exists(path_checker.root_output_path))
     expected_log_path = os.path.join(self.tmp_dir, 'MockBaseTest')
@@ -84,33 +85,33 @@
     self.assertTrue(os.path.exists(path_checker.log_path))
 
   def test_current_test_name(self):
-
-    class MockBaseTest(base_test.BaseTestClass):
-
-      def test_func(self):
-        asserts.assert_true(self.current_test_info.name == "test_func",
-                            ("Got "
-                             "unexpected test name %s.") %
-                            self.current_test_info.name)
-
-    bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
-    actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
-    self.assertIsNone(actual_record.details)
-    self.assertIsNone(actual_record.extras)
-
-  def test_current_test_info(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
         asserts.assert_true(
             self.current_test_info.name == 'test_func',
-            'Got unexpected test name %s.' % self.current_test_info.name)
+            'Got unexpected test name %s.' % self.current_test_info.name,
+        )
+
+    bt_cls = MockBaseTest(self.mock_test_cls_configs)
+    bt_cls.run(test_names=['test_func'])
+    actual_record = bt_cls.results.passed[0]
+    self.assertEqual(actual_record.test_name, 'test_func')
+    self.assertIsNone(actual_record.details)
+    self.assertIsNone(actual_record.extras)
+
+  def test_current_test_info(self):
+    class MockBaseTest(base_test.BaseTestClass):
+
+      def test_func(self):
+        asserts.assert_true(
+            self.current_test_info.name == 'test_func',
+            'Got unexpected test name %s.' % self.current_test_info.name,
+        )
         output_path = self.current_test_info.output_path
-        asserts.assert_true(os.path.exists(output_path),
-                            'test output path missing')
+        asserts.assert_true(
+            os.path.exists(output_path), 'test output path missing'
+        )
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run(test_names=['test_func'])
@@ -120,16 +121,17 @@
     self.assertIsNone(actual_record.extras)
 
   def test_current_test_info_in_setup_class(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_class(self):
         asserts.assert_true(
             self.current_test_info.name == 'setup_class',
-            'Got unexpected test name %s.' % self.current_test_info.name)
+            'Got unexpected test name %s.' % self.current_test_info.name,
+        )
         output_path = self.current_test_info.output_path
-        asserts.assert_true(os.path.exists(output_path),
-                            'test output path missing')
+        asserts.assert_true(
+            os.path.exists(output_path), 'test output path missing'
+        )
         raise Exception(MSG_EXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
@@ -140,12 +142,11 @@
     self.assertIsNone(actual_record.extras)
 
   def test_self_tests_list(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def __init__(self, controllers):
         super().__init__(controllers)
-        self.tests = ("test_something",)
+        self.tests = ('test_something',)
 
       def test_something(self):
         pass
@@ -157,15 +158,14 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_something")
+    self.assertEqual(actual_record.test_name, 'test_something')
 
   def test_self_tests_list_fail_by_convention(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def __init__(self, controllers):
         super().__init__(controllers)
-        self.tests = ("not_a_test_something",)
+        self.tests = ('not_a_test_something',)
 
       def not_a_test_something(self):
         pass
@@ -175,18 +175,19 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    expected_msg = (r'Test method name not_a_test_something does not follow '
-                    r'naming convention test_\*, abort.')
+    expected_msg = (
+        r'Test method name not_a_test_something does not follow '
+        r'naming convention test_\*, abort.'
+    )
     with self.assertRaisesRegex(base_test.Error, expected_msg):
       bt_cls.run()
 
   def test_cli_test_selection_override_self_tests_list(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def __init__(self, controllers):
         super().__init__(controllers)
-        self.tests = ("test_never",)
+        self.tests = ('test_never',)
 
       def test_something(self):
         pass
@@ -196,17 +197,16 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_something"])
+    bt_cls.run(test_names=['test_something'])
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_something")
+    self.assertEqual(actual_record.test_name, 'test_something')
 
   def test_cli_test_selection_fail_by_convention(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def __init__(self, controllers):
         super().__init__(controllers)
-        self.tests = ("not_a_test_something",)
+        self.tests = ('not_a_test_something',)
 
       def not_a_test_something(self):
         pass
@@ -216,13 +216,14 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    expected_msg = (r'Test method name not_a_test_something does not follow '
-                    r'naming convention test_\*, abort.')
+    expected_msg = (
+        r'Test method name not_a_test_something does not follow '
+        r'naming convention test_\*, abort.'
+    )
     with self.assertRaisesRegex(base_test.Error, expected_msg):
-      bt_cls.run(test_names=["not_a_test_something"])
+      bt_cls.run(test_names=['not_a_test_something'])
 
   def test_default_execution_of_all_tests(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_something(self):
@@ -236,7 +237,7 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_something")
+    self.assertEqual(actual_record.test_name, 'test_something')
 
   def test_default_execution_skip_noncallable_tests(self):
     mock_decorated = mock.MagicMock()
@@ -268,13 +269,13 @@
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    self.assertNotIn('test_noncallable',
-                     [test.test_name for test in bt_cls.results.executed])
+    self.assertNotIn(
+        'test_noncallable', [test.test_name for test in bt_cls.results.executed]
+    )
     mock_decorated.assert_called_once_with('test_decorated')
     mock_undecorated.assert_called_once_with('test_undecorated')
 
   def test_get_existing_tests_do_not_call_properties(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_something(self):
@@ -289,14 +290,13 @@
     bt_cls.run()
 
   def test_missing_requested_test_func(self):
-
     class MockBaseTest(base_test.BaseTestClass):
       pass
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    expected_msg = ".* does not have test method test_something"
+    expected_msg = '.* does not have test method test_something'
     with self.assertRaisesRegex(base_test.Error, expected_msg):
-      bt_cls.run(test_names=["test_something"])
+      bt_cls.run(test_names=['test_something'])
     self.assertFalse(bt_cls.results.executed)
 
   def test_setup_class_fail_by_exception(self):
@@ -320,10 +320,10 @@
         # This should execute because the setup_class failure should
         # have already been recorded.
         if not self.results.is_all_pass:
-          teardown_class_call_check("heehee")
+          teardown_class_call_check('heehee')
 
       def on_fail(self, record):
-        on_fail_call_check("haha")
+        on_fail_call_check('haha')
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
@@ -332,23 +332,27 @@
     self.assertIsNone(skipped_record.begin_time)
     self.assertIsNone(skipped_record.end_time)
     utils.validate_test_result(bt_cls.results)
-    self.assertEqual(actual_record.test_name, "setup_class")
+    self.assertEqual(actual_record.test_name, 'setup_class')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
-                        "Requested 2, Skipped 2")
+    expected_summary = (
+        'Error 1, Executed 0, Failed 0, Passed 0, Requested 2, Skipped 2'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
-    teardown_class_call_check.assert_called_once_with("heehee")
-    on_fail_call_check.assert_called_once_with("haha")
+    teardown_class_call_check.assert_called_once_with('heehee')
+    on_fail_call_check.assert_called_once_with('haha')
 
   def test_teardown_class_fail_by_exception(self):
     mock_test_config = self.mock_test_cls_configs.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    mock_ctrlr_2_config_name = (
+        mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    )
     my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
-        my_config)
+        my_config
+    )
 
     class MockBaseTest(base_test.BaseTestClass):
 
@@ -371,8 +375,9 @@
     self.assertIsNotNone(class_record.begin_time)
     self.assertIsNotNone(class_record.end_time)
     self.assertIsNone(class_record.extras)
-    expected_summary = ('Error 1, Executed 1, Failed 0, Passed 1, '
-                        'Requested 1, Skipped 0')
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 1, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
     # Verify the controller info is recorded correctly.
     info = bt_cls.results.controller_info[0]
@@ -383,11 +388,14 @@
   def test_teardown_class_raise_abort_all(self):
     mock_test_config = self.mock_test_cls_configs.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    mock_ctrlr_2_config_name = (
+        mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    )
     my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
-        my_config)
+        my_config
+    )
 
     class MockBaseTest(base_test.BaseTestClass):
 
@@ -405,8 +413,9 @@
       bt_cls.run()
     test_record = bt_cls.results.passed[0]
     self.assertTrue(bt_cls.results.is_all_pass)
-    expected_summary = ('Error 0, Executed 1, Failed 0, Passed 1, '
-                        'Requested 1, Skipped 0')
+    expected_summary = (
+        'Error 0, Executed 1, Failed 0, Passed 1, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
     # Verify the controller info is recorded correctly.
     info = bt_cls.results.controller_info[0]
@@ -430,7 +439,7 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_something"])
+    bt_cls.run(test_names=['test_something'])
     mock_on_fail.assert_called_once_with('on_fail')
     actual_record = bt_cls.results.error[0]
     self.assertEqual(actual_record.test_name, self.mock_test_name)
@@ -438,14 +447,16 @@
     self.assertIn(
         'in setup_test\n    '
         'raise Exception(MSG_EXPECTED_EXCEPTION)\n'
-        'Exception: This is an expected exception.\n', actual_record.stacktrace)
+        'Exception: This is an expected exception.\n',
+        actual_record.stacktrace,
+    )
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_setup_test_fail_by_test_signal(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_test(self):
@@ -456,7 +467,7 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_something"])
+    bt_cls.run(test_names=['test_something'])
     actual_record = bt_cls.results.error[0]
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
@@ -464,12 +475,12 @@
     self.assertTrue('self.setup_test()' in actual_record.stacktrace)
     self.assertIsNone(actual_record.extras)
     self.assertTrue(actual_record.end_time)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_teardown_test_assert_fail(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def teardown_test(self):
@@ -485,12 +496,12 @@
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertTrue(actual_record.end_time)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_teardown_test_raise_exception(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def teardown_test(self):
@@ -506,12 +517,12 @@
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
     self.assertFalse(actual_record.extra_errors)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_teardown_test_expects_error(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def teardown_test(self):
@@ -528,8 +539,9 @@
     self.assertIsNone(actual_record.extras)
     self.assertFalse(actual_record.extra_errors)
     self.assertTrue(actual_record.end_time)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_teardown_test_executed_if_test_pass(self):
@@ -538,7 +550,7 @@
     class MockBaseTest(base_test.BaseTestClass):
 
       def teardown_test(self):
-        my_mock("teardown_test")
+        my_mock('teardown_test')
 
       def test_something(self):
         pass
@@ -546,13 +558,14 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.passed[0]
-    my_mock.assert_called_once_with("teardown_test")
+    my_mock.assert_called_once_with('teardown_test')
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertIsNone(actual_record.details)
     self.assertIsNone(actual_record.extras)
     self.assertTrue(actual_record.end_time)
-    expected_summary = ("Error 0, Executed 1, Failed 0, Passed 1, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 0, Executed 1, Failed 0, Passed 1, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_teardown_test_executed_if_setup_test_fails(self):
@@ -564,7 +577,7 @@
         raise Exception(MSG_EXPECTED_EXCEPTION)
 
       def teardown_test(self):
-        my_mock("teardown_test")
+        my_mock('teardown_test')
 
       def test_something(self):
         pass
@@ -572,13 +585,14 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    my_mock.assert_called_once_with("teardown_test")
+    my_mock.assert_called_once_with('teardown_test')
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
     self.assertTrue(actual_record.end_time)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_teardown_test_executed_if_test_fails(self):
@@ -587,7 +601,7 @@
     class MockBaseTest(base_test.BaseTestClass):
 
       def teardown_test(self):
-        my_mock("teardown_test")
+        my_mock('teardown_test')
 
       def on_pass(self, record):
         never_call()
@@ -598,12 +612,13 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    my_mock.assert_called_once_with("teardown_test")
+    my_mock.assert_called_once_with('teardown_test')
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_fail_executed_if_teardown_test_fails(self):
@@ -612,7 +627,7 @@
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_fail(self, record):
-        my_mock("on_fail")
+        my_mock('on_fail')
 
       def on_pass(self, record):
         never_call()
@@ -630,8 +645,9 @@
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_fail_executed_if_test_fails(self):
@@ -641,7 +657,7 @@
 
       def on_fail(self, record):
         assert self.current_test_info.name == 'test_something'
-        my_mock("on_fail")
+        my_mock('on_fail')
 
       def on_pass(self, record):
         never_call()
@@ -651,13 +667,14 @@
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    my_mock.assert_called_once_with("on_fail")
+    my_mock.assert_called_once_with('on_fail')
     actual_record = bt_cls.results.failed[0]
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 0, Executed 1, Failed 1, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_procedure_function_gets_correct_record(self):
@@ -680,13 +697,13 @@
     self.assertEqual(on_fail_mock.record.end_time, actual_record.end_time)
     self.assertEqual(on_fail_mock.record.stacktrace, actual_record.stacktrace)
     self.assertEqual(on_fail_mock.record.extras, actual_record.extras)
-    self.assertEqual(on_fail_mock.record.extra_errors,
-                     actual_record.extra_errors)
+    self.assertEqual(
+        on_fail_mock.record.extra_errors, actual_record.extra_errors
+    )
     # But they are not the same object.
     self.assertIsNot(on_fail_mock.record, actual_record)
 
   def test_on_fail_cannot_modify_original_record(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_fail(self, record):
@@ -706,7 +723,7 @@
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_fail(self, record):
-        on_fail_mock("on_fail")
+        on_fail_mock('on_fail')
 
       def on_pass(self, record):
         never_call()
@@ -719,15 +736,18 @@
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    on_fail_mock.assert_called_once_with("on_fail")
+    on_fail_mock.assert_called_once_with('on_fail')
     actual_record = bt_cls.results.error[0]
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
-    self.assertEqual(actual_record.extra_errors['teardown_test'].details,
-                     'This is an expected exception.ha')
+    self.assertEqual(
+        actual_record.extra_errors['teardown_test'].details,
+        'This is an expected exception.ha',
+    )
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_fail_executed_if_setup_test_fails_by_exception(self):
@@ -739,20 +759,21 @@
         raise Exception(MSG_EXPECTED_EXCEPTION)
 
       def on_fail(self, record):
-        my_mock("on_fail")
+        my_mock('on_fail')
 
       def test_something(self):
         pass
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    my_mock.assert_called_once_with("on_fail")
+    my_mock.assert_called_once_with('on_fail')
     actual_record = bt_cls.results.error[0]
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_fail_executed_if_setup_class_fails_by_exception(self):
@@ -764,20 +785,21 @@
         raise Exception(MSG_EXPECTED_EXCEPTION)
 
       def on_fail(self, record):
-        my_mock("on_fail")
+        my_mock('on_fail')
 
       def test_something(self):
         pass
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    my_mock.assert_called_once_with("on_fail")
+    my_mock.assert_called_once_with('on_fail')
     actual_record = bt_cls.results.error[0]
     self.assertEqual(actual_record.test_name, 'setup_class')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 1")
+    expected_summary = (
+        'Error 1, Executed 0, Failed 0, Passed 0, Requested 1, Skipped 1'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_fail_triggered_by_setup_class_failure_then_fail_too(self):
@@ -799,14 +821,16 @@
     setup_class_record = bt_cls.results.error[0]
     self.assertEqual(setup_class_record.test_name, 'setup_class')
     self.assertEqual(setup_class_record.details, MSG_EXPECTED_EXCEPTION)
-    self.assertEqual(setup_class_record.extra_errors['on_fail'].details,
-                     'Failure in on_fail.')
-    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 1")
+    self.assertEqual(
+        setup_class_record.extra_errors['on_fail'].details,
+        'Failure in on_fail.',
+    )
+    expected_summary = (
+        'Error 1, Executed 0, Failed 0, Passed 0, Requested 1, Skipped 1'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_failure_to_call_procedure_function_is_recorded(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_fail(self):
@@ -822,12 +846,13 @@
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 0, Executed 1, Failed 1, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_failure_in_procedure_functions_is_recorded(self):
-    expected_msg = "Something failed in on_pass."
+    expected_msg = 'Something failed in on_pass.'
 
     class MockBaseTest(base_test.BaseTestClass):
 
@@ -840,41 +865,44 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    self.assertEqual(actual_record.extra_errors['on_pass'].details,
-                     expected_msg)
+    self.assertEqual(
+        actual_record.extra_errors['on_pass'].details, expected_msg
+    )
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_both_teardown_and_test_body_raise_exceptions(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def teardown_test(self):
         asserts.assert_true(False, MSG_EXPECTED_EXCEPTION)
 
       def test_something(self):
-        raise Exception("Test Body Exception.")
+        raise Exception('Test Body Exception.')
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
     self.assertEqual(actual_record.test_name, self.mock_test_name)
-    self.assertEqual(actual_record.details, "Test Body Exception.")
+    self.assertEqual(actual_record.details, 'Test Body Exception.')
     self.assertIsNone(actual_record.extras)
-    self.assertEqual(actual_record.extra_errors['teardown_test'].details,
-                     MSG_EXPECTED_EXCEPTION)
+    self.assertEqual(
+        actual_record.extra_errors['teardown_test'].details,
+        MSG_EXPECTED_EXCEPTION,
+    )
     self.assertIsNone(actual_record.extra_errors['teardown_test'].extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_exception_objects_in_record(self):
-    """Checks that the exception objects are correctly tallied.
-    """
+    """Checks that the exception objects are correctly tallied."""
     expected_termination_signal = Exception('Test Body Exception.')
     expected_extra_error = Exception('teardown_test Exception.')
 
@@ -889,8 +917,9 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    self.assertIs(actual_record.termination_signal.exception,
-                  expected_termination_signal)
+    self.assertIs(
+        actual_record.termination_signal.exception, expected_termination_signal
+    )
     self.assertIsNotNone(actual_record.termination_signal.stacktrace)
     self.assertEqual(len(actual_record.extra_errors), 1)
     extra_error = actual_record.extra_errors['teardown_test']
@@ -920,8 +949,7 @@
     self.assertIsNotNone(actual_record.stacktrace)
 
   def test_explicit_pass_but_teardown_test_raises_an_exception(self):
-    """Test record result should be marked as ERROR as opposed to PASS.
-    """
+    """Test record result should be marked as ERROR as opposed to PASS."""
 
     class MockBaseTest(base_test.BaseTestClass):
 
@@ -937,15 +965,17 @@
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, 'Test Passed!')
     self.assertIsNone(actual_record.extras)
-    self.assertEqual(actual_record.extra_errors['teardown_test'].details,
-                     MSG_EXPECTED_EXCEPTION)
+    self.assertEqual(
+        actual_record.extra_errors['teardown_test'].details,
+        MSG_EXPECTED_EXCEPTION,
+    )
     self.assertIsNone(actual_record.extra_errors['teardown_test'].extras)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_pass_cannot_modify_original_record(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_pass(self, record):
@@ -960,7 +990,6 @@
     self.assertEqual(actual_record.test_name, 'test_something')
 
   def test_on_pass_raise_exception(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_pass(self, record):
@@ -975,14 +1004,15 @@
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
-    self.assertEqual(actual_record.extra_errors['on_pass'].details,
-                     MSG_EXPECTED_EXCEPTION)
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+    self.assertEqual(
+        actual_record.extra_errors['on_pass'].details, MSG_EXPECTED_EXCEPTION
+    )
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_on_fail_raise_exception(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def on_fail(self, record):
@@ -997,10 +1027,12 @@
     self.assertEqual(actual_record.test_name, self.mock_test_name)
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
-    self.assertEqual(actual_record.extra_errors['on_fail'].details,
-                     MSG_EXPECTED_EXCEPTION)
-    expected_summary = ("Error 0, Executed 1, Failed 1, Passed 0, "
-                        "Requested 1, Skipped 0")
+    self.assertEqual(
+        actual_record.extra_errors['on_fail'].details, MSG_EXPECTED_EXCEPTION
+    )
+    expected_summary = (
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_abort_class_setup_class(self):
@@ -1026,14 +1058,14 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertEqual(len(bt_cls.results.skipped), 3)
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 0, Failed 0, Passed 0, "
-                      "Requested 3, Skipped 3"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 0, Failed 0, Passed 0, Requested 3, Skipped 3',
+    )
 
   def test_abort_class_in_setup_test(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_test(self):
@@ -1049,14 +1081,14 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertEqual(len(bt_cls.results.skipped), 2)
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 1, Failed 1, Passed 0, "
-                      "Requested 3, Skipped 2"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 3, Skipped 2',
+    )
 
   def test_abort_class_in_on_fail(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_1(self):
@@ -1072,14 +1104,14 @@
         asserts.abort_class(MSG_EXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertEqual(len(bt_cls.results.skipped), 2)
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 1, Failed 1, Passed 0, "
-                      "Requested 3, Skipped 2"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 3, Skipped 2',
+    )
 
   def test_setup_and_teardown_execution_count(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1100,7 +1132,6 @@
     self.assertEqual(bt_cls.teardown_test.call_count, 2)
 
   def test_abort_class_in_test(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_1(self):
@@ -1114,15 +1145,15 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
-    self.assertEqual(bt_cls.results.passed[0].test_name, "test_1")
+    bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
+    self.assertEqual(bt_cls.results.passed[0].test_name, 'test_1')
     self.assertEqual(bt_cls.results.failed[0].details, MSG_EXPECTED_EXCEPTION)
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 2, Failed 1, Passed 1, "
-                      "Requested 3, Skipped 1"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 2, Failed 1, Passed 1, Requested 3, Skipped 1',
+    )
 
   def test_abort_all_in_setup_class(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_class(self):
@@ -1138,16 +1169,17 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    with self.assertRaisesRegex(signals.TestAbortAll,
-                                MSG_EXPECTED_EXCEPTION) as context:
-      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    with self.assertRaisesRegex(
+        signals.TestAbortAll, MSG_EXPECTED_EXCEPTION
+    ) as context:
+      bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertTrue(hasattr(context.exception, 'results'))
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 0, Failed 0, Passed 0, "
-                      "Requested 3, Skipped 3"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 0, Failed 0, Passed 0, Requested 3, Skipped 3',
+    )
 
   def test_abort_all_in_teardown_class(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_1(self):
@@ -1160,16 +1192,17 @@
         asserts.abort_all(MSG_EXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    with self.assertRaisesRegex(signals.TestAbortAll,
-                                MSG_EXPECTED_EXCEPTION) as context:
-      bt_cls.run(test_names=["test_1", "test_2"])
+    with self.assertRaisesRegex(
+        signals.TestAbortAll, MSG_EXPECTED_EXCEPTION
+    ) as context:
+      bt_cls.run(test_names=['test_1', 'test_2'])
     self.assertTrue(hasattr(context.exception, 'results'))
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 2, Failed 0, Passed 2, "
-                      "Requested 2, Skipped 0"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 2, Failed 0, Passed 2, Requested 2, Skipped 0',
+    )
 
   def test_abort_all_in_setup_test(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_test(self):
@@ -1185,16 +1218,17 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    with self.assertRaisesRegex(signals.TestAbortAll,
-                                MSG_EXPECTED_EXCEPTION) as context:
-      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    with self.assertRaisesRegex(
+        signals.TestAbortAll, MSG_EXPECTED_EXCEPTION
+    ) as context:
+      bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertTrue(hasattr(context.exception, 'results'))
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 1, Failed 1, Passed 0, "
-                      "Requested 3, Skipped 2"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 3, Skipped 2',
+    )
 
   def test_abort_all_in_on_fail(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_1(self):
@@ -1210,16 +1244,17 @@
         asserts.abort_all(MSG_EXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    with self.assertRaisesRegex(signals.TestAbortAll,
-                                MSG_EXPECTED_EXCEPTION) as context:
-      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    with self.assertRaisesRegex(
+        signals.TestAbortAll, MSG_EXPECTED_EXCEPTION
+    ) as context:
+      bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertTrue(hasattr(context.exception, 'results'))
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 1, Failed 1, Passed 0, "
-                      "Requested 3, Skipped 2"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 1, Failed 1, Passed 0, Requested 3, Skipped 2',
+    )
 
   def test_abort_all_in_on_fail_from_setup_class(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_class(self):
@@ -1238,18 +1273,19 @@
         asserts.abort_all(MSG_EXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    with self.assertRaisesRegex(signals.TestAbortAll,
-                                MSG_EXPECTED_EXCEPTION) as context:
-      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    with self.assertRaisesRegex(
+        signals.TestAbortAll, MSG_EXPECTED_EXCEPTION
+    ) as context:
+      bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     setup_class_record = bt_cls.results.error[0]
     self.assertEqual(setup_class_record.test_name, 'setup_class')
     self.assertTrue(hasattr(context.exception, 'results'))
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 1, Executed 0, Failed 0, Passed 0, "
-                      "Requested 3, Skipped 3"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 1, Executed 0, Failed 0, Passed 0, Requested 3, Skipped 3',
+    )
 
   def test_abort_all_in_test(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_1(self):
@@ -1263,18 +1299,19 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    with self.assertRaisesRegex(signals.TestAbortAll,
-                                MSG_EXPECTED_EXCEPTION) as context:
-      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
+    with self.assertRaisesRegex(
+        signals.TestAbortAll, MSG_EXPECTED_EXCEPTION
+    ) as context:
+      bt_cls.run(test_names=['test_1', 'test_2', 'test_3'])
     self.assertTrue(hasattr(context.exception, 'results'))
-    self.assertEqual(bt_cls.results.passed[0].test_name, "test_1")
+    self.assertEqual(bt_cls.results.passed[0].test_name, 'test_1')
     self.assertEqual(bt_cls.results.failed[0].details, MSG_EXPECTED_EXCEPTION)
-    self.assertEqual(bt_cls.results.summary_str(),
-                     ("Error 0, Executed 2, Failed 1, Passed 1, "
-                      "Requested 3, Skipped 1"))
+    self.assertEqual(
+        bt_cls.results.summary_str(),
+        'Error 0, Executed 2, Failed 1, Passed 1, Requested 3, Skipped 1',
+    )
 
   def test_uncaught_exception(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1282,20 +1319,21 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.error[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
     # Stacktraces can vary. Just check for key words
     self.assertIn('test_method()', actual_record.stacktrace)
-    self.assertIn('raise Exception(MSG_EXPECTED_EXCEPTION)',
-                  actual_record.stacktrace)
-    self.assertIn('Exception: This is an expected exception.',
-                  actual_record.stacktrace)
+    self.assertIn(
+        'raise Exception(MSG_EXPECTED_EXCEPTION)', actual_record.stacktrace
+    )
+    self.assertIn(
+        'Exception: This is an expected exception.', actual_record.stacktrace
+    )
 
   def test_fail(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1303,14 +1341,13 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_true(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1318,14 +1355,13 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_equal_pass(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1334,12 +1370,11 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertIsNone(actual_record.details)
     self.assertIsNone(actual_record.extras)
 
   def test_assert_equal_fail(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1348,30 +1383,27 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
-    self.assertEqual(actual_record.details, "1 != 2")
+    self.assertEqual(actual_record.test_name, 'test_func')
+    self.assertEqual(actual_record.details, '1 != 2')
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_equal_fail_with_msg(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
-        asserts.assert_equal(1,
-                             2,
-                             msg=MSG_EXPECTED_EXCEPTION,
-                             extras=MOCK_EXTRA)
+        asserts.assert_equal(
+            1, 2, msg=MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA
+        )
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
-    expected_msg = "1 != 2 " + MSG_EXPECTED_EXCEPTION
+    self.assertEqual(actual_record.test_name, 'test_func')
+    expected_msg = '1 != 2 ' + MSG_EXPECTED_EXCEPTION
     self.assertEqual(actual_record.details, expected_msg)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_raises_pass(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1381,12 +1413,11 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertIsNone(actual_record.details)
     self.assertIsNone(actual_record.extras)
 
   def test_assert_raises_fail_with_noop(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1396,12 +1427,11 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
-    self.assertEqual(actual_record.details, "SomeError not raised")
+    self.assertEqual(actual_record.test_name, 'test_func')
+    self.assertEqual(actual_record.details, 'SomeError not raised')
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_raises_fail_with_wrong_error(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1411,83 +1441,80 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_UNEXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
 
   def test_assert_raises_regex_pass(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
-        with asserts.assert_raises_regex(SomeError,
-                                         expected_regex=MSG_EXPECTED_EXCEPTION,
-                                         extras=MOCK_EXTRA):
+        with asserts.assert_raises_regex(
+            SomeError, expected_regex=MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA
+        ):
           raise SomeError(MSG_EXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertIsNone(actual_record.details)
     self.assertIsNone(actual_record.extras)
 
   def test_assert_raises_regex_fail_with_noop(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
-        with asserts.assert_raises_regex(SomeError,
-                                         expected_regex=MSG_EXPECTED_EXCEPTION,
-                                         extras=MOCK_EXTRA):
+        with asserts.assert_raises_regex(
+            SomeError, expected_regex=MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA
+        ):
           pass
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
-    self.assertEqual(actual_record.details, "SomeError not raised")
+    self.assertEqual(actual_record.test_name, 'test_func')
+    self.assertEqual(actual_record.details, 'SomeError not raised')
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_raises_fail_with_wrong_regex(self):
-    wrong_msg = "ha"
+    wrong_msg = 'ha'
 
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
-        with asserts.assert_raises_regex(SomeError,
-                                         expected_regex=MSG_EXPECTED_EXCEPTION,
-                                         extras=MOCK_EXTRA):
+        with asserts.assert_raises_regex(
+            SomeError, expected_regex=MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA
+        ):
           raise SomeError(wrong_msg)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.failed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
-    expected_details = ('"This is an expected exception." does not match '
-                        '"%s"') % wrong_msg
+    self.assertEqual(actual_record.test_name, 'test_func')
+    expected_details = (
+        '"This is an expected exception." does not match "%s"'
+    ) % wrong_msg
     self.assertEqual(actual_record.details, expected_details)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_assert_raises_regex_fail_with_wrong_error(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
-        with asserts.assert_raises_regex(SomeError,
-                                         expected_regex=MSG_EXPECTED_EXCEPTION,
-                                         extras=MOCK_EXTRA):
+        with asserts.assert_raises_regex(
+            SomeError, expected_regex=MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA
+        ):
           raise AttributeError(MSG_UNEXPECTED_EXCEPTION)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_UNEXPECTED_EXCEPTION)
     self.assertIsNone(actual_record.extras)
 
   def test_explicit_pass(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1495,28 +1522,26 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_implicit_pass(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
         pass
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertIsNone(actual_record.details)
     self.assertIsNone(actual_record.extras)
 
   def test_skip(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1524,16 +1549,15 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.skipped[0]
     self.assertIsNotNone(actual_record.begin_time)
     self.assertIsNotNone(actual_record.end_time)
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_skip_if(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -1542,16 +1566,15 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.skipped[0]
     self.assertIsNotNone(actual_record.begin_time)
     self.assertIsNotNone(actual_record.end_time)
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_skip_in_setup_test(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_test(self):
@@ -1561,11 +1584,11 @@
         never_call()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_func"])
+    bt_cls.run(test_names=['test_func'])
     actual_record = bt_cls.results.skipped[0]
     self.assertIsNotNone(actual_record.begin_time)
     self.assertIsNotNone(actual_record.end_time)
-    self.assertEqual(actual_record.test_name, "test_func")
+    self.assertEqual(actual_record.test_name, 'test_func')
     self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
@@ -1619,8 +1642,7 @@
     self.assertEqual(second_error.extras, '2')
 
   def test_expect_two_tests(self):
-    """Errors in `expect` should not leak across tests.
-    """
+    """Errors in `expect` should not leak across tests."""
     must_call = mock.Mock()
 
     class MockBaseTest(base_test.BaseTestClass):
@@ -1643,8 +1665,7 @@
     self.assertEqual(another_record.test_name, 'test_2')
 
   def test_expect_no_op(self):
-    """Tests don't fail when expect is not triggered.
-    """
+    """Tests don't fail when expect is not triggered."""
     must_call = mock.Mock()
 
     class MockBaseTest(base_test.BaseTestClass):
@@ -1851,8 +1872,10 @@
     must_call.assert_called_once_with('ha')
     actual_record = bt_cls.results.failed[0]
     self.assertEqual(actual_record.test_name, 'test_func')
-    self.assertEqual(actual_record.details,
-                     'Got an unexpected exception: %s' % MSG_EXPECTED_EXCEPTION)
+    self.assertEqual(
+        actual_record.details,
+        'Got an unexpected exception: %s' % MSG_EXPECTED_EXCEPTION,
+    )
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_expect_no_raises_custom_msg(self):
@@ -1871,13 +1894,13 @@
     must_call.assert_called_once_with('ha')
     actual_record = bt_cls.results.failed[0]
     self.assertEqual(actual_record.test_name, 'test_func')
-    self.assertEqual(actual_record.details,
-                     '%s: %s' % (msg, MSG_EXPECTED_EXCEPTION))
+    self.assertEqual(
+        actual_record.details, '%s: %s' % (msg, MSG_EXPECTED_EXCEPTION)
+    )
     self.assertEqual(actual_record.extras, MOCK_EXTRA)
 
   def test_expect_true_and_assert_true(self):
-    """Error thrown by assert_true should be considered the termination.
-    """
+    """Error thrown by assert_true should be considered the termination."""
     must_call = mock.Mock()
 
     class MockBaseTest(base_test.BaseTestClass):
@@ -1897,18 +1920,19 @@
 
   def test_unpack_userparams_required(self):
     """Missing a required param should raise an error."""
-    required = ["some_param"]
+    required = ['some_param']
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
     bc.unpack_userparams(required)
-    expected_value = self.mock_test_cls_configs.user_params["some_param"]
+    expected_value = self.mock_test_cls_configs.user_params['some_param']
     self.assertEqual(bc.some_param, expected_value)
 
   def test_unpack_userparams_required_missing(self):
     """Missing a required param should raise an error."""
-    required = ["something"]
+    required = ['something']
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
-    expected_msg = ('Missing required user param "%s" in test '
-                    'configuration.') % required[0]
+    expected_msg = (
+        'Missing required user param "%s" in test configuration.'
+    ) % required[0]
     with self.assertRaisesRegex(base_test.Error, expected_msg):
       bc.unpack_userparams(required)
 
@@ -1916,10 +1940,10 @@
     """If an optional param is specified, the value should be what's in the
     config.
     """
-    opt = ["some_param"]
+    opt = ['some_param']
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
     bc.unpack_userparams(opt_param_names=opt)
-    expected_value = self.mock_test_cls_configs.user_params["some_param"]
+    expected_value = self.mock_test_cls_configs.user_params['some_param']
     self.assertEqual(bc.some_param, expected_value)
 
   def test_unpack_userparams_optional_with_default(self):
@@ -1927,16 +1951,16 @@
     param is not in the config, the value should be the default value.
     """
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
-    bc.unpack_userparams(optional_thing="whatever")
-    self.assertEqual(bc.optional_thing, "whatever")
+    bc.unpack_userparams(optional_thing='whatever')
+    self.assertEqual(bc.optional_thing, 'whatever')
 
   def test_unpack_userparams_default_overwrite_by_optional_param_list(self):
     """If an optional param is specified in kwargs, and the param is in the
     config, the value should be the one in the config.
     """
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
-    bc.unpack_userparams(some_param="whatever")
-    expected_value = self.mock_test_cls_configs.user_params["some_param"]
+    bc.unpack_userparams(some_param='whatever')
+    expected_value = self.mock_test_cls_configs.user_params['some_param']
     self.assertEqual(bc.some_param, expected_value)
 
   def test_unpack_userparams_default_overwrite_by_required_param_list(self):
@@ -1946,32 +1970,33 @@
     thrown.
     """
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
-    bc.unpack_userparams(req_param_names=['a_kwarg_param'],
-                         a_kwarg_param="whatever")
-    self.assertEqual(bc.a_kwarg_param, "whatever")
+    bc.unpack_userparams(
+        req_param_names=['a_kwarg_param'], a_kwarg_param='whatever'
+    )
+    self.assertEqual(bc.a_kwarg_param, 'whatever')
 
   def test_unpack_userparams_optional_missing(self):
     """Missing an optional param should not raise an error."""
-    opt = ["something"]
+    opt = ['something']
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
     bc.unpack_userparams(opt_param_names=opt)
 
   def test_unpack_userparams_basic(self):
     """Required and optional params are unpacked properly."""
-    required = ["something"]
-    optional = ["something_else"]
+    required = ['something']
+    optional = ['something_else']
     configs = self.mock_test_cls_configs.copy()
-    configs.user_params["something"] = 42
-    configs.user_params["something_else"] = 53
+    configs.user_params['something'] = 42
+    configs.user_params['something_else'] = 53
     bc = base_test.BaseTestClass(configs)
     bc.unpack_userparams(req_param_names=required, opt_param_names=optional)
     self.assertEqual(bc.something, 42)
     self.assertEqual(bc.something_else, 53)
 
   def test_unpack_userparams_default_overwrite(self):
-    default_arg_val = "haha"
-    actual_arg_val = "wawa"
-    arg_name = "arg1"
+    default_arg_val = 'haha'
+    actual_arg_val = 'wawa'
+    arg_name = 'arg1'
     configs = self.mock_test_cls_configs.copy()
     configs.user_params[arg_name] = actual_arg_val
     bc = base_test.BaseTestClass(configs)
@@ -1980,8 +2005,8 @@
 
   def test_unpack_userparams_default_None(self):
     bc = base_test.BaseTestClass(self.mock_test_cls_configs)
-    bc.unpack_userparams(arg1="haha")
-    self.assertEqual(bc.arg1, "haha")
+    bc.unpack_userparams(arg1='haha')
+    self.assertEqual(bc.arg1, 'haha')
 
   def test_pre_run_failure(self):
     """Test code path for `pre_run` failure.
@@ -2015,13 +2040,14 @@
 
   # TODO(angli): remove after the full deprecation of `setup_generated_tests`.
   def test_setup_generated_tests(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def setup_generated_tests(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'test_%s_%s' % (a, b)
@@ -2070,13 +2096,14 @@
     self.assertEqual(bt_cls.results.skipped, [])
 
   def test_generate_tests_run(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def pre_run(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'test_%s_%s' % (a, b)
@@ -2094,14 +2121,15 @@
     self.assertEqual(bt_cls.results.passed[1].test_name, 'test_3_4')
 
   def test_generate_tests_with_uid(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def pre_run(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            uid_func=self.uid_logic,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            uid_func=self.uid_logic,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'test_%s_%s' % (a, b)
@@ -2118,14 +2146,15 @@
     self.assertEqual(bt_cls.results.passed[1].uid, 'uid-3-4')
 
   def test_generate_tests_with_none_uid(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def pre_run(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            uid_func=self.uid_logic,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            uid_func=self.uid_logic,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'test_%s_%s' % (a, b)
@@ -2144,13 +2173,14 @@
     self.assertEqual(bt_cls.results.passed[1].uid, 'uid-3-4')
 
   def test_generate_tests_selected_run(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def pre_run(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'test_%s_%s' % (a, b)
@@ -2165,13 +2195,14 @@
     self.assertEqual(bt_cls.results.passed[0].test_name, 'test_3_4')
 
   def test_generate_tests_call_outside_of_pre_run(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_ha(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'test_%s_%s' % (a, b)
@@ -2183,23 +2214,26 @@
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
     utils.validate_test_result(bt_cls.results)
-    self.assertEqual(actual_record.test_name, "test_ha")
+    self.assertEqual(actual_record.test_name, 'test_ha')
     self.assertEqual(
         actual_record.details,
         "'generate_tests' cannot be called outside of the followin"
-        "g functions: ['pre_run', 'setup_generated_tests'].")
-    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
-                        "Requested 1, Skipped 0")
+        "g functions: ['pre_run', 'setup_generated_tests'].",
+    )
+    expected_summary = (
+        'Error 1, Executed 1, Failed 0, Passed 0, Requested 1, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_generate_tests_dup_test_name(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def pre_run(self):
-        self.generate_tests(test_logic=self.logic,
-                            name_func=self.name_gen,
-                            arg_sets=[(1, 2), (3, 4)])
+        self.generate_tests(
+            test_logic=self.logic,
+            name_func=self.name_gen,
+            arg_sets=[(1, 2), (3, 4)],
+        )
 
       def name_gen(self, a, b):
         return 'ha'
@@ -2210,13 +2244,15 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     actual_record = bt_cls.results.error[0]
-    self.assertEqual(actual_record.test_name, "pre_run")
+    self.assertEqual(actual_record.test_name, 'pre_run')
     self.assertEqual(
         actual_record.details,
         'During test generation of "logic": Test name "ha" already exists'
-        ', cannot be duplicated!')
-    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
-                        "Requested 0, Skipped 0")
+        ', cannot be duplicated!',
+    )
+    expected_summary = (
+        'Error 1, Executed 0, Failed 0, Passed 0, Requested 0, Skipped 0'
+    )
     self.assertEqual(bt_cls.results.summary_str(), expected_summary)
 
   def test_write_user_data(self):
@@ -2229,9 +2265,9 @@
         self.record_data(content)
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
-    bt_cls.run(test_names=["test_something"])
+    bt_cls.run(test_names=['test_something'])
     actual_record = bt_cls.results.passed[0]
-    self.assertEqual(actual_record.test_name, "test_something")
+    self.assertEqual(actual_record.test_name, 'test_something')
     hit = False
     with io.open(self.summary_file, 'r', encoding='utf-8') as f:
       for c in yaml.safe_load_all(f):
@@ -2252,11 +2288,14 @@
     """
     mock_test_config = self.mock_test_cls_configs.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    mock_ctrlr_2_config_name = (
+        mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    )
     my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
-        my_config)
+        my_config
+    )
 
     class ControllerInfoTest(base_test.BaseTestClass):
       """Registers two different controller types and modifies controller
@@ -2282,21 +2321,22 @@
     self.assertEqual(info1.controller_info, [{'MyMagic': {'magic': 'Magic'}}])
     self.assertEqual(info2.test_class, 'ControllerInfoTest')
     self.assertEqual(info2.controller_name, 'AnotherMagicDevice')
-    self.assertEqual(info2.controller_info, [{
-        'MyOtherMagic': {
-            'magic': 'Magic',
-            'extra_magic': 'haha'
-        }
-    }])
+    self.assertEqual(
+        info2.controller_info,
+        [{'MyOtherMagic': {'magic': 'Magic', 'extra_magic': 'haha'}}],
+    )
 
   def test_record_controller_info_fail(self):
     mock_test_config = self.mock_test_cls_configs.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    mock_ctrlr_2_config_name = (
+        mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    )
     my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
-        my_config)
+        my_config
+    )
 
     class ControllerInfoTest(base_test.BaseTestClass):
       """Registers two different controller types and modifies controller
@@ -2320,25 +2360,24 @@
     self.assertEqual(len(bt_cls.results.controller_info), 1)
     self.assertEqual(info.test_class, 'ControllerInfoTest')
     self.assertEqual(info.controller_name, 'AnotherMagicDevice')
-    self.assertEqual(info.controller_info, [{
-        'MyOtherMagic': {
-            'magic': 'Magic',
-            'extra_magic': 'haha'
-        }
-    }])
+    self.assertEqual(
+        info.controller_info,
+        [{'MyOtherMagic': {'magic': 'Magic', 'extra_magic': 'haha'}}],
+    )
     record = bt_cls.results.error[0]
     print(record.to_dict())
     self.assertEqual(record.test_name, 'clean_up')
     self.assertIsNotNone(record.begin_time)
     self.assertIsNotNone(record.end_time)
-    expected_msg = ('Failed to collect controller info from '
-                    'mock_controller: Some failure')
+    expected_msg = (
+        'Failed to collect controller info from mock_controller: Some failure'
+    )
     self.assertEqual(record.details, expected_msg)
 
   def test_repeat_invalid_count(self):
-
     with self.assertRaisesRegex(
-        ValueError, 'The `count` for `repeat` must be larger than 1, got "1".'):
+        ValueError, 'The `count` for `repeat` must be larger than 1, got "1".'
+    ):
 
       class MockBaseTest(base_test.BaseTestClass):
 
@@ -2347,11 +2386,13 @@
           pass
 
   def test_repeat_invalid_max_consec_error(self):
-
     with self.assertRaisesRegex(
         ValueError,
-        re.escape('The `max_consecutive_error` (4) for `repeat` must be '
-                  'smaller than `count` (3).')):
+        re.escape(
+            'The `max_consecutive_error` (4) for `repeat` must be '
+            'smaller than `count` (3).'
+        ),
+    ):
 
       class MockBaseTest(base_test.BaseTestClass):
 
@@ -2384,9 +2425,11 @@
         pass
 
       def pre_run(self):
-        self.generate_tests(self._run_test_logic,
-                            name_func=lambda arg: f'test_generated_{arg}',
-                            arg_sets=[(1,)])
+        self.generate_tests(
+            self._run_test_logic,
+            name_func=lambda arg: f'test_generated_{arg}',
+            arg_sets=[(1,)],
+        )
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
@@ -2418,7 +2461,8 @@
 
   @mock.patch('logging.error')
   def test_repeat_with_consec_error_at_the_beginning_aborts_repeat(
-      self, mock_logging_error):
+      self, mock_logging_error
+  ):
     repeat_count = 5
     max_consec_error = 2
     mock_action = mock.MagicMock()
@@ -2430,16 +2474,21 @@
 
     class MockBaseTest(base_test.BaseTestClass):
 
-      @base_test.repeat(count=repeat_count,
-                        max_consecutive_error=max_consec_error)
+      @base_test.repeat(
+          count=repeat_count, max_consecutive_error=max_consec_error
+      )
       def test_something(self):
         mock_action()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     mock_logging_error.assert_called_with(
-        'Repeated test case "%s" has consecutively failed %d iterations, aborting'
-        ' the remaining %d iterations.', 'test_something', 2, 3)
+        'Repeated test case "%s" has consecutively failed %d iterations,'
+        ' aborting the remaining %d iterations.',
+        'test_something',
+        2,
+        3,
+    )
     self.assertEqual(max_consec_error, len(bt_cls.results.executed))
     self.assertEqual(max_consec_error, len(bt_cls.results.error))
     for i, record in enumerate(bt_cls.results.error):
@@ -2447,7 +2496,8 @@
 
   @mock.patch('logging.error')
   def test_repeat_with_consec_error_in_the_middle_aborts_repeat(
-      self, mock_logging_error):
+      self, mock_logging_error
+  ):
     repeat_count = 5
     max_consec_error = 2
     mock_action = mock.MagicMock()
@@ -2461,16 +2511,21 @@
 
     class MockBaseTest(base_test.BaseTestClass):
 
-      @base_test.repeat(count=repeat_count,
-                        max_consecutive_error=max_consec_error)
+      @base_test.repeat(
+          count=repeat_count, max_consecutive_error=max_consec_error
+      )
       def test_something(self):
         mock_action()
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     mock_logging_error.assert_called_with(
-        'Repeated test case "%s" has consecutively failed %d iterations, aborting'
-        ' the remaining %d iterations.', 'test_something', 2, 1)
+        'Repeated test case "%s" has consecutively failed %d iterations,'
+        ' aborting the remaining %d iterations.',
+        'test_something',
+        2,
+        1,
+    )
     self.assertEqual(4, len(bt_cls.results.executed))
     self.assertEqual(2, len(bt_cls.results.error))
     self.assertEqual(2, len(bt_cls.results.passed))
@@ -2491,8 +2546,9 @@
 
     class MockBaseTest(base_test.BaseTestClass):
 
-      @base_test.repeat(count=repeat_count,
-                        max_consecutive_error=max_consec_error)
+      @base_test.repeat(
+          count=repeat_count, max_consecutive_error=max_consec_error
+      )
       def test_something(self):
         mock_action()
 
@@ -2502,10 +2558,10 @@
     self.assertEqual(3, len(bt_cls.results.error))
 
   def test_retry_invalid_count(self):
-
     with self.assertRaisesRegex(
         ValueError,
-        'The `max_count` for `retry` must be larger than 1, got "1".'):
+        'The `max_count` for `retry` must be larger than 1, got "1".',
+    ):
 
       class MockBaseTest(base_test.BaseTestClass):
 
@@ -2525,8 +2581,9 @@
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    self.assertTrue(bt_cls.results.is_all_pass,
-                    'This test run should be considered pass.')
+    self.assertTrue(
+        bt_cls.results.is_all_pass, 'This test run should be considered pass.'
+    )
     self.assertEqual(1, len(bt_cls.results.executed))
     self.assertEqual(1, len(bt_cls.results.passed))
     pass_record = bt_cls.results.passed[0]
@@ -2546,8 +2603,9 @@
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    self.assertTrue(bt_cls.results.is_all_pass,
-                    'This test run should be considered pass.')
+    self.assertTrue(
+        bt_cls.results.is_all_pass, 'This test run should be considered pass.'
+    )
     self.assertEqual(3, len(bt_cls.results.executed))
     self.assertEqual(1, len(bt_cls.results.passed))
     pass_record = bt_cls.results.passed[0]
@@ -2557,13 +2615,19 @@
     self.assertEqual(error_record_1.test_name, 'test_something')
     self.assertEqual(error_record_2.test_name, 'test_something_retry_1')
     self.assertIs(error_record_1, error_record_2.retry_parent)
+    self.assertEqual(
+        (error_record_1, records.TestParentType.RETRY), error_record_2.parent
+    )
     self.assertIs(error_record_2, pass_record.retry_parent)
+    self.assertEqual(
+        (error_record_2, records.TestParentType.RETRY), pass_record.parent
+    )
 
   def test_retry_generated_test_last_pass(self):
     max_count = 3
     mock_action = mock.MagicMock(
-        side_effect=[Exception('Fail 1'),
-                     Exception('Fail 2'), None])
+        side_effect=[Exception('Fail 1'), Exception('Fail 2'), None]
+    )
 
     class MockBaseTest(base_test.BaseTestClass):
 
@@ -2572,14 +2636,17 @@
         mock_action()
 
       def pre_run(self):
-        self.generate_tests(self._run_test_logic,
-                            name_func=lambda arg: f'test_generated_{arg}',
-                            arg_sets=[(1,)])
+        self.generate_tests(
+            self._run_test_logic,
+            name_func=lambda arg: f'test_generated_{arg}',
+            arg_sets=[(1,)],
+        )
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    self.assertTrue(bt_cls.results.is_all_pass,
-                    'This test run should be considered pass.')
+    self.assertTrue(
+        bt_cls.results.is_all_pass, 'This test run should be considered pass.'
+    )
     self.assertEqual(3, len(bt_cls.results.executed))
     self.assertEqual(1, len(bt_cls.results.passed))
     pass_record = bt_cls.results.passed[0]
@@ -2589,7 +2656,13 @@
     self.assertEqual(error_record_1.test_name, 'test_generated_1')
     self.assertEqual(error_record_2.test_name, 'test_generated_1_retry_1')
     self.assertIs(error_record_1, error_record_2.retry_parent)
+    self.assertEqual(
+        (error_record_1, records.TestParentType.RETRY), error_record_2.parent
+    )
     self.assertIs(error_record_2, pass_record.retry_parent)
+    self.assertEqual(
+        (error_record_2, records.TestParentType.RETRY), pass_record.parent
+    )
 
   def test_retry_all_fail(self):
     max_count = 3
@@ -2597,7 +2670,7 @@
     mock_action.side_effect = [
         Exception('Fail 1'),
         Exception('Fail 2'),
-        Exception('Fail 3')
+        Exception('Fail 3'),
     ]
 
     class MockBaseTest(base_test.BaseTestClass):
@@ -2608,8 +2681,9 @@
 
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
-    self.assertFalse(bt_cls.results.is_all_pass,
-                     'This test run should be considered fail.')
+    self.assertFalse(
+        bt_cls.results.is_all_pass, 'This test run should be considered fail.'
+    )
     self.assertEqual(3, len(bt_cls.results.executed))
     self.assertEqual(3, len(bt_cls.results.error))
     error_record_1, error_record_2, error_record_3 = bt_cls.results.error
@@ -2617,10 +2691,15 @@
     self.assertEqual(error_record_2.test_name, 'test_something_retry_1')
     self.assertEqual(error_record_3.test_name, 'test_something_retry_2')
     self.assertIs(error_record_1, error_record_2.retry_parent)
+    self.assertEqual(
+        (error_record_1, records.TestParentType.RETRY), error_record_2.parent
+    )
     self.assertIs(error_record_2, error_record_3.retry_parent)
+    self.assertEqual(
+        (error_record_2, records.TestParentType.RETRY), error_record_3.parent
+    )
 
   def test_uid(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       @records.uid('some-uid')
@@ -2633,7 +2712,6 @@
     self.assertEqual(actual_record.uid, 'some-uid')
 
   def test_uid_not_specified(self):
-
     class MockBaseTest(base_test.BaseTestClass):
 
       def test_func(self):
@@ -2666,9 +2744,17 @@
     bt_cls = MockBaseTest(self.mock_test_cls_configs)
     bt_cls.run()
     self.assertEqual(repeat_count, len(bt_cls.results.passed))
+    previous_record = None
     for i, record in enumerate(bt_cls.results.passed):
       self.assertEqual(record.test_name, f'test_something_{i}')
       self.assertEqual(record.uid, 'some-uid')
+      if i == 0:
+        self.assertIsNone(record.parent)
+      else:
+        self.assertEqual(
+            record.parent, (previous_record, records.TestParentType.REPEAT)
+        )
+      previous_record = record
 
   def test_uid_with_repeat(self):
     repeat_count = 3
@@ -2705,5 +2791,5 @@
     logging_patch.debug.assert_called_with('[TestClass]#stage <<< END <<<')
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/config_parser_test.py b/tests/mobly/config_parser_test.py
index 6901819..46548f0 100644
--- a/tests/mobly/config_parser_test.py
+++ b/tests/mobly/config_parser_test.py
@@ -35,26 +35,26 @@
   def test__load_config_file(self):
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u'TestBeds:\n')
-      f.write(u'  # A test bed where adb will find Android devices.\n')
-      f.write(u'  - Name: SampleTestBed\n')
-      f.write(u'    Controllers:\n')
-      f.write(u'        AndroidDevice: \'*\'\n')
+      f.write('TestBeds:\n')
+      f.write('  # A test bed where adb will find Android devices.\n')
+      f.write('  - Name: SampleTestBed\n')
+      f.write('    Controllers:\n')
+      f.write("        AndroidDevice: '*'\n")
 
     config = config_parser._load_config_file(tmp_file_path)
-    self.assertEqual(config['TestBeds'][0]['Name'], u'SampleTestBed')
+    self.assertEqual(config['TestBeds'][0]['Name'], 'SampleTestBed')
 
   def test__load_config_file_with_unicode(self):
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u'TestBeds:\n')
-      f.write(u'  # A test bed where adb will find Android devices.\n')
-      f.write(u'  - Name: \u901a\n')
-      f.write(u'    Controllers:\n')
-      f.write(u'        AndroidDevice: \'*\'\n')
+      f.write('TestBeds:\n')
+      f.write('  # A test bed where adb will find Android devices.\n')
+      f.write('  - Name: \u901a\n')
+      f.write('    Controllers:\n')
+      f.write("        AndroidDevice: '*'\n")
 
     config = config_parser._load_config_file(tmp_file_path)
-    self.assertEqual(config['TestBeds'][0]['Name'], u'\u901a')
+    self.assertEqual(config['TestBeds'][0]['Name'], '\u901a')
 
   def test_run_config_type(self):
     config = config_parser.TestRunConfig()
@@ -66,13 +66,16 @@
     expected_value = 'SOME_VALUE'
     self.assertEqual(
         config.controller_configs.get('NON_EXISTENT_KEY', expected_value),
-        expected_value)
+        expected_value,
+    )
 
   def test_run_config_user_params_is_already_initialized(self):
     config = config_parser.TestRunConfig()
     expected_value = 'SOME_VALUE'
-    self.assertEqual(config.user_params.get('NON_EXISTENT_KEY', expected_value),
-                     expected_value)
+    self.assertEqual(
+        config.user_params.get('NON_EXISTENT_KEY', expected_value),
+        expected_value,
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/controller_manager_test.py b/tests/mobly/controller_manager_test.py
index 53e4cfa..46aa273 100755
--- a/tests/mobly/controller_manager_test.py
+++ b/tests/mobly/controller_manager_test.py
@@ -49,14 +49,16 @@
 
   def test_register_controller_no_config(self):
     c_manager = controller_manager.ControllerManager('SomeClass', {})
-    with self.assertRaisesRegex(signals.ControllerError,
-                                'No corresponding config found for'):
+    with self.assertRaisesRegex(
+        signals.ControllerError, 'No corresponding config found for'
+    ):
       c_manager.register_controller(mock_controller)
 
   def test_register_controller_no_config_for_not_required(self):
     c_manager = controller_manager.ControllerManager('SomeClass', {})
     self.assertIsNone(
-        c_manager.register_controller(mock_controller, required=False))
+        c_manager.register_controller(mock_controller, required=False)
+    )
 
   def test_register_controller_dup_register(self):
     """Verifies correctness of registration, internal tally of controllers
@@ -65,8 +67,9 @@
     """
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.register_controller(mock_controller)
     registered_name = 'mock_controller'
     self.assertTrue(registered_name in c_manager._controller_objects)
@@ -81,8 +84,9 @@
   def test_register_controller_return_value(self):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     magic_devices = c_manager.register_controller(mock_controller)
     self.assertEqual(magic_devices[0].magic, 'magic1')
     self.assertEqual(magic_devices[1].magic, 'magic2')
@@ -90,8 +94,9 @@
   def test_register_controller_change_return_value(self):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     magic_devices = c_manager.register_controller(mock_controller)
     magic1 = magic_devices.pop(0)
     self.assertIs(magic1, c_manager._controller_objects['mock_controller'][0])
@@ -100,8 +105,9 @@
   def test_register_controller_less_than_min_number(self):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     expected_msg = 'Expected to get at least 3 controller objects, got 2.'
     with self.assertRaisesRegex(signals.ControllerError, expected_msg):
       c_manager.register_controller(mock_controller, min_number=3)
@@ -110,19 +116,22 @@
   def test_get_controller_info_record_not_serializable(self, _):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.register_controller(mock_controller)
     record = c_manager.get_controller_info_records()[0]
     actual_controller_info = record.controller_info
-    self.assertEqual(actual_controller_info,
-                     "[{'MyMagic': 'magic1'}, {'MyMagic': 'magic2'}]")
+    self.assertEqual(
+        actual_controller_info, "[{'MyMagic': 'magic1'}, {'MyMagic': 'magic2'}]"
+    )
 
   def test_controller_record_exists_without_get_info(self):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     get_info = getattr(mock_controller, 'get_info')
     delattr(mock_controller, 'get_info')
     try:
@@ -139,8 +148,9 @@
     mock_get_info_func.return_value = None
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.register_controller(mock_controller)
     record = c_manager.get_controller_info_records()[0]
     self.assertIsNone(record.controller_info)
@@ -149,13 +159,15 @@
 
   @mock.patch('mobly.expects._ExpectErrorRecorder.add_error')
   @mock.patch('tests.lib.mock_controller.get_info')
-  def test_get_controller_info_records_error(self, mock_get_info_func,
-                                             mock_add_error):
+  def test_get_controller_info_records_error(
+      self, mock_get_info_func, mock_add_error
+  ):
     mock_get_info_func.side_effect = Exception('Record info failed.')
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.register_controller(mock_controller)
     self.assertFalse(c_manager.get_controller_info_records())
     mock_add_error.assert_called_once()
@@ -165,36 +177,37 @@
   def test_get_controller_info_records(self):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.register_controller(mock_controller)
     record = c_manager.get_controller_info_records()[0]
     record_dict = record.to_dict()
     record_dict.pop('Timestamp')
     self.assertEqual(
-        record_dict, {
-            'Controller Info': [{
-                'MyMagic': 'magic1'
-            }, {
-                'MyMagic': 'magic2'
-            }],
+        record_dict,
+        {
+            'Controller Info': [{'MyMagic': 'magic1'}, {'MyMagic': 'magic2'}],
             'Controller Name': 'MagicDevice',
-            'Test Class': 'SomeClass'
-        })
+            'Test Class': 'SomeClass',
+        },
+    )
 
   def test_get_controller_info_without_registration(self):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     self.assertFalse(c_manager.get_controller_info_records())
 
   @mock.patch('tests.lib.mock_controller.destroy')
   def test_unregister_controller(self, mock_destroy_func):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     objects = c_manager.register_controller(mock_controller)
     c_manager.unregister_controllers()
     mock_destroy_func.assert_called_once_with(objects)
@@ -206,8 +219,9 @@
   def test_unregister_controller_error(self, mock_destroy_func, mock_add_error):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.register_controller(mock_controller)
     mock_destroy_func.side_effect = Exception('Failed in destroy.')
     c_manager.unregister_controllers()
@@ -221,13 +235,14 @@
   def test_unregister_controller_without_registration(self, mock_destroy_func):
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
     controller_configs = {mock_ctrlr_config_name: ['magic1', 'magic2']}
-    c_manager = controller_manager.ControllerManager('SomeClass',
-                                                     controller_configs)
+    c_manager = controller_manager.ControllerManager(
+        'SomeClass', controller_configs
+    )
     c_manager.unregister_controllers()
     mock_destroy_func.assert_not_called()
     self.assertFalse(c_manager._controller_objects)
     self.assertFalse(c_manager._controller_modules)
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/controllers/android_device_lib/adb_test.py b/tests/mobly/controllers/android_device_lib/adb_test.py
index a013959..65c7eb5 100755
--- a/tests/mobly/controllers/android_device_lib/adb_test.py
+++ b/tests/mobly/controllers/android_device_lib/adb_test.py
@@ -28,23 +28,30 @@
     ('option2', 'value2'),
 ])
 # Mock android instrumentation commands.
-MOCK_BASIC_INSTRUMENTATION_COMMAND = ('am instrument -r -w  com.my'
-                                      '.instrumentation.tests/com.android'
-                                      '.common.support.test.runner'
-                                      '.AndroidJUnitRunner')
-MOCK_RUNNER_INSTRUMENTATION_COMMAND = ('am instrument -r -w  com.my'
-                                       '.instrumentation.tests/com.my'
-                                       '.instrumentation.runner')
-MOCK_OPTIONS_INSTRUMENTATION_COMMAND = ('am instrument -r -w -e option1 value1'
-                                        ' -e option2 value2 com.my'
-                                        '.instrumentation.tests/com.android'
-                                        '.common.support.test.runner'
-                                        '.AndroidJUnitRunner')
+MOCK_BASIC_INSTRUMENTATION_COMMAND = (
+    'am instrument -r -w  com.my'
+    '.instrumentation.tests/com.android'
+    '.common.support.test.runner'
+    '.AndroidJUnitRunner'
+)
+MOCK_RUNNER_INSTRUMENTATION_COMMAND = (
+    'am instrument -r -w  com.my'
+    '.instrumentation.tests/com.my'
+    '.instrumentation.runner'
+)
+MOCK_OPTIONS_INSTRUMENTATION_COMMAND = (
+    'am instrument -r -w -e option1 value1'
+    ' -e option2 value2 com.my'
+    '.instrumentation.tests/com.android'
+    '.common.support.test.runner'
+    '.AndroidJUnitRunner'
+)
 
 # Mock root command outputs.
 MOCK_ROOT_SUCCESS_OUTPUT = 'adbd is already running as root'
-MOCK_ROOT_ERROR_OUTPUT = (
-    'adb: unable to connect for root: closed'.encode('utf-8'))
+MOCK_ROOT_ERROR_OUTPUT = 'adb: unable to connect for root: closed'.encode(
+    'utf-8'
+)
 
 # Mock Shell Command
 MOCK_SHELL_COMMAND = 'ls'
@@ -66,14 +73,18 @@
     mock_popen.return_value.stdout.readline.side_effect = ['']
 
     mock_proc.communicate = mock.Mock(
-        return_value=('', MOCK_DEFAULT_STDERR.encode('utf-8')))
+        return_value=('', MOCK_DEFAULT_STDERR.encode('utf-8'))
+    )
     mock_proc.returncode = 0
     return mock_popen
 
   @mock.patch('mobly.utils.run_command')
   def test_is_adb_available(self, mock_run_command):
-    mock_run_command.return_value = (0, '/usr/local/bin/adb\n'.encode('utf-8'),
-                                     ''.encode('utf-8'))
+    mock_run_command.return_value = (
+        0,
+        '/usr/local/bin/adb\n'.encode('utf-8'),
+        ''.encode('utf-8'),
+    )
     self.assertTrue(adb.is_adb_available())
 
   @mock.patch('mobly.utils.run_command')
@@ -83,23 +94,29 @@
 
   @mock.patch('mobly.utils.run_command')
   def test_exec_cmd_no_timeout_success(self, mock_run_command):
-    mock_run_command.return_value = (0, MOCK_DEFAULT_STDOUT.encode('utf-8'),
-                                     MOCK_DEFAULT_STDERR.encode('utf-8'))
-    out = adb.AdbProxy()._exec_cmd(['fake_cmd'],
-                                   shell=False,
-                                   timeout=None,
-                                   stderr=None)
+    mock_run_command.return_value = (
+        0,
+        MOCK_DEFAULT_STDOUT.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
+    out = adb.AdbProxy()._exec_cmd(
+        ['fake_cmd'], shell=False, timeout=None, stderr=None
+    )
     self.assertEqual(MOCK_DEFAULT_STDOUT, out.decode('utf-8'))
     mock_run_command.assert_called_with(['fake_cmd'], shell=False, timeout=None)
 
   @mock.patch('mobly.utils.run_command')
   def test_exec_cmd_error_with_serial(self, mock_run_command):
     # Return 1 for retcode for error.
-    mock_run_command.return_value = (1, MOCK_DEFAULT_STDOUT.encode('utf-8'),
-                                     MOCK_DEFAULT_STDERR.encode('utf-8'))
+    mock_run_command.return_value = (
+        1,
+        MOCK_DEFAULT_STDOUT.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
     mock_serial = 'ABCD1234'
-    with self.assertRaisesRegex(adb.AdbError,
-                                'Error executing adb cmd .*') as context:
+    with self.assertRaisesRegex(
+        adb.AdbError, 'Error executing adb cmd .*'
+    ) as context:
       adb.AdbProxy(mock_serial).fake_cmd()
     self.assertEqual(context.exception.serial, mock_serial)
     self.assertIn(mock_serial, context.exception.cmd)
@@ -107,38 +124,45 @@
   @mock.patch('mobly.utils.run_command')
   def test_exec_cmd_error_without_serial(self, mock_run_command):
     # Return 1 for retcode for error.
-    mock_run_command.return_value = (1, MOCK_DEFAULT_STDOUT.encode('utf-8'),
-                                     MOCK_DEFAULT_STDERR.encode('utf-8'))
-    with self.assertRaisesRegex(adb.AdbError,
-                                'Error executing adb cmd .*') as context:
-      adb.AdbProxy()._exec_cmd(['fake_cmd'],
-                               shell=False,
-                               timeout=None,
-                               stderr=None)
+    mock_run_command.return_value = (
+        1,
+        MOCK_DEFAULT_STDOUT.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
+    with self.assertRaisesRegex(
+        adb.AdbError, 'Error executing adb cmd .*'
+    ) as context:
+      adb.AdbProxy()._exec_cmd(
+          ['fake_cmd'], shell=False, timeout=None, stderr=None
+      )
     self.assertFalse(context.exception.serial)
     mock_run_command.assert_called_with(['fake_cmd'], shell=False, timeout=None)
 
   @mock.patch('mobly.utils.run_command')
   def test_exec_cmd_with_timeout_success(self, mock_run_command):
-    mock_run_command.return_value = (0, MOCK_DEFAULT_STDOUT.encode('utf-8'),
-                                     MOCK_DEFAULT_STDERR.encode('utf-8'))
+    mock_run_command.return_value = (
+        0,
+        MOCK_DEFAULT_STDOUT.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
 
-    out = adb.AdbProxy()._exec_cmd(['fake_cmd'],
-                                   shell=False,
-                                   timeout=1,
-                                   stderr=None)
+    out = adb.AdbProxy()._exec_cmd(
+        ['fake_cmd'], shell=False, timeout=1, stderr=None
+    )
     self.assertEqual(MOCK_DEFAULT_STDOUT, out.decode('utf-8'))
     mock_run_command.assert_called_with(['fake_cmd'], shell=False, timeout=1)
 
   @mock.patch('mobly.utils.run_command')
   def test_exec_cmd_timed_out(self, mock_run_command):
-    mock_run_command.side_effect = subprocess.TimeoutExpired(cmd='mock_command',
-                                                             timeout=0.01)
+    mock_run_command.side_effect = subprocess.TimeoutExpired(
+        cmd='mock_command', timeout=0.01
+    )
     mock_serial = '1234Abcd'
 
     with self.assertRaisesRegex(
-        adb.AdbTimeoutError, 'Timed out executing command "adb -s '
-        '1234Abcd fake-cmd" after 0.01s.') as context:
+        adb.AdbTimeoutError,
+        'Timed out executing command "adb -s 1234Abcd fake-cmd" after 0.01s.',
+    ) as context:
       adb.AdbProxy(mock_serial).fake_cmd(timeout=0.01)
 
     self.assertEqual(context.exception.serial, mock_serial)
@@ -146,21 +170,23 @@
 
   @mock.patch('mobly.utils.run_command')
   def test_exec_cmd_timed_out_without_serial(self, mock_run_command):
-    mock_run_command.side_effect = subprocess.TimeoutExpired(cmd='mock_command',
-                                                             timeout=0.01)
+    mock_run_command.side_effect = subprocess.TimeoutExpired(
+        cmd='mock_command', timeout=0.01
+    )
 
     with self.assertRaisesRegex(
         adb.AdbTimeoutError,
-        'Timed out executing command "adb fake-cmd" after 0.01s.'):
+        'Timed out executing command "adb fake-cmd" after 0.01s.',
+    ):
       adb.AdbProxy().fake_cmd(timeout=0.01)
 
   def test_exec_cmd_with_negative_timeout_value(self):
-    with self.assertRaisesRegex(ValueError,
-                                'Timeout is not a positive value: -1'):
-      adb.AdbProxy()._exec_cmd(['fake_cmd'],
-                               shell=False,
-                               timeout=-1,
-                               stderr=None)
+    with self.assertRaisesRegex(
+        ValueError, 'Timeout is not a positive value: -1'
+    ):
+      adb.AdbProxy()._exec_cmd(
+          ['fake_cmd'], shell=False, timeout=-1, stderr=None
+      )
 
   @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
   def test_execute_and_process_stdout_reads_stdout(self, mock_popen):
@@ -168,9 +194,9 @@
     mock_popen.return_value.stdout.readline.side_effect = ['1', '2', '']
     mock_handler = mock.MagicMock()
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock_handler)
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock_handler
+    )
     self.assertEqual(mock_handler.call_count, 2)
     mock_handler.assert_any_call('1')
     mock_handler.assert_any_call('2')
@@ -182,50 +208,63 @@
     self._mock_execute_and_process_stdout_process(mock_popen)
     mock_handler = mock.MagicMock()
     mock_popen.return_value.communicate = mock.Mock(
-        return_value=(unexpected_stdout, MOCK_DEFAULT_STDERR.encode('utf-8')))
+        return_value=(unexpected_stdout, MOCK_DEFAULT_STDERR.encode('utf-8'))
+    )
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock_handler)
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock_handler
+    )
     self.assertEqual(mock_handler.call_count, 1)
     mock_handler.assert_called_with(unexpected_stdout)
 
   @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
   @mock.patch('logging.debug')
-  def test_execute_and_process_stdout_logs_cmd(self, mock_debug_logger,
-                                               mock_popen):
+  def test_execute_and_process_stdout_logs_cmd(
+      self, mock_debug_logger, mock_popen
+  ):
     raw_expected_stdout = ''
     expected_stdout = '[elided, processed via handler]'
     expected_stderr = MOCK_DEFAULT_STDERR.encode('utf-8')
     self._mock_execute_and_process_stdout_process(mock_popen)
     mock_popen.return_value.communicate = mock.Mock(
-        return_value=(raw_expected_stdout, expected_stderr))
+        return_value=(raw_expected_stdout, expected_stderr)
+    )
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock.MagicMock())
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock.MagicMock()
+    )
     mock_debug_logger.assert_called_with(
-        'cmd: %s, stdout: %s, stderr: %s, ret: %s', 'fake_cmd', expected_stdout,
-        expected_stderr, 0)
+        'cmd: %s, stdout: %s, stderr: %s, ret: %s',
+        'fake_cmd',
+        expected_stdout,
+        expected_stderr,
+        0,
+    )
 
   @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
   @mock.patch('logging.debug')
   def test_execute_and_process_stdout_logs_cmd_with_unexpected_stdout(
-      self, mock_debug_logger, mock_popen):
+      self, mock_debug_logger, mock_popen
+  ):
     raw_expected_stdout = MOCK_DEFAULT_STDOUT.encode('utf-8')
     expected_stdout = '[unexpected stdout] %s' % raw_expected_stdout
     expected_stderr = MOCK_DEFAULT_STDERR.encode('utf-8')
 
     self._mock_execute_and_process_stdout_process(mock_popen)
     mock_popen.return_value.communicate = mock.Mock(
-        return_value=(raw_expected_stdout, expected_stderr))
+        return_value=(raw_expected_stdout, expected_stderr)
+    )
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock.MagicMock())
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock.MagicMock()
+    )
     mock_debug_logger.assert_called_with(
-        'cmd: %s, stdout: %s, stderr: %s, ret: %s', 'fake_cmd', expected_stdout,
-        expected_stderr, 0)
+        'cmd: %s, stdout: %s, stderr: %s, ret: %s',
+        'fake_cmd',
+        expected_stdout,
+        expected_stderr,
+        0,
+    )
 
   @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
   def test_execute_and_process_stdout_despite_cmd_exits(self, mock_popen):
@@ -234,9 +273,9 @@
     mock_popen.return_value.stdout.readline.side_effect = ['1', '2', '3', '']
     mock_handler = mock.MagicMock()
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock_handler)
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock_handler
+    )
 
     self.assertEqual(mock_handler.call_count, 3)
     mock_handler.assert_any_call('1')
@@ -249,9 +288,9 @@
     mock_popen.return_value.stdout.readline.side_effect = ['1', '2', '3', '']
     mock_handler = mock.MagicMock()
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock_handler)
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock_handler
+    )
 
     self.assertEqual(mock_handler.call_count, 3)
     mock_handler.assert_any_call('1')
@@ -262,9 +301,9 @@
   def test_execute_and_process_stdout_returns_stderr(self, mock_popen):
     self._mock_execute_and_process_stdout_process(mock_popen)
 
-    err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                     shell=False,
-                                                     handler=mock.MagicMock())
+    err = adb.AdbProxy()._execute_and_process_stdout(
+        ['fake_cmd'], shell=False, handler=mock.MagicMock()
+    )
     self.assertEqual(MOCK_DEFAULT_STDERR, err.decode('utf-8'))
 
   @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
@@ -273,9 +312,9 @@
     mock_popen.return_value.returncode = 1
 
     with self.assertRaisesRegex(adb.AdbError, 'Error executing adb cmd .*'):
-      err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                       shell=False,
-                                                       handler=mock.MagicMock())
+      err = adb.AdbProxy()._execute_and_process_stdout(
+          ['fake_cmd'], shell=False, handler=mock.MagicMock()
+      )
 
   @mock.patch('mobly.controllers.android_device_lib.adb.subprocess.Popen')
   def test_execute_and_process_stdout_when_handler_crash(self, mock_popen):
@@ -285,9 +324,9 @@
     mock_handler.side_effect = ['', TypeError('fake crash'), '', '']
 
     with self.assertRaisesRegex(TypeError, 'fake crash'):
-      err = adb.AdbProxy()._execute_and_process_stdout(['fake_cmd'],
-                                                       shell=False,
-                                                       handler=mock_handler)
+      err = adb.AdbProxy()._execute_and_process_stdout(
+          ['fake_cmd'], shell=False, handler=mock_handler
+      )
 
     mock_popen.return_value.communicate.assert_called_once_with()
 
@@ -297,180 +336,192 @@
 
   def test_construct_adb_cmd_with_one_command(self):
     adb_cmd = adb.AdbProxy()._construct_adb_cmd(
-        'shell ls /asdafsfd/asdf-asfd/asa', [], shell=False)
+        'shell ls /asdafsfd/asdf-asfd/asa', [], shell=False
+    )
     self.assertEqual(adb_cmd, ['adb', 'shell ls /asdafsfd/asdf-asfd/asa'])
 
   def test_construct_adb_cmd_with_one_arg_command(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                'ls /asdafsfd/asdf-asfd/asa',
-                                                shell=False)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', 'ls /asdafsfd/asdf-asfd/asa', shell=False
+    )
     self.assertEqual(adb_cmd, ['adb', 'shell', 'ls /asdafsfd/asdf-asfd/asa'])
 
   def test_construct_adb_cmd_with_one_arg_command_list(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                ['ls /asdafsfd/asdf-asfd/asa'],
-                                                shell=False)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', ['ls /asdafsfd/asdf-asfd/asa'], shell=False
+    )
     self.assertEqual(adb_cmd, ['adb', 'shell', 'ls /asdafsfd/asdf-asfd/asa'])
 
   def test_construct_adb_cmd_with_special_characters(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                ['a b', '"blah"', r'\/\/'],
-                                                shell=False)
-    self.assertEqual(adb_cmd, ['adb', 'shell', 'a b', '"blah"', r"\/\/"])
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', ['a b', '"blah"', r'\/\/'], shell=False
+    )
+    self.assertEqual(adb_cmd, ['adb', 'shell', 'a b', '"blah"', r'\/\/'])
 
   def test_construct_adb_cmd_with_serial(self):
-    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
-                                                       'arg1',
-                                                       shell=False)
+    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd(
+        'shell', 'arg1', shell=False
+    )
     self.assertEqual(adb_cmd, ['adb', '-s', '12345', 'shell', 'arg1'])
 
   def test_construct_adb_cmd_with_list(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell', ['arg1', 'arg2'],
-                                                shell=False)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', ['arg1', 'arg2'], shell=False
+    )
     self.assertEqual(adb_cmd, ['adb', 'shell', 'arg1', 'arg2'])
 
   def test_construct_adb_cmd_with_serial_with_list(self):
-    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
-                                                       ['arg1', 'arg2'],
-                                                       shell=False)
+    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd(
+        'shell', ['arg1', 'arg2'], shell=False
+    )
     self.assertEqual(adb_cmd, ['adb', '-s', '12345', 'shell', 'arg1', 'arg2'])
 
   def test_construct_adb_cmd_with_shell_true(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                'arg1 arg2',
-                                                shell=True)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', 'arg1 arg2', shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" shell arg1 arg2')
 
   def test_construct_adb_cmd_with_shell_true_with_one_command(self):
     adb_cmd = adb.AdbProxy()._construct_adb_cmd(
-        'shell ls /asdafsfd/asdf-asfd/asa', [], shell=True)
+        'shell ls /asdafsfd/asdf-asfd/asa', [], shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" shell ls /asdafsfd/asdf-asfd/asa ')
 
   def test_construct_adb_cmd_with_shell_true_with_one_arg_command(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                'ls /asdafsfd/asdf-asfd/asa',
-                                                shell=True)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', 'ls /asdafsfd/asdf-asfd/asa', shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" shell ls /asdafsfd/asdf-asfd/asa')
 
   def test_construct_adb_cmd_with_shell_true_with_one_arg_command_list(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                ['ls /asdafsfd/asdf-asfd/asa'],
-                                                shell=True)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', ['ls /asdafsfd/asdf-asfd/asa'], shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" shell \'ls /asdafsfd/asdf-asfd/asa\'')
 
   def test_construct_adb_cmd_with_shell_true_with_auto_quotes(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell',
-                                                ['a b', '"blah"', r'\/\/'],
-                                                shell=True)
-    self.assertEqual(adb_cmd, '"adb" shell \'a b\' \'"blah"\' \'\\/\\/\'')
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', ['a b', '"blah"', r'\/\/'], shell=True
+    )
+    self.assertEqual(adb_cmd, "\"adb\" shell 'a b' '\"blah\"' '\\/\\/'")
 
   def test_construct_adb_cmd_with_shell_true_with_serial(self):
-    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
-                                                       'arg1 arg2',
-                                                       shell=True)
+    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd(
+        'shell', 'arg1 arg2', shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" -s "12345" shell arg1 arg2')
 
   def test_construct_adb_cmd_with_shell_true_with_list(self):
-    adb_cmd = adb.AdbProxy()._construct_adb_cmd('shell', ['arg1', 'arg2'],
-                                                shell=True)
+    adb_cmd = adb.AdbProxy()._construct_adb_cmd(
+        'shell', ['arg1', 'arg2'], shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" shell arg1 arg2')
 
   def test_construct_adb_cmd_with_shell_true_with_serial_with_list(self):
-    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd('shell',
-                                                       ['arg1', 'arg2'],
-                                                       shell=True)
+    adb_cmd = adb.AdbProxy('12345')._construct_adb_cmd(
+        'shell', ['arg1', 'arg2'], shell=True
+    )
     self.assertEqual(adb_cmd, '"adb" -s "12345" shell arg1 arg2')
 
   def test_exec_adb_cmd(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
       mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
       adb.AdbProxy().shell(['arg1', 'arg2'])
-      mock_exec_cmd.assert_called_once_with(['adb', 'shell', 'arg1', 'arg2'],
-                                            shell=False,
-                                            timeout=None,
-                                            stderr=None)
+      mock_exec_cmd.assert_called_once_with(
+          ['adb', 'shell', 'arg1', 'arg2'],
+          shell=False,
+          timeout=None,
+          stderr=None,
+      )
 
   def test_exec_adb_cmd_with_shell_true(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
       mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
       adb.AdbProxy().shell('arg1 arg2', shell=True)
-      mock_exec_cmd.assert_called_once_with('"adb" shell arg1 arg2',
-                                            shell=True,
-                                            timeout=None,
-                                            stderr=None)
+      mock_exec_cmd.assert_called_once_with(
+          '"adb" shell arg1 arg2', shell=True, timeout=None, stderr=None
+      )
 
   def test_exec_adb_cmd_formats_command(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
-      with mock.patch.object(adb.AdbProxy,
-                             '_construct_adb_cmd') as mock_construct_adb_cmd:
+      with mock.patch.object(
+          adb.AdbProxy, '_construct_adb_cmd'
+      ) as mock_construct_adb_cmd:
         mock_adb_cmd = mock.MagicMock()
         mock_adb_args = mock.MagicMock()
         mock_construct_adb_cmd.return_value = mock_adb_cmd
         mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
 
         adb.AdbProxy().shell(mock_adb_args)
-        mock_construct_adb_cmd.assert_called_once_with('shell',
-                                                       mock_adb_args,
-                                                       shell=False)
-        mock_exec_cmd.assert_called_once_with(mock_adb_cmd,
-                                              shell=False,
-                                              timeout=None,
-                                              stderr=None)
+        mock_construct_adb_cmd.assert_called_once_with(
+            'shell', mock_adb_args, shell=False
+        )
+        mock_exec_cmd.assert_called_once_with(
+            mock_adb_cmd, shell=False, timeout=None, stderr=None
+        )
 
   def test_exec_adb_cmd_formats_command_with_shell_true(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
-      with mock.patch.object(adb.AdbProxy,
-                             '_construct_adb_cmd') as mock_construct_adb_cmd:
+      with mock.patch.object(
+          adb.AdbProxy, '_construct_adb_cmd'
+      ) as mock_construct_adb_cmd:
         mock_adb_cmd = mock.MagicMock()
         mock_adb_args = mock.MagicMock()
         mock_construct_adb_cmd.return_value = mock_adb_cmd
 
         adb.AdbProxy().shell(mock_adb_args, shell=True)
-        mock_construct_adb_cmd.assert_called_once_with('shell',
-                                                       mock_adb_args,
-                                                       shell=True)
-        mock_exec_cmd.assert_called_once_with(mock_adb_cmd,
-                                              shell=True,
-                                              timeout=None,
-                                              stderr=None)
+        mock_construct_adb_cmd.assert_called_once_with(
+            'shell', mock_adb_args, shell=True
+        )
+        mock_exec_cmd.assert_called_once_with(
+            mock_adb_cmd, shell=True, timeout=None, stderr=None
+        )
 
   def test_execute_adb_and_process_stdout_formats_command(self):
     with mock.patch.object(
-        adb.AdbProxy,
-        '_execute_and_process_stdout') as mock_execute_and_process_stdout:
-      with mock.patch.object(adb.AdbProxy,
-                             '_construct_adb_cmd') as mock_construct_adb_cmd:
+        adb.AdbProxy, '_execute_and_process_stdout'
+    ) as mock_execute_and_process_stdout:
+      with mock.patch.object(
+          adb.AdbProxy, '_construct_adb_cmd'
+      ) as mock_construct_adb_cmd:
         mock_adb_cmd = mock.MagicMock()
         mock_adb_args = mock.MagicMock()
         mock_handler = mock.MagicMock()
         mock_construct_adb_cmd.return_value = mock_adb_cmd
 
-        adb.AdbProxy()._execute_adb_and_process_stdout('shell',
-                                                       mock_adb_args,
-                                                       shell=False,
-                                                       handler=mock_handler)
-        mock_construct_adb_cmd.assert_called_once_with('shell',
-                                                       mock_adb_args,
-                                                       shell=False)
+        adb.AdbProxy()._execute_adb_and_process_stdout(
+            'shell', mock_adb_args, shell=False, handler=mock_handler
+        )
+        mock_construct_adb_cmd.assert_called_once_with(
+            'shell', mock_adb_args, shell=False
+        )
         mock_execute_and_process_stdout.assert_called_once_with(
-            mock_adb_cmd, shell=False, handler=mock_handler)
+            mock_adb_cmd, shell=False, handler=mock_handler
+        )
 
   @mock.patch('mobly.utils.run_command')
   def test_exec_adb_cmd_with_stderr_pipe(self, mock_run_command):
-    mock_run_command.return_value = (0, MOCK_DEFAULT_STDOUT.encode('utf-8'),
-                                     MOCK_DEFAULT_STDERR.encode('utf-8'))
+    mock_run_command.return_value = (
+        0,
+        MOCK_DEFAULT_STDOUT.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
     stderr_redirect = io.BytesIO()
     out = adb.AdbProxy().shell('arg1 arg2', shell=True, stderr=stderr_redirect)
     self.assertEqual(MOCK_DEFAULT_STDOUT, out.decode('utf-8'))
-    self.assertEqual(MOCK_DEFAULT_STDERR,
-                     stderr_redirect.getvalue().decode('utf-8'))
+    self.assertEqual(
+        MOCK_DEFAULT_STDERR, stderr_redirect.getvalue().decode('utf-8')
+    )
 
   @mock.patch('mobly.utils.run_command')
   def test_connect_success(self, mock_run_command):
     mock_address = 'localhost:1234'
     mock_run_command.return_value = (
-        0, f'connected to {mock_address}'.encode('utf-8'),
-        MOCK_DEFAULT_STDERR.encode('utf-8'))
+        0,
+        f'connected to {mock_address}'.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
 
     out = adb.AdbProxy().connect(mock_address)
     self.assertEqual('connected to localhost:1234', out.decode('utf-8'))
@@ -479,8 +530,10 @@
   def test_connect_already_connected(self, mock_run_command):
     mock_address = 'localhost:1234'
     mock_run_command.return_value = (
-        0, f'already connected to {mock_address}'.encode('utf-8'),
-        MOCK_DEFAULT_STDERR.encode('utf-8'))
+        0,
+        f'already connected to {mock_address}'.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
 
     out = adb.AdbProxy().connect(mock_address)
     self.assertEqual('already connected to localhost:1234', out.decode('utf-8'))
@@ -488,11 +541,15 @@
   @mock.patch('mobly.utils.run_command')
   def test_connect_fail(self, mock_run_command):
     mock_address = 'localhost:1234'
-    mock_run_command.return_value = (0, 'Connection refused\n'.encode('utf-8'),
-                                     MOCK_DEFAULT_STDERR.encode('utf-8'))
+    mock_run_command.return_value = (
+        0,
+        'Connection refused\n'.encode('utf-8'),
+        MOCK_DEFAULT_STDERR.encode('utf-8'),
+    )
 
     with self.assertRaisesRegex(
-        adb.AdbError, 'Error executing adb cmd "connect localhost:1234".'):
+        adb.AdbError, 'Error executing adb cmd "connect localhost:1234".'
+    ):
       out = adb.AdbProxy().connect(mock_address)
 
   def test_getprop(self):
@@ -503,18 +560,22 @@
           ['adb', 'shell', 'getprop', 'haha'],
           shell=False,
           stderr=None,
-          timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
+          timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC,
+      )
 
   def test_getprop_custom_timeout(self):
     timeout_s = adb.DEFAULT_GETPROP_TIMEOUT_SEC * 2
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
       mock_exec_cmd.return_value = b'blah'
-      self.assertEqual(adb.AdbProxy().getprop('haha', timeout=timeout_s),
-                       'blah')
-      mock_exec_cmd.assert_called_once_with(['adb', 'shell', 'getprop', 'haha'],
-                                            shell=False,
-                                            stderr=None,
-                                            timeout=timeout_s)
+      self.assertEqual(
+          adb.AdbProxy().getprop('haha', timeout=timeout_s), 'blah'
+      )
+      mock_exec_cmd.assert_called_once_with(
+          ['adb', 'shell', 'getprop', 'haha'],
+          shell=False,
+          stderr=None,
+          timeout=timeout_s,
+      )
 
   def test__parse_getprop_output_special_values(self):
     mock_adb_output = (
@@ -530,9 +591,10 @@
     )
     parsed_props = adb.AdbProxy()._parse_getprop_output(mock_adb_output)
     expected_output = {
-        'persist.sys.boot.reason.history':
-            ('reboot,adb,1558549857\nreboot,factory_reset,1558483886\n'
-             'reboot,1558483823'),
+        'persist.sys.boot.reason.history': (
+            'reboot,adb,1558549857\nreboot,factory_reset,1558483886\n'
+            'reboot,1558483823'
+        ),
         'selinux.abc': 'key: value',
         'persist.something': 'haha\n',
         'selinux.restorecon_recursive': '/data/misc_ce/10',
@@ -542,26 +604,28 @@
     self.assertEqual(parsed_props, expected_output)
 
   def test__parse_getprop_output_malformat_output(self):
-    mock_adb_output = (
-        b'[selinux.restorecon_recursive][/data/misc_ce/10]\n'  # Malformat
+    mock_adb_output = (  # Malformat
+        b'[selinux.restorecon_recursive][/data/misc_ce/10]\n'
         b'[persist.sys.boot.reason]: [reboot,adb,1558549857]\n'
-        b'[persist.something]: [haha]\n')
+        b'[persist.something]: [haha]\n'
+    )
     parsed_props = adb.AdbProxy()._parse_getprop_output(mock_adb_output)
     expected_output = {
         'persist.sys.boot.reason': 'reboot,adb,1558549857',
-        'persist.something': 'haha'
+        'persist.something': 'haha',
     }
     self.assertEqual(parsed_props, expected_output)
 
   def test__parse_getprop_output_special_line_separator(self):
-    mock_adb_output = (
-        b'[selinux.restorecon_recursive][/data/misc_ce/10]\r\n'  # Malformat
+    mock_adb_output = (  # Malformat
+        b'[selinux.restorecon_recursive][/data/misc_ce/10]\r\n'
         b'[persist.sys.boot.reason]: [reboot,adb,1558549857]\r\n'
-        b'[persist.something]: [haha]\r\n')
+        b'[persist.something]: [haha]\r\n'
+    )
     parsed_props = adb.AdbProxy()._parse_getprop_output(mock_adb_output)
     expected_output = {
         'persist.sys.boot.reason': 'reboot,adb,1558549857',
-        'persist.something': 'haha'
+        'persist.something': 'haha',
     }
     self.assertEqual(parsed_props, expected_output)
 
@@ -572,42 +636,51 @@
           b'\n[sendbug.preferred.domain]: [google.com]\n'
           b'[sys.uidcpupower]: []\n'
           b'[sys.wifitracing.started]: [1]\n'
-          b'[telephony.lteOnCdmaDevice]: [1]\n\n')
+          b'[telephony.lteOnCdmaDevice]: [1]\n\n'
+      )
       actual_output = adb.AdbProxy().getprops([
           'sys.wifitracing.started',  # "numeric" value
           'sys.uidcpupower',  # empty value
           'sendbug.preferred.domain',  # string value
-          'nonExistentProp'
+          'nonExistentProp',
       ])
       self.assertEqual(
-          actual_output, {
+          actual_output,
+          {
               'sys.wifitracing.started': '1',
               'sys.uidcpupower': '',
-              'sendbug.preferred.domain': 'google.com'
-          })
+              'sendbug.preferred.domain': 'google.com',
+          },
+      )
       mock_exec_cmd.assert_called_once_with(
           ['adb', 'shell', 'getprop'],
           shell=False,
           stderr=None,
-          timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
+          timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC,
+      )
       mock_sleep.assert_not_called()
 
   @mock.patch('time.sleep', return_value=mock.MagicMock())
   def test_getprops_when_empty_string_randomly_returned(self, mock_sleep):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
       mock_exec_cmd.side_effect = [
-          b'', (b'\n[ro.build.id]: [AB42]\n'
-                b'[ro.build.type]: [userdebug]\n\n')
+          b'',
+          b'\n[ro.build.id]: [AB42]\n[ro.build.type]: [userdebug]\n\n',
       ]
       actual_output = adb.AdbProxy().getprops(['ro.build.id'])
-      self.assertEqual(actual_output, {
-          'ro.build.id': 'AB42',
-      })
+      self.assertEqual(
+          actual_output,
+          {
+              'ro.build.id': 'AB42',
+          },
+      )
       self.assertEqual(mock_exec_cmd.call_count, 2)
-      mock_exec_cmd.assert_called_with(['adb', 'shell', 'getprop'],
-                                       shell=False,
-                                       stderr=None,
-                                       timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
+      mock_exec_cmd.assert_called_with(
+          ['adb', 'shell', 'getprop'],
+          shell=False,
+          stderr=None,
+          timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC,
+      )
       self.assertEqual(mock_sleep.call_count, 1)
       mock_sleep.assert_called_with(1)
 
@@ -618,16 +691,34 @@
       actual_output = adb.AdbProxy().getprops(['ro.build.id'])
       self.assertEqual(actual_output, {})
       self.assertEqual(mock_exec_cmd.call_count, 3)
-      mock_exec_cmd.assert_called_with(['adb', 'shell', 'getprop'],
-                                       shell=False,
-                                       stderr=None,
-                                       timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC)
+      mock_exec_cmd.assert_called_with(
+          ['adb', 'shell', 'getprop'],
+          shell=False,
+          stderr=None,
+          timeout=adb.DEFAULT_GETPROP_TIMEOUT_SEC,
+      )
       self.assertEqual(mock_sleep.call_count, 2)
       mock_sleep.assert_called_with(1)
 
   def test_forward(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
-      adb.AdbProxy().forward(MOCK_SHELL_COMMAND)
+      adb.AdbProxy().forward(['tcp:12345', 'tcp:98765'])
+      mock_exec_cmd.assert_called_with(
+          ['adb', 'forward', 'tcp:12345', 'tcp:98765'],
+          shell=False,
+          timeout=None,
+          stderr=None,
+      )
+
+  def test_reverse(self):
+    with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
+      adb.AdbProxy().reverse(['tcp:12345', 'tcp:98765'])
+      mock_exec_cmd.assert_called_with(
+          ['adb', 'reverse', 'tcp:12345', 'tcp:98765'],
+          shell=False,
+          timeout=None,
+          stderr=None,
+      )
 
   def test_instrument_without_parameters(self):
     """Verifies the AndroidDevice object's instrument command is correct in
@@ -639,7 +730,8 @@
           ['adb', 'shell', MOCK_BASIC_INSTRUMENTATION_COMMAND],
           shell=False,
           timeout=None,
-          stderr=None)
+          stderr=None,
+      )
       self.assertEqual(output, mock_exec_cmd.return_value)
 
   def test_instrument_with_runner(self):
@@ -647,13 +739,15 @@
     with a runner specified.
     """
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
-      stdout = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE,
-                                         runner=MOCK_INSTRUMENTATION_RUNNER)
+      stdout = adb.AdbProxy().instrument(
+          MOCK_INSTRUMENTATION_PACKAGE, runner=MOCK_INSTRUMENTATION_RUNNER
+      )
       mock_exec_cmd.assert_called_once_with(
           ['adb', 'shell', MOCK_RUNNER_INSTRUMENTATION_COMMAND],
           shell=False,
           timeout=None,
-          stderr=None)
+          stderr=None,
+      )
       self.assertEqual(stdout, mock_exec_cmd.return_value)
 
   def test_instrument_with_options(self):
@@ -661,13 +755,15 @@
     with options.
     """
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
-      stdout = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE,
-                                         options=MOCK_INSTRUMENTATION_OPTIONS)
+      stdout = adb.AdbProxy().instrument(
+          MOCK_INSTRUMENTATION_PACKAGE, options=MOCK_INSTRUMENTATION_OPTIONS
+      )
       mock_exec_cmd.assert_called_once_with(
           ['adb', 'shell', MOCK_OPTIONS_INSTRUMENTATION_COMMAND],
           shell=False,
           timeout=None,
-          stderr=None)
+          stderr=None,
+      )
       self.assertEqual(stdout, mock_exec_cmd.return_value)
 
   def test_instrument_with_handler(self):
@@ -679,14 +775,16 @@
       pass
 
     with mock.patch.object(
-        adb.AdbProxy,
-        '_execute_and_process_stdout') as mock_execute_and_process_stdout:
-      stderr = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE,
-                                         handler=mock_handler)
+        adb.AdbProxy, '_execute_and_process_stdout'
+    ) as mock_execute_and_process_stdout:
+      stderr = adb.AdbProxy().instrument(
+          MOCK_INSTRUMENTATION_PACKAGE, handler=mock_handler
+      )
       mock_execute_and_process_stdout.assert_called_once_with(
           ['adb', 'shell', MOCK_BASIC_INSTRUMENTATION_COMMAND],
           shell=False,
-          handler=mock_handler)
+          handler=mock_handler,
+      )
       self.assertEqual(stderr, mock_execute_and_process_stdout.return_value)
 
   def test_instrument_with_handler_with_runner(self):
@@ -698,15 +796,18 @@
       pass
 
     with mock.patch.object(
-        adb.AdbProxy,
-        '_execute_and_process_stdout') as mock_execute_and_process_stdout:
-      stderr = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE,
-                                         runner=MOCK_INSTRUMENTATION_RUNNER,
-                                         handler=mock_handler)
+        adb.AdbProxy, '_execute_and_process_stdout'
+    ) as mock_execute_and_process_stdout:
+      stderr = adb.AdbProxy().instrument(
+          MOCK_INSTRUMENTATION_PACKAGE,
+          runner=MOCK_INSTRUMENTATION_RUNNER,
+          handler=mock_handler,
+      )
       mock_execute_and_process_stdout.assert_called_once_with(
           ['adb', 'shell', MOCK_RUNNER_INSTRUMENTATION_COMMAND],
           shell=False,
-          handler=mock_handler)
+          handler=mock_handler,
+      )
       self.assertEqual(stderr, mock_execute_and_process_stdout.return_value)
 
   def test_instrument_with_handler_with_options(self):
@@ -718,25 +819,27 @@
       pass
 
     with mock.patch.object(
-        adb.AdbProxy,
-        '_execute_and_process_stdout') as mock_execute_and_process_stdout:
-      stderr = adb.AdbProxy().instrument(MOCK_INSTRUMENTATION_PACKAGE,
-                                         options=MOCK_INSTRUMENTATION_OPTIONS,
-                                         handler=mock_handler)
+        adb.AdbProxy, '_execute_and_process_stdout'
+    ) as mock_execute_and_process_stdout:
+      stderr = adb.AdbProxy().instrument(
+          MOCK_INSTRUMENTATION_PACKAGE,
+          options=MOCK_INSTRUMENTATION_OPTIONS,
+          handler=mock_handler,
+      )
       mock_execute_and_process_stdout.assert_called_once_with(
           ['adb', 'shell', MOCK_OPTIONS_INSTRUMENTATION_COMMAND],
           shell=False,
-          handler=mock_handler)
+          handler=mock_handler,
+      )
       self.assertEqual(stderr, mock_execute_and_process_stdout.return_value)
 
   @mock.patch.object(adb.AdbProxy, '_exec_cmd')
   def test_root_success(self, mock_exec_cmd):
     mock_exec_cmd.return_value = MOCK_ROOT_SUCCESS_OUTPUT
     output = adb.AdbProxy().root()
-    mock_exec_cmd.assert_called_once_with(['adb', 'root'],
-                                          shell=False,
-                                          timeout=None,
-                                          stderr=None)
+    mock_exec_cmd.assert_called_once_with(
+        ['adb', 'root'], shell=False, timeout=None, stderr=None
+    )
     self.assertEqual(output, MOCK_ROOT_SUCCESS_OUTPUT)
 
   @mock.patch('time.sleep', return_value=mock.MagicMock())
@@ -744,13 +847,12 @@
   def test_root_success_with_retry(self, mock_exec_cmd, mock_sleep):
     mock_exec_cmd.side_effect = [
         adb.AdbError('adb root', '', MOCK_ROOT_ERROR_OUTPUT, 1),
-        MOCK_ROOT_SUCCESS_OUTPUT
+        MOCK_ROOT_SUCCESS_OUTPUT,
     ]
     output = adb.AdbProxy().root()
-    mock_exec_cmd.assert_called_with(['adb', 'root'],
-                                     shell=False,
-                                     timeout=None,
-                                     stderr=None)
+    mock_exec_cmd.assert_called_with(
+        ['adb', 'root'], shell=False, timeout=None, stderr=None
+    )
     self.assertEqual(output, MOCK_ROOT_SUCCESS_OUTPUT)
     self.assertEqual(mock_sleep.call_count, 1)
     mock_sleep.assert_called_with(10)
@@ -758,17 +860,20 @@
   @mock.patch('time.sleep', return_value=mock.MagicMock())
   @mock.patch.object(adb.AdbProxy, '_exec_cmd')
   def test_root_raises_adb_error_when_all_retries_failed(
-      self, mock_exec_cmd, mock_sleep):
-    mock_exec_cmd.side_effect = adb.AdbError('adb root', '',
-                                             MOCK_ROOT_ERROR_OUTPUT, 1)
-    expected_msg = ('Error executing adb cmd "adb root". '
-                    'ret: 1, stdout: , stderr: %s' % MOCK_ROOT_ERROR_OUTPUT)
+      self, mock_exec_cmd, mock_sleep
+  ):
+    mock_exec_cmd.side_effect = adb.AdbError(
+        'adb root', '', MOCK_ROOT_ERROR_OUTPUT, 1
+    )
+    expected_msg = (
+        'Error executing adb cmd "adb root". ret: 1, stdout: , stderr: %s'
+        % MOCK_ROOT_ERROR_OUTPUT
+    )
     with self.assertRaisesRegex(adb.AdbError, expected_msg):
       adb.AdbProxy().root()
-      mock_exec_cmd.assert_called_with(['adb', 'root'],
-                                       shell=False,
-                                       timeout=None,
-                                       stderr=None)
+      mock_exec_cmd.assert_called_with(
+          ['adb', 'root'], shell=False, timeout=None, stderr=None
+      )
     self.assertEqual(mock_sleep.call_count, adb.ADB_ROOT_RETRY_ATTEMPTS - 1)
     mock_sleep.assert_has_calls([mock.call(10), mock.call(20)])
 
@@ -780,7 +885,8 @@
           ['adb', 'shell', 'command', '-v', MOCK_SHELL_COMMAND],
           shell=False,
           timeout=None,
-          stderr=None)
+          stderr=None,
+      )
 
   def test_has_shell_command_with_existing_command(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
@@ -790,15 +896,17 @@
   def test_has_shell_command_with_missing_command_on_older_devices(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
       mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
-      mock_exec_cmd.side_effect = adb.AdbError(MOCK_ADB_SHELL_COMMAND_CHECK, '',
-                                               '', 0)
+      mock_exec_cmd.side_effect = adb.AdbError(
+          MOCK_ADB_SHELL_COMMAND_CHECK, '', '', 0
+      )
       self.assertFalse(adb.AdbProxy().has_shell_command(MOCK_SHELL_COMMAND))
 
   def test_has_shell_command_with_missing_command_on_newer_devices(self):
     with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
       mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT
-      mock_exec_cmd.side_effect = adb.AdbError(MOCK_ADB_SHELL_COMMAND_CHECK, '',
-                                               '', 1)
+      mock_exec_cmd.side_effect = adb.AdbError(
+          MOCK_ADB_SHELL_COMMAND_CHECK, '', '', 1
+      )
       self.assertFalse(adb.AdbProxy().has_shell_command(MOCK_SHELL_COMMAND))
 
   @mock.patch.object(adb.AdbProxy, 'getprop')
@@ -811,25 +919,30 @@
         ['adb', 'shell', 'am', 'get-current-user'],
         shell=False,
         stderr=None,
-        timeout=None)
+        timeout=None,
+    )
     self.assertEqual(user_id, 123)
 
   @mock.patch.object(adb.AdbProxy, 'getprop')
   @mock.patch.object(adb.AdbProxy, '_exec_cmd')
   def test_current_user_id_between_21_and_24(self, mock_exec_cmd, mock_getprop):
     mock_getprop.return_value = b'23'
-    mock_exec_cmd.return_value = (b'Users:\n'
-                                  b'UserInfo{123:Owner:13} serialNo=0\n'
-                                  b'Created: <unknown>\n'
-                                  b'Last logged in: +1h22m12s497ms ago\n'
-                                  b'UserInfo{456:Owner:14} serialNo=0\n'
-                                  b'Created: <unknown>\n'
-                                  b'Last logged in: +1h01m12s497ms ago\n')
+    mock_exec_cmd.return_value = (
+        b'Users:\n'
+        b'UserInfo{123:Owner:13} serialNo=0\n'
+        b'Created: <unknown>\n'
+        b'Last logged in: +1h22m12s497ms ago\n'
+        b'UserInfo{456:Owner:14} serialNo=0\n'
+        b'Created: <unknown>\n'
+        b'Last logged in: +1h01m12s497ms ago\n'
+    )
     user_id = adb.AdbProxy().current_user_id
-    mock_exec_cmd.assert_called_once_with(['adb', 'shell', 'dumpsys', 'user'],
-                                          shell=False,
-                                          stderr=None,
-                                          timeout=None)
+    mock_exec_cmd.assert_called_once_with(
+        ['adb', 'shell', 'dumpsys', 'user'],
+        shell=False,
+        stderr=None,
+        timeout=None,
+    )
     self.assertEqual(user_id, 123)
 
 
diff --git a/tests/mobly/controllers/android_device_lib/callback_handler_test.py b/tests/mobly/controllers/android_device_lib/callback_handler_test.py
index a30408f..2f3398c 100755
--- a/tests/mobly/controllers/android_device_lib/callback_handler_test.py
+++ b/tests/mobly/controllers/android_device_lib/callback_handler_test.py
@@ -18,7 +18,7 @@
 from mobly.controllers.android_device_lib import callback_handler
 from mobly.controllers.android_device_lib import jsonrpc_client_base
 
-MOCK_CALLBACK_ID = "1-0"
+MOCK_CALLBACK_ID = '1-0'
 MOCK_RAW_EVENT = {
     'callbackId': '2-1',
     'name': 'AsyncTaskResult',
@@ -26,26 +26,28 @@
     'data': {
         'exampleData': "Here's a simple event.",
         'successful': True,
-        'secretNumber': 12
-    }
+        'secretNumber': 12,
+    },
 }
 
 
 class CallbackHandlerTest(unittest.TestCase):
-  """Unit tests for mobly.controllers.android_device_lib.callback_handler.
-  """
+  """Unit tests for mobly.controllers.android_device_lib.callback_handler."""
 
   def test_timeout_value(self):
-    self.assertGreaterEqual(jsonrpc_client_base._SOCKET_READ_TIMEOUT,
-                            callback_handler.MAX_TIMEOUT)
+    self.assertGreaterEqual(
+        jsonrpc_client_base._SOCKET_READ_TIMEOUT, callback_handler.MAX_TIMEOUT
+    )
 
   def test_callback_id_property(self):
     mock_event_client = mock.Mock()
-    handler = callback_handler.CallbackHandler(callback_id=MOCK_CALLBACK_ID,
-                                               event_client=mock_event_client,
-                                               ret_value=None,
-                                               method_name=None,
-                                               ad=mock.Mock())
+    handler = callback_handler.CallbackHandler(
+        callback_id=MOCK_CALLBACK_ID,
+        event_client=mock_event_client,
+        ret_value=None,
+        method_name=None,
+        ad=mock.Mock(),
+    )
     self.assertEqual(handler.callback_id, MOCK_CALLBACK_ID)
     with self.assertRaises(AttributeError):
       handler.callback_id = 'ha'
@@ -53,11 +55,13 @@
   def test_event_dict_to_snippet_event(self):
     mock_event_client = mock.Mock()
     mock_event_client.eventWaitAndGet = mock.Mock(return_value=MOCK_RAW_EVENT)
-    handler = callback_handler.CallbackHandler(callback_id=MOCK_CALLBACK_ID,
-                                               event_client=mock_event_client,
-                                               ret_value=None,
-                                               method_name=None,
-                                               ad=mock.Mock())
+    handler = callback_handler.CallbackHandler(
+        callback_id=MOCK_CALLBACK_ID,
+        event_client=mock_event_client,
+        ret_value=None,
+        method_name=None,
+        ad=mock.Mock(),
+    )
     event = handler.waitAndGet('ha')
     self.assertEqual(event.name, MOCK_RAW_EVENT['name'])
     self.assertEqual(event.creation_time, MOCK_RAW_EVENT['time'])
@@ -66,15 +70,20 @@
 
   def test_wait_and_get_timeout(self):
     mock_event_client = mock.Mock()
-    java_timeout_msg = ('com.google.android.mobly.snippet.event.'
-                        'EventSnippet$EventSnippetException: timeout.')
+    java_timeout_msg = (
+        'com.google.android.mobly.snippet.event.'
+        'EventSnippet$EventSnippetException: timeout.'
+    )
     mock_event_client.eventWaitAndGet = mock.Mock(
-        side_effect=jsonrpc_client_base.ApiError(mock.Mock(), java_timeout_msg))
-    handler = callback_handler.CallbackHandler(callback_id=MOCK_CALLBACK_ID,
-                                               event_client=mock_event_client,
-                                               ret_value=None,
-                                               method_name=None,
-                                               ad=mock.Mock())
+        side_effect=jsonrpc_client_base.ApiError(mock.Mock(), java_timeout_msg)
+    )
+    handler = callback_handler.CallbackHandler(
+        callback_id=MOCK_CALLBACK_ID,
+        event_client=mock_event_client,
+        ret_value=None,
+        method_name=None,
+        ad=mock.Mock(),
+    )
     expected_msg = 'Timed out after waiting .*s for event "ha" .*'
     with self.assertRaisesRegex(callback_handler.TimeoutError, expected_msg):
       handler.waitAndGet('ha')
@@ -82,11 +91,13 @@
   def test_wait_for_event(self):
     mock_event_client = mock.Mock()
     mock_event_client.eventWaitAndGet = mock.Mock(return_value=MOCK_RAW_EVENT)
-    handler = callback_handler.CallbackHandler(callback_id=MOCK_CALLBACK_ID,
-                                               event_client=mock_event_client,
-                                               ret_value=None,
-                                               method_name=None,
-                                               ad=mock.Mock())
+    handler = callback_handler.CallbackHandler(
+        callback_id=MOCK_CALLBACK_ID,
+        event_client=mock_event_client,
+        ret_value=None,
+        method_name=None,
+        ad=mock.Mock(),
+    )
 
     def some_condition(event):
       return event.data['successful']
@@ -96,14 +107,17 @@
   def test_wait_for_event_negative(self):
     mock_event_client = mock.Mock()
     mock_event_client.eventWaitAndGet = mock.Mock(return_value=MOCK_RAW_EVENT)
-    handler = callback_handler.CallbackHandler(callback_id=MOCK_CALLBACK_ID,
-                                               event_client=mock_event_client,
-                                               ret_value=None,
-                                               method_name=None,
-                                               ad=mock.Mock())
+    handler = callback_handler.CallbackHandler(
+        callback_id=MOCK_CALLBACK_ID,
+        event_client=mock_event_client,
+        ret_value=None,
+        method_name=None,
+        ad=mock.Mock(),
+    )
     expected_msg = (
         'Timed out after 0.01s waiting for an "AsyncTaskResult" event that'
-        ' satisfies the predicate "some_condition".')
+        ' satisfies the predicate "some_condition".'
+    )
 
     def some_condition(event):
       return False
@@ -112,25 +126,26 @@
       handler.waitForEvent('AsyncTaskResult', some_condition, 0.01)
 
   def test_wait_for_event_max_timeout(self):
-    """waitForEvent should not raise the timeout exceed threshold error.
-    """
+    """waitForEvent should not raise the timeout exceed threshold error."""
     mock_event_client = mock.Mock()
     mock_event_client.eventWaitAndGet = mock.Mock(return_value=MOCK_RAW_EVENT)
-    handler = callback_handler.CallbackHandler(callback_id=MOCK_CALLBACK_ID,
-                                               event_client=mock_event_client,
-                                               ret_value=None,
-                                               method_name=None,
-                                               ad=mock.Mock())
+    handler = callback_handler.CallbackHandler(
+        callback_id=MOCK_CALLBACK_ID,
+        event_client=mock_event_client,
+        ret_value=None,
+        method_name=None,
+        ad=mock.Mock(),
+    )
 
     def some_condition(event):
       return event.data['successful']
 
     big_timeout = callback_handler.MAX_TIMEOUT * 2
     # This line should not raise.
-    event = handler.waitForEvent('AsyncTaskResult',
-                                 some_condition,
-                                 timeout=big_timeout)
+    event = handler.waitForEvent(
+        'AsyncTaskResult', some_condition, timeout=big_timeout
+    )
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/controllers/android_device_lib/callback_handler_v2_test.py b/tests/mobly/controllers/android_device_lib/callback_handler_v2_test.py
index b598cae..a7b8e9f 100644
--- a/tests/mobly/controllers/android_device_lib/callback_handler_v2_test.py
+++ b/tests/mobly/controllers/android_device_lib/callback_handler_v2_test.py
@@ -28,22 +28,24 @@
     'data': {
         'exampleData': "Here's a simple event.",
         'successful': True,
-        'secretNumber': 12
-    }
+        'secretNumber': 12,
+    },
 }
 
 
 class CallbackHandlerV2Test(unittest.TestCase):
   """Unit tests for callback_handler_v2.CallbackHandlerV2."""
 
-  def _make_callback_handler(self,
-                             callback_id=None,
-                             event_client=None,
-                             ret_value=None,
-                             method_name=None,
-                             device=None,
-                             rpc_max_timeout_sec=600,
-                             default_timeout_sec=120):
+  def _make_callback_handler(
+      self,
+      callback_id=None,
+      event_client=None,
+      ret_value=None,
+      method_name=None,
+      device=None,
+      rpc_max_timeout_sec=600,
+      default_timeout_sec=120,
+  ):
     return callback_handler_v2.CallbackHandlerV2(
         callback_id=callback_id,
         event_client=event_client,
@@ -51,7 +53,8 @@
         method_name=method_name,
         device=device,
         rpc_max_timeout_sec=rpc_max_timeout_sec,
-        default_timeout_sec=default_timeout_sec)
+        default_timeout_sec=default_timeout_sec,
+    )
 
   def assert_event_correct(self, actual_event, expected_raw_event_dict):
     expected_event = callback_event.from_dict(expected_raw_event_dict)
@@ -60,12 +63,14 @@
   def test_wait_and_get(self):
     mock_event_client = mock.Mock()
     mock_event_client.eventWaitAndGet = mock.Mock(return_value=MOCK_RAW_EVENT)
-    handler = self._make_callback_handler(callback_id=MOCK_CALLBACK_ID,
-                                          event_client=mock_event_client)
+    handler = self._make_callback_handler(
+        callback_id=MOCK_CALLBACK_ID, event_client=mock_event_client
+    )
     event = handler.waitAndGet('ha')
     self.assert_event_correct(event, MOCK_RAW_EVENT)
     mock_event_client.eventWaitAndGet.assert_called_once_with(
-        MOCK_CALLBACK_ID, 'ha', mock.ANY)
+        MOCK_CALLBACK_ID, 'ha', mock.ANY
+    )
 
   def test_wait_and_get_timeout_arg_transform(self):
     mock_event_client = mock.Mock()
@@ -76,12 +81,14 @@
     expected_rpc_timeout_ms = 10000
     _ = handler.waitAndGet('ha', timeout=wait_and_get_timeout_sec)
     mock_event_client.eventWaitAndGet.assert_called_once_with(
-        mock.ANY, mock.ANY, expected_rpc_timeout_ms)
+        mock.ANY, mock.ANY, expected_rpc_timeout_ms
+    )
 
   def test_wait_for_event(self):
     mock_event_client = mock.Mock()
-    handler = self._make_callback_handler(callback_id=MOCK_CALLBACK_ID,
-                                          event_client=mock_event_client)
+    handler = self._make_callback_handler(
+        callback_id=MOCK_CALLBACK_ID, event_client=mock_event_client
+    )
 
     event_should_ignore = {
         'callbackId': '2-1',
@@ -89,10 +96,11 @@
         'time': 20460228696,
         'data': {
             'successful': False,
-        }
+        },
     }
     mock_event_client.eventWaitAndGet.side_effect = [
-        event_should_ignore, MOCK_RAW_EVENT
+        event_should_ignore,
+        MOCK_RAW_EVENT,
     ]
 
     def some_condition(event):
@@ -107,11 +115,13 @@
 
   def test_get_all(self):
     mock_event_client = mock.Mock()
-    handler = self._make_callback_handler(callback_id=MOCK_CALLBACK_ID,
-                                          event_client=mock_event_client)
+    handler = self._make_callback_handler(
+        callback_id=MOCK_CALLBACK_ID, event_client=mock_event_client
+    )
 
     mock_event_client.eventGetAll = mock.Mock(
-        return_value=[MOCK_RAW_EVENT, MOCK_RAW_EVENT])
+        return_value=[MOCK_RAW_EVENT, MOCK_RAW_EVENT]
+    )
 
     all_events = handler.getAll('ha')
     self.assertEqual(len(all_events), 2)
@@ -119,29 +129,36 @@
       self.assert_event_correct(event, MOCK_RAW_EVENT)
 
     mock_event_client.eventGetAll.assert_called_once_with(
-        MOCK_CALLBACK_ID, 'ha')
+        MOCK_CALLBACK_ID, 'ha'
+    )
 
   def test_wait_and_get_timeout_message_pattern_matches(self):
     mock_event_client = mock.Mock()
     android_snippet_timeout_msg = (
         'com.google.android.mobly.snippet.event.EventSnippet$'
-        'EventSnippetException: timeout.')
+        'EventSnippetException: timeout.'
+    )
     mock_event_client.eventWaitAndGet = mock.Mock(
-        side_effect=errors.ApiError(mock.Mock(), android_snippet_timeout_msg))
-    handler = self._make_callback_handler(event_client=mock_event_client,
-                                          method_name='test_method')
+        side_effect=errors.ApiError(mock.Mock(), android_snippet_timeout_msg)
+    )
+    handler = self._make_callback_handler(
+        event_client=mock_event_client, method_name='test_method'
+    )
 
-    expected_msg = ('Timed out after waiting .*s for event "ha" triggered by '
-                    'test_method .*')
-    with self.assertRaisesRegex(errors.CallbackHandlerTimeoutError,
-                                expected_msg):
+    expected_msg = (
+        'Timed out after waiting .*s for event "ha" triggered by test_method .*'
+    )
+    with self.assertRaisesRegex(
+        errors.CallbackHandlerTimeoutError, expected_msg
+    ):
       handler.waitAndGet('ha')
 
   def test_wait_and_get_reraise_if_pattern_not_match(self):
     mock_event_client = mock.Mock()
     snippet_timeout_msg = 'Snippet executed with error.'
     mock_event_client.eventWaitAndGet = mock.Mock(
-        side_effect=errors.ApiError(mock.Mock(), snippet_timeout_msg))
+        side_effect=errors.ApiError(mock.Mock(), snippet_timeout_msg)
+    )
     handler = self._make_callback_handler(event_client=mock_event_client)
 
     with self.assertRaisesRegex(errors.ApiError, snippet_timeout_msg):
diff --git a/tests/mobly/controllers/android_device_lib/errors_test.py b/tests/mobly/controllers/android_device_lib/errors_test.py
index 196aa03..38a0ac1 100755
--- a/tests/mobly/controllers/android_device_lib/errors_test.py
+++ b/tests/mobly/controllers/android_device_lib/errors_test.py
@@ -31,19 +31,20 @@
     device = mock.MagicMock()
     device.__repr__ = lambda _: '[MockDevice]'
     exception = errors.ServiceError(device, 'Some error message.')
-    self.assertEqual(str(exception),
-                     '[MockDevice]::Service<None> Some error message.')
+    self.assertEqual(
+        str(exception), '[MockDevice]::Service<None> Some error message.'
+    )
 
   def test_subclass_service_error(self):
-
     class Error(errors.ServiceError):
       SERVICE_TYPE = 'SomeType'
 
     device = mock.MagicMock()
     device.__repr__ = lambda _: '[MockDevice]'
     exception = Error(device, 'Some error message.')
-    self.assertEqual(str(exception),
-                     '[MockDevice]::Service<SomeType> Some error message.')
+    self.assertEqual(
+        str(exception), '[MockDevice]::Service<SomeType> Some error message.'
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/controllers/android_device_lib/fastboot_test.py b/tests/mobly/controllers/android_device_lib/fastboot_test.py
index 6e59dea..86b697a 100644
--- a/tests/mobly/controllers/android_device_lib/fastboot_test.py
+++ b/tests/mobly/controllers/android_device_lib/fastboot_test.py
@@ -24,19 +24,24 @@
   @mock.patch('mobly.controllers.android_device_lib.fastboot.Popen')
   @mock.patch('logging.debug')
   def test_fastboot_commands_and_results_are_logged_to_debug_log(
-      self, mock_debug_logger, mock_popen):
+      self, mock_debug_logger, mock_popen
+  ):
     expected_stdout = 'stdout'
     expected_stderr = b'stderr'
     mock_popen.return_value.communicate = mock.Mock(
-        return_value=(expected_stdout, expected_stderr))
+        return_value=(expected_stdout, expected_stderr)
+    )
     mock_popen.return_value.returncode = 123
 
     fastboot.FastbootProxy().fake_command('extra', 'flags')
 
     mock_debug_logger.assert_called_with(
         'cmd: %s, stdout: %s, stderr: %s, ret: %s',
-        '\'fastboot fake-command extra flags\'', expected_stdout,
-        expected_stderr, 123)
+        "'fastboot fake-command extra flags'",
+        expected_stdout,
+        expected_stderr,
+        123,
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/controllers/android_device_lib/jsonrpc_client_base_test.py b/tests/mobly/controllers/android_device_lib/jsonrpc_client_base_test.py
index 4cbeb35..1861cc0 100755
--- a/tests/mobly/controllers/android_device_lib/jsonrpc_client_base_test.py
+++ b/tests/mobly/controllers/android_device_lib/jsonrpc_client_base_test.py
@@ -28,8 +28,7 @@
 
 
 class JsonRpcClientBaseTest(jsonrpc_client_test_base.JsonRpcClientTestBase):
-  """Unit tests for mobly.controllers.android_device_lib.jsonrpc_client_base.
-  """
+  """Unit tests for mobly.controllers.android_device_lib.jsonrpc_client_base."""
 
   @mock.patch('socket.create_connection')
   def test_open_timeout_io_error(self, mock_create_connection):
@@ -66,7 +65,8 @@
     client = FakeRpcClient()
     with self.assertRaisesRegex(
         jsonrpc_client_base.ProtocolError,
-        jsonrpc_client_base.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE):
+        jsonrpc_client_base.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE,
+    ):
       client.connect()
 
   def test_disconnect(self):
@@ -124,8 +124,9 @@
     Test that when the handshake is given an unknown status then the client
     will not be given a uid.
     """
-    self.setup_mock_socket_file(mock_create_connection,
-                                resp=self.MOCK_RESP_UNKNOWN_STATUS)
+    self.setup_mock_socket_file(
+        mock_create_connection, resp=self.MOCK_RESP_UNKNOWN_STATUS
+    )
     client = FakeRpcClient()
     client.connect()
     self.assertEqual(client.uid, jsonrpc_client_base.UNKNOWN_UID)
@@ -182,7 +183,8 @@
 
     with self.assertRaisesRegex(
         jsonrpc_client_base.ProtocolError,
-        jsonrpc_client_base.ProtocolError.MISMATCHED_API_ID):
+        jsonrpc_client_base.ProtocolError.MISMATCHED_API_ID,
+    ):
       client.some_rpc(1, 2, 3)
 
   @mock.patch('socket.create_connection')
@@ -201,7 +203,8 @@
 
     with self.assertRaisesRegex(
         jsonrpc_client_base.ProtocolError,
-        jsonrpc_client_base.ProtocolError.NO_RESPONSE_FROM_SERVER):
+        jsonrpc_client_base.ProtocolError.NO_RESPONSE_FROM_SERVER,
+    ):
       client.some_rpc(1, 2, 3)
 
   @mock.patch('socket.create_connection')
@@ -232,7 +235,8 @@
     Logic is the same as test_rpc_send_to_socket.
     """
     fake_file = self.setup_mock_socket_file(
-        mock_create_connection, resp=self.MOCK_RESP_WITHOUT_CALLBACK)
+        mock_create_connection, resp=self.MOCK_RESP_WITHOUT_CALLBACK
+    )
 
     client = FakeRpcClient()
     client.connect()
@@ -275,15 +279,17 @@
     response = client._client_receive()
     self.assertEqual(response, testing_rpc_response)
 
-    client.log.debug.assert_called_with('Snippet received: %s',
-                                        testing_rpc_response)
+    client.log.debug.assert_called_with(
+        'Snippet received: %s', testing_rpc_response
+    )
 
   @mock.patch('socket.create_connection')
   def test_rpc_truncated_logging_short_response(self, mock_create_connection):
     """Test rpc response will full logged when length is short."""
     fake_file = self.setup_mock_socket_file(mock_create_connection)
     testing_rpc_response = self.generate_rpc_response(
-        int(jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH / 2))
+        int(jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH / 2)
+    )
     fake_file.resp = testing_rpc_response
 
     client = FakeRpcClient()
@@ -293,17 +299,19 @@
     response = client._client_receive()
 
     self.assertEqual(response, testing_rpc_response)
-    client.log.debug.assert_called_with('Snippet received: %s',
-                                        testing_rpc_response)
+    client.log.debug.assert_called_with(
+        'Snippet received: %s', testing_rpc_response
+    )
 
   @mock.patch('socket.create_connection')
-  def test_rpc_truncated_logging_fit_size_response(self,
-                                                   mock_create_connection):
-    """Test rpc response will full logged when length is equal to threshold.
-    """
+  def test_rpc_truncated_logging_fit_size_response(
+      self, mock_create_connection
+  ):
+    """Test rpc response will full logged when length is equal to threshold."""
     fake_file = self.setup_mock_socket_file(mock_create_connection)
     testing_rpc_response = self.generate_rpc_response(
-        jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH)
+        jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH
+    )
     fake_file.resp = testing_rpc_response
 
     client = FakeRpcClient()
@@ -313,8 +321,9 @@
     response = client._client_receive()
 
     self.assertEqual(response, testing_rpc_response)
-    client.log.debug.assert_called_with('Snippet received: %s',
-                                        testing_rpc_response)
+    client.log.debug.assert_called_with(
+        'Snippet received: %s', testing_rpc_response
+    )
 
   @mock.patch('socket.create_connection')
   def test_rpc_truncated_logging_long_response(self, mock_create_connection):
@@ -334,8 +343,11 @@
     # DEBUG level log should truncated by given length.
     client.log.debug.assert_called_with(
         'Snippet received: %s... %d chars are truncated',
-        testing_rpc_response[:jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH],
-        resp_len - jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH)
+        testing_rpc_response[
+            : jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH
+        ],
+        resp_len - jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH,
+    )
 
   def test_close_scoket_connection(self):
     client = FakeRpcClient()
diff --git a/tests/mobly/controllers/android_device_lib/jsonrpc_shell_base_test.py b/tests/mobly/controllers/android_device_lib/jsonrpc_shell_base_test.py
index 8ac7b78..2cdcd5c 100755
--- a/tests/mobly/controllers/android_device_lib/jsonrpc_shell_base_test.py
+++ b/tests/mobly/controllers/android_device_lib/jsonrpc_shell_base_test.py
@@ -37,8 +37,9 @@
   @mock.patch.object(android_device, 'list_adb_devices')
   @mock.patch.object(android_device, 'get_instances')
   @mock.patch.object(os, 'environ', new={})
-  def test_load_device_when_one_device(self, mock_get_instances,
-                                       mock_list_adb_devices):
+  def test_load_device_when_one_device(
+      self, mock_get_instances, mock_list_adb_devices
+  ):
     mock_list_adb_devices.return_value = ['1234']
     mock_device = mock.MagicMock(spec=android_device.AndroidDevice)
     mock_get_instances.return_value = [mock_device]
@@ -49,8 +50,9 @@
   @mock.patch.object(android_device, 'list_adb_devices')
   @mock.patch.object(android_device, 'get_instances')
   @mock.patch.object(os, 'environ', new={'ANDROID_SERIAL': '1234'})
-  def test_load_device_when_android_serial(self, mock_get_instances,
-                                           mock_list_adb_devices):
+  def test_load_device_when_android_serial(
+      self, mock_get_instances, mock_list_adb_devices
+  ):
     mock_list_adb_devices.return_value = ['1234', '4321']
     mock_device = mock.MagicMock(spec=android_device.AndroidDevice)
     mock_get_instances.return_value = [mock_device]
@@ -62,8 +64,9 @@
   def test_load_device_when_no_devices(self, mock_list_adb_devices):
     mock_list_adb_devices.return_value = []
     json_shell = jsonrpc_shell_base.JsonRpcShellBase()
-    with self.assertRaisesRegex(jsonrpc_shell_base.Error,
-                                'No adb device found!'):
+    with self.assertRaisesRegex(
+        jsonrpc_shell_base.Error, 'No adb device found!'
+    ):
       json_shell.load_device()
 
   @mock.patch.object(android_device, 'list_adb_devices')
@@ -71,8 +74,9 @@
   def test_load_device_when_unspecified_device(self, mock_list_adb_devices):
     mock_list_adb_devices.return_value = ['1234', '4321']
     json_shell = jsonrpc_shell_base.JsonRpcShellBase()
-    with self.assertRaisesRegex(jsonrpc_shell_base.Error,
-                                'Expected one phone.*'):
+    with self.assertRaisesRegex(
+        jsonrpc_shell_base.Error, 'Expected one phone.*'
+    ):
       json_shell.load_device()
 
   @mock.patch.object(android_device, 'list_adb_devices')
@@ -80,8 +84,9 @@
   def test_load_device_when_device_not_found(self, mock_list_adb_devices):
     mock_list_adb_devices.return_value = ['4321']
     json_shell = jsonrpc_shell_base.JsonRpcShellBase()
-    with self.assertRaisesRegex(jsonrpc_shell_base.Error,
-                                'Device "1234" is not found by adb.'):
+    with self.assertRaisesRegex(
+        jsonrpc_shell_base.Error, 'Device "1234" is not found by adb.'
+    ):
       json_shell.load_device(serial='1234')
 
 
diff --git a/tests/mobly/controllers/android_device_lib/service_manager_test.py b/tests/mobly/controllers/android_device_lib/service_manager_test.py
index 1eae045..471c83f 100755
--- a/tests/mobly/controllers/android_device_lib/service_manager_test.py
+++ b/tests/mobly/controllers/android_device_lib/service_manager_test.py
@@ -62,7 +62,7 @@
 
   def assert_recorded_one_error(self, message):
     self.assertEqual(expects.recorder.error_count, 1)
-    for _, error in (expects.DEFAULT_TEST_RESULT_RECORD.extra_errors.items()):
+    for _, error in expects.DEFAULT_TEST_RESULT_RECORD.extra_errors.items():
       self.assertIn(message, error.details)
 
   def test_service_manager_instantiation(self):
@@ -102,13 +102,13 @@
       manager.register('mock_service', base_service)
 
   def test_register_wrong_subclass_type(self):
-
     class MyClass:
       pass
 
     manager = service_manager.ServiceManager(mock.MagicMock())
-    with self.assertRaisesRegex(service_manager.Error,
-                                '.* is not a subclass of BaseService!'):
+    with self.assertRaisesRegex(
+        service_manager.Error, '.* is not a subclass of BaseService!'
+    ):
       manager.register('mock_service', MyClass)
 
   def test_register_dup_alias(self):
@@ -139,7 +139,8 @@
     service1.ha = mock.MagicMock()
     service2.ha = mock.MagicMock()
     manager.for_each(
-        lambda service: manager._service_objects.pop(service.alias))
+        lambda service: manager._service_objects.pop(service.alias)
+    )
     self.assertFalse(manager._service_objects)
 
   def test_for_each_one_fail(self):
@@ -169,14 +170,16 @@
     service3.create_output_excerpts = mock.MagicMock()
     service1.create_output_excerpts.return_value = ['path/to/1.txt']
     service2.create_output_excerpts.return_value = [
-        'path/to/2-1.txt', 'path/to/2-2.txt'
+        'path/to/2-1.txt',
+        'path/to/2-2.txt',
     ]
     service3.create_output_excerpts.return_value = []
     mock_test_info = mock.MagicMock(output_path='path/to')
     result = manager.create_output_excerpts_all(mock_test_info)
     self.assertEqual(result['mock_service1'], ['path/to/1.txt'])
-    self.assertEqual(result['mock_service2'],
-                     ['path/to/2-1.txt', 'path/to/2-2.txt'])
+    self.assertEqual(
+        result['mock_service2'], ['path/to/2-1.txt', 'path/to/2-2.txt']
+    )
     self.assertEqual(result['mock_service3'], [])
 
   def test_unregister(self):
@@ -201,7 +204,8 @@
     manager = service_manager.ServiceManager(mock.MagicMock())
     with self.assertRaisesRegex(
         service_manager.Error,
-        '.* No service is registered with alias "mock_service"'):
+        '.* No service is registered with alias "mock_service"',
+    ):
       manager.unregister('mock_service')
 
   def test_unregister_handle_error_from_stop(self):
@@ -211,7 +215,8 @@
     service.stop_func.side_effect = Exception('Something failed in stop.')
     manager.unregister('mock_service')
     self.assert_recorded_one_error(
-        'Failed to stop service instance "mock_service".')
+        'Failed to stop service instance "mock_service".'
+    )
 
   def test_unregister_all(self):
     manager = service_manager.ServiceManager(mock.MagicMock())
@@ -238,7 +243,8 @@
     self.assertTrue(service1.is_alive)
     self.assertFalse(service2.is_alive)
     self.assert_recorded_one_error(
-        'Failed to stop service instance "mock_service1".')
+        'Failed to stop service instance "mock_service1".'
+    )
 
   def test_start_all(self):
     manager = service_manager.ServiceManager(mock.MagicMock())
@@ -256,7 +262,8 @@
     self.assertEqual(service2.start_func.call_count, 1)
     self.assertEqual(
         mock_call_tracker.mock_calls,
-        [mock.call.start1(None), mock.call.start2(None)])
+        [mock.call.start1(None), mock.call.start2(None)],
+    )
 
   def test_start_all_with_already_started_services(self):
     manager = service_manager.ServiceManager(mock.MagicMock())
@@ -295,8 +302,9 @@
     manager.stop_all()
     self.assertFalse(service1.is_alive)
     self.assertFalse(service2.is_alive)
-    self.assertEqual(mock_call_tracker.mock_calls,
-                     [mock.call.stop2(), mock.call.stop1()])
+    self.assertEqual(
+        mock_call_tracker.mock_calls, [mock.call.stop2(), mock.call.stop1()]
+    )
     self.assertEqual(service1.start_func.call_count, 1)
     self.assertEqual(service2.start_func.call_count, 1)
     self.assertEqual(service1.stop_func.call_count, 1)
@@ -359,8 +367,8 @@
     mock_call_tracker.pause2 = service2.pause_func
     manager.pause_all()
     self.assertEqual(
-        mock_call_tracker.mock_calls,
-        [mock.call.pause2(), mock.call.pause1()])
+        mock_call_tracker.mock_calls, [mock.call.pause2(), mock.call.pause1()]
+    )
     self.assertEqual(service1.pause_func.call_count, 1)
     self.assertEqual(service2.pause_func.call_count, 1)
     self.assertEqual(service1.resume_func.call_count, 0)
@@ -392,8 +400,8 @@
     manager.pause_all()
     manager.resume_all()
     self.assertEqual(
-        mock_call_tracker.mock_calls,
-        [mock.call.resume1(), mock.call.resume2()])
+        mock_call_tracker.mock_calls, [mock.call.resume1(), mock.call.resume2()]
+    )
     self.assertEqual(service1.pause_func.call_count, 1)
     self.assertEqual(service2.pause_func.call_count, 1)
     self.assertEqual(service1.resume_func.call_count, 1)
@@ -434,8 +442,10 @@
 
   def test_start_services_non_existent(self):
     manager = service_manager.ServiceManager(mock.MagicMock())
-    msg = ('.* No service is registered under the name "mock_service", '
-           'cannot start.')
+    msg = (
+        '.* No service is registered under the name "mock_service", '
+        'cannot start.'
+    )
     with self.assertRaisesRegex(service_manager.Error, msg):
       manager.start_services(['mock_service'])
 
@@ -452,8 +462,10 @@
 
   def test_resume_services_non_existent(self):
     manager = service_manager.ServiceManager(mock.MagicMock())
-    msg = ('.* No service is registered under the name "mock_service", '
-           'cannot resume.')
+    msg = (
+        '.* No service is registered under the name "mock_service", '
+        'cannot resume.'
+    )
     with self.assertRaisesRegex(service_manager.Error, msg):
       manager.resume_services(['mock_service'])
 
diff --git a/tests/mobly/controllers/android_device_lib/services/logcat_test.py b/tests/mobly/controllers/android_device_lib/services/logcat_test.py
index df15d76..66a20f8 100755
--- a/tests/mobly/controllers/android_device_lib/services/logcat_test.py
+++ b/tests/mobly/controllers/android_device_lib/services/logcat_test.py
@@ -29,24 +29,25 @@
 # The expected result of the cat adb operation.
 MOCK_ADB_LOGCAT_CAT_RESULT = [
     '02-29 14:02:21.456  4454  Something\n',
-    '02-29 14:02:21.789  4454  Something again\n'
+    '02-29 14:02:21.789  4454  Something again\n',
 ]
 # A mocked piece of adb logcat output.
-MOCK_ADB_LOGCAT = (u'02-29 14:02:19.123  4454  Nothing\n'
-                   u'%s'
-                   u'02-29 14:02:22.123  4454  Something again and again\n'
-                  ) % u''.join(MOCK_ADB_LOGCAT_CAT_RESULT)
+MOCK_ADB_LOGCAT = (
+    '02-29 14:02:19.123  4454  Nothing\n'
+    '%s'
+    '02-29 14:02:22.123  4454  Something again and again\n'
+) % ''.join(MOCK_ADB_LOGCAT_CAT_RESULT)
 # The expected result of the cat adb operation.
 MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT = [
     '02-29 14:02:21.456  4454  Something \u901a\n',
-    '02-29 14:02:21.789  4454  Something again\n'
+    '02-29 14:02:21.789  4454  Something again\n',
 ]
 # A mocked piece of adb logcat output.
 MOCK_ADB_UNICODE_LOGCAT = (
-    u'02-29 14:02:19.123  4454  Nothing\n'
-    u'%s'
-    u'02-29 14:02:22.123  4454  Something again and again\n'
-) % u''.join(MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT)
+    '02-29 14:02:19.123  4454  Nothing\n'
+    '%s'
+    '02-29 14:02:22.123  4454  Something again and again\n'
+) % ''.join(MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT)
 
 # Mock start and end time of the adb cat.
 MOCK_ADB_LOGCAT_BEGIN_TIME = '02-29 14:02:20.123'
@@ -54,11 +55,17 @@
 
 # Mock AdbError for missing logpersist scripts
 MOCK_LOGPERSIST_STOP_MISSING_ADB_ERROR = adb.AdbError(
-    'logpersist.stop --clear', b'',
-    '/system/bin/sh: logpersist.stop: not found', 0)
+    'logpersist.stop --clear',
+    b'',
+    '/system/bin/sh: logpersist.stop: not found',
+    0,
+)
 MOCK_LOGPERSIST_START_MISSING_ADB_ERROR = adb.AdbError(
-    'logpersist.start --clear', b'',
-    b'/system/bin/sh: logpersist.stop: not found', 0)
+    'logpersist.start --clear',
+    b'',
+    b'/system/bin/sh: logpersist.stop: not found',
+    0,
+)
 
 
 class LogcatTest(unittest.TestCase):
@@ -72,8 +79,7 @@
     self.tmp_dir = tempfile.mkdtemp()
 
   def tearDown(self):
-    """Removes the temp dir.
-    """
+    """Removes the temp dir."""
     shutil.rmtree(self.tmp_dir)
 
   def AssertFileContains(self, content, file_path):
@@ -86,18 +92,29 @@
       output = f.read()
     self.assertNotIn(content, output)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   @mock.patch('mobly.logger.get_log_file_timestamp')
-  def test_start_and_stop(self, get_timestamp_mock, open_logcat_mock,
-                          stop_proc_mock, start_proc_mock, create_dir_mock,
-                          FastbootProxy, MockAdbProxy):
+  def test_start_and_stop(
+      self,
+      get_timestamp_mock,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     """Verifies the steps of collecting adb logcat on an AndroidDevice
     object, including various function calls and the expected behaviors of
     the calls.
@@ -109,17 +126,18 @@
     logcat_service.start()
     # Verify start did the correct operations.
     self.assertTrue(logcat_service._adb_logcat_process)
-    expected_log_path = os.path.join(logging.log_path,
-                                     'AndroidDevice%s' % ad.serial,
-                                     'logcat,%s,fakemodel,123.txt' % ad.serial)
+    expected_log_path = os.path.join(
+        logging.log_path,
+        'AndroidDevice%s' % ad.serial,
+        'logcat,%s,fakemodel,123.txt' % ad.serial,
+    )
     create_dir_mock.assert_called_with(os.path.dirname(expected_log_path))
     adb_cmd = ' "adb" -s %s logcat -v threadtime -T 1  >> %s'
-    start_proc_mock.assert_called_with(adb_cmd %
-                                       (ad.serial, '"%s" ' % expected_log_path),
-                                       shell=True)
+    start_proc_mock.assert_called_with(
+        adb_cmd % (ad.serial, '"%s" ' % expected_log_path), shell=True
+    )
     self.assertEqual(logcat_service.adb_logcat_file_path, expected_log_path)
-    expected_msg = ('Logcat thread is already running, cannot start another'
-                    ' one.')
+    expected_msg = 'Logcat thread is already running, cannot start another one.'
     # Expect error if start is called back to back.
     with self.assertRaisesRegex(logcat.Error, expected_msg):
       logcat_service.start()
@@ -129,15 +147,21 @@
     self.assertIsNone(logcat_service._adb_logcat_process)
     self.assertEqual(logcat_service.adb_logcat_file_path, expected_log_path)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device.list_fastboot_devices',
-              return_value='1')
-  def test_start_in_fastboot_mode(self, _, start_proc_mock, FastbootProxy,
-                                  MockAdbProxy):
+  @mock.patch(
+      'mobly.controllers.android_device.list_fastboot_devices', return_value='1'
+  )
+  def test_start_in_fastboot_mode(
+      self, _, start_proc_mock, FastbootProxy, MockAdbProxy
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     logcat_service = logcat.Logcat(ad)
@@ -146,17 +170,27 @@
     self.assertFalse(logcat_service._adb_logcat_process)
     start_proc_mock.assert_not_called()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
-  def test_update_config(self, open_logcat_mock, stop_proc_mock,
-                         start_proc_mock, create_dir_mock, FastbootProxy,
-                         MockAdbProxy):
+  def test_update_config(
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     logcat_service = logcat.Logcat(ad)
@@ -164,56 +198,82 @@
     logcat_service.stop()
     new_log_params = '-a -b -c'
     new_file_path = 'some/path/log.txt'
-    new_config = logcat.Config(logcat_params=new_log_params,
-                               output_file_path=new_file_path)
+    new_config = logcat.Config(
+        logcat_params=new_log_params, output_file_path=new_file_path
+    )
     logcat_service.update_config(new_config)
     logcat_service.start()
     self.assertTrue(logcat_service._adb_logcat_process)
     create_dir_mock.assert_has_calls([mock.call('some/path')])
-    expected_adb_cmd = (' "adb" -s 1 logcat -v threadtime -T 1 -a -b -c >> '
-                        '"some/path/log.txt" ')
+    expected_adb_cmd = (
+        ' "adb" -s 1 logcat -v threadtime -T 1 -a -b -c >> "some/path/log.txt" '
+    )
     start_proc_mock.assert_called_with(expected_adb_cmd, shell=True)
     self.assertEqual(logcat_service.adb_logcat_file_path, 'some/path/log.txt')
     logcat_service.stop()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
-  def test_update_config_while_running(self, open_logcat_mock, stop_proc_mock,
-                                       start_proc_mock, create_dir_mock,
-                                       FastbootProxy, MockAdbProxy):
+  def test_update_config_while_running(
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     logcat_service = logcat.Logcat(ad)
     logcat_service.start()
-    new_config = logcat.Config(logcat_params='-blah',
-                               output_file_path='some/path/file.txt')
+    new_config = logcat.Config(
+        logcat_params='-blah', output_file_path='some/path/file.txt'
+    )
     with self.assertRaisesRegex(
         logcat.Error,
-        'Logcat thread is already running, cannot start another one'):
+        'Logcat thread is already running, cannot start another one',
+    ):
       logcat_service.update_config(new_config)
     self.assertTrue(logcat_service.is_alive)
     logcat_service.stop()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   @mock.patch(
       'mobly.controllers.android_device_lib.services.logcat.Logcat.clear_adb_log',
-      return_value=mock_android_device.MockAdbProxy('1'))
-  def test_pause_and_resume(self, clear_adb_mock, open_logcat_mock,
-                            stop_proc_mock, start_proc_mock, create_dir_mock,
-                            FastbootProxy, MockAdbProxy):
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  def test_pause_and_resume(
+      self,
+      clear_adb_mock,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     logcat_service = logcat.Logcat(ad, logcat.Config(clear_log=True))
@@ -230,44 +290,58 @@
     clear_adb_mock.assert_not_called()
     logcat_service.stop()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch(
       'mobly.controllers.android_device_lib.services.logcat.Logcat.clear_adb_log',
-      return_value=mock_android_device.MockAdbProxy('1'))
-  def test_logcat_service_create_output_excerpts(self, clear_adb_mock,
-                                                 stop_proc_mock,
-                                                 start_proc_mock, FastbootProxy,
-                                                 MockAdbProxy):
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  def test_logcat_service_create_output_excerpts(
+      self,
+      clear_adb_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     logcat_service = logcat.Logcat(ad)
     logcat_service._start()
 
-    def _write_logcat_file_and_assert_excerpts_exists(logcat_file_content,
-                                                      test_begin_time,
-                                                      test_name):
+    def _write_logcat_file_and_assert_excerpts_exists(
+        logcat_file_content, test_begin_time, test_name
+    ):
       with open(logcat_service.adb_logcat_file_path, 'a') as f:
         f.write(logcat_file_content)
       test_output_dir = os.path.join(self.tmp_dir, test_name)
       mock_record = records.TestResultRecord(test_name)
       mock_record.begin_time = test_begin_time
       mock_record.signature = f'{test_name}-{test_begin_time}'
-      test_run_info = runtime_test_info.RuntimeTestInfo(test_name,
-                                                        test_output_dir,
-                                                        mock_record)
+      test_run_info = runtime_test_info.RuntimeTestInfo(
+          test_name, test_output_dir, mock_record
+      )
       actual_path = logcat_service.create_output_excerpts(test_run_info)[0]
       expected_path = os.path.join(
-          test_output_dir, '{test_name}-{test_begin_time}'.format(
-              test_name=test_name, test_begin_time=test_begin_time),
-          'logcat,{mock_serial},fakemodel,{test_name}-{test_begin_time}.txt'.
-          format(mock_serial=mock_serial,
-                 test_name=test_name,
-                 test_begin_time=test_begin_time))
+          test_output_dir,
+          '{test_name}-{test_begin_time}'.format(
+              test_name=test_name, test_begin_time=test_begin_time
+          ),
+          'logcat,{mock_serial},fakemodel,{test_name}-{test_begin_time}.txt'
+          .format(
+              mock_serial=mock_serial,
+              test_name=test_name,
+              test_begin_time=test_begin_time,
+          ),
+      )
       self.assertEqual(actual_path, expected_path)
       self.assertTrue(os.path.exists(expected_path))
       return expected_path
@@ -306,19 +380,29 @@
     )
     self.assertEqual(os.stat(expected_path3).st_size, 0)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   @mock.patch('mobly.logger.get_log_file_timestamp')
-  def test_take_logcat_with_extra_params(self, get_timestamp_mock,
-                                         open_logcat_mock, stop_proc_mock,
-                                         start_proc_mock, create_dir_mock,
-                                         FastbootProxy, MockAdbProxy):
+  def test_take_logcat_with_extra_params(
+      self,
+      get_timestamp_mock,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     """Verifies the steps of collecting adb logcat on an AndroidDevice
     object, including various function calls and the expected behaviors of
     the calls.
@@ -332,21 +416,27 @@
     logcat_service.start()
     # Verify start did the correct operations.
     self.assertTrue(logcat_service._adb_logcat_process)
-    expected_log_path = os.path.join(logging.log_path,
-                                     'AndroidDevice%s' % ad.serial,
-                                     'logcat,%s,fakemodel,123.txt' % ad.serial)
+    expected_log_path = os.path.join(
+        logging.log_path,
+        'AndroidDevice%s' % ad.serial,
+        'logcat,%s,fakemodel,123.txt' % ad.serial,
+    )
     create_dir_mock.assert_called_with(os.path.dirname(expected_log_path))
     adb_cmd = ' "adb" -s %s logcat -v threadtime -T 1 -b radio >> %s'
-    start_proc_mock.assert_called_with(adb_cmd %
-                                       (ad.serial, '"%s" ' % expected_log_path),
-                                       shell=True)
+    start_proc_mock.assert_called_with(
+        adb_cmd % (ad.serial, '"%s" ' % expected_log_path), shell=True
+    )
     self.assertEqual(logcat_service.adb_logcat_file_path, expected_log_path)
     logcat_service.stop()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_instantiation(self, MockFastboot, MockAdbProxy):
     """Verifies the AndroidDevice object's basic attributes are correctly
     set after instantiation.
@@ -357,10 +447,14 @@
     self.assertIsNone(logcat_service._adb_logcat_process)
     self.assertIsNone(logcat_service.adb_logcat_file_path)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock.MagicMock())
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock.MagicMock(),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test__enable_logpersist_with_logpersist(self, MockFastboot, MockAdbProxy):
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
@@ -381,12 +475,17 @@
         mock.call('logpersist.start'),
     ])
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock.MagicMock())
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
-  def test__enable_logpersist_with_user_build_device(self, MockFastboot,
-                                                     MockAdbProxy):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock.MagicMock(),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  def test__enable_logpersist_with_user_build_device(
+      self, MockFastboot, MockAdbProxy
+  ):
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
     mock_adb_proxy.getprops.return_value = {
@@ -403,13 +502,17 @@
     logcat_service._enable_logpersist()
     mock_adb_proxy.shell.assert_not_called()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock.MagicMock())
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock.MagicMock(),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test__enable_logpersist_with_missing_all_logpersist(
-      self, MockFastboot, MockAdbProxy):
-
+      self, MockFastboot, MockAdbProxy
+  ):
     def adb_shell_helper(command):
       if command == 'logpersist.start':
         raise MOCK_LOGPERSIST_START_MISSING_ADB_ERROR
@@ -435,13 +538,17 @@
     logcat_service._enable_logpersist()
     mock_adb_proxy.shell.assert_not_called()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock.MagicMock())
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock.MagicMock(),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test__enable_logpersist_with_missing_logpersist_stop(
-      self, MockFastboot, MockAdbProxy):
-
+      self, MockFastboot, MockAdbProxy
+  ):
     def adb_shell_helper(command):
       if command == 'logpersist.stop --clear':
         raise MOCK_LOGPERSIST_STOP_MISSING_ADB_ERROR
@@ -467,13 +574,17 @@
         mock.call('logpersist.stop --clear'),
     ])
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock.MagicMock())
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock.MagicMock(),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test__enable_logpersist_with_missing_logpersist_start(
-      self, MockFastboot, MockAdbProxy):
-
+      self, MockFastboot, MockAdbProxy
+  ):
     def adb_shell_helper(command):
       if command == 'logpersist.start':
         raise MOCK_LOGPERSIST_START_MISSING_ADB_ERROR
@@ -498,14 +609,17 @@
     mock_adb_proxy.shell.assert_not_called()
 
   @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy')
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_clear_adb_log(self, MockFastboot, MockAdbProxy):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     ad.adb.logcat = mock.MagicMock()
     ad.adb.logcat.side_effect = adb.AdbError(
-        cmd='cmd', stdout=b'', stderr=b'failed to clear "main" log', ret_code=1)
+        cmd='cmd', stdout=b'', stderr=b'failed to clear "main" log', ret_code=1
+    )
     logcat_service = logcat.Logcat(ad)
     logcat_service.clear_adb_log()
 
diff --git a/tests/mobly/controllers/android_device_lib/services/snippet_management_service_test.py b/tests/mobly/controllers/android_device_lib/services/snippet_management_service_test.py
index 16a30aa..b6431d5 100755
--- a/tests/mobly/controllers/android_device_lib/services/snippet_management_service_test.py
+++ b/tests/mobly/controllers/android_device_lib/services/snippet_management_service_test.py
@@ -19,7 +19,9 @@
 from mobly.controllers.android_device_lib.services import snippet_management_service
 
 MOCK_PACKAGE = 'com.mock.package'
-SNIPPET_CLIENT_V2_CLASS_PATH = 'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+SNIPPET_CLIENT_V2_CLASS_PATH = (
+    'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+)
 
 
 class SnippetManagementServiceTest(unittest.TestCase):
@@ -27,7 +29,8 @@
 
   def test_empty_manager_start_stop(self):
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.start()
     # When no client is registered, manager is never alive.
     self.assertFalse(manager.is_alive)
@@ -38,21 +41,24 @@
   def test_get_snippet_client(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     self.assertEqual(manager.get_snippet_client('foo'), mock_client)
 
   @mock.patch(SNIPPET_CLIENT_V2_CLASS_PATH)
   def test_get_snippet_client_fail(self, _):
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     self.assertIsNone(manager.get_snippet_client('foo'))
 
   @mock.patch(SNIPPET_CLIENT_V2_CLASS_PATH)
   def test_stop_with_live_client(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     mock_client.initialize.assert_called_once_with()
     manager.stop()
@@ -67,28 +73,35 @@
   def test_add_snippet_client_without_config(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     mock_class.assert_called_once_with(
-        package=mock.ANY, ad=mock.ANY, config=None)
+        package=mock.ANY, ad=mock.ANY, config=None
+    )
 
   @mock.patch(SNIPPET_CLIENT_V2_CLASS_PATH)
   def test_add_snippet_client_with_config(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     snippet_config = snippet_client_v2.Config()
     manager.add_snippet_client('foo', MOCK_PACKAGE, snippet_config)
     mock_class.assert_called_once_with(
-        package=mock.ANY, ad=mock.ANY, config=snippet_config)
+        package=mock.ANY, ad=mock.ANY, config=snippet_config
+    )
 
   @mock.patch(SNIPPET_CLIENT_V2_CLASS_PATH)
   def test_add_snippet_client_dup_name(self, _):
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
-    msg = ('.* Name "foo" is already registered with package ".*", it '
-           'cannot be used again.')
+    msg = (
+        '.* Name "foo" is already registered with package ".*", it '
+        'cannot be used again.'
+    )
     with self.assertRaisesRegex(snippet_management_service.Error, msg):
       manager.add_snippet_client('foo', MOCK_PACKAGE + 'ha')
 
@@ -97,10 +110,13 @@
     mock_client = mock_class.return_value
     mock_client.package = MOCK_PACKAGE
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
-    msg = ('Snippet package "com.mock.package" has already been loaded '
-           'under name "foo".')
+    msg = (
+        'Snippet package "com.mock.package" has already been loaded '
+        'under name "foo".'
+    )
     with self.assertRaisesRegex(snippet_management_service.Error, msg):
       manager.add_snippet_client('bar', MOCK_PACKAGE)
 
@@ -109,7 +125,8 @@
     mock_client = mock.MagicMock()
     mock_class.return_value = mock_client
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     manager.remove_snippet_client('foo')
     msg = 'No snippet client is registered with name "foo".'
@@ -121,17 +138,20 @@
     mock_client = mock.MagicMock()
     mock_class.return_value = mock_client
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     with self.assertRaisesRegex(
         snippet_management_service.Error,
-        'No snippet client is registered with name "foo".'):
+        'No snippet client is registered with name "foo".',
+    ):
       manager.remove_snippet_client('foo')
 
   @mock.patch(SNIPPET_CLIENT_V2_CLASS_PATH)
   def test_start_with_live_service(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     mock_client.initialize.reset_mock()
     mock_client.is_alive = True
@@ -146,7 +166,8 @@
   def test_pause(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     manager.pause()
     mock_client.close_connection.assert_called_once_with()
@@ -155,7 +176,8 @@
   def test_resume_positive_case(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     mock_client.is_alive = False
     manager.resume()
@@ -165,7 +187,8 @@
   def test_resume_negative_case(self, mock_class):
     mock_client = mock_class.return_value
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     mock_client.is_alive = True
     manager.resume()
@@ -176,7 +199,8 @@
     mock_client = mock.MagicMock()
     mock_class.return_value = mock_client
     manager = snippet_management_service.SnippetManagementService(
-        mock.MagicMock())
+        mock.MagicMock()
+    )
     manager.add_snippet_client('foo', MOCK_PACKAGE)
     manager.foo.ha('param')
     mock_client.ha.assert_called_once_with('param')
diff --git a/tests/mobly/controllers/android_device_lib/sl4a_client_test.py b/tests/mobly/controllers/android_device_lib/sl4a_client_test.py
index 08560d4..bf11b07 100755
--- a/tests/mobly/controllers/android_device_lib/sl4a_client_test.py
+++ b/tests/mobly/controllers/android_device_lib/sl4a_client_test.py
@@ -22,43 +22,60 @@
 
 
 class Sl4aClientTest(jsonrpc_client_test_base.JsonRpcClientTestBase):
-  """Unit tests for mobly.controllers.android_device_lib.sl4a_client.
-  """
+  """Unit tests for mobly.controllers.android_device_lib.sl4a_client."""
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
-  def test_start_app_and_connect(self, mock_get_port,
-                                 mock_start_standing_subprocess,
-                                 mock_create_connection):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
+  def test_start_app_and_connect(
+      self,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
-    self._setup_mock_instrumentation_cmd(mock_start_standing_subprocess,
-                                         resp_lines=[b'\n'])
+    self._setup_mock_instrumentation_cmd(
+        mock_start_standing_subprocess, resp_lines=[b'\n']
+    )
     client = self._make_client()
     client.start_app_and_connect()
     self.assertEqual(8080, client.device_port)
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
-  def test_app_not_installed(self, mock_get_port,
-                             mock_start_standing_subprocess,
-                             mock_create_connection):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
+  def test_app_not_installed(
+      self,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
-    self._setup_mock_instrumentation_cmd(mock_start_standing_subprocess,
-                                         resp_lines=[b'\n'])
+    self._setup_mock_instrumentation_cmd(
+        mock_start_standing_subprocess, resp_lines=[b'\n']
+    )
     client = self._make_client(adb_proxy=mock_android_device.MockAdbProxy())
-    with self.assertRaisesRegex(jsonrpc_client_base.AppStartError,
-                                '.* SL4A is not installed on .*'):
+    with self.assertRaisesRegex(
+        jsonrpc_client_base.AppStartError, '.* SL4A is not installed on .*'
+    ):
       client.start_app_and_connect()
 
   def _make_client(self, adb_proxy=None):
     adb_proxy = adb_proxy or mock_android_device.MockAdbProxy(
-        installed_packages=['com.googlecode.android_scripting'])
+        installed_packages=['com.googlecode.android_scripting']
+    )
     ad = mock.Mock()
     ad.adb = adb_proxy
     ad.build_info = {
@@ -67,11 +84,12 @@
     }
     return sl4a_client.Sl4aClient(ad=ad)
 
-  def _setup_mock_instrumentation_cmd(self, mock_start_standing_subprocess,
-                                      resp_lines):
+  def _setup_mock_instrumentation_cmd(
+      self, mock_start_standing_subprocess, resp_lines
+  ):
     mock_proc = mock_start_standing_subprocess()
     mock_proc.stdout.readline.side_effect = resp_lines
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/controllers/android_device_lib/snippet_client_test.py b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
index 53da1ae..5f31c47 100755
--- a/tests/mobly/controllers/android_device_lib/snippet_client_test.py
+++ b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
@@ -23,13 +23,14 @@
 
 MOCK_PACKAGE_NAME = 'some.package.name'
 MOCK_MISSING_PACKAGE_NAME = 'not.installed'
-JSONRPC_BASE_CLASS = 'mobly.controllers.android_device_lib.jsonrpc_client_base.JsonRpcClientBase'
+JSONRPC_BASE_CLASS = (
+    'mobly.controllers.android_device_lib.jsonrpc_client_base.JsonRpcClientBase'
+)
 MOCK_USER_ID = 0
 
 
 class SnippetClientTest(jsonrpc_client_test_base.JsonRpcClientTestBase):
-  """Unit tests for mobly.controllers.android_device_lib.snippet_client.
-  """
+  """Unit tests for mobly.controllers.android_device_lib.snippet_client."""
 
   def test_check_app_installed_normal(self):
     sc = self._make_client()
@@ -38,29 +39,40 @@
   def test_check_app_installed_fail_app_not_installed(self):
     sc = self._make_client(mock_android_device.MockAdbProxy())
     expected_msg = '.* %s is not installed.' % MOCK_PACKAGE_NAME
-    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
-                                expected_msg):
+    with self.assertRaisesRegex(
+        snippet_client.AppStartPreCheckError, expected_msg
+    ):
       sc._check_app_installed()
 
   def test_check_app_installed_fail_not_instrumented(self):
     sc = self._make_client(
-        mock_android_device.MockAdbProxy(
-            installed_packages=[MOCK_PACKAGE_NAME]))
-    expected_msg = ('.* %s is installed, but it is not instrumented.' %
-                    MOCK_PACKAGE_NAME)
-    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
-                                expected_msg):
+        mock_android_device.MockAdbProxy(installed_packages=[MOCK_PACKAGE_NAME])
+    )
+    expected_msg = (
+        '.* %s is installed, but it is not instrumented.' % MOCK_PACKAGE_NAME
+    )
+    with self.assertRaisesRegex(
+        snippet_client.AppStartPreCheckError, expected_msg
+    ):
       sc._check_app_installed()
 
   def test_check_app_installed_fail_target_not_installed(self):
     sc = self._make_client(
-        mock_android_device.MockAdbProxy(instrumented_packages=[(
-            MOCK_PACKAGE_NAME, snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
-            MOCK_MISSING_PACKAGE_NAME)]))
-    expected_msg = ('.* Instrumentation target %s is not installed.' %
-                    MOCK_MISSING_PACKAGE_NAME)
-    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
-                                expected_msg):
+        mock_android_device.MockAdbProxy(
+            instrumented_packages=[(
+                MOCK_PACKAGE_NAME,
+                snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+                MOCK_MISSING_PACKAGE_NAME,
+            )]
+        )
+    )
+    expected_msg = (
+        '.* Instrumentation target %s is not installed.'
+        % MOCK_MISSING_PACKAGE_NAME
+    )
+    with self.assertRaisesRegex(
+        snippet_client.AppStartPreCheckError, expected_msg
+    ):
       sc._check_app_installed()
 
   @mock.patch('socket.create_connection')
@@ -91,10 +103,13 @@
       callback.getAll('eventName')
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
-  def test_snippet_restore_event_client(self, mock_get_port,
-                                        mock_create_connection):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
+  def test_snippet_restore_event_client(
+      self, mock_get_port, mock_create_connection
+  ):
     mock_get_port.return_value = 789
     fake_file = self.setup_mock_socket_file(mock_create_connection)
     client = self._make_client()
@@ -130,24 +145,37 @@
     mock_create_connection.side_effect = IOError('socket timed out')
     with self.assertRaisesRegex(
         jsonrpc_client_base.AppRestoreConnectionError,
-        ('Failed to restore app connection for %s at host port %s, '
-         'device port %s') % (MOCK_PACKAGE_NAME, 789, 456)):
+        (
+            'Failed to restore app connection for %s at host port %s, '
+            'device port %s'
+        )
+        % (MOCK_PACKAGE_NAME, 789, 456),
+    ):
       client.restore_app_connection()
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
-  def test_snippet_start_app_and_connect(self, mock_get_port,
-                                         mock_start_standing_subprocess,
-                                         mock_create_connection):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
+  def test_snippet_start_app_and_connect(
+      self,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
-    self._setup_mock_instrumentation_cmd(mock_start_standing_subprocess,
-                                         resp_lines=[
-                                             b'SNIPPET START, PROTOCOL 1 0\n',
-                                             b'SNIPPET SERVING, PORT 123\n',
-                                         ])
+    self._setup_mock_instrumentation_cmd(
+        mock_start_standing_subprocess,
+        resp_lines=[
+            b'SNIPPET START, PROTOCOL 1 0\n',
+            b'SNIPPET SERVING, PORT 123\n',
+        ],
+    )
     client = self._make_client()
     client.start_app_and_connect()
     self.assertEqual(123, client.device_port)
@@ -155,8 +183,9 @@
 
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_snippet_stop_app(self, mock_stop_standing_subprocess,
-                            mock_create_connection):
+  def test_snippet_stop_app(
+      self, mock_stop_standing_subprocess, mock_create_connection
+  ):
     adb_proxy = mock.MagicMock()
     adb_proxy.shell.return_value = b'OK (0 tests)'
     client = self._make_client(adb_proxy)
@@ -179,14 +208,15 @@
 
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_snippet_stop_app_stops_event_client(self,
-                                               mock_stop_standing_subprocess,
-                                               mock_create_connection):
+  def test_snippet_stop_app_stops_event_client(
+      self, mock_stop_standing_subprocess, mock_create_connection
+  ):
     adb_proxy = mock.MagicMock()
     adb_proxy.shell.return_value = b'OK (0 tests)'
     client = self._make_client(adb_proxy)
     event_client = snippet_client.SnippetClient(
-        package=MOCK_PACKAGE_NAME, ad=client._ad)
+        package=MOCK_PACKAGE_NAME, ad=client._ad
+    )
     client._event_client = event_client
     event_client_conn = mock.Mock()
     event_client._conn = event_client_conn
@@ -200,12 +230,14 @@
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   def test_snippet_stop_app_stops_event_client_without_connection(
-      self, mock_stop_standing_subprocess, mock_create_connection):
+      self, mock_stop_standing_subprocess, mock_create_connection
+  ):
     adb_proxy = mock.MagicMock()
     adb_proxy.shell.return_value = b'OK (0 tests)'
     client = self._make_client(adb_proxy)
     event_client = snippet_client.SnippetClient(
-        package=MOCK_PACKAGE_NAME, ad=client._ad)
+        package=MOCK_PACKAGE_NAME, ad=client._ad
+    )
     client._event_client = event_client
     event_client._conn = None
 
@@ -217,7 +249,8 @@
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   def test_snippet_stop_app_without_event_client(
-      self, mock_stop_standing_subprocess, mock_create_connection):
+      self, mock_stop_standing_subprocess, mock_create_connection
+  ):
     adb_proxy = mock.MagicMock()
     adb_proxy.shell.return_value = b'OK (0 tests)'
     client = self._make_client(adb_proxy)
@@ -231,8 +264,8 @@
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(snippet_client.SnippetClient, 'connect')
   def test_event_client_does_not_stop_port_forwarding(
-      self, mock_stop_standing_subprocess, mock_create_connection,
-      mock_connect):
+      self, mock_stop_standing_subprocess, mock_create_connection, mock_connect
+  ):
     adb_proxy = mock.MagicMock()
     adb_proxy.shell.return_value = b'OK (0 tests)'
     client = self._make_client(adb_proxy)
@@ -253,55 +286,78 @@
     event_client._adb.forward.assert_not_called()
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client.SnippetClient.'
-      'disable_hidden_api_blacklist')
+      'disable_hidden_api_blacklist'
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client.SnippetClient.'
-      'stop_app')
-  def test_start_app_and_connect_precheck_fail(self, mock_stop, mock_precheck,
-                                               mock_get_port,
-                                               mock_start_standing_subprocess,
-                                               mock_create_connection):
+      'stop_app'
+  )
+  def test_start_app_and_connect_precheck_fail(
+      self,
+      mock_stop,
+      mock_precheck,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
-    self._setup_mock_instrumentation_cmd(mock_start_standing_subprocess,
-                                         resp_lines=[
-                                             b'SNIPPET START, PROTOCOL 1 0\n',
-                                             b'SNIPPET SERVING, PORT 123\n',
-                                         ])
+    self._setup_mock_instrumentation_cmd(
+        mock_start_standing_subprocess,
+        resp_lines=[
+            b'SNIPPET START, PROTOCOL 1 0\n',
+            b'SNIPPET SERVING, PORT 123\n',
+        ],
+    )
     client = self._make_client()
     mock_precheck.side_effect = snippet_client.AppStartPreCheckError(
-        client.ad, 'ha')
+        client.ad, 'ha'
+    )
     with self.assertRaisesRegex(snippet_client.AppStartPreCheckError, 'ha'):
       client.start_app_and_connect()
     mock_stop.assert_not_called()
     self.assertFalse(client.is_alive)
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client.SnippetClient._start_app_and_connect'
   )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client.SnippetClient.stop_app'
   )
-  def test_start_app_and_connect_generic_error(self, mock_stop, mock_start,
-                                               mock_get_port,
-                                               mock_start_standing_subprocess,
-                                               mock_create_connection):
+  def test_start_app_and_connect_generic_error(
+      self,
+      mock_stop,
+      mock_start,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
-    self._setup_mock_instrumentation_cmd(mock_start_standing_subprocess,
-                                         resp_lines=[
-                                             b'SNIPPET START, PROTOCOL 1 0\n',
-                                             b'SNIPPET SERVING, PORT 123\n',
-                                         ])
+    self._setup_mock_instrumentation_cmd(
+        mock_start_standing_subprocess,
+        resp_lines=[
+            b'SNIPPET START, PROTOCOL 1 0\n',
+            b'SNIPPET SERVING, PORT 123\n',
+        ],
+    )
     client = self._make_client()
     mock_start.side_effect = Exception('ha')
     with self.assertRaisesRegex(Exception, 'ha'):
@@ -310,10 +366,14 @@
     self.assertFalse(client.is_alive)
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client.SnippetClient._start_app_and_connect'
   )
@@ -321,14 +381,21 @@
       'mobly.controllers.android_device_lib.snippet_client.SnippetClient.stop_app'
   )
   def test_start_app_and_connect_fail_stop_also_fail(
-      self, mock_stop, mock_start, mock_get_port,
-      mock_start_standing_subprocess, mock_create_connection):
+      self,
+      mock_stop,
+      mock_start,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
-    self._setup_mock_instrumentation_cmd(mock_start_standing_subprocess,
-                                         resp_lines=[
-                                             b'SNIPPET START, PROTOCOL 1 0\n',
-                                             b'SNIPPET SERVING, PORT 123\n',
-                                         ])
+    self._setup_mock_instrumentation_cmd(
+        mock_start_standing_subprocess,
+        resp_lines=[
+            b'SNIPPET START, PROTOCOL 1 0\n',
+            b'SNIPPET SERVING, PORT 123\n',
+        ],
+    )
     client = self._make_client()
     mock_start.side_effect = Exception('Some error')
     mock_stop.side_effect = Exception('Another error')
@@ -337,19 +404,34 @@
     mock_stop.assert_called_once_with()
     self.assertFalse(client.is_alive)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient._do_start_app')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient._check_app_installed')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient._read_protocol_line')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient.connect')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
-  def test_snippet_start_on_sdk_21(self, mock_get_port, mock_connect,
-                                   mock_read_protocol_line,
-                                   mock_check_app_installed, mock_do_start_app):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient._do_start_app'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient._check_app_installed'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient._read_protocol_line'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient.connect'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
+  def test_snippet_start_on_sdk_21(
+      self,
+      mock_get_port,
+      mock_connect,
+      mock_read_protocol_line,
+      mock_check_app_installed,
+      mock_do_start_app,
+  ):
     """Check that `--user` is not added to start command on SDK < 24."""
 
     def _mocked_shell(arg):
@@ -374,24 +456,40 @@
     client._adb.shell = mock.Mock(return_value=b'setsid')
     client.start_app_and_connect()
     cmd_setsid = '%s am instrument  -w -e action start %s/%s' % (
-        snippet_client._SETSID_COMMAND, MOCK_PACKAGE_NAME,
-        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
+        snippet_client._SETSID_COMMAND,
+        MOCK_PACKAGE_NAME,
+        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+    )
     mock_do_start_app.assert_has_calls([mock.call(cmd_setsid)])
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient._do_start_app')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient._check_app_installed')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient._read_protocol_line')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'SnippetClient.connect')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient._do_start_app'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient._check_app_installed'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient._read_protocol_line'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'SnippetClient.connect'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   def test_snippet_start_app_and_connect_persistent_session(
-      self, mock_get_port, mock_connect, mock_read_protocol_line,
-      mock_check_app_installed, mock_do_start_app):
-
+      self,
+      mock_get_port,
+      mock_connect,
+      mock_read_protocol_line,
+      mock_check_app_installed,
+      mock_do_start_app,
+  ):
     def _mocked_shell(arg):
       if 'setsid' in arg:
         raise adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')
@@ -415,8 +513,11 @@
     client._adb.current_user_id = MOCK_USER_ID
     client.start_app_and_connect()
     cmd_setsid = '%s am instrument --user %s -w -e action start %s/%s' % (
-        snippet_client._SETSID_COMMAND, MOCK_USER_ID, MOCK_PACKAGE_NAME,
-        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
+        snippet_client._SETSID_COMMAND,
+        MOCK_USER_ID,
+        MOCK_PACKAGE_NAME,
+        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+    )
     mock_do_start_app.assert_has_calls([mock.call(cmd_setsid)])
 
     # Test 'setsid' does not exist, but 'nohup' exsits
@@ -424,67 +525,97 @@
     client._adb.shell = _mocked_shell
     client.start_app_and_connect()
     cmd_nohup = '%s am instrument --user %s -w -e action start %s/%s' % (
-        snippet_client._NOHUP_COMMAND, MOCK_USER_ID, MOCK_PACKAGE_NAME,
-        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
+        snippet_client._NOHUP_COMMAND,
+        MOCK_USER_ID,
+        MOCK_PACKAGE_NAME,
+        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+    )
     mock_do_start_app.assert_has_calls(
-        [mock.call(cmd_setsid), mock.call(cmd_nohup)])
+        [mock.call(cmd_setsid), mock.call(cmd_nohup)]
+    )
 
     # Test both 'setsid' and 'nohup' do not exist
     client._adb.shell = mock.Mock(
-        side_effect=adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code'))
+        side_effect=adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')
+    )
     client = self._make_client()
     client.start_app_and_connect()
     cmd_not_persist = ' am instrument --user %s -w -e action start %s/%s' % (
-        MOCK_USER_ID, MOCK_PACKAGE_NAME,
-        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
+        MOCK_USER_ID,
+        MOCK_PACKAGE_NAME,
+        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+    )
     mock_do_start_app.assert_has_calls([
         mock.call(cmd_setsid),
         mock.call(cmd_nohup),
-        mock.call(cmd_not_persist)
+        mock.call(cmd_not_persist),
     ])
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
-  def test_snippet_start_app_crash(self, mock_get_port,
-                                   mock_start_standing_subprocess,
-                                   mock_create_connection):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
+  def test_snippet_start_app_crash(
+      self,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     mock_get_port.return_value = 456
     self.setup_mock_socket_file(mock_create_connection)
     self._setup_mock_instrumentation_cmd(
         mock_start_standing_subprocess,
-        resp_lines=[b'INSTRUMENTATION_RESULT: shortMsg=Process crashed.\n'])
+        resp_lines=[b'INSTRUMENTATION_RESULT: shortMsg=Process crashed.\n'],
+    )
     client = self._make_client()
     with self.assertRaisesRegex(
         snippet_client.ProtocolVersionError,
-        'INSTRUMENTATION_RESULT: shortMsg=Process crashed.'):
+        'INSTRUMENTATION_RESULT: shortMsg=Process crashed.',
+    ):
       client.start_app_and_connect()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   def test_snippet_start_app_and_connect_unknown_protocol(
-      self, mock_get_port, mock_start_standing_subprocess):
+      self, mock_get_port, mock_start_standing_subprocess
+  ):
     mock_get_port.return_value = 789
     self._setup_mock_instrumentation_cmd(
         mock_start_standing_subprocess,
-        resp_lines=[b'SNIPPET START, PROTOCOL 99 0\n'])
+        resp_lines=[b'SNIPPET START, PROTOCOL 99 0\n'],
+    )
     client = self._make_client()
-    with self.assertRaisesRegex(snippet_client.ProtocolVersionError,
-                                'SNIPPET START, PROTOCOL 99 0'):
+    with self.assertRaisesRegex(
+        snippet_client.ProtocolVersionError, 'SNIPPET START, PROTOCOL 99 0'
+    ):
       client.start_app_and_connect()
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   def test_snippet_start_app_and_connect_header_junk(
-      self, mock_get_port, mock_start_standing_subprocess,
-      mock_create_connection):
+      self,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     self.setup_mock_socket_file(mock_create_connection)
     self._setup_mock_instrumentation_cmd(
         mock_start_standing_subprocess,
@@ -494,19 +625,27 @@
             b'SNIPPET START, PROTOCOL 1 0\n',
             b'Maybe in the middle too\n',
             b'SNIPPET SERVING, PORT 123\n',
-        ])
+        ],
+    )
     client = self._make_client()
     client.start_app_and_connect()
     self.assertEqual(123, client.device_port)
 
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
-              'utils.get_available_host_port')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client.'
+      'utils.get_available_host_port'
+  )
   def test_snippet_start_app_and_connect_no_valid_line(
-      self, mock_get_port, mock_start_standing_subprocess,
-      mock_create_connection):
+      self,
+      mock_get_port,
+      mock_start_standing_subprocess,
+      mock_create_connection,
+  ):
     mock_get_port.return_value = 456
     self.setup_mock_socket_file(mock_create_connection)
     self._setup_mock_instrumentation_cmd(
@@ -515,10 +654,13 @@
             b'This is some header junk\n',
             b'Some phones print arbitrary output\n',
             b'',  # readline uses '' to mark EOF
-        ])
+        ],
+    )
     client = self._make_client()
-    with self.assertRaisesRegex(jsonrpc_client_base.AppStartError,
-                                'Unexpected EOF waiting for app to start'):
+    with self.assertRaisesRegex(
+        jsonrpc_client_base.AppStartError,
+        'Unexpected EOF waiting for app to start',
+    ):
       client.start_app_and_connect()
 
   @mock.patch('builtins.print')
@@ -545,9 +687,12 @@
 
   def _make_client(self, adb_proxy=None):
     adb_proxy = adb_proxy or mock_android_device.MockAdbProxy(
-        instrumented_packages=[(MOCK_PACKAGE_NAME,
-                                snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
-                                MOCK_PACKAGE_NAME)])
+        instrumented_packages=[(
+            MOCK_PACKAGE_NAME,
+            snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+            MOCK_PACKAGE_NAME,
+        )]
+    )
     ad = mock.Mock()
     ad.adb = adb_proxy
     ad.adb.current_user_id = MOCK_USER_ID
@@ -557,11 +702,12 @@
     }
     return snippet_client.SnippetClient(package=MOCK_PACKAGE_NAME, ad=ad)
 
-  def _setup_mock_instrumentation_cmd(self, mock_start_standing_subprocess,
-                                      resp_lines):
+  def _setup_mock_instrumentation_cmd(
+      self, mock_start_standing_subprocess, resp_lines
+  ):
     mock_proc = mock_start_standing_subprocess()
     mock_proc.stdout.readline.side_effect = resp_lines
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py b/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py
index 86d889b..07e3d0d 100644
--- a/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py
+++ b/tests/mobly/controllers/android_device_lib/snippet_client_v2_test.py
@@ -24,9 +24,12 @@
 from tests.lib import mock_android_device
 
 MOCK_PACKAGE_NAME = 'some.package.name'
-MOCK_SERVER_PATH = f'{MOCK_PACKAGE_NAME}/{snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE}'
+MOCK_SERVER_PATH = (
+    f'{MOCK_PACKAGE_NAME}/{snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE}'
+)
 MOCK_USER_ID = 0
 MOCK_DEVICE_PORT = 1234
+MOCK_HOST_PORT = 2345
 
 
 class _MockAdbProxy(mock_android_device.MockAdbProxy):
@@ -41,6 +44,8 @@
 
 
   Attributes:
+    default_host_port: int, return this port if `self.forward` got 'tcp:0' as
+      host port.
     mock_shell_func: mock.Mock, used for recording the calls to the shell
       method.
     mock_forward_func: mock.Mock, used for recording the calls to the forward
@@ -50,6 +55,7 @@
   def __init__(self, *args, **kwargs):
     """Initializes the instance of _MockAdbProxy."""
     super().__init__(*args, **kwargs)
+    self.default_host_port = MOCK_HOST_PORT
     self.mock_shell_func = mock.Mock()
     self.mock_forward_func = mock.Mock()
 
@@ -69,6 +75,18 @@
     """Mock `forward` of mobly.controllers.android_device_lib.adb.AdbProxy."""
     self.mock_forward_func(*args, **kwargs)
 
+    adb_args = None
+    if 'args' in kwargs:
+      adb_args = kwargs['args']
+    else:
+      adb_args = args[0]
+
+    host_port = str(self.default_host_port)
+    if len(adb_args) >= 1 and adb_args[0] != 'tcp:0':
+      # Extract port from strings like 'tcp:12345'
+      host_port = adb_args[0][4:]
+    return f'{host_port}\n'.encode('utf-8')
+
 
 def _setup_mock_socket_file(mock_socket_create_conn, resp):
   """Sets up a mock socket file from the mock connection.
@@ -92,24 +110,25 @@
 class SnippetClientV2Test(unittest.TestCase):
   """Unit tests for SnippetClientV2."""
 
-  def _make_client(
-      self, adb_proxy=None, mock_properties=None, config=None
-  ):
-    adb_proxy = adb_proxy or _MockAdbProxy(instrumented_packages=[
-        (MOCK_PACKAGE_NAME, snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE,
-         MOCK_PACKAGE_NAME)
-    ],
-                                           mock_properties=mock_properties)
+  def _make_client(self, adb_proxy=None, mock_properties=None, config=None):
+    adb_proxy = adb_proxy or _MockAdbProxy(
+        instrumented_packages=[(
+            MOCK_PACKAGE_NAME,
+            snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE,
+            MOCK_PACKAGE_NAME,
+        )],
+        mock_properties=mock_properties,
+    )
     self.adb = adb_proxy
 
     device = mock.Mock()
     device.adb = adb_proxy
     device.adb.current_user_id = MOCK_USER_ID
     device.build_info = {
-        'build_version_codename':
-            adb_proxy.getprop('ro.build.version.codename'),
-        'build_version_sdk':
-            adb_proxy.getprop('ro.build.version.sdk'),
+        'build_version_codename': adb_proxy.getprop(
+            'ro.build.version.codename'
+        ),
+        'build_version_sdk': adb_proxy.getprop('ro.build.version.sdk'),
     }
     self.device = device
 
@@ -122,63 +141,75 @@
     mock_properties.update(extra_properties)
     self._make_client(mock_properties=mock_properties)
 
-  def _mock_server_process_starting_response(self,
-                                             mock_start_subprocess,
-                                             resp_lines=None):
+  def _mock_server_process_starting_response(
+      self, mock_start_subprocess, resp_lines=None
+  ):
     resp_lines = resp_lines or [
-        b'SNIPPET START, PROTOCOL 1 0', b'SNIPPET SERVING, PORT 1234'
+        b'SNIPPET START, PROTOCOL 1 0',
+        b'SNIPPET SERVING, PORT 1234',
     ]
     mock_proc = mock_start_subprocess.return_value
     mock_proc.stdout.readline.side_effect = resp_lines
 
-  def _make_client_and_mock_socket_conn(self,
-                                        mock_socket_create_conn,
-                                        socket_resp=None,
-                                        device_port=MOCK_DEVICE_PORT,
-                                        adb_proxy=None,
-                                        mock_properties=None,
-                                        set_counter=True):
+  def _make_client_and_mock_socket_conn(
+      self,
+      mock_socket_create_conn,
+      socket_resp=None,
+      device_port=MOCK_DEVICE_PORT,
+      adb_proxy=None,
+      mock_properties=None,
+      set_counter=True,
+  ):
     """Makes the snippet client and mocks the socket connection."""
     self._make_client(adb_proxy, mock_properties)
 
     if socket_resp is None:
       socket_resp = [b'{"status": true, "uid": 1}']
-    self.mock_socket_file = _setup_mock_socket_file(mock_socket_create_conn,
-                                                    socket_resp)
+    self.mock_socket_file = _setup_mock_socket_file(
+        mock_socket_create_conn, socket_resp
+    )
     self.client.device_port = device_port
     self.socket_conn = mock_socket_create_conn.return_value
     if set_counter:
       self.client._counter = self.client._id_counter()
 
-  def _assert_client_resources_released(self, mock_start_subprocess,
-                                        mock_stop_standing_subprocess,
-                                        mock_get_port):
+  def _assert_client_resources_released(
+      self, mock_start_subprocess, mock_stop_standing_subprocess, host_port
+  ):
     """Asserts the resources had been released before the client stopped."""
     self.assertIs(self.client._proc, None)
     self.adb.mock_shell_func.assert_any_call(
         f'am instrument --user {MOCK_USER_ID} -w -e action stop '
-        f'{MOCK_SERVER_PATH}')
+        f'{MOCK_SERVER_PATH}'
+    )
     mock_stop_standing_subprocess.assert_called_once_with(
-        mock_start_subprocess.return_value)
+        mock_start_subprocess.return_value
+    )
     self.assertFalse(self.client.is_alive)
     self.assertIs(self.client._conn, None)
     self.socket_conn.close.assert_called()
     self.assertIs(self.client.host_port, None)
-    self.adb.mock_forward_func.assert_any_call(
-        ['--remove', f'tcp:{mock_get_port.return_value}'])
+    self.adb.mock_forward_func.assert_any_call(['--remove', f'tcp:{host_port}'])
     self.assertIsNone(self.client._event_client)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  def test_the_whole_lifecycle_with_a_sync_rpc(self, mock_start_subprocess,
-                                               mock_stop_standing_subprocess,
-                                               mock_socket_create_conn,
-                                               mock_get_port):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_the_whole_lifecycle_with_a_sync_rpc(
+      self,
+      mock_start_subprocess,
+      mock_stop_standing_subprocess,
+      mock_socket_create_conn,
+      _,
+  ):
     """Tests the whole lifecycle of the client with sending a sync RPC."""
     socket_resp = [
         b'{"status": true, "uid": 1}',
@@ -186,40 +217,51 @@
     ]
     expected_socket_writes = [
         mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
-        mock.call(b'{"id": 0, "method": "some_sync_rpc", '
-                  b'"params": [1, 2, "hello"]}\n'),
+        mock.call(
+            b'{"id": 0, "method": "some_sync_rpc", "params": [1, 2, "hello"]}\n'
+        ),
     ]
-    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
-                                           socket_resp,
-                                           set_counter=False)
+    self._make_client_and_mock_socket_conn(
+        mock_socket_create_conn, socket_resp, set_counter=False
+    )
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.initialize()
     rpc_result = self.client.some_sync_rpc(1, 2, 'hello')
     self.client.stop()
 
-    self._assert_client_resources_released(mock_start_subprocess,
-                                           mock_stop_standing_subprocess,
-                                           mock_get_port)
+    self._assert_client_resources_released(
+        mock_start_subprocess, mock_stop_standing_subprocess, MOCK_HOST_PORT
+    )
 
-    self.assertListEqual(self.mock_socket_file.write.call_args_list,
-                         expected_socket_writes)
+    self.assertListEqual(
+        self.mock_socket_file.write.call_args_list, expected_socket_writes
+    )
     self.assertEqual(rpc_result, 123)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.callback_handler_v2.'
-              'CallbackHandlerV2')
-  def test_the_whole_lifecycle_with_an_async_rpc(self, mock_callback_class,
-                                                 mock_start_subprocess,
-                                                 mock_stop_standing_subprocess,
-                                                 mock_socket_create_conn,
-                                                 mock_get_port):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.callback_handler_v2.'
+      'CallbackHandlerV2'
+  )
+  def test_the_whole_lifecycle_with_an_async_rpc(
+      self,
+      mock_callback_class,
+      mock_start_subprocess,
+      mock_stop_standing_subprocess,
+      mock_socket_create_conn,
+      _,
+  ):
     """Tests the whole lifecycle of the client with sending an async RPC."""
     mock_socket_resp = [
         b'{"status": true, "uid": 1}',
@@ -228,13 +270,15 @@
     ]
     expected_socket_writes = [
         mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
-        mock.call(b'{"id": 0, "method": "some_async_rpc", '
-                  b'"params": [1, 2, "async"]}\n'),
+        mock.call(
+            b'{"id": 0, "method": "some_async_rpc", '
+            b'"params": [1, 2, "async"]}\n'
+        ),
         mock.call(b'{"cmd": "continue", "uid": 1}\n'),
     ]
-    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
-                                           mock_socket_resp,
-                                           set_counter=False)
+    self._make_client_and_mock_socket_conn(
+        mock_socket_create_conn, mock_socket_resp, set_counter=False
+    )
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.initialize()
@@ -242,12 +286,13 @@
     event_client = self.client._event_client
     self.client.stop()
 
-    self._assert_client_resources_released(mock_start_subprocess,
-                                           mock_stop_standing_subprocess,
-                                           mock_get_port)
+    self._assert_client_resources_released(
+        mock_start_subprocess, mock_stop_standing_subprocess, MOCK_HOST_PORT
+    )
 
-    self.assertListEqual(self.mock_socket_file.write.call_args_list,
-                         expected_socket_writes)
+    self.assertListEqual(
+        self.mock_socket_file.write.call_args_list, expected_socket_writes
+    )
     mock_callback_class.assert_called_with(
         callback_id='1-0',
         event_client=event_client,
@@ -255,25 +300,35 @@
         method_name='some_async_rpc',
         device=self.device,
         rpc_max_timeout_sec=snippet_client_v2._SOCKET_READ_TIMEOUT,
-        default_timeout_sec=snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC)
+        default_timeout_sec=snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC,
+    )
     self.assertIs(rpc_result, mock_callback_class.return_value)
     self.assertIsNone(event_client.host_port, None)
     self.assertIsNone(event_client.device_port, None)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.callback_handler_v2.'
-              'CallbackHandlerV2')
-  def test_the_whole_lifecycle_with_multiple_rpcs(self, mock_callback_class,
-                                                  mock_start_subprocess,
-                                                  mock_stop_standing_subprocess,
-                                                  mock_socket_create_conn,
-                                                  mock_get_port):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.callback_handler_v2.'
+      'CallbackHandlerV2'
+  )
+  def test_the_whole_lifecycle_with_multiple_rpcs(
+      self,
+      mock_callback_class,
+      mock_start_subprocess,
+      mock_stop_standing_subprocess,
+      mock_socket_create_conn,
+      _,
+  ):
     """Tests the whole lifecycle of the client with sending multiple RPCs."""
     # Prepare the test
     mock_socket_resp = [
@@ -285,9 +340,9 @@
         b'{"id": 2, "result": 789, "error": null, "callback": null}',
         b'{"id": 3, "result": 321, "error": null, "callback": "2-0"}',
     ]
-    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
-                                           mock_socket_resp,
-                                           set_counter=False)
+    self._make_client_and_mock_socket_conn(
+        mock_socket_create_conn, mock_socket_resp, set_counter=False
+    )
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     rpc_results_expected = [
@@ -299,7 +354,8 @@
     # Extract the two mock objects to use as return values of callback handler
     # class
     mock_callback_class.side_effect = [
-        rpc_results_expected[1], rpc_results_expected[3]
+        rpc_results_expected[1],
+        rpc_results_expected[3],
     ]
 
     # Run tests
@@ -314,14 +370,17 @@
 
     # Assertions
     mock_callback_class_calls_expected = [
-        mock.call(callback_id='1-0',
-                  event_client=event_client,
-                  ret_value=456,
-                  method_name='some_async_rpc',
-                  device=self.device,
-                  rpc_max_timeout_sec=snippet_client_v2._SOCKET_READ_TIMEOUT,
-                  default_timeout_sec=(
-                      snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC)),
+        mock.call(
+            callback_id='1-0',
+            event_client=event_client,
+            ret_value=456,
+            method_name='some_async_rpc',
+            device=self.device,
+            rpc_max_timeout_sec=snippet_client_v2._SOCKET_READ_TIMEOUT,
+            default_timeout_sec=(
+                snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC
+            ),
+        ),
         mock.call(
             callback_id='2-0',
             event_client=event_client,
@@ -329,13 +388,14 @@
             method_name='some_async_rpc',
             device=self.device,
             rpc_max_timeout_sec=snippet_client_v2._SOCKET_READ_TIMEOUT,
-            default_timeout_sec=snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC)
+            default_timeout_sec=snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC,
+        ),
     ]
     self.assertListEqual(rpc_results, rpc_results_expected)
     mock_callback_class.assert_has_calls(mock_callback_class_calls_expected)
-    self._assert_client_resources_released(mock_start_subprocess,
-                                           mock_stop_standing_subprocess,
-                                           mock_get_port)
+    self._assert_client_resources_released(
+        mock_start_subprocess, mock_stop_standing_subprocess, MOCK_HOST_PORT
+    )
     self.assertIsNone(event_client.host_port, None)
     self.assertIsNone(event_client.device_port, None)
 
@@ -355,18 +415,23 @@
     """Tests that app checker fails without instrumenting app."""
     self._make_client(_MockAdbProxy(installed_packages=[MOCK_PACKAGE_NAME]))
     expected_msg = (
-        f'.* {MOCK_PACKAGE_NAME} is installed, but it is not instrumented.')
+        f'.* {MOCK_PACKAGE_NAME} is installed, but it is not instrumented.'
+    )
     with self.assertRaisesRegex(errors.ServerStartPreCheckError, expected_msg):
       self.client._validate_snippet_app_on_device()
 
   def test_check_app_installed_fail_instrumentation_not_installed(self):
     """Tests that app checker fails without installing instrumentation."""
     self._make_client(
-        _MockAdbProxy(instrumented_packages=[(
-            MOCK_PACKAGE_NAME,
-            snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE,
-            'not.installed')]))
-    expected_msg = ('.* Instrumentation target not.installed is not installed.')
+        _MockAdbProxy(
+            instrumented_packages=[(
+                MOCK_PACKAGE_NAME,
+                snippet_client_v2._INSTRUMENTATION_RUNNER_PACKAGE,
+                'not.installed',
+            )]
+        )
+    )
+    expected_msg = '.* Instrumentation target not.installed is not installed.'
     with self.assertRaisesRegex(errors.ServerStartPreCheckError, expected_msg):
       self.client._validate_snippet_app_on_device()
 
@@ -379,7 +444,8 @@
     self.device.is_rootable = True
     self.client._disable_hidden_api_blocklist()
     self.adb.mock_shell_func.assert_called_with(
-        'settings put global hidden_api_blacklist_exemptions "*"')
+        'settings put global hidden_api_blacklist_exemptions "*"'
+    )
 
   def test_disable_hidden_api_low_sdk(self):
     """Tests it doesn't disable hidden api with low SDK."""
@@ -401,8 +467,10 @@
     self.client._disable_hidden_api_blocklist()
     self.adb.mock_shell_func.assert_not_called()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'setsid')
   def test_start_server_with_user_id(self, mock_adb, mock_start_subprocess):
     """Tests that `--user` is added to starting command with SDK >= 24."""
@@ -411,17 +479,51 @@
 
     self.client.start_server()
     start_cmd_list = [
-        'adb', 'shell',
-        (f'setsid am instrument --user {MOCK_USER_ID} -w -e action start  '
-         f'{MOCK_SERVER_PATH}')
+        'adb',
+        'shell',
+        (
+            f'setsid am instrument --user {MOCK_USER_ID} -w -e action start  '
+            f'{MOCK_SERVER_PATH}'
+        ),
     ]
-    self.assertListEqual(mock_start_subprocess.call_args_list,
-                         [mock.call(start_cmd_list, shell=False)])
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
     self.assertEqual(self.client.device_port, 1234)
     mock_adb.assert_called_with(['which', 'setsid'])
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'setsid')
+  def test_start_server_with_config_specific_user_id(
+      self, _, mock_start_subprocess
+  ):
+    """Tests that the correct `--user` argument is passed."""
+    self._make_client(config=snippet_client_v2.Config(user_id=42))
+    self._mock_server_process_starting_response(mock_start_subprocess)
+    self.assertEqual(self.client.user_id, 42)
+
+    self.client.start_server()
+    start_cmd_list = [
+        'adb',
+        'shell',
+        (
+            'setsid am instrument --user 42 -w -e action start  '
+            f'{MOCK_SERVER_PATH}'
+        ),
+    ]
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
+
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'setsid')
   def test_start_server_without_user_id(self, mock_adb, mock_start_subprocess):
     """Tests that `--user` is not added to starting command on SDK < 24."""
@@ -430,41 +532,55 @@
 
     self.client.start_server()
     start_cmd_list = [
-        'adb', 'shell',
-        f'setsid am instrument  -w -e action start  {MOCK_SERVER_PATH}'
+        'adb',
+        'shell',
+        f'setsid am instrument  -w -e action start  {MOCK_SERVER_PATH}',
     ]
-    self.assertListEqual(mock_start_subprocess.call_args_list,
-                         [mock.call(start_cmd_list, shell=False)])
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
     mock_adb.assert_called_with(['which', 'setsid'])
     self.assertEqual(self.client.device_port, 1234)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch.object(_MockAdbProxy,
-                     'shell',
-                     side_effect=adb.AdbError('cmd', 'stdout', 'stderr',
-                                              'ret_code'))
-  def test_start_server_without_persisting_commands(self, mock_adb,
-                                                    mock_start_subprocess):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch.object(
+      _MockAdbProxy,
+      'shell',
+      side_effect=adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code'),
+  )
+  def test_start_server_without_persisting_commands(
+      self, mock_adb, mock_start_subprocess
+  ):
     """Checks the starting server command without persisting commands."""
     self._make_client()
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.start_server()
     start_cmd_list = [
-        'adb', 'shell',
-        (f' am instrument --user {MOCK_USER_ID} -w -e action start  '
-         f'{MOCK_SERVER_PATH}')
+        'adb',
+        'shell',
+        (
+            f' am instrument --user {MOCK_USER_ID} -w -e action start  '
+            f'{MOCK_SERVER_PATH}'
+        ),
     ]
-    self.assertListEqual(mock_start_subprocess.call_args_list,
-                         [mock.call(start_cmd_list, shell=False)])
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
     mock_adb.assert_has_calls(
-        [mock.call(['which', 'setsid']),
-         mock.call(['which', 'nohup'])])
+        [mock.call(['which', 'setsid']), mock.call(['which', 'nohup'])]
+    )
     self.assertEqual(self.client.device_port, 1234)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_with_nohup(self, mock_start_subprocess):
     """Checks the starting server command with nohup."""
     self._make_client()
@@ -479,16 +595,23 @@
 
     self.client.start_server()
     start_cmd_list = [
-        'adb', 'shell',
-        (f'nohup am instrument --user {MOCK_USER_ID} -w -e action start  '
-         f'{MOCK_SERVER_PATH}')
+        'adb',
+        'shell',
+        (
+            f'nohup am instrument --user {MOCK_USER_ID} -w -e action start  '
+            f'{MOCK_SERVER_PATH}'
+        ),
     ]
-    self.assertListEqual(mock_start_subprocess.call_args_list,
-                         [mock.call(start_cmd_list, shell=False)])
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
     self.assertEqual(self.client.device_port, 1234)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_with_setsid(self, mock_start_subprocess):
     """Checks the starting server command with setsid."""
     self._make_client()
@@ -502,16 +625,23 @@
     self.client._adb.shell = _mocked_shell
     self.client.start_server()
     start_cmd_list = [
-        'adb', 'shell',
-        (f'setsid am instrument --user {MOCK_USER_ID} -w -e action start  '
-         f'{MOCK_SERVER_PATH}')
+        'adb',
+        'shell',
+        (
+            f'setsid am instrument --user {MOCK_USER_ID} -w -e action start  '
+            f'{MOCK_SERVER_PATH}'
+        ),
     ]
-    self.assertListEqual(mock_start_subprocess.call_args_list,
-                         [mock.call(start_cmd_list, shell=False)])
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
     self.assertEqual(self.client.device_port, 1234)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_with_instrument_options(self, mock_start_subprocess):
     """Checks the starting server command with instrument options."""
     config = snippet_client_v2.Config(
@@ -524,57 +654,79 @@
     self.client.start_server()
 
     start_cmd_list = [
-        'adb', 'shell',
-        (f' am instrument --user {MOCK_USER_ID} -w -e action start '
-         f'{instrument_options_str} {MOCK_SERVER_PATH}')
+        'adb',
+        'shell',
+        (
+            f' am instrument --user {MOCK_USER_ID} -w -e action start '
+            f'{instrument_options_str} {MOCK_SERVER_PATH}'
+        ),
     ]
-    self.assertListEqual(mock_start_subprocess.call_args_list,
-                         [mock.call(start_cmd_list, shell=False)])
+    self.assertListEqual(
+        mock_start_subprocess.call_args_list,
+        [mock.call(start_cmd_list, shell=False)],
+    )
     self.assertEqual(self.client.device_port, 1234)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_server_crash(self, mock_start_standing_subprocess):
     """Tests that starting server process crashes."""
     self._make_client()
     self._mock_server_process_starting_response(
         mock_start_standing_subprocess,
-        resp_lines=[b'INSTRUMENTATION_RESULT: shortMsg=Process crashed.\n'])
+        resp_lines=[b'INSTRUMENTATION_RESULT: shortMsg=Process crashed.\n'],
+    )
     with self.assertRaisesRegex(
         errors.ServerStartProtocolError,
-        'INSTRUMENTATION_RESULT: shortMsg=Process crashed.'):
+        'INSTRUMENTATION_RESULT: shortMsg=Process crashed.',
+    ):
       self.client.start_server()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_unknown_protocol_version(
-      self, mock_start_standing_subprocess):
+      self, mock_start_standing_subprocess
+  ):
     """Tests that starting server process reports unknown protocol version."""
     self._make_client()
     self._mock_server_process_starting_response(
         mock_start_standing_subprocess,
-        resp_lines=[b'SNIPPET START, PROTOCOL 99 0\n'])
-    with self.assertRaisesRegex(errors.ServerStartProtocolError,
-                                'SNIPPET START, PROTOCOL 99 0'):
+        resp_lines=[b'SNIPPET START, PROTOCOL 99 0\n'],
+    )
+    with self.assertRaisesRegex(
+        errors.ServerStartProtocolError, 'SNIPPET START, PROTOCOL 99 0'
+    ):
       self.client.start_server()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  def test_start_server_invalid_device_port(self,
-                                            mock_start_standing_subprocess):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_start_server_invalid_device_port(
+      self, mock_start_standing_subprocess
+  ):
     """Tests that starting server process reports invalid device port."""
     self._make_client()
     self._mock_server_process_starting_response(
         mock_start_standing_subprocess,
         resp_lines=[
-            b'SNIPPET START, PROTOCOL 1 0\n', b'SNIPPET SERVING, PORT ABC\n'
-        ])
-    with self.assertRaisesRegex(errors.ServerStartProtocolError,
-                                'SNIPPET SERVING, PORT ABC'):
+            b'SNIPPET START, PROTOCOL 1 0\n',
+            b'SNIPPET SERVING, PORT ABC\n',
+        ],
+    )
+    with self.assertRaisesRegex(
+        errors.ServerStartProtocolError, 'SNIPPET SERVING, PORT ABC'
+    ):
       self.client.start_server()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_with_junk(self, mock_start_standing_subprocess):
     """Tests that starting server process reports known protocol with junk."""
     self._make_client()
@@ -586,12 +738,15 @@
             b'SNIPPET START, PROTOCOL 1 0\n',
             b'Maybe in the middle too\n',
             b'SNIPPET SERVING, PORT 123\n',
-        ])
+        ],
+    )
     self.client.start_server()
     self.assertEqual(123, self.client.device_port)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_start_server_no_valid_line(self, mock_start_standing_subprocess):
     """Tests that starting server process reports unknown protocol message."""
     self._make_client()
@@ -601,10 +756,12 @@
             b'This is some header junk\n',
             b'Some phones print arbitrary output\n',
             b'',  # readline uses '' to mark EOF
-        ])
+        ],
+    )
     with self.assertRaisesRegex(
         errors.ServerStartError,
-        'Unexpected EOF when waiting for server to start.'):
+        'Unexpected EOF when waiting for server to start.',
+    ):
       self.client.start_server()
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
@@ -622,19 +779,22 @@
     self.assertIs(self.client._proc, None)
     self.adb.mock_shell_func.assert_called_once_with(
         f'am instrument --user {MOCK_USER_ID} -w -e action stop '
-        f'{MOCK_SERVER_PATH}')
+        f'{MOCK_SERVER_PATH}'
+    )
     mock_stop_standing_subprocess.assert_called_once_with(mock_proc)
     self.assertFalse(self.client.is_alive)
     self.assertIs(self.client._conn, None)
     mock_conn.close.assert_called_once_with()
     self.assertIs(self.client.host_port, None)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
     self.assertIsNone(self.client._event_client)
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_stop_when_server_is_already_cleaned(self,
-                                               mock_stop_standing_subprocess):
+  def test_stop_when_server_is_already_cleaned(
+      self, mock_stop_standing_subprocess
+  ):
     """Tests that stop server process when subprocess is already cleaned."""
     self._make_client()
     self.client._proc = None
@@ -648,17 +808,20 @@
     mock_stop_standing_subprocess.assert_not_called()
     self.adb.assert_called_once_with(
         f'am instrument --user {MOCK_USER_ID} -w -e action stop '
-        f'{MOCK_SERVER_PATH}')
+        f'{MOCK_SERVER_PATH}'
+    )
     self.assertFalse(self.client.is_alive)
     self.assertIs(self.client._conn, None)
     mock_conn.close.assert_called_once_with()
     self.assertIs(self.client.host_port, None)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_stop_when_conn_is_already_cleaned(self,
-                                             mock_stop_standing_subprocess):
+  def test_stop_when_conn_is_already_cleaned(
+      self, mock_stop_standing_subprocess
+  ):
     """Tests that stop server process when the connection is already closed."""
     self._make_client()
     mock_proc = mock.Mock()
@@ -672,17 +835,20 @@
     mock_stop_standing_subprocess.assert_called_once_with(mock_proc)
     self.adb.assert_called_once_with(
         f'am instrument --user {MOCK_USER_ID} -w -e action stop '
-        f'{MOCK_SERVER_PATH}')
+        f'{MOCK_SERVER_PATH}'
+    )
     self.assertFalse(self.client.is_alive)
     self.assertIs(self.client._conn, None)
     self.assertIs(self.client.host_port, None)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(_MockAdbProxy, 'shell', return_value=b'Closed with error.')
-  def test_stop_with_device_side_error(self, mock_adb_shell,
-                                       mock_stop_standing_subprocess):
+  def test_stop_with_device_side_error(
+      self, mock_adb_shell, mock_stop_standing_subprocess
+  ):
     """Tests all resources will be cleaned when server stop throws an error."""
     self._make_client()
     mock_proc = mock.Mock()
@@ -690,21 +856,24 @@
     mock_conn = mock.Mock()
     self.client._conn = mock_conn
     self.client.host_port = 12345
-    with self.assertRaisesRegex(android_device_lib_errors.DeviceError,
-                                'Closed with error'):
+    with self.assertRaisesRegex(
+        android_device_lib_errors.DeviceError, 'Closed with error'
+    ):
       self.client.stop()
 
     self.assertIs(self.client._proc, None)
     mock_stop_standing_subprocess.assert_called_once_with(mock_proc)
     mock_adb_shell.assert_called_once_with(
         f'am instrument --user {MOCK_USER_ID} -w -e action stop '
-        f'{MOCK_SERVER_PATH}')
+        f'{MOCK_SERVER_PATH}'
+    )
     self.assertFalse(self.client.is_alive)
     self.assertIs(self.client._conn, None)
     mock_conn.close.assert_called_once_with()
     self.assertIs(self.client.host_port, None)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
   def test_stop_with_conn_close_error(self, mock_stop_standing_subprocess):
@@ -723,16 +892,22 @@
       self.client.stop()
 
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'create_socket_connection')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'send_handshake_request')
-  def test_stop_with_event_client(self, mock_send_handshake_func,
-                                  mock_create_socket_conn_func,
-                                  mock_stop_standing_subprocess):
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'create_socket_connection'
+  )
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'send_handshake_request'
+  )
+  def test_stop_with_event_client(
+      self,
+      mock_send_handshake_func,
+      mock_create_socket_conn_func,
+      mock_stop_standing_subprocess,
+  ):
     """Tests that stopping with an event client works normally."""
     del mock_send_handshake_func
     del mock_create_socket_conn_func
@@ -759,16 +934,22 @@
     self.assertIsNone(self.client._event_client)
     self.assertIs(self.client.host_port, None)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
 
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'create_socket_connection')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'send_handshake_request')
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'create_socket_connection'
+  )
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'send_handshake_request'
+  )
   def test_stop_with_event_client_stops_port_forwarding_once(
-      self, mock_send_handshake_func, mock_create_socket_conn_func,
-      mock_stop_standing_subprocess):
+      self,
+      mock_send_handshake_func,
+      mock_create_socket_conn_func,
+      mock_stop_standing_subprocess,
+  ):
     """Tests that client with an event client stops port forwarding once."""
     del mock_send_handshake_func
     del mock_create_socket_conn_func
@@ -785,7 +966,8 @@
 
     self.assertIsNone(self.client._event_client)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:12345'])
+        ['--remove', 'tcp:12345']
+    )
 
   def test_close_connection_normally(self):
     """Tests that closing connection works normally."""
@@ -800,7 +982,8 @@
     self.assertIs(self.client.host_port, None)
     mock_conn.close.assert_called_once_with()
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:123'])
+        ['--remove', 'tcp:123']
+    )
 
   def test_close_connection_when_host_port_has_been_released(self):
     """Tests that close connection when the host port has been released."""
@@ -827,18 +1010,23 @@
     self.assertIs(self.client._conn, None)
     self.assertIs(self.client.host_port, None)
     self.device.adb.mock_forward_func.assert_called_once_with(
-        ['--remove', 'tcp:123'])
+        ['--remove', 'tcp:123']
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  def test_send_sync_rpc_normally(self, mock_start_subprocess,
-                                  mock_socket_create_conn, mock_get_port):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_send_sync_rpc_normally(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that sending a sync RPC works normally."""
-    del mock_get_port
     socket_resp = [
         b'{"status": true, "uid": 1}',
         b'{"id": 0, "result": 123, "error": null, "callback": null}',
@@ -851,16 +1039,30 @@
 
     self.assertEqual(rpc_result, 123)
     self.mock_socket_file.write.assert_called_with(
-        b'{"id": 0, "method": "some_rpc", "params": [1, 2, "hello"]}\n')
+        b'{"id": 0, "method": "some_rpc", "params": [1, 2, "hello"]}\n'
+    )
 
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.callback_handler_v2.'
-              'CallbackHandlerV2')
-  def test_async_rpc_start_event_client(self, mock_callback_class,
-                                        mock_start_subprocess,
-                                        mock_socket_create_conn):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.callback_handler_v2.'
+      'CallbackHandlerV2'
+  )
+  def test_async_rpc_start_event_client(
+      self,
+      mock_callback_class,
+      mock_start_subprocess,
+      mock_socket_create_conn,
+      _,
+  ):
     """Tests that sending an async RPC starts the event client."""
     socket_resp = [
         b'{"status": true, "uid": 1}',
@@ -870,15 +1072,19 @@
     ]
     socket_write_expected = [
         mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
-        mock.call(b'{"id": 0, "method": "some_async_rpc", '
-                  b'"params": [1, 2, "hello"]}\n'),
+        mock.call(
+            b'{"id": 0, "method": "some_async_rpc", '
+            b'"params": [1, 2, "hello"]}\n'
+        ),
         mock.call(b'{"cmd": "continue", "uid": 1}\n'),
-        mock.call(b'{"id": 1, "method": "eventGetAll", '
-                  b'"params": ["1-0", "eventName"]}\n'),
+        mock.call(
+            b'{"id": 1, "method": "eventGetAll", '
+            b'"params": ["1-0", "eventName"]}\n'
+        ),
     ]
-    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
-                                           socket_resp,
-                                           set_counter=True)
+    self._make_client_and_mock_socket_conn(
+        mock_socket_create_conn, socket_resp, set_counter=True
+    )
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.host_port = 12345
@@ -892,7 +1098,8 @@
         method_name='some_async_rpc',
         device=self.device,
         rpc_max_timeout_sec=snippet_client_v2._SOCKET_READ_TIMEOUT,
-        default_timeout_sec=snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC)
+        default_timeout_sec=snippet_client_v2._CALLBACK_DEFAULT_TIMEOUT_SEC,
+    )
     self.assertIs(rpc_result, mock_callback_class.return_value)
 
     # Ensure the event client is alive
@@ -915,38 +1122,52 @@
         socket_write_expected,
     )
 
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port')
-  def test_initialize_client_normally(self, mock_get_port,
-                                      mock_start_subprocess,
-                                      mock_socket_create_conn):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_initialize_client_normally(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that initializing the client works normally."""
-    mock_get_port.return_value = 12345
+    host_port = 12345
     socket_resp = [b'{"status": true, "uid": 1}']
-    self._make_client_and_mock_socket_conn(mock_socket_create_conn,
-                                           socket_resp,
-                                           set_counter=True)
+    self._make_client_and_mock_socket_conn(
+        mock_socket_create_conn,
+        socket_resp,
+        set_counter=True,
+    )
+    self.device.adb.default_host_port = host_port
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.initialize()
     self.assertTrue(self.client.is_alive)
     self.assertEqual(self.client.uid, 1)
-    self.assertEqual(self.client.host_port, 12345)
+    self.assertEqual(self.client.host_port, host_port)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
     self.assertEqual(next(self.client._counter), 0)
 
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port')
-  def test_restore_event_client(self, mock_get_port, mock_start_subprocess,
-                                mock_socket_create_conn):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_restore_event_client(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests restoring the event client."""
-    mock_get_port.return_value = 12345
+    host_port = 12345
     socket_resp = [
         # response of handshake when initializing the client
         b'{"status": true, "uid": 1}',
@@ -980,33 +1201,36 @@
         mock.call(b'{"cmd": "initiate", "uid": -1}\n'),
     ]
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
+    self.device.adb.default_host_port = host_port
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.make_connection()
     callback = self.client.some_async_rpc()
 
     # before reconnect, clients use previously selected ports
-    self.assertEqual(self.client.host_port, 12345)
+    self.assertEqual(self.client.host_port, host_port)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
-    self.assertEqual(callback._event_client.host_port, 12345)
+    self.assertEqual(callback._event_client.host_port, host_port)
     self.assertEqual(callback._event_client.device_port, MOCK_DEVICE_PORT)
     self.assertEqual(next(self.client._event_client._counter), 0)
 
     # after reconnect, if host port specified, clients use specified port
-    self.client.restore_server_connection(port=54321)
-    self.assertEqual(self.client.host_port, 54321)
+    host_port_2 = 54321
+    self.client.restore_server_connection(port=host_port_2)
+    self.assertEqual(self.client.host_port, host_port_2)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
-    self.assertEqual(callback._event_client.host_port, 54321)
+    self.assertEqual(callback._event_client.host_port, host_port_2)
     self.assertEqual(callback._event_client.device_port, MOCK_DEVICE_PORT)
     self.assertEqual(next(self.client._event_client._counter), 0)
 
     # after reconnect, if host port not specified, clients use selected
     # available port
-    mock_get_port.return_value = 56789
+    host_port_3 = 56789
+    self.device.adb.default_host_port = host_port_3
     self.client.restore_server_connection()
-    self.assertEqual(self.client.host_port, 56789)
+    self.assertEqual(self.client.host_port, host_port_3)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
-    self.assertEqual(callback._event_client.host_port, 56789)
+    self.assertEqual(callback._event_client.host_port, host_port_3)
     self.assertEqual(callback._event_client.device_port, MOCK_DEVICE_PORT)
     self.assertEqual(next(self.client._event_client._counter), 0)
 
@@ -1015,25 +1239,35 @@
     mock_socket_create_conn.side_effect = IOError('socket timed out')
     with self.assertRaisesRegex(
         errors.ServerRestoreConnectionError,
-        (f'Failed to restore server connection for {MOCK_PACKAGE_NAME} at '
-         f'host port 56789, device port {MOCK_DEVICE_PORT}')):
+        (
+            f'Failed to restore server connection for {MOCK_PACKAGE_NAME} at '
+            f'host port {host_port_3}, device port {MOCK_DEVICE_PORT}'
+        ),
+    ):
       self.client.restore_server_connection()
 
-    self.assertListEqual(self.mock_socket_file.write.call_args_list,
-                         socket_write_expected)
+    self.assertListEqual(
+        self.mock_socket_file.write.call_args_list, socket_write_expected
+    )
 
   @mock.patch.object(snippet_client_v2.SnippetClientV2, '_make_connection')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'send_handshake_request')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'create_socket_connection')
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'send_handshake_request'
+  )
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'create_socket_connection'
+  )
   def test_restore_server_connection_with_event_client(
-      self, mock_create_socket_conn_func, mock_send_handshake_func,
-      mock_make_connection):
+      self,
+      mock_create_socket_conn_func,
+      mock_send_handshake_func,
+      mock_make_connection,
+  ):
     """Tests restoring server connection when the event client is not None."""
     self._make_client()
-    event_client = snippet_client_v2.SnippetClientV2('mock-package',
-                                                     mock.Mock())
+    event_client = snippet_client_v2.SnippetClientV2(
+        'mock-package', mock.Mock()
+    )
     self.client._event_client = event_client
     self.client.device_port = 54321
     self.client.uid = 5
@@ -1046,7 +1280,8 @@
     self.assertEqual(next(event_client._counter), 0)
     mock_create_socket_conn_func.assert_called_once_with()
     mock_send_handshake_func.assert_called_once_with(
-        -1, snippet_client_v2.ConnectionHandshakeCommand.INIT)
+        -1, snippet_client_v2.ConnectionHandshakeCommand.INIT
+    )
 
   @mock.patch('builtins.print')
   def test_help_rpc_when_printing_by_default(self, mock_print):
@@ -1072,70 +1307,118 @@
     self.assertEqual(mock_rpc.return_value, result)
     mock_print.assert_not_called()
 
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
-  def test_make_connection_normally(self, mock_get_port, mock_start_subprocess,
-                                    mock_socket_create_conn):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_make_connection_normally(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that making a connection works normally."""
-    del mock_get_port
     socket_resp = [b'{"status": true, "uid": 1}']
+    host_port = 12345
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
+    self.device.adb.default_host_port = host_port
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     self.client.make_connection()
     self.assertEqual(self.client.uid, 1)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
     self.adb.mock_forward_func.assert_called_once_with(
-        ['tcp:12345', f'tcp:{MOCK_DEVICE_PORT}'])
+        ['tcp:0', f'tcp:{MOCK_DEVICE_PORT}']
+    )
     mock_socket_create_conn.assert_called_once_with(
-        ('localhost', 12345), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT)
+        ('localhost', host_port), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT
+    )
     self.socket_conn.settimeout.assert_called_once_with(
-        snippet_client_v2._SOCKET_READ_TIMEOUT)
+        snippet_client_v2._SOCKET_READ_TIMEOUT
+    )
 
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
-  def test_make_connection_with_preset_host_port(self, mock_get_port,
-                                                 mock_start_subprocess,
-                                                 mock_socket_create_conn):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_make_connection_with_preset_host_port(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that make a connection with the preset host port."""
-    del mock_get_port
+    host_port = 23456
     socket_resp = [b'{"status": true, "uid": 1}']
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
     self._mock_server_process_starting_response(mock_start_subprocess)
 
-    self.client.host_port = 23456
+    self.client.host_port = host_port
     self.client.make_connection()
     self.assertEqual(self.client.uid, 1)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
     # Test that the host port for forwarding is 23456 instead of 12345
     self.adb.mock_forward_func.assert_called_once_with(
-        ['tcp:23456', f'tcp:{MOCK_DEVICE_PORT}'])
+        [f'tcp:{host_port}', f'tcp:{MOCK_DEVICE_PORT}']
+    )
     mock_socket_create_conn.assert_called_once_with(
-        ('localhost', 23456), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT)
+        ('localhost', host_port), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT
+    )
     self.socket_conn.settimeout.assert_called_once_with(
-        snippet_client_v2._SOCKET_READ_TIMEOUT)
+        snippet_client_v2._SOCKET_READ_TIMEOUT
+    )
 
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
-  def test_make_connection_with_ip(self, mock_get_port, mock_start_subprocess,
-                                   mock_socket_create_conn):
-    """Tests that make a connection with 127.0.0.1 instead of localhost."""
-    del mock_get_port
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_make_connection_with_preset_host_port_that_is_forwarded(
+      self, mock_start_subprocess, mock_socket_create_conn, mock_occupied_ports
+  ):
+    """Tests that make a connection with the preset host port."""
+    host_port = 23456
+    mock_occupied_ports.return_value = [host_port]
     socket_resp = [b'{"status": true, "uid": 1}']
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
     self._mock_server_process_starting_response(mock_start_subprocess)
+    self.client.host_port = host_port
+
+    with self.assertRaisesRegex(
+        errors.Error, f'Cannot forward to host port {host_port}'
+    ):
+      self.client.make_connection()
+
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
+  @mock.patch('socket.create_connection')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_make_connection_with_ip(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
+    """Tests that make a connection with 127.0.0.1 instead of localhost."""
+    host_port = 12345
+    socket_resp = [b'{"status": true, "uid": 1}']
+    self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
+    self.device.adb.default_host_port = host_port
+    self._mock_server_process_starting_response(mock_start_subprocess)
 
     mock_conn = mock_socket_create_conn.return_value
 
@@ -1153,86 +1436,103 @@
     self.assertEqual(self.client.uid, 1)
     self.assertEqual(self.client.device_port, MOCK_DEVICE_PORT)
     self.adb.mock_forward_func.assert_called_once_with(
-        ['tcp:12345', f'tcp:{MOCK_DEVICE_PORT}'])
+        ['tcp:0', f'tcp:{MOCK_DEVICE_PORT}']
+    )
     mock_socket_create_conn.assert_any_call(
-        ('127.0.0.1', 12345), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT)
+        ('127.0.0.1', host_port), snippet_client_v2._SOCKET_CONNECTION_TIMEOUT
+    )
     self.socket_conn.settimeout.assert_called_once_with(
-        snippet_client_v2._SOCKET_READ_TIMEOUT)
+        snippet_client_v2._SOCKET_READ_TIMEOUT
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  def test_make_connection_io_error(self, mock_socket_create_conn,
-                                    mock_get_port):
+  def test_make_connection_io_error(self, mock_socket_create_conn, _):
     """Tests IOError occurred trying to create a socket connection."""
-    del mock_get_port
     mock_socket_create_conn.side_effect = IOError()
     with self.assertRaises(IOError):
       self._make_client()
       self.client.device_port = 123
       self.client.make_connection()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  def test_make_connection_timeout(self, mock_socket_create_conn,
-                                   mock_get_port):
+  def test_make_connection_timeout(self, mock_socket_create_conn, _):
     """Tests timeout occurred trying to create a socket connection."""
-    del mock_get_port
     mock_socket_create_conn.side_effect = socket.timeout
     with self.assertRaises(socket.timeout):
       self._make_client()
       self.client.device_port = 123
       self.client.make_connection()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_make_connection_receives_none_handshake_response(
-      self, mock_start_subprocess, mock_socket_create_conn, mock_get_port):
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests make_connection receives None as the handshake response."""
-    del mock_get_port
     socket_resp = [None]
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     with self.assertRaisesRegex(
-        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE):
+        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE
+    ):
       self.client.make_connection()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_make_connection_receives_empty_handshake_response(
-      self, mock_start_subprocess, mock_socket_create_conn, mock_get_port):
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests make_connection receives an empty handshake response."""
-    del mock_get_port
     socket_resp = [b'']
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
     self._mock_server_process_starting_response(mock_start_subprocess)
 
     with self.assertRaisesRegex(
-        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE):
+        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE
+    ):
       self.client.make_connection()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_make_connection_receives_invalid_handshake_response(
-      self, mock_start_subprocess, mock_socket_create_conn, mock_get_port):
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests make_connection receives an invalid handshake response."""
-    del mock_get_port
     socket_resp = [b'{"status": false, "uid": 1}']
     self._make_client_and_mock_socket_conn(mock_socket_create_conn, socket_resp)
     self._mock_server_process_starting_response(mock_start_subprocess)
@@ -1240,18 +1540,20 @@
     self.client.make_connection()
     self.assertEqual(self.client.uid, -1)
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
-  def test_make_connection_send_handshake_request_error(self,
-                                                        mock_start_subprocess,
-                                                        mock_socket_create_conn,
-                                                        mock_get_port):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
+  def test_make_connection_send_handshake_request_error(
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that an error occurred trying to send a handshake request."""
-    del mock_get_port
     self._make_client_and_mock_socket_conn(mock_socket_create_conn)
     self._mock_server_process_starting_response(mock_start_subprocess)
     self.mock_socket_file.write.side_effect = socket.error('Socket write error')
@@ -1259,34 +1561,43 @@
     with self.assertRaisesRegex(errors.Error, 'Socket write error'):
       self.client.make_connection()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_make_connection_receive_handshake_response_error(
-      self, mock_start_subprocess, mock_socket_create_conn, mock_get_port):
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that an error occurred trying to receive a handshake response."""
-    del mock_get_port
     self._make_client_and_mock_socket_conn(mock_socket_create_conn)
     self._mock_server_process_starting_response(mock_start_subprocess)
     self.mock_socket_file.readline.side_effect = socket.error(
-        'Socket read error')
+        'Socket read error'
+    )
 
     with self.assertRaisesRegex(errors.Error, 'Socket read error'):
       self.client.make_connection()
 
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.get_available_host_port',
-              return_value=12345)
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'adb.list_occupied_adb_ports',
+      return_value=[],
+  )
   @mock.patch('socket.create_connection')
-  @mock.patch('mobly.controllers.android_device_lib.snippet_client_v2.'
-              'utils.start_standing_subprocess')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.'
+      'utils.start_standing_subprocess'
+  )
   def test_make_connection_decode_handshake_response_bytes_error(
-      self, mock_start_subprocess, mock_socket_create_conn, mock_get_port):
+      self, mock_start_subprocess, mock_socket_create_conn, _
+  ):
     """Tests that an error occurred trying to decode a handshake response."""
-    del mock_get_port
     self._make_client_and_mock_socket_conn(mock_socket_create_conn)
     self._mock_server_process_starting_response(mock_start_subprocess)
     self.client.log = mock.Mock()
@@ -1299,7 +1610,8 @@
     self.client.log.error.assert_has_calls([
         mock.call(
             'Failed to decode socket response bytes using encoding utf8: %s',
-            socket_response)
+            socket_response,
+        )
     ])
 
   def test_rpc_sending_and_receiving(self):
@@ -1309,14 +1621,16 @@
     """
     self._make_client()
     rpc_request = '{"id": 0, "method": "some_rpc", "params": []}'
-    rpc_response_expected = ('{"id": 0, "result": 123, "error": null, '
-                             '"callback": null}')
+    rpc_response_expected = (
+        '{"id": 0, "result": 123, "error": null, "callback": null}'
+    )
 
     socket_write_expected = [
         mock.call(b'{"id": 0, "method": "some_rpc", "params": []}\n')
     ]
-    socket_response = (b'{"id": 0, "result": 123, "error": null, '
-                       b'"callback": null}')
+    socket_response = (
+        b'{"id": 0, "result": 123, "error": null, "callback": null}'
+    )
 
     mock_socket_file = mock.Mock()
     mock_socket_file.readline.return_value = socket_response
@@ -1325,8 +1639,9 @@
     rpc_response = self.client.send_rpc_request(rpc_request)
 
     self.assertEqual(rpc_response, rpc_response_expected)
-    self.assertEqual(mock_socket_file.write.call_args_list,
-                     socket_write_expected)
+    self.assertEqual(
+        mock_socket_file.write.call_args_list, socket_write_expected
+    )
 
   def test_rpc_send_socket_write_error(self):
     """Tests that an error occurred trying to write the socket file."""
@@ -1355,7 +1670,8 @@
     self.client._client = mock.Mock()
     socket_response = bytes(
         '{"id": 0, "result": 123, "error": null, "callback": null}',
-        encoding='cp037')
+        encoding='cp037',
+    )
     self.client._client.readline.return_value = socket_response
 
     rpc_request = '{"id": 0, "method": "some_rpc", "params": []}'
@@ -1365,16 +1681,19 @@
     self.client.log.error.assert_has_calls([
         mock.call(
             'Failed to decode socket response bytes using encoding utf8: %s',
-            socket_response)
+            socket_response,
+        )
     ])
 
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'send_handshake_request')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'create_socket_connection')
-  def test_make_conn_with_forwarded_port_init(self,
-                                              mock_create_socket_conn_func,
-                                              mock_send_handshake_func):
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'send_handshake_request'
+  )
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'create_socket_connection'
+  )
+  def test_make_conn_with_forwarded_port_init(
+      self, mock_create_socket_conn_func, mock_send_handshake_func
+  ):
     """Tests make_connection_with_forwarded_port initiates a new session."""
     self._make_client()
     self.client._counter = None
@@ -1385,27 +1704,32 @@
     self.assertEqual(next(self.client._counter), 0)
     mock_create_socket_conn_func.assert_called_once_with()
     mock_send_handshake_func.assert_called_once_with(
-        -1, snippet_client_v2.ConnectionHandshakeCommand.INIT)
+        -1, snippet_client_v2.ConnectionHandshakeCommand.INIT
+    )
 
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'send_handshake_request')
-  @mock.patch.object(snippet_client_v2.SnippetClientV2,
-                     'create_socket_connection')
-  def test_make_conn_with_forwarded_port_continue(self,
-                                                  mock_create_socket_conn_func,
-                                                  mock_send_handshake_func):
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'send_handshake_request'
+  )
+  @mock.patch.object(
+      snippet_client_v2.SnippetClientV2, 'create_socket_connection'
+  )
+  def test_make_conn_with_forwarded_port_continue(
+      self, mock_create_socket_conn_func, mock_send_handshake_func
+  ):
     """Tests make_connection_with_forwarded_port continues current session."""
     self._make_client()
     self.client._counter = None
     self.client.make_connection_with_forwarded_port(
-        12345, 54321, 3, snippet_client_v2.ConnectionHandshakeCommand.CONTINUE)
+        12345, 54321, 3, snippet_client_v2.ConnectionHandshakeCommand.CONTINUE
+    )
 
     self.assertEqual(self.client.host_port, 12345)
     self.assertEqual(self.client.device_port, 54321)
     self.assertEqual(next(self.client._counter), 0)
     mock_create_socket_conn_func.assert_called_once_with()
     mock_send_handshake_func.assert_called_once_with(
-        3, snippet_client_v2.ConnectionHandshakeCommand.CONTINUE)
+        3, snippet_client_v2.ConnectionHandshakeCommand.CONTINUE
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/controllers/android_device_lib/snippet_event_test.py b/tests/mobly/controllers/android_device_lib/snippet_event_test.py
index e59461c..367a139 100755
--- a/tests/mobly/controllers/android_device_lib/snippet_event_test.py
+++ b/tests/mobly/controllers/android_device_lib/snippet_event_test.py
@@ -25,14 +25,15 @@
 class SnippetEventTest(unittest.TestCase):
 
   def test_basic(self):
-    """Verifies that an event object can be created and logged properly.
-    """
-    event = snippet_event.SnippetEvent(MOCK_CALLBACK_ID, MOCK_EVENT_NAME,
-                                       MOCK_CREATION_TIME, MOCK_DATA)
+    """Verifies that an event object can be created and logged properly."""
+    event = snippet_event.SnippetEvent(
+        MOCK_CALLBACK_ID, MOCK_EVENT_NAME, MOCK_CREATION_TIME, MOCK_DATA
+    )
     self.assertEqual(
         repr(event),
-        "SnippetEvent(callback_id: myCallbackId, name: onXyzEvent, "
-        "creation_time: 12345678, data: {'foo': 'bar'})")
+        'SnippetEvent(callback_id: myCallbackId, name: onXyzEvent, '
+        "creation_time: 12345678, data: {'foo': 'bar'})",
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/controllers/android_device_test.py b/tests/mobly/controllers/android_device_test.py
index 3682c94..81c2965 100755
--- a/tests/mobly/controllers/android_device_test.py
+++ b/tests/mobly/controllers/android_device_test.py
@@ -50,68 +50,88 @@
     self.tmp_dir = tempfile.mkdtemp()
 
   def tearDown(self):
-    """Removes the temp dir.
-    """
+    """Removes the temp dir."""
     shutil.rmtree(self.tmp_dir)
 
   # Tests for android_device module functions.
   # These tests use mock AndroidDevice instances.
 
-  @mock.patch.object(android_device,
-                     'get_all_instances',
-                     new=mock_android_device.get_all_instances)
-  @mock.patch.object(android_device,
-                     'list_adb_devices',
-                     new=mock_android_device.list_adb_devices)
-  @mock.patch.object(android_device,
-                     'list_adb_devices_by_usb_id',
-                     new=mock_android_device.list_adb_devices)
+  @mock.patch.object(
+      android_device,
+      'get_all_instances',
+      new=mock_android_device.get_all_instances,
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices',
+      new=mock_android_device.list_adb_devices,
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices_by_usb_id',
+      new=mock_android_device.list_adb_devices,
+  )
   def test_create_with_pickup_all(self):
     pick_all_token = android_device.ANDROID_DEVICE_PICK_ALL_TOKEN
     actual_ads = android_device.create(pick_all_token)
-    for actual, expected in zip(actual_ads,
-                                mock_android_device.get_mock_ads(5)):
+    for actual, expected in zip(
+        actual_ads, mock_android_device.get_mock_ads(5)
+    ):
       self.assertEqual(actual.serial, expected.serial)
 
-  @mock.patch.object(android_device,
-                     'get_instances',
-                     new=mock_android_device.get_instances)
-  @mock.patch.object(android_device,
-                     'list_adb_devices',
-                     new=mock_android_device.list_adb_devices)
-  @mock.patch.object(android_device,
-                     'list_adb_devices_by_usb_id',
-                     new=mock_android_device.list_adb_devices)
+  @mock.patch.object(
+      android_device, 'get_instances', new=mock_android_device.get_instances
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices',
+      new=mock_android_device.list_adb_devices,
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices_by_usb_id',
+      new=mock_android_device.list_adb_devices,
+  )
   def test_create_with_string_list(self):
-    string_list = [u'1', '2']
+    string_list = ['1', '2']
     actual_ads = android_device.create(string_list)
     for actual_ad, expected_serial in zip(actual_ads, ['1', '2']):
       self.assertEqual(actual_ad.serial, expected_serial)
 
-  @mock.patch.object(android_device,
-                     'get_instances_with_configs',
-                     new=mock_android_device.get_instances_with_configs)
-  @mock.patch.object(android_device,
-                     'list_adb_devices',
-                     new=mock_android_device.list_adb_devices)
-  @mock.patch.object(android_device,
-                     'list_adb_devices_by_usb_id',
-                     new=mock_android_device.list_adb_devices)
+  @mock.patch.object(
+      android_device,
+      'get_instances_with_configs',
+      new=mock_android_device.get_instances_with_configs,
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices',
+      new=mock_android_device.list_adb_devices,
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices_by_usb_id',
+      new=mock_android_device.list_adb_devices,
+  )
   def test_create_with_dict_list(self):
     string_list = [{'serial': '1'}, {'serial': '2'}]
     actual_ads = android_device.create(string_list)
     for actual_ad, expected_serial in zip(actual_ads, ['1', '2']):
       self.assertEqual(actual_ad.serial, expected_serial)
 
-  @mock.patch.object(android_device,
-                     'get_instances_with_configs',
-                     new=mock_android_device.get_instances_with_configs)
-  @mock.patch.object(android_device,
-                     'list_adb_devices',
-                     new=mock_android_device.list_adb_devices)
-  @mock.patch.object(android_device,
-                     'list_adb_devices_by_usb_id',
-                     return_value=['usb:1'])
+  @mock.patch.object(
+      android_device,
+      'get_instances_with_configs',
+      new=mock_android_device.get_instances_with_configs,
+  )
+  @mock.patch.object(
+      android_device,
+      'list_adb_devices',
+      new=mock_android_device.list_adb_devices,
+  )
+  @mock.patch.object(
+      android_device, 'list_adb_devices_by_usb_id', return_value=['usb:1']
+  )
   def test_create_with_usb_id(self, mock_list_adb_devices_by_usb_id):
     string_list = [{'serial': '1'}, {'serial': '2'}, {'serial': 'usb:1'}]
     actual_ads = android_device.create(string_list)
@@ -137,8 +157,9 @@
   @mock.patch('mobly.controllers.android_device.list_adb_devices')
   @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id')
   @mock.patch('mobly.controllers.android_device.AndroidDevice')
-  def test_get_instances(self, mock_ad_class, mock_list_adb_usb, mock_list_adb,
-                         mock_list_fastboot):
+  def test_get_instances(
+      self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot
+  ):
     mock_list_fastboot.return_value = ['0']
     mock_list_adb.return_value = ['1']
     mock_list_adb_usb.return_value = []
@@ -150,14 +171,15 @@
   @mock.patch('mobly.controllers.android_device.list_adb_devices')
   @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id')
   @mock.patch('mobly.controllers.android_device.AndroidDevice')
-  def test_get_instances_do_not_exist(self, mock_ad_class, mock_list_adb_usb,
-                                      mock_list_adb, mock_list_fastboot):
+  def test_get_instances_do_not_exist(
+      self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot
+  ):
     mock_list_fastboot.return_value = []
     mock_list_adb.return_value = []
     mock_list_adb_usb.return_value = []
     with self.assertRaisesRegex(
         errors.Error,
-        'Android device serial "1" is specified in config but is not reachable'
+        'Android device serial "1" is specified in config but is not reachable',
     ):
       android_device.get_instances(['1'])
 
@@ -165,8 +187,9 @@
   @mock.patch('mobly.controllers.android_device.list_adb_devices')
   @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id')
   @mock.patch('mobly.controllers.android_device.AndroidDevice')
-  def test_get_instances_with_configs(self, mock_ad_class, mock_list_adb_usb,
-                                      mock_list_adb, mock_list_fastboot):
+  def test_get_instances_with_configs(
+      self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot
+  ):
     mock_list_fastboot.return_value = ['1']
     mock_list_adb.return_value = ['2']
     mock_list_adb_usb.return_value = []
@@ -179,24 +202,24 @@
     config = {'something': 'random'}
     with self.assertRaisesRegex(
         errors.Error,
-        f'Required value "serial" is missing in AndroidDevice config {config}'):
+        f'Required value "serial" is missing in AndroidDevice config {config}',
+    ):
       android_device.get_instances_with_configs([config])
 
   @mock.patch('mobly.controllers.android_device.list_fastboot_devices')
   @mock.patch('mobly.controllers.android_device.list_adb_devices')
   @mock.patch('mobly.controllers.android_device.list_adb_devices_by_usb_id')
   @mock.patch('mobly.controllers.android_device.AndroidDevice')
-  def test_get_instances_with_configsdo_not_exist(self, mock_ad_class,
-                                                  mock_list_adb_usb,
-                                                  mock_list_adb,
-                                                  mock_list_fastboot):
+  def test_get_instances_with_configsdo_not_exist(
+      self, mock_ad_class, mock_list_adb_usb, mock_list_adb, mock_list_fastboot
+  ):
     mock_list_fastboot.return_value = []
     mock_list_adb.return_value = []
     mock_list_adb_usb.return_value = []
     config = {'serial': '1'}
     with self.assertRaisesRegex(
         errors.Error,
-        'Android device serial "1" is specified in config but is not reachable'
+        'Android device serial "1" is specified in config but is not reachable',
     ):
       android_device.get_instances_with_configs([config])
 
@@ -213,8 +236,10 @@
 
   def test_get_devices_no_match(self):
     ads = mock_android_device.get_mock_ads(5)
-    expected_msg = ('Could not find a target device that matches condition'
-                    ": {'label': 'selected'}.")
+    expected_msg = (
+        'Could not find a target device that matches condition'
+        ": {'label': 'selected'}."
+    )
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       selected_ads = android_device.get_devices(ads, label='selected')
 
@@ -229,16 +254,17 @@
     expected_serial = '1'
     expected_h_port = 5555
     ads[1].h_port = expected_h_port
-    ad = android_device.get_device(ads,
-                                   serial=expected_serial,
-                                   h_port=expected_h_port)
+    ad = android_device.get_device(
+        ads, serial=expected_serial, h_port=expected_h_port
+    )
     self.assertEqual(ad.serial, expected_serial)
     self.assertEqual(ad.h_port, expected_h_port)
 
   def test_get_device_no_match(self):
     ads = mock_android_device.get_mock_ads(5)
-    expected_msg = ('Could not find a target device that matches condition'
-                    ": {'serial': 5}.")
+    expected_msg = (
+        "Could not find a target device that matches condition: {'serial': 5}."
+    )
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad = android_device.get_device(ads, serial=len(ads))
 
@@ -261,7 +287,8 @@
       ad.skip_logcat = False
       ad.is_required = True
     ads[1].services.logcat.start = mock.MagicMock(
-        side_effect=android_device.Error(msg))
+        side_effect=android_device.Error(msg)
+    )
     with self.assertRaisesRegex(android_device.Error, msg):
       android_device._start_services_on_ads(ads)
     ads[0].services.stop_all.assert_called_once_with()
@@ -273,35 +300,36 @@
     ads[0].services.logcat.start = mock.MagicMock()
     ads[1].services.logcat.start = mock.MagicMock()
     ads[2].services.logcat.start = mock.MagicMock(
-        side_effect=Exception('Should not have called this.'))
+        side_effect=Exception('Should not have called this.')
+    )
     ads[2].skip_logcat = True
     android_device._start_services_on_ads(ads)
 
   def test_take_bug_reports(self):
     ads = mock_android_device.get_mock_ads(3)
     android_device.take_bug_reports(ads, 'test_something', 'sometime')
-    ads[0].take_bug_report.assert_called_once_with(test_name='test_something',
-                                                   begin_time='sometime',
-                                                   destination=None)
-    ads[1].take_bug_report.assert_called_once_with(test_name='test_something',
-                                                   begin_time='sometime',
-                                                   destination=None)
-    ads[2].take_bug_report.assert_called_once_with(test_name='test_something',
-                                                   begin_time='sometime',
-                                                   destination=None)
+    ads[0].take_bug_report.assert_called_once_with(
+        test_name='test_something', begin_time='sometime', destination=None
+    )
+    ads[1].take_bug_report.assert_called_once_with(
+        test_name='test_something', begin_time='sometime', destination=None
+    )
+    ads[2].take_bug_report.assert_called_once_with(
+        test_name='test_something', begin_time='sometime', destination=None
+    )
 
   def test_take_bug_reports_with_int_begin_time(self):
     ads = mock_android_device.get_mock_ads(3)
     android_device.take_bug_reports(ads, 'test_something', 123)
-    ads[0].take_bug_report.assert_called_once_with(test_name='test_something',
-                                                   begin_time='123',
-                                                   destination=None)
-    ads[1].take_bug_report.assert_called_once_with(test_name='test_something',
-                                                   begin_time='123',
-                                                   destination=None)
-    ads[2].take_bug_report.assert_called_once_with(test_name='test_something',
-                                                   begin_time='123',
-                                                   destination=None)
+    ads[0].take_bug_report.assert_called_once_with(
+        test_name='test_something', begin_time='123', destination=None
+    )
+    ads[1].take_bug_report.assert_called_once_with(
+        test_name='test_something', begin_time='123', destination=None
+    )
+    ads[2].take_bug_report.assert_called_once_with(
+        test_name='test_something', begin_time='123', destination=None
+    )
 
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_take_bug_reports_with_none_values(self, get_log_file_timestamp_mock):
@@ -309,24 +337,28 @@
     get_log_file_timestamp_mock.return_value = mock_timestamp
     ads = mock_android_device.get_mock_ads(3)
     android_device.take_bug_reports(ads)
-    ads[0].take_bug_report.assert_called_once_with(test_name=None,
-                                                   begin_time=mock_timestamp,
-                                                   destination=None)
-    ads[1].take_bug_report.assert_called_once_with(test_name=None,
-                                                   begin_time=mock_timestamp,
-                                                   destination=None)
-    ads[2].take_bug_report.assert_called_once_with(test_name=None,
-                                                   begin_time=mock_timestamp,
-                                                   destination=None)
+    ads[0].take_bug_report.assert_called_once_with(
+        test_name=None, begin_time=mock_timestamp, destination=None
+    )
+    ads[1].take_bug_report.assert_called_once_with(
+        test_name=None, begin_time=mock_timestamp, destination=None
+    )
+    ads[2].take_bug_report.assert_called_once_with(
+        test_name=None, begin_time=mock_timestamp, destination=None
+    )
 
   # Tests for android_device.AndroidDevice class.
   # These tests mock out any interaction with the OS and real android device
   # in AndroidDeivce.
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_instantiation(self, MockFastboot, MockAdbProxy):
     """Verifies the AndroidDevice object's basic attributes are correctly
     set after instantiation.
@@ -335,19 +367,25 @@
     ad = android_device.AndroidDevice(serial=mock_serial)
     self.assertEqual(ad.serial, '1')
     self.assertEqual(ad.model, 'fakemodel')
-    expected_lp = os.path.join(logging.log_path,
-                               'AndroidDevice%s' % mock_serial)
+    expected_lp = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % mock_serial
+    )
     self.assertEqual(ad.log_path, expected_lp)
     self.assertIsNotNone(ad.services.logcat)
     self.assertIsNotNone(ad.services.snippets)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
   @mock.patch('mobly.utils.create_dir')
-  def test_AndroidDevice_load_config(self, create_dir_mock, FastbootProxy,
-                                     MockAdbProxy):
+  def test_AndroidDevice_load_config(
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     mock_serial = '1'
     config = {'space': 'the final frontier', 'number': 1, 'debug_tag': 'my_tag'}
     ad = android_device.AndroidDevice(serial=mock_serial)
@@ -356,24 +394,34 @@
     self.assertEqual(ad.number, 1)
     self.assertEqual(ad.debug_tag, 'my_tag')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
   @mock.patch('mobly.utils.create_dir')
-  def test_AndroidDevice_load_config_dup(self, create_dir_mock, FastbootProxy,
-                                         MockAdbProxy):
+  def test_AndroidDevice_load_config_dup(
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     mock_serial = '1'
     config = {'serial': 'new_serial'}
     ad = android_device.AndroidDevice(serial=mock_serial)
-    with self.assertRaisesRegex(android_device.DeviceError,
-                                'Attribute serial already exists with'):
+    with self.assertRaisesRegex(
+        android_device.DeviceError, 'Attribute serial already exists with'
+    ):
       ad.load_config(config)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_build_info(self, MockFastboot, MockAdbProxy):
     """Verifies the AndroidDevice object's basic attributes are correctly
     set after instantiation.
@@ -382,8 +430,10 @@
     build_info = ad.build_info
     self.assertEqual(build_info['build_id'], 'AB42')
     self.assertEqual(build_info['build_type'], 'userdebug')
-    self.assertEqual(build_info['build_fingerprint'],
-                     'FakeModel:Dessert/AB42/1234567:userdebug/dev-keys')
+    self.assertEqual(
+        build_info['build_fingerprint'],
+        'FakeModel:Dessert/AB42/1234567:userdebug/dev-keys',
+    )
     self.assertEqual(build_info['build_version_codename'], 'Z')
     self.assertEqual(build_info['build_version_incremental'], '1234567')
     self.assertEqual(build_info['build_version_sdk'], '28')
@@ -394,17 +444,23 @@
     self.assertEqual(build_info['hardware'], 'marlin')
     self.assertEqual(len(build_info), len(android_device.CACHED_SYSTEM_PROPS))
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  '1',
-                  mock_properties={
-                      'ro.build.id': 'AB42',
-                      'ro.build.type': 'userdebug',
-                  }))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(
+          '1',
+          mock_properties={
+              'ro.build.id': 'AB42',
+              'ro.build.type': 'userdebug',
+          },
+      ),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_build_info_with_minimal_properties(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     build_info = ad.build_info
     self.assertEqual(build_info['build_id'], 'AB42')
@@ -419,10 +475,14 @@
     self.assertEqual(build_info['debuggable'], '')
     self.assertEqual(build_info['hardware'], '')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_build_info_cached(self, MockFastboot, MockAdbProxy):
     """Verifies the AndroidDevice object's basic attributes are correctly
     set after instantiation.
@@ -433,40 +493,80 @@
     _ = ad.build_info
     self.assertEqual(ad.adb.getprops_call_count, 1)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  '1',
-                  mock_properties={
-                      'ro.build.id': 'AB42',
-                      'ro.build.type': 'userdebug',
-                      'ro.debuggable': '1',
-                  }))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device.list_fastboot_devices',
+      return_value=mock.MagicMock(),
+  )
+  def test_AndroidDevice_model_property_is_cached(
+      self, mock_list_fastboot_devices, _
+  ):
+    """Accessing `model` a second time shouldn't invoke all the fastboot/adb
+    calls again.
+    """
+    mock_serial = 1
+    # mock returns '2' so the device is not considered in bootloader mode.
+    mock_list_fastboot_devices.return_value = ['2']
+    ad = android_device.AndroidDevice(serial=mock_serial)
+    ad.model
+    mock_count_first = mock_list_fastboot_devices.call_count
+    ad.model  # access `model` again.
+    mock_count_second = mock_list_fastboot_devices.call_count
+    self.assertEqual(mock_count_first, mock_count_second)
+
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(
+          '1',
+          mock_properties={
+              'ro.build.id': 'AB42',
+              'ro.build.type': 'userdebug',
+              'ro.debuggable': '1',
+          },
+      ),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_is_rootable_when_userdebug_device(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     self.assertTrue(ad.is_rootable)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  '1',
-                  mock_properties={
-                      'ro.build.id': 'AB42',
-                      'ro.build.type': 'user',
-                      'ro.debuggable': '0',
-                  }))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
-  def test_AndroidDevice_is_rootable_when_user_device(self, MockFastboot,
-                                                      MockAdbProxy):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(
+          '1',
+          mock_properties={
+              'ro.build.id': 'AB42',
+              'ro.build.type': 'user',
+              'ro.debuggable': '0',
+          },
+      ),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  def test_AndroidDevice_is_rootable_when_user_device(
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     self.assertFalse(ad.is_rootable)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_device_info(self, MockFastboot, MockAdbProxy):
     ad = android_device.AndroidDevice(serial=1)
     device_info = ad.device_info
@@ -480,237 +580,328 @@
     self.assertEqual(device_info['user_added_info']['sim_type'], 'Fi')
     self.assertEqual(device_info['user_added_info']['build_id'], 'CD42')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_serial_is_valid(self, MockFastboot, MockAdbProxy):
-    """Verifies that the serial is a primitive string type and serializable.
-    """
+    """Verifies that the serial is a primitive string type and serializable."""
     ad = android_device.AndroidDevice(serial=1)
     self.assertTrue(isinstance(ad.serial, str))
     yaml.safe_dump(ad.serial)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_is_emulator_when_realish_device(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     self.assertFalse(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('localhost:123'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('localhost:123'),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-      return_value=mock_android_device.MockFastbootProxy('localhost:123'))
+      return_value=mock_android_device.MockFastbootProxy('localhost:123'),
+  )
   def test_AndroidDevice_is_emulator_when_local_networked_device(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     # Although these devices are usually emulators, there might be a reason
     # to do this with a real device.
     ad = android_device.AndroidDevice(serial='localhost:123')
     self.assertFalse(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('example.com:123'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('example:123'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('example.com:123'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('example:123'),
+  )
   def test_AndroidDevice_is_emulator_when_remote_networked_device(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='example.com:123')
     self.assertFalse(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  'localhost:5554',
-                  mock_properties={
-                      'ro.hardware': 'ranchu',
-                      'ro.build.id': 'AB42',
-                      'ro.build.type': 'userdebug',
-                  }))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(
+          'localhost:5554',
+          mock_properties={
+              'ro.hardware': 'ranchu',
+              'ro.build.id': 'AB42',
+              'ro.build.type': 'userdebug',
+          },
+      ),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-      return_value=mock_android_device.MockFastbootProxy('localhost:5554'))
-  def test_AndroidDevice_is_emulator_when_ranchu_device(self, MockFastboot,
-                                                        MockAdbProxy):
+      return_value=mock_android_device.MockFastbootProxy('localhost:5554'),
+  )
+  def test_AndroidDevice_is_emulator_when_ranchu_device(
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='localhost:5554')
     self.assertTrue(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  '1',
-                  mock_properties={
-                      'ro.build.id': 'AB42',
-                      'ro.build.type': 'userdebug',
-                      'ro.hardware': 'goldfish',
-                  }))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(
+          '1',
+          mock_properties={
+              'ro.build.id': 'AB42',
+              'ro.build.type': 'userdebug',
+              'ro.hardware': 'goldfish',
+          },
+      ),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_is_emulator_when_goldfish_device(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     self.assertTrue(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  'example.com:123',
-                  mock_properties={
-                      'ro.build.id': 'AB42',
-                      'ro.build.type': 'userdebug',
-                      'ro.build.characteristics': 'emulator',
-                  }))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(
+          'example.com:123',
+          mock_properties={
+              'ro.build.id': 'AB42',
+              'ro.build.type': 'userdebug',
+              'ro.build.characteristics': 'emulator',
+          },
+      ),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-      return_value=mock_android_device.MockFastbootProxy('example.com:123'))
+      return_value=mock_android_device.MockFastbootProxy('example.com:123'),
+  )
   def test_AndroidDevice_is_emulator_when_emulator_characteristic(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='example.com:123')
     self.assertTrue(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('emulator-5554'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('emulator-5554'),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-      return_value=mock_android_device.MockFastbootProxy('emulator-5554'))
+      return_value=mock_android_device.MockFastbootProxy('emulator-5554'),
+  )
   def test_AndroidDevice_is_emulator_when_emulator_serial(
-      self, MockFastboot, MockAdbProxy):
+      self, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='emulator-5554')
     self.assertTrue(ad.is_emulator)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
-  @mock.patch('mobly.controllers.android_device.list_fastboot_devices',
-              return_value='1')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device.list_fastboot_devices', return_value='1'
+  )
   def test_AndroidDevice_is_fastboot(self, _, MockFastboot, MockAdbProxy):
     ad = android_device.AndroidDevice(serial='1')
     self.assertTrue(ad.is_bootloader)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.logger.get_log_file_timestamp')
-  def test_AndroidDevice_generate_filename_default(self,
-                                                   get_log_file_timestamp_mock,
-                                                   MockFastboot, MockAdbProxy):
+  def test_AndroidDevice_generate_filename_default(
+      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy
+  ):
     mock_serial = 1
     ad = android_device.AndroidDevice(serial=mock_serial)
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     filename = ad.generate_filename('MagicLog')
     self.assertEqual(filename, 'MagicLog,1,fakemodel,07-22-2019_17-53-34-450')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.logger.get_log_file_timestamp')
   @mock.patch('mobly.logger.sanitize_filename')
   def test_AndroidDevice_generate_filename_assert_sanitation(
-      self, sanitize_filename_mock, get_log_file_timestamp_mock, MockFastboot,
-      MockAdbProxy):
+      self,
+      sanitize_filename_mock,
+      get_log_file_timestamp_mock,
+      MockFastboot,
+      MockAdbProxy,
+  ):
     mock_serial = 1
     sanitize_filename_mock.return_value = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     filename = ad.generate_filename('MagicLog')
     sanitize_filename_mock.assert_called_with(
-        'MagicLog,1,fakemodel,07-22-2019_17-53-34-450')
+        'MagicLog,1,fakemodel,07-22-2019_17-53-34-450'
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.logger.get_log_file_timestamp')
-  def test_AndroidDevice_generate_filename_with_ext(self,
-                                                    get_log_file_timestamp_mock,
-                                                    MockFastboot, MockAdbProxy):
+  def test_AndroidDevice_generate_filename_with_ext(
+      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy
+  ):
     mock_serial = 1
     ad = android_device.AndroidDevice(serial=mock_serial)
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     filename = ad.generate_filename('MagicLog', extension_name='log')
-    self.assertEqual(filename,
-                     'MagicLog,1,fakemodel,07-22-2019_17-53-34-450.log')
+    self.assertEqual(
+        filename, 'MagicLog,1,fakemodel,07-22-2019_17-53-34-450.log'
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_AndroidDevice_generate_filename_with_debug_tag(
-      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy):
+      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy
+  ):
     mock_serial = 1
     ad = android_device.AndroidDevice(serial=mock_serial)
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     ad.debug_tag = 'RoleX'
     filename = ad.generate_filename('MagicLog')
-    self.assertEqual(filename,
-                     'MagicLog,RoleX,1,fakemodel,07-22-2019_17-53-34-450')
+    self.assertEqual(
+        filename, 'MagicLog,RoleX,1,fakemodel,07-22-2019_17-53-34-450'
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_AndroidDevice_generate_filename_with_runtime_info(
-      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy):
+      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy
+  ):
     mock_serial = 1
     ad = android_device.AndroidDevice(serial=mock_serial)
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
-    mock_record = mock.MagicMock(test_name='test_xyz',
-                                 begin_time='1234567',
-                                 signature='test_xyz-1234567')
-    mock_test_info = runtime_test_info.RuntimeTestInfo(mock_record.test_name,
-                                                       '/tmp/blah/',
-                                                       mock_record)
+    mock_record = mock.MagicMock(
+        test_name='test_xyz', begin_time='1234567', signature='test_xyz-1234567'
+    )
+    mock_test_info = runtime_test_info.RuntimeTestInfo(
+        mock_record.test_name, '/tmp/blah/', mock_record
+    )
     filename = ad.generate_filename('MagicLog', time_identifier=mock_test_info)
     self.assertEqual(filename, 'MagicLog,1,fakemodel,test_xyz-1234567')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_AndroidDevice_generate_filename_with_custom_timestamp(
-      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy):
+      self, get_log_file_timestamp_mock, MockFastboot, MockAdbProxy
+  ):
     mock_serial = 1
     ad = android_device.AndroidDevice(serial=mock_serial)
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
-    filename = ad.generate_filename('MagicLog',
-                                    time_identifier='my_special_time')
+    filename = ad.generate_filename(
+        'MagicLog', time_identifier='my_special_time'
+    )
     self.assertEqual(filename, 'MagicLog,1,fakemodel,my_special_time')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
   @mock.patch('mobly.utils.create_dir')
-  def test_AndroidDevice_take_bug_report(self, create_dir_mock, FastbootProxy,
-                                         MockAdbProxy):
+  def test_AndroidDevice_take_bug_report(
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     """Verifies AndroidDevice.take_bug_report calls the correct adb command
     and writes the bugreport file to the correct path.
     """
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
-    output_path = ad.take_bug_report(test_name='test_something',
-                                     begin_time='sometime')
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
+    output_path = ad.take_bug_report(
+        test_name='test_something', begin_time='sometime'
+    )
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
     create_dir_mock.assert_called_with(expected_path)
     self.assertEqual(
         output_path,
-        os.path.join(expected_path,
-                     'bugreport,test_something,1,fakemodel,sometime.zip'))
+        os.path.join(
+            expected_path, 'bugreport,test_something,1,fakemodel,sometime.zip'
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1', fail_br=True))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1', fail_br=True),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
-  def test_AndroidDevice_take_bug_report_fail(self, create_dir_mock,
-                                              FastbootProxy, MockAdbProxy):
+  def test_AndroidDevice_take_bug_report_fail(
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     """Verifies AndroidDevice.take_bug_report writes out the correct message
     when taking bugreport fails.
     """
@@ -720,170 +911,247 @@
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.take_bug_report(test_name='test_something', begin_time='sometime')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_AndroidDevice_take_bug_report_without_args(
-      self, get_log_file_timestamp_mock, create_dir_mock, FastbootProxy,
-      MockAdbProxy):
+      self,
+      get_log_file_timestamp_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     output_path = ad.take_bug_report()
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
     self.assertEqual(
         output_path,
-        os.path.join(expected_path,
-                     'bugreport,1,fakemodel,07-22-2019_17-53-34-450.zip'))
+        os.path.join(
+            expected_path, 'bugreport,1,fakemodel,07-22-2019_17-53-34-450.zip'
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_AndroidDevice_take_bug_report_with_only_test_name(
-      self, get_log_file_timestamp_mock, create_dir_mock, FastbootProxy,
-      MockAdbProxy):
+      self,
+      get_log_file_timestamp_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     output_path = ad.take_bug_report(test_name='test_something')
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
     create_dir_mock.assert_called_with(expected_path)
     self.assertEqual(
         output_path,
         os.path.join(
             expected_path,
-            'bugreport,test_something,1,fakemodel,07-22-2019_17-53-34-450.zip'))
+            'bugreport,test_something,1,fakemodel,07-22-2019_17-53-34-450.zip',
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
   @mock.patch('mobly.utils.create_dir')
   def test_AndroidDevice_take_bug_report_with_only_begin_time(
-      self, create_dir_mock, FastbootProxy, MockAdbProxy):
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     output_path = ad.take_bug_report(begin_time='sometime')
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
     create_dir_mock.assert_called_with(expected_path)
     self.assertEqual(
         output_path,
-        os.path.join(expected_path, 'bugreport,1,fakemodel,sometime.zip'))
+        os.path.join(expected_path, 'bugreport,1,fakemodel,sometime.zip'),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
   @mock.patch('mobly.utils.create_dir')
   def test_AndroidDevice_take_bug_report_with_int_begin_time(
-      self, create_dir_mock, FastbootProxy, MockAdbProxy):
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     output_path = ad.take_bug_report(begin_time=123)
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
-    create_dir_mock.assert_called_with(expected_path)
-    self.assertEqual(
-        output_path, os.path.join(expected_path,
-                                  'bugreport,1,fakemodel,123.zip'))
-
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
-  @mock.patch('mobly.utils.create_dir')
-  def test_AndroidDevice_take_bug_report_with_positional_args(
-      self, create_dir_mock, FastbootProxy, MockAdbProxy):
-    mock_serial = '1'
-    ad = android_device.AndroidDevice(serial=mock_serial)
-    output_path = ad.take_bug_report('test_something', 'sometime')
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
     create_dir_mock.assert_called_with(expected_path)
     self.assertEqual(
         output_path,
-        os.path.join(expected_path,
-                     'bugreport,test_something,1,fakemodel,sometime.zip'))
+        os.path.join(expected_path, 'bugreport,1,fakemodel,123.zip'),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
+  @mock.patch('mobly.utils.create_dir')
+  def test_AndroidDevice_take_bug_report_with_positional_args(
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
+    mock_serial = '1'
+    ad = android_device.AndroidDevice(serial=mock_serial)
+    output_path = ad.take_bug_report('test_something', 'sometime')
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
+    create_dir_mock.assert_called_with(expected_path)
+    self.assertEqual(
+        output_path,
+        os.path.join(
+            expected_path, 'bugreport,test_something,1,fakemodel,sometime.zip'
+        ),
+    )
+
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   def test_AndroidDevice_take_bug_report_with_destination(
-      self, create_dir_mock, FastbootProxy, MockAdbProxy):
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     dest = tempfile.gettempdir()
-    output_path = ad.take_bug_report(test_name="test_something",
-                                     begin_time="sometime",
-                                     destination=dest)
+    output_path = ad.take_bug_report(
+        test_name='test_something', begin_time='sometime', destination=dest
+    )
     expected_path = os.path.join(dest)
     create_dir_mock.assert_called_with(expected_path)
     self.assertEqual(
         output_path,
-        os.path.join(expected_path,
-                     'bugreport,test_something,1,fakemodel,sometime.zip'))
+        os.path.join(
+            expected_path, 'bugreport,test_something,1,fakemodel,sometime.zip'
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(
-                  '1', fail_br_before_N=True))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1', fail_br_before_N=True),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
-  def test_AndroidDevice_take_bug_report_fallback(self, create_dir_mock,
-                                                  FastbootProxy, MockAdbProxy):
+  def test_AndroidDevice_take_bug_report_fallback(
+      self, create_dir_mock, FastbootProxy, MockAdbProxy
+  ):
     """Verifies AndroidDevice.take_bug_report falls back to traditional
     bugreport on builds that do not have bugreportz.
     """
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
-    output_path = ad.take_bug_report(test_name='test_something',
-                                     begin_time='sometime')
-    expected_path = os.path.join(logging.log_path,
-                                 'AndroidDevice%s' % ad.serial, 'BugReports')
+    output_path = ad.take_bug_report(
+        test_name='test_something', begin_time='sometime'
+    )
+    expected_path = os.path.join(
+        logging.log_path, 'AndroidDevice%s' % ad.serial, 'BugReports'
+    )
     create_dir_mock.assert_called_with(expected_path)
     self.assertEqual(
         output_path,
-        os.path.join(expected_path,
-                     'bugreport,test_something,1,fakemodel,sometime.txt'))
+        os.path.join(
+            expected_path, 'bugreport,test_something,1,fakemodel,sometime.txt'
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.logger.get_log_file_timestamp')
-  def test_AndroidDevice_take_screenshot(self, get_log_file_timestamp_mock,
-                                         create_dir_mock, FastbootProxy,
-                                         MockAdbProxy):
+  def test_AndroidDevice_take_screenshot(
+      self,
+      get_log_file_timestamp_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     full_pic_path = ad.take_screenshot(self.tmp_dir)
     self.assertEqual(
         full_pic_path,
-        os.path.join(self.tmp_dir,
-                     'screenshot,1,fakemodel,07-22-2019_17-53-34-450.png'))
+        os.path.join(
+            self.tmp_dir, 'screenshot,1,fakemodel,07-22-2019_17-53-34-450.png'
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.logger.get_log_file_timestamp')
   def test_AndroidDevice_take_screenshot_with_prefix(
-      self, get_log_file_timestamp_mock, create_dir_mock, FastbootProxy,
-      MockAdbProxy):
+      self,
+      get_log_file_timestamp_mock,
+      create_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     get_log_file_timestamp_mock.return_value = '07-22-2019_17-53-34-450'
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
@@ -892,65 +1160,89 @@
 
     self.assertEqual(
         full_pic_path,
-        os.path.join(self.tmp_dir,
-                     'page_a,1,fakemodel,07-22-2019_17-53-34-450.png'))
+        os.path.join(
+            self.tmp_dir, 'page_a,1,fakemodel,07-22-2019_17-53-34-450.png'
+        ),
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
-  @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
-  @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_AndroidDevice_change_log_path(self, stop_proc_mock, start_proc_mock,
-                                         FastbootProxy, MockAdbProxy):
-    ad = android_device.AndroidDevice(serial='1')
-    old_path = ad.log_path
-    new_log_path = tempfile.mkdtemp()
-    ad.log_path = new_log_path
-    self.assertTrue(os.path.exists(new_log_path))
-    self.assertFalse(os.path.exists(old_path))
-
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
-  @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
-  @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_AndroidDevice_change_log_path_no_log_exists(self, stop_proc_mock,
-                                                       start_proc_mock,
-                                                       FastbootProxy,
-                                                       MockAdbProxy):
-    ad = android_device.AndroidDevice(serial='1')
-    old_path = ad.log_path
-    new_log_path = tempfile.mkdtemp()
-    ad.log_path = new_log_path
-    self.assertTrue(os.path.exists(new_log_path))
-    self.assertFalse(os.path.exists(old_path))
-
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('127.0.0.1:5557'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-      return_value=mock_android_device.MockFastbootProxy('127.0.0.1:5557'))
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
+  @mock.patch('mobly.utils.stop_standing_subprocess')
+  def test_AndroidDevice_change_log_path(
+      self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy
+  ):
+    ad = android_device.AndroidDevice(serial='1')
+    old_path = ad.log_path
+    new_log_path = tempfile.mkdtemp()
+    ad.log_path = new_log_path
+    self.assertTrue(os.path.exists(new_log_path))
+    self.assertFalse(os.path.exists(old_path))
+
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
+  @mock.patch('mobly.utils.stop_standing_subprocess')
+  def test_AndroidDevice_change_log_path_no_log_exists(
+      self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy
+  ):
+    ad = android_device.AndroidDevice(serial='1')
+    old_path = ad.log_path
+    new_log_path = tempfile.mkdtemp()
+    ad.log_path = new_log_path
+    self.assertTrue(os.path.exists(new_log_path))
+    self.assertFalse(os.path.exists(old_path))
+
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('127.0.0.1:5557'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('127.0.0.1:5557'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   def test_AndroidDevice_with_reserved_character_in_serial_log_path(
-      self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy):
+      self, stop_proc_mock, start_proc_mock, FastbootProxy, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='127.0.0.1:5557')
     base_log_path = os.path.basename(ad.log_path)
     self.assertEqual(base_log_path, 'AndroidDevice127.0.0.1-5557')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   def test_AndroidDevice_change_log_path_with_service(
-      self, open_logcat_mock, stop_proc_mock, start_proc_mock, creat_dir_mock,
-      FastbootProxy, MockAdbProxy):
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      creat_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.services.logcat.start()
     new_log_path = tempfile.mkdtemp()
@@ -958,35 +1250,53 @@
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.log_path = new_log_path
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   def test_AndroidDevice_change_log_path_with_existing_file(
-      self, stop_proc_mock, start_proc_mock, creat_dir_mock, FastbootProxy,
-      MockAdbProxy):
+      self,
+      stop_proc_mock,
+      start_proc_mock,
+      creat_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     new_log_path = tempfile.mkdtemp()
     new_file_path = os.path.join(new_log_path, 'file.txt')
     with io.open(new_file_path, 'w', encoding='utf-8') as f:
-      f.write(u'hahah.')
+      f.write('hahah.')
     expected_msg = '.* Logs already exist .*'
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.log_path = new_log_path
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
-  def test_AndroidDevice_update_serial(self, stop_proc_mock, start_proc_mock,
-                                       creat_dir_mock, FastbootProxy,
-                                       MockAdbProxy):
+  def test_AndroidDevice_update_serial(
+      self,
+      stop_proc_mock,
+      start_proc_mock,
+      creat_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.update_serial('2')
     self.assertEqual(ad.serial, '2')
@@ -994,114 +1304,160 @@
     self.assertEqual(ad.adb.serial, ad.serial)
     self.assertEqual(ad.fastboot.serial, ad.serial)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.create_dir')
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   def test_AndroidDevice_update_serial_with_service_running(
-      self, open_logcat_mock, stop_proc_mock, start_proc_mock, creat_dir_mock,
-      FastbootProxy, MockAdbProxy):
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      creat_dir_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.services.logcat.start()
-    expected_msg = '.* Cannot change device serial number when there is service running.'
+    expected_msg = (
+        '.* Cannot change device serial number when there is service running.'
+    )
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.update_serial('2')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
-  def test_AndroidDevice_load_snippet(self, MockGetPort, MockSnippetClient,
-                                      MockFastboot, MockAdbProxy):
+  def test_AndroidDevice_load_snippet(
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
     self.assertTrue(hasattr(ad, 'snippet'))
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
-  def test_AndroidDevice_getattr(self, MockGetPort, MockSnippetClient,
-                                 MockFastboot, MockAdbProxy):
+  def test_AndroidDevice_getattr(
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
     value = {'value': 42}
     actual_value = getattr(ad, 'some_attr', value)
     self.assertEqual(actual_value, value)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2',
-      return_value=MockSnippetClient)
+      return_value=MockSnippetClient,
+  )
   @mock.patch('mobly.utils.get_available_host_port')
-  def test_AndroidDevice_load_snippet_dup_package(self, MockGetPort,
-                                                  MockSnippetClient,
-                                                  MockFastboot, MockAdbProxy):
+  def test_AndroidDevice_load_snippet_dup_package(
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
-    expected_msg = ('Snippet package "%s" has already been loaded under '
-                    'name "snippet".') % MOCK_SNIPPET_PACKAGE_NAME
+    expected_msg = (
+        'Snippet package "%s" has already been loaded under name "snippet".'
+    ) % MOCK_SNIPPET_PACKAGE_NAME
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.load_snippet('snippet2', MOCK_SNIPPET_PACKAGE_NAME)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2',
-      return_value=MockSnippetClient)
+      return_value=MockSnippetClient,
+  )
   @mock.patch('mobly.utils.get_available_host_port')
-  def test_AndroidDevice_load_snippet_dup_snippet_name(self, MockGetPort,
-                                                       MockSnippetClient,
-                                                       MockFastboot,
-                                                       MockAdbProxy):
+  def test_AndroidDevice_load_snippet_dup_snippet_name(
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
-    expected_msg = ('.* Attribute "snippet" already exists, please use a '
-                    'different name.')
+    expected_msg = (
+        '.* Attribute "snippet" already exists, please use a different name.'
+    )
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME + 'haha')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
   def test_AndroidDevice_load_snippet_dup_attribute_name(
-      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy):
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
-    expected_msg = ('Attribute "%s" already exists, please use a different'
-                    ' name') % 'adb'
+    expected_msg = (
+        'Attribute "%s" already exists, please use a different name'
+    ) % 'adb'
     with self.assertRaisesRegex(android_device.Error, expected_msg):
       ad.load_snippet('adb', MOCK_SNIPPET_PACKAGE_NAME)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
-  def test_AndroidDevice_load_snippet_start_app_fails(self, MockGetPort,
-                                                      MockSnippetClient,
-                                                      MockFastboot,
-                                                      MockAdbProxy):
+  def test_AndroidDevice_load_snippet_start_app_fails(
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     """Verifies that the correct exception is raised if start app failed.
 
     It's possible that the `stop` call as part of the start app failure
@@ -1117,15 +1473,21 @@
     except Exception as e:
       assertIs(e, expected_e)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
   def test_AndroidDevice_load_snippet_with_snippet_config(
-      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy):
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     snippet_config = snippet_client_v2.Config()
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME, snippet_config)
@@ -1134,78 +1496,110 @@
         package=mock.ANY, ad=mock.ANY, config=snippet_config
     )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
-  def test_AndroidDevice_unload_snippet(self, MockGetPort, MockSnippetClient,
-                                        MockFastboot, MockAdbProxy):
+  def test_AndroidDevice_unload_snippet(
+      self, MockGetPort, MockSnippetClient, MockFastboot, MockAdbProxy
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
     ad.unload_snippet('snippet')
     self.assertFalse(hasattr(ad, 'snippet'))
     with self.assertRaisesRegex(
         android_device.SnippetError,
-        '<AndroidDevice|1> No snippet registered with name "snippet"'):
+        '<AndroidDevice|1> No snippet registered with name "snippet"',
+    ):
       ad.unload_snippet('snippet')
     # Loading the same snippet again should succeed
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
     self.assertTrue(hasattr(ad, 'snippet'))
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
   @mock.patch(
-      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2')
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.snippet_client_v2.SnippetClientV2'
+  )
   @mock.patch('mobly.utils.get_available_host_port')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
-  def test_AndroidDevice_snippet_cleanup(self, open_logcat_mock, MockGetPort,
-                                         MockSnippetClient, MockFastboot,
-                                         MockAdbProxy):
+  def test_AndroidDevice_snippet_cleanup(
+      self,
+      open_logcat_mock,
+      MockGetPort,
+      MockSnippetClient,
+      MockFastboot,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     ad.services.start_all()
     ad.load_snippet('snippet', MOCK_SNIPPET_PACKAGE_NAME)
     ad.unload_snippet('snippet')
     self.assertFalse(hasattr(ad, 'snippet'))
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   def test_AndroidDevice_debug_tag(self, MockFastboot, MockAdbProxy):
     mock_serial = '1'
     ad = android_device.AndroidDevice(serial=mock_serial)
     self.assertEqual(ad.debug_tag, '1')
-    with self.assertRaisesRegex(android_device.DeviceError,
-                                r'<AndroidDevice\|1> Something'):
+    with self.assertRaisesRegex(
+        android_device.DeviceError, r'<AndroidDevice\|1> Something'
+    ):
       raise android_device.DeviceError(ad, 'Something')
 
     # Verify that debug tag's setter updates the debug prefix correctly.
     ad.debug_tag = 'Mememe'
-    with self.assertRaisesRegex(android_device.DeviceError,
-                                r'<AndroidDevice\|Mememe> Something'):
+    with self.assertRaisesRegex(
+        android_device.DeviceError, r'<AndroidDevice\|Mememe> Something'
+    ):
       raise android_device.DeviceError(ad, 'Something')
 
     # Verify that repr is changed correctly.
-    with self.assertRaisesRegex(Exception,
-                                r'(<AndroidDevice\|Mememe>, \'Something\')'):
+    with self.assertRaisesRegex(
+        Exception, r'(<AndroidDevice\|Mememe>, \'Something\')'
+    ):
       raise Exception(ad, 'Something')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
-  def test_AndroidDevice_handle_usb_disconnect(self, open_logcat_mock,
-                                               stop_proc_mock, start_proc_mock,
-                                               FastbootProxy, MockAdbProxy):
-
+  def test_AndroidDevice_handle_usb_disconnect(
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     class MockService(base_service.BaseService):
 
       def __init__(self, device, configs=None):
@@ -1241,17 +1635,25 @@
     self.assertTrue(ad.services.is_any_alive)
     self.assertTrue(ad.services.mock_service.resume_called)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
-  def test_AndroidDevice_handle_reboot(self, open_logcat_mock, stop_proc_mock,
-                                       start_proc_mock, FastbootProxy,
-                                       MockAdbProxy):
-
+  def test_AndroidDevice_handle_reboot(
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     class MockService(base_service.BaseService):
 
       def __init__(self, device, configs=None):
@@ -1287,16 +1689,25 @@
     self.assertTrue(ad.services.is_any_alive)
     self.assertFalse(ad.services.mock_service.resume_called)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   def test_AndroidDevice_handle_reboot_changes_build_info(
-      self, open_logcat_mock, stop_proc_mock, start_proc_mock, FastbootProxy,
-      MockAdbProxy):
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     with ad.handle_reboot():
       ad.adb.mock_properties['ro.build.type'] = 'user'
@@ -1306,16 +1717,25 @@
     self.assertFalse(ad.is_rootable)
     self.assertEqual(ad.adb.getprops_call_count, 2)
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch('mobly.utils.start_standing_subprocess', return_value='process')
   @mock.patch('mobly.utils.stop_standing_subprocess')
   @mock.patch.object(logcat.Logcat, '_open_logcat_file')
   def test_AndroidDevice_handle_reboot_changes_build_info_with_caching(
-      self, open_logcat_mock, stop_proc_mock, start_proc_mock, FastbootProxy,
-      MockAdbProxy):
+      self,
+      open_logcat_mock,
+      stop_proc_mock,
+      start_proc_mock,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')  # Call getprops 1.
     rootable_states = [ad.is_rootable]
     with ad.handle_reboot():
@@ -1328,25 +1748,37 @@
     self.assertEqual(ad.adb.getprops_call_count, 4)
     self.assertEqual(rootable_states, [True, True, False, False, False])
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch(
       'mobly.controllers.android_device.AndroidDevice.is_boot_completed',
       side_effect=[
-          False, False,
-          adb.AdbTimeoutError(['adb', 'shell', 'getprop sys.boot_completed'],
-                              timeout=5,
-                              serial=1), True
-      ])
+          False,
+          False,
+          adb.AdbTimeoutError(
+              ['adb', 'shell', 'getprop sys.boot_completed'],
+              timeout=5,
+              serial=1,
+          ),
+          True,
+      ],
+  )
   @mock.patch('time.sleep', return_value=None)
   @mock.patch('time.time', side_effect=[0, 5, 10, 15, 20, 25, 30])
-  def test_AndroidDevice_wait_for_completion_completed(self, MockTime,
-                                                       MockSleep,
-                                                       MockIsBootCompleted,
-                                                       FastbootProxy,
-                                                       MockAdbProxy):
+  def test_AndroidDevice_wait_for_completion_completed(
+      self,
+      MockTime,
+      MockSleep,
+      MockIsBootCompleted,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     raised = False
     try:
@@ -1355,27 +1787,43 @@
       raised = True
     self.assertFalse(
         raised,
-        'adb.AdbError or adb.AdbTimeoutError exception raised but not handled.')
+        'adb.AdbError or adb.AdbTimeoutError exception raised but not handled.',
+    )
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy('1'))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy('1'))
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy('1'),
+  )
   @mock.patch(
       'mobly.controllers.android_device.AndroidDevice.is_boot_completed',
       side_effect=[
-          False, False,
-          adb.AdbTimeoutError(['adb', 'shell', 'getprop sys.boot_completed'],
-                              timeout=5,
-                              serial=1), False, False, False, False
-      ])
+          False,
+          False,
+          adb.AdbTimeoutError(
+              ['adb', 'shell', 'getprop sys.boot_completed'],
+              timeout=5,
+              serial=1,
+          ),
+          False,
+          False,
+          False,
+          False,
+      ],
+  )
   @mock.patch('time.sleep', return_value=None)
   @mock.patch('time.perf_counter', side_effect=[0, 5, 10, 15, 20, 25, 30])
-  def test_AndroidDevice_wait_for_completion_never_boot(self, MockTime,
-                                                        MockSleep,
-                                                        MockIsBootCompleted,
-                                                        FastbootProxy,
-                                                        MockAdbProxy):
+  def test_AndroidDevice_wait_for_completion_never_boot(
+      self,
+      MockTime,
+      MockSleep,
+      MockIsBootCompleted,
+      FastbootProxy,
+      MockAdbProxy,
+  ):
     ad = android_device.AndroidDevice(serial='1')
     raised = False
     try:
@@ -1385,7 +1833,8 @@
       raised = True
     self.assertFalse(
         raised,
-        'adb.AdbError or adb.AdbTimeoutError exception raised but not handled.')
+        'adb.AdbError or adb.AdbTimeoutError exception raised but not handled.',
+    )
 
   def test_AndroidDevice_parse_device_list_when_decode_error(self):
     gbk_str = b'\xc4\xe3\xba\xc3'
diff --git a/tests/mobly/logger_test.py b/tests/mobly/logger_test.py
index e0ac14d..d975ac7 100755
--- a/tests/mobly/logger_test.py
+++ b/tests/mobly/logger_test.py
@@ -33,18 +33,19 @@
     shutil.rmtree(self.log_dir)
 
   def test_epoch_to_log_line_timestamp(self):
-    actual_stamp = logger.epoch_to_log_line_timestamp(1469134262116,
-                                                      time_zone=pytz.utc)
-    self.assertEqual("07-21 20:51:02.116", actual_stamp)
+    actual_stamp = logger.epoch_to_log_line_timestamp(
+        1469134262116, time_zone=pytz.utc
+    )
+    self.assertEqual('07-21 20:51:02.116', actual_stamp)
 
   def test_is_valid_logline_timestamp(self):
-    self.assertTrue(logger.is_valid_logline_timestamp("06-21 17:44:42.336"))
+    self.assertTrue(logger.is_valid_logline_timestamp('06-21 17:44:42.336'))
 
   def test_is_valid_logline_timestamp_when_wrong_length(self):
-    self.assertFalse(logger.is_valid_logline_timestamp("  06-21 17:44:42.336"))
+    self.assertFalse(logger.is_valid_logline_timestamp('  06-21 17:44:42.336'))
 
   def test_is_valid_logline_timestamp_when_invalid_content(self):
-    self.assertFalse(logger.is_valid_logline_timestamp("------------------"))
+    self.assertFalse(logger.is_valid_logline_timestamp('------------------'))
 
   @mock.patch('mobly.utils.create_alias')
   def test_create_latest_log_alias(self, mock_create_alias):
@@ -53,24 +54,28 @@
 
   @mock.patch('mobly.logger._setup_test_logger')
   @mock.patch('mobly.logger.create_latest_log_alias')
-  def test_setup_test_logger_creates_log_alias(self,
-                                               mock_create_latest_log_alias,
-                                               mock__setup_test_logger):
+  def test_setup_test_logger_creates_log_alias(
+      self, mock_create_latest_log_alias, mock__setup_test_logger
+  ):
     logger.setup_test_logger(self.log_dir)
-    mock__setup_test_logger.assert_called_once_with(self.log_dir, logging.INFO,
-                                                    None)
-    mock_create_latest_log_alias.assert_called_once_with(self.log_dir,
-                                                         alias='latest')
+    mock__setup_test_logger.assert_called_once_with(
+        self.log_dir, logging.INFO, None
+    )
+    mock_create_latest_log_alias.assert_called_once_with(
+        self.log_dir, alias='latest'
+    )
 
   @mock.patch('mobly.logger._setup_test_logger')
   @mock.patch('mobly.logger.create_latest_log_alias')
   def test_setup_test_logger_creates_log_alias_with_custom_value(
-      self, mock_create_latest_log_alias, mock__setup_test_logger):
+      self, mock_create_latest_log_alias, mock__setup_test_logger
+  ):
     mock_alias = mock.MagicMock()
     logger.setup_test_logger(self.log_dir, alias=mock_alias)
 
-    mock_create_latest_log_alias.assert_called_once_with(self.log_dir,
-                                                         alias=mock_alias)
+    mock_create_latest_log_alias.assert_called_once_with(
+        self.log_dir, alias=mock_alias
+    )
 
   def test_sanitize_filename_when_valid(self):
     fake_filename = 'logcat.txt'
@@ -114,8 +119,9 @@
   def test__sanitize_windows_filename_when_path_characters(self):
     fake_filename = '/\\'
     expected_filename = '__'
-    self.assertEqual(logger._sanitize_windows_filename(fake_filename),
-                     expected_filename)
+    self.assertEqual(
+        logger._sanitize_windows_filename(fake_filename), expected_filename
+    )
 
   def test_sanitize_filename_when_specical_characters(self):
     fake_filename = '<>:"|?*\x00'
@@ -129,8 +135,9 @@
         ('con.txt', 'mobly_con.txt'),
         ('connections.log', 'connections.log'),
     ]:
-      self.assertEqual(logger.sanitize_filename(fake_filename),
-                       expected_filename)
+      self.assertEqual(
+          logger.sanitize_filename(fake_filename), expected_filename
+      )
 
   def test_sanitize_filename_when_prn(self):
     for fake_filename, expected_filename in [
@@ -139,8 +146,9 @@
         ('prn.txt', 'mobly_prn.txt'),
         ('prnters.log', 'prnters.log'),
     ]:
-      self.assertEqual(logger.sanitize_filename(fake_filename),
-                       expected_filename)
+      self.assertEqual(
+          logger.sanitize_filename(fake_filename), expected_filename
+      )
 
   def test_sanitize_filename_when_aux(self):
     for fake_filename, expected_filename in [
@@ -149,8 +157,9 @@
         ('aux.txt', 'mobly_aux.txt'),
         ('auxiliaries.log', 'auxiliaries.log'),
     ]:
-      self.assertEqual(logger.sanitize_filename(fake_filename),
-                       expected_filename)
+      self.assertEqual(
+          logger.sanitize_filename(fake_filename), expected_filename
+      )
 
   def test_sanitize_filename_when_nul(self):
     for fake_filename, expected_filename in [
@@ -159,8 +168,9 @@
         ('nul.txt', 'mobly_nul.txt'),
         ('nullptrs.log', 'nullptrs.log'),
     ]:
-      self.assertEqual(logger.sanitize_filename(fake_filename),
-                       expected_filename)
+      self.assertEqual(
+          logger.sanitize_filename(fake_filename), expected_filename
+      )
 
   def test_sanitize_filename_when_com(self):
     for fake_filename, expected_filename in [
@@ -178,8 +188,9 @@
         ('com0.log', 'mobly_com0.log'),
         ('com0files.log', 'com0files.log'),
     ]:
-      self.assertEqual(logger.sanitize_filename(fake_filename),
-                       expected_filename)
+      self.assertEqual(
+          logger.sanitize_filename(fake_filename), expected_filename
+      )
 
   def test_sanitize_filename_when_lpt(self):
     for fake_filename, expected_filename in [
@@ -197,8 +208,9 @@
         ('lpt3.txt', 'mobly_lpt3.txt'),
         ('lpt3_file.txt', 'lpt3_file.txt'),
     ]:
-      self.assertEqual(logger.sanitize_filename(fake_filename),
-                       expected_filename)
+      self.assertEqual(
+          logger.sanitize_filename(fake_filename), expected_filename
+      )
 
   def test_sanitize_filename_when_ends_with_space(self):
     fake_filename = 'logcat.txt '
@@ -217,8 +229,9 @@
     adapted_logger = logger.PrefixLoggerAdapter(mock.Mock(), extra)
 
     kwargs = mock.Mock()
-    processed_log, processed_kwargs = adapted_logger.process('mock log line',
-                                                             kwargs=kwargs)
+    processed_log, processed_kwargs = adapted_logger.process(
+        'mock log line', kwargs=kwargs
+    )
 
     self.assertEqual(processed_log, '[MOCK_PREFIX] mock log line')
     self.assertIs(processed_kwargs, kwargs)
@@ -231,12 +244,13 @@
     adapted_logger.set_log_prefix('[NEW]')
 
     kwargs = mock.Mock()
-    processed_log, processed_kwargs = adapted_logger.process('mock log line',
-                                                             kwargs=kwargs)
+    processed_log, processed_kwargs = adapted_logger.process(
+        'mock log line', kwargs=kwargs
+    )
 
     self.assertEqual(processed_log, '[NEW] mock log line')
     self.assertIs(processed_kwargs, kwargs)
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/output_test.py b/tests/mobly/output_test.py
index 4b2d94a..bbffa89 100755
--- a/tests/mobly/output_test.py
+++ b/tests/mobly/output_test.py
@@ -47,7 +47,7 @@
     self.base_mock_test_config.controller_configs = {}
     self.base_mock_test_config.user_params = {
         'icecream': 42,
-        'extra_param': 'haha'
+        'extra_param': 'haha',
     }
     self.base_mock_test_config.log_path = self.tmp_dir
     self.log_dir = self.base_mock_test_config.log_path
@@ -59,13 +59,10 @@
   def create_mock_test_config(self, base_mock_test_config):
     mock_test_config = base_mock_test_config.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    my_config = [{
-        'serial': 'xxxx',
-        'magic': 'Magic1'
-    }, {
-        'serial': 'xxxx',
-        'magic': 'Magic2'
-    }]
+    my_config = [
+        {'serial': 'xxxx', 'magic': 'Magic1'},
+        {'serial': 'xxxx', 'magic': 'Magic2'},
+    ]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     return mock_test_config
 
@@ -76,8 +73,9 @@
     return (summary_file_path, debug_log_path, info_log_path)
 
   def assert_output_logs_exist(self, output_dir):
-    (summary_file_path, debug_log_path,
-     info_log_path) = self.get_output_logs(output_dir)
+    (summary_file_path, debug_log_path, info_log_path) = self.get_output_logs(
+        output_dir
+    )
     self.assertTrue(os.path.isfile(summary_file_path))
     self.assertTrue(os.path.isfile(debug_log_path))
     self.assertTrue(os.path.isfile(info_log_path))
@@ -96,8 +94,10 @@
     with tr.mobly_logger() as log_path:
       self.assertEqual(log_path, logging.log_path)
 
-  @unittest.skipIf(platform.system() == 'Windows',
-                   'Symlinks are usually specific to Unix operating systems')
+  @unittest.skipIf(
+      platform.system() == 'Windows',
+      'Symlinks are usually specific to Unix operating systems',
+  )
   def test_symlink(self):
     """Verifies the symlink is created and links properly."""
     mock_test_config = self.create_mock_test_config(self.base_mock_test_config)
@@ -107,12 +107,14 @@
     symlink = os.path.join(self.log_dir, self.testbed_name, 'latest')
     self.assertEqual(os.readlink(symlink), logging.log_path)
 
-  @unittest.skipIf(platform.system() != 'Windows',
-                   'Shortcuts are specific to Windows operating systems')
+  @unittest.skipIf(
+      platform.system() != 'Windows',
+      'Shortcuts are specific to Windows operating systems',
+  )
   def test_shortcut(self):
     """Verifies the shortcut is created and links properly."""
     shortcut_path = os.path.join(self.log_dir, self.testbed_name, 'latest.lnk')
-    shell = client.Dispatch("WScript.Shell")
+    shell = client.Dispatch('WScript.Shell')
     shortcut = shell.CreateShortCut(shortcut_path)
     self.assertFalse(shortcut.Targetpath)
     mock_test_config = self.create_mock_test_config(self.base_mock_test_config)
@@ -122,9 +124,11 @@
     shortcut = shell.CreateShortCut(shortcut_path)
     # Normalize paths for case and truncation
     normalized_shortcut_path = os.path.normcase(
-        win32file.GetLongPathName(shortcut.Targetpath))
+        win32file.GetLongPathName(shortcut.Targetpath)
+    )
     normalized_logger_path = os.path.normcase(
-        win32file.GetLongPathName(logging.log_path))
+        win32file.GetLongPathName(logging.log_path)
+    )
     self.assertEqual(normalized_shortcut_path, normalized_logger_path)
 
   @mock.patch('mobly.utils.create_alias')
@@ -134,8 +138,9 @@
     with tr.mobly_logger():
       pass
     expected_alias_dir = os.path.join(self.log_dir, self.testbed_name, 'latest')
-    mock_create_alias.assert_called_once_with(logging.log_path,
-                                              expected_alias_dir)
+    mock_create_alias.assert_called_once_with(
+        logging.log_path, expected_alias_dir
+    )
 
   @mock.patch('mobly.utils.create_alias')
   def test_mobly_logger_with_custom_latest_log_alias(self, mock_create_alias):
@@ -143,14 +148,17 @@
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger(alias='history'):
       pass
-    expected_alias_dir = os.path.join(self.log_dir, self.testbed_name,
-                                      'history')
-    mock_create_alias.assert_called_once_with(logging.log_path,
-                                              expected_alias_dir)
+    expected_alias_dir = os.path.join(
+        self.log_dir, self.testbed_name, 'history'
+    )
+    mock_create_alias.assert_called_once_with(
+        logging.log_path, expected_alias_dir
+    )
 
   @mock.patch('mobly.utils.create_alias')
   def test_mobly_logger_skips_latest_log_alias_when_none(
-      self, mock_create_alias):
+      self, mock_create_alias
+  ):
     mock_test_config = self.create_mock_test_config(self.base_mock_test_config)
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger(alias=None):
@@ -159,7 +167,8 @@
 
   @mock.patch('mobly.utils.create_alias')
   def test_mobly_logger_skips_latest_log_alias_when_empty(
-      self, mock_create_alias):
+      self, mock_create_alias
+  ):
     mock_test_config = self.create_mock_test_config(self.base_mock_test_config)
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger(alias=''):
@@ -182,15 +191,17 @@
       tr.add_test_class(mock_test_config, integration_test.IntegrationTest)
       tr.run()
     output_dir = logging.root_output_path
-    (summary_file_path, debug_log_path,
-     info_log_path) = self.assert_output_logs_exist(output_dir)
+    (summary_file_path, debug_log_path, info_log_path) = (
+        self.assert_output_logs_exist(output_dir)
+    )
     self.assert_log_contents(debug_log_path, whitelist=[debug_uuid, info_uuid])
-    self.assert_log_contents(info_log_path,
-                             whitelist=[info_uuid],
-                             blacklist=[debug_uuid])
+    self.assert_log_contents(
+        info_log_path, whitelist=[info_uuid], blacklist=[debug_uuid]
+    )
 
-  @mock.patch('mobly.logger.get_log_file_timestamp',
-              side_effect=str(time.time()))
+  @mock.patch(
+      'mobly.logger.get_log_file_timestamp', side_effect=str(time.time())
+  )
   def test_run_twice_for_two_sets_of_logs(self, mock_timestamp):
     """Verifies the expected output files from a test run.
 
@@ -210,8 +221,9 @@
     self.assert_output_logs_exist(output_dir1)
     self.assert_output_logs_exist(output_dir2)
 
-  @mock.patch('mobly.logger.get_log_file_timestamp',
-              side_effect=str(time.time()))
+  @mock.patch(
+      'mobly.logger.get_log_file_timestamp', side_effect=str(time.time())
+  )
   def test_teardown_erases_logs(self, mock_timestamp):
     """Verifies the expected output files from a test run.
 
@@ -237,17 +249,23 @@
 
     self.assertNotEqual(output_dir1, output_dir2)
 
-    (summary_file_path1, debug_log_path1,
-     info_log_path1) = self.get_output_logs(output_dir1)
-    (summary_file_path2, debug_log_path2,
-     info_log_path2) = self.get_output_logs(output_dir2)
+    (summary_file_path1, debug_log_path1, info_log_path1) = (
+        self.get_output_logs(output_dir1)
+    )
+    (summary_file_path2, debug_log_path2, info_log_path2) = (
+        self.get_output_logs(output_dir2)
+    )
 
-    self.assert_log_contents(debug_log_path1,
-                             whitelist=[debug_uuid1, info_uuid1],
-                             blacklist=[info_uuid2, debug_uuid2])
-    self.assert_log_contents(debug_log_path2,
-                             whitelist=[debug_uuid2, info_uuid2],
-                             blacklist=[info_uuid1, debug_uuid1])
+    self.assert_log_contents(
+        debug_log_path1,
+        whitelist=[debug_uuid1, info_uuid1],
+        blacklist=[info_uuid2, debug_uuid2],
+    )
+    self.assert_log_contents(
+        debug_log_path2,
+        whitelist=[debug_uuid2, info_uuid2],
+        blacklist=[info_uuid1, debug_uuid1],
+    )
 
   def test_basic_output(self):
     """Verifies the expected output files from a test run.
@@ -260,22 +278,24 @@
     with tr.mobly_logger():
       tr.add_test_class(mock_test_config, integration_test.IntegrationTest)
       tr.run()
-    expected_class_path = os.path.join(logging.root_output_path,
-                                       'IntegrationTest')
+    expected_class_path = os.path.join(
+        logging.root_output_path, 'IntegrationTest'
+    )
     self.assertEqual(expected_class_path, logging.log_path)
     os.path.exists(logging.log_path)
     output_dir = logging.root_output_path
-    (summary_file_path, debug_log_path,
-     info_log_path) = self.assert_output_logs_exist(output_dir)
+    (summary_file_path, debug_log_path, info_log_path) = (
+        self.assert_output_logs_exist(output_dir)
+    )
     summary_entries = []
     with io.open(summary_file_path, 'r', encoding='utf-8') as f:
       for entry in yaml.safe_load_all(f):
         self.assertTrue(entry['Type'])
         summary_entries.append(entry)
     self.assert_log_contents(debug_log_path, whitelist=['DEBUG', 'INFO'])
-    self.assert_log_contents(info_log_path,
-                             whitelist=['INFO'],
-                             blacklist=['DEBUG'])
+    self.assert_log_contents(
+        info_log_path, whitelist=['INFO'], blacklist=['DEBUG']
+    )
 
   def test_teardown_class_output(self):
     """Verifies the summary file includes the failure record for
@@ -284,8 +304,9 @@
     mock_test_config = self.base_mock_test_config.copy()
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger():
-      tr.add_test_class(mock_test_config,
-                        teardown_class_failure_test.TearDownClassFailureTest)
+      tr.add_test_class(
+          mock_test_config, teardown_class_failure_test.TearDownClassFailureTest
+      )
       tr.run()
     output_dir = logging.root_output_path
     summary_file_path = os.path.join(output_dir, records.OUTPUT_FILE_SUMMARY)
@@ -294,14 +315,18 @@
       raw_content = f.read()
       f.seek(0)
       for entry in yaml.safe_load_all(f):
-        if (entry['Type'] == 'Record' and
-            entry[records.TestResultEnums.RECORD_NAME] == 'teardown_class'):
+        if (
+            entry['Type'] == 'Record'
+            and entry[records.TestResultEnums.RECORD_NAME] == 'teardown_class'
+        ):
           found = True
           break
       self.assertTrue(
-          found, 'No record for teardown_class found in the output file:\n %s' %
-          raw_content)
+          found,
+          'No record for teardown_class found in the output file:\n %s'
+          % raw_content,
+      )
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/records_test.py b/tests/mobly/records_test.py
index ec6254d..5c1d027 100755
--- a/tests/mobly/records_test.py
+++ b/tests/mobly/records_test.py
@@ -50,8 +50,7 @@
 
 
 class RecordsTest(unittest.TestCase):
-  """This test class tests the implementation of classes in mobly.records.
-  """
+  """This test class tests the implementation of classes in mobly.records."""
 
   def setUp(self):
     self.tn = 'test_name'
@@ -63,13 +62,15 @@
   def tearDown(self):
     shutil.rmtree(self.tmp_path)
 
-  def verify_record(self,
-                    record,
-                    result,
-                    details,
-                    extras,
-                    termination_signal_type=None,
-                    stacktrace=None):
+  def verify_record(
+      self,
+      record,
+      result,
+      details,
+      extras,
+      termination_signal_type=None,
+      stacktrace=None,
+  ):
     record.update_record()
     # Verify each field.
     self.assertEqual(record.test_name, self.tn)
@@ -86,15 +87,18 @@
     d[records.TestResultEnums.RECORD_NAME] = self.tn
     d[records.TestResultEnums.RECORD_RESULT] = result
     d[records.TestResultEnums.RECORD_DETAILS] = details
-    d[records.TestResultEnums.
-      RECORD_TERMINATION_SIGNAL_TYPE] = termination_signal_type
+    d[records.TestResultEnums.RECORD_TERMINATION_SIGNAL_TYPE] = (
+        termination_signal_type
+    )
     d[records.TestResultEnums.RECORD_EXTRAS] = extras
     d[records.TestResultEnums.RECORD_BEGIN_TIME] = record.begin_time
     d[records.TestResultEnums.RECORD_END_TIME] = record.end_time
-    d[records.TestResultEnums.
-      RECORD_SIGNATURE] = f'{self.tn}-{record.begin_time}'
+    d[records.TestResultEnums.RECORD_SIGNATURE] = (
+        f'{self.tn}-{record.begin_time}'
+    )
     d[records.TestResultEnums.RECORD_UID] = None
     d[records.TestResultEnums.RECORD_RETRY_PARENT] = None
+    d[records.TestResultEnums.RECORD_PARENT] = None
     d[records.TestResultEnums.RECORD_CLASS] = None
     d[records.TestResultEnums.RECORD_EXTRA_ERRORS] = {}
     d[records.TestResultEnums.RECORD_STACKTRACE] = stacktrace
@@ -114,42 +118,50 @@
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     record.test_pass()
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_PASS,
-                       details=None,
-                       extras=None)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_PASS,
+        details=None,
+        extras=None,
+    )
 
   def test_result_record_explicit_pass_with_float_extra(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     s = signals.TestPass(self.details, self.float_extra)
     record.test_pass(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_PASS,
-                       details=self.details,
-                       termination_signal_type='TestPass',
-                       extras=self.float_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_PASS,
+        details=self.details,
+        termination_signal_type='TestPass',
+        extras=self.float_extra,
+    )
 
   def test_result_record_explicit_pass_with_json_extra(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     s = signals.TestPass(self.details, self.json_extra)
     record.test_pass(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_PASS,
-                       details=self.details,
-                       termination_signal_type='TestPass',
-                       extras=self.json_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_PASS,
+        details=self.details,
+        termination_signal_type='TestPass',
+        extras=self.json_extra,
+    )
 
   def test_result_record_fail_none(self):
     """Verifies that `test_fail` can be called without an error object."""
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     record.test_fail()
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_FAIL,
-                       details=None,
-                       extras=None)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_FAIL,
+        details=None,
+        extras=None,
+    )
 
   def test_result_record_fail_stacktrace(self):
     record = records.TestResultRecord(self.tn)
@@ -161,91 +173,109 @@
     # Verify stacktrace separately if we expect a non-None value.
     # Because stacktrace includes file names and line numbers, we can't do
     # a simple equality check.
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_FAIL,
-                       details='Something failed.',
-                       termination_signal_type='Exception',
-                       extras=None,
-                       stacktrace='in test_result_record_fail_stacktrace\n    '
-                       'raise Exception(\'Something failed.\')\nException: '
-                       'Something failed.\n')
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_FAIL,
+        details='Something failed.',
+        termination_signal_type='Exception',
+        extras=None,
+        stacktrace=(
+            'in test_result_record_fail_stacktrace\n    '
+            "raise Exception('Something failed.')\nException: "
+            'Something failed.\n'
+        ),
+    )
 
   def test_result_record_fail_with_float_extra(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     s = signals.TestFailure(self.details, self.float_extra)
     record.test_fail(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_FAIL,
-                       details=self.details,
-                       termination_signal_type='TestFailure',
-                       extras=self.float_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_FAIL,
+        details=self.details,
+        termination_signal_type='TestFailure',
+        extras=self.float_extra,
+    )
 
   def test_result_record_fail_with_unicode_test_signal(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
-    details = u'\u2022'
+    details = '\u2022'
     s = signals.TestFailure(details, self.float_extra)
     record.test_fail(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_FAIL,
-                       details=details,
-                       termination_signal_type='TestFailure',
-                       extras=self.float_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_FAIL,
+        details=details,
+        termination_signal_type='TestFailure',
+        extras=self.float_extra,
+    )
 
   def test_result_record_fail_with_unicode_exception(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
-    details = u'\u2022'
+    details = '\u2022'
     s = Exception(details)
     record.test_fail(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_FAIL,
-                       details=details,
-                       termination_signal_type='Exception',
-                       extras=None)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_FAIL,
+        details=details,
+        termination_signal_type='Exception',
+        extras=None,
+    )
 
   def test_result_record_fail_with_json_extra(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     s = signals.TestFailure(self.details, self.json_extra)
     record.test_fail(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_FAIL,
-                       details=self.details,
-                       termination_signal_type='TestFailure',
-                       extras=self.json_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_FAIL,
+        details=self.details,
+        termination_signal_type='TestFailure',
+        extras=self.json_extra,
+    )
 
   def test_result_record_skip_none(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     record.test_skip()
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_SKIP,
-                       details=None,
-                       extras=None)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_SKIP,
+        details=None,
+        extras=None,
+    )
 
   def test_result_record_skip_with_float_extra(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     s = signals.TestSkip(self.details, self.float_extra)
     record.test_skip(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_SKIP,
-                       details=self.details,
-                       termination_signal_type='TestSkip',
-                       extras=self.float_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_SKIP,
+        details=self.details,
+        termination_signal_type='TestSkip',
+        extras=self.float_extra,
+    )
 
   def test_result_record_skip_with_json_extra(self):
     record = records.TestResultRecord(self.tn)
     record.test_begin()
     s = signals.TestSkip(self.details, self.json_extra)
     record.test_skip(s)
-    self.verify_record(record=record,
-                       result=records.TestResultEnums.TEST_RESULT_SKIP,
-                       details=self.details,
-                       termination_signal_type='TestSkip',
-                       extras=self.json_extra)
+    self.verify_record(
+        record=record,
+        result=records.TestResultEnums.TEST_RESULT_SKIP,
+        details=self.details,
+        termination_signal_type='TestSkip',
+        extras=self.json_extra,
+    )
 
   def test_result_add_operator_success(self):
     record1 = records.TestResultRecord(self.tn)
@@ -254,8 +284,9 @@
     record1.test_pass(s)
     tr1 = records.TestResult()
     tr1.add_record(record1)
-    controller_info = records.ControllerInfoRecord('SomeClass', 'MockDevice',
-                                                   ['magicA', 'magicB'])
+    controller_info = records.ControllerInfoRecord(
+        'SomeClass', 'MockDevice', ['magicA', 'magicB']
+    )
     tr1.add_controller_info_record(controller_info)
     record2 = records.TestResultRecord(self.tn)
     record2.test_begin()
@@ -263,8 +294,9 @@
     record2.test_pass(s)
     tr2 = records.TestResult()
     tr2.add_record(record2)
-    controller_info = records.ControllerInfoRecord('SomeClass', 'MockDevice',
-                                                   ['magicC'])
+    controller_info = records.ControllerInfoRecord(
+        'SomeClass', 'MockDevice', ['magicC']
+    )
     tr2.add_controller_info_record(controller_info)
     tr2 += tr1
     self.assertTrue(tr2.passed, [tr1, tr2])
@@ -348,6 +380,36 @@
     utils.validate_test_result(tr)
     self.assertFalse(tr.is_all_pass)
 
+  def test_is_all_pass_with_retry(self):
+    s = signals.TestFailure(self.details, self.float_extra)
+    record1 = records.TestResultRecord(self.tn)
+    record1.test_begin()
+    record1.test_fail(s)
+    record2 = records.TestResultRecord(self.tn)
+    record2.test_begin()
+    record2.test_pass()
+    record2.parent = (record1, records.TestParentType.RETRY)
+    tr = records.TestResult()
+    tr.add_record(record1)
+    tr.add_record(record2)
+    utils.validate_test_result(tr)
+    self.assertTrue(tr.is_all_pass)
+
+  def test_is_all_pass_with_repeat(self):
+    s = signals.TestFailure(self.details, self.float_extra)
+    record1 = records.TestResultRecord(self.tn)
+    record1.test_begin()
+    record1.test_fail(s)
+    record2 = records.TestResultRecord(self.tn)
+    record2.test_begin()
+    record2.test_pass()
+    record2.parent = (record1, records.TestParentType.REPEAT)
+    tr = records.TestResult()
+    tr.add_record(record1)
+    tr.add_record(record2)
+    utils.validate_test_result(tr)
+    self.assertFalse(tr.is_all_pass)
+
   def test_is_all_pass_with_add_class_error(self):
     """Verifies that is_all_pass yields correct value when add_class_error is
     used.
@@ -378,16 +440,19 @@
     writer.dump(record1.to_dict(), records.TestSummaryEntryType.RECORD)
     with io.open(dump_path, 'r', encoding='utf-8') as f:
       content = yaml.safe_load(f)
-      self.assertEqual(content['Type'],
-                       records.TestSummaryEntryType.RECORD.value)
-      self.assertEqual(content[records.TestResultEnums.RECORD_DETAILS],
-                       self.details)
-      self.assertEqual(content[records.TestResultEnums.RECORD_EXTRAS],
-                       self.float_extra)
+      self.assertEqual(
+          content['Type'], records.TestSummaryEntryType.RECORD.value
+      )
+      self.assertEqual(
+          content[records.TestResultEnums.RECORD_DETAILS], self.details
+      )
+      self.assertEqual(
+          content[records.TestResultEnums.RECORD_EXTRAS], self.float_extra
+      )
 
   def test_summary_write_dump_with_unicode(self):
-    unicode_details = u'\u901a'  # utf-8 -> b'\xe9\x80\x9a'
-    unicode_extras = u'\u8fc7'  # utf-8 -> b'\xe8\xbf\x87'
+    unicode_details = '\u901a'  # utf-8 -> b'\xe9\x80\x9a'
+    unicode_extras = '\u8fc7'  # utf-8 -> b'\xe8\xbf\x87'
     s = signals.TestFailure(unicode_details, unicode_extras)
     record1 = records.TestResultRecord(self.tn)
     record1.test_begin()
@@ -397,12 +462,15 @@
     writer.dump(record1.to_dict(), records.TestSummaryEntryType.RECORD)
     with io.open(dump_path, 'r', encoding='utf-8') as f:
       content = yaml.safe_load(f)
-      self.assertEqual(content['Type'],
-                       records.TestSummaryEntryType.RECORD.value)
-      self.assertEqual(content[records.TestResultEnums.RECORD_DETAILS],
-                       unicode_details)
-      self.assertEqual(content[records.TestResultEnums.RECORD_EXTRAS],
-                       unicode_extras)
+      self.assertEqual(
+          content['Type'], records.TestSummaryEntryType.RECORD.value
+      )
+      self.assertEqual(
+          content[records.TestResultEnums.RECORD_DETAILS], unicode_details
+      )
+      self.assertEqual(
+          content[records.TestResultEnums.RECORD_EXTRAS], unicode_extras
+      )
 
   @mock.patch('mobly.utils.get_current_epoch_time')
   def test_signature(self, mock_time_src):
@@ -424,8 +492,9 @@
       for c in yaml.safe_load_all(f):
         contents.append(c)
     for content in contents:
-      self.assertEqual(content['Type'],
-                       records.TestSummaryEntryType.USER_DATA.value)
+      self.assertEqual(
+          content['Type'], records.TestSummaryEntryType.USER_DATA.value
+      )
     self.assertEqual(contents[0]['a'], user_data1['a'])
     self.assertEqual(contents[1]['b'], user_data2['b'])
 
@@ -456,16 +525,17 @@
   def test_add_controller_info_record(self):
     tr = records.TestResult()
     self.assertFalse(tr.controller_info)
-    controller_info = records.ControllerInfoRecord('SomeClass', 'MockDevice',
-                                                   ['magicA', 'magicB'])
+    controller_info = records.ControllerInfoRecord(
+        'SomeClass', 'MockDevice', ['magicA', 'magicB']
+    )
     tr.add_controller_info_record(controller_info)
     self.assertTrue(tr.controller_info[0])
     self.assertEqual(tr.controller_info[0].controller_name, 'MockDevice')
-    self.assertEqual(tr.controller_info[0].controller_info,
-                     ['magicA', 'magicB'])
+    self.assertEqual(
+        tr.controller_info[0].controller_info, ['magicA', 'magicB']
+    )
 
   def test_uid(self):
-
     @records.uid('some-uuid')
     def test_uid_helper():
       """Dummy test used by `test_uid` for testing the uid decorator."""
diff --git a/tests/mobly/snippet/callback_event_test.py b/tests/mobly/snippet/callback_event_test.py
index 2593cc3..afd122d 100755
--- a/tests/mobly/snippet/callback_event_test.py
+++ b/tests/mobly/snippet/callback_event_test.py
@@ -28,12 +28,14 @@
 
   def test_basic(self):
     """Verifies that an event object can be created and logged properly."""
-    event = callback_event.CallbackEvent(MOCK_CALLBACK_ID, MOCK_EVENT_NAME,
-                                         MOCK_CREATION_TIME, MOCK_DATA)
+    event = callback_event.CallbackEvent(
+        MOCK_CALLBACK_ID, MOCK_EVENT_NAME, MOCK_CREATION_TIME, MOCK_DATA
+    )
     self.assertEqual(
         repr(event),
-        "CallbackEvent(callback_id: myCallbackId, name: onXyzEvent, "
-        "creation_time: 12345678, data: {'foo': 'bar'})")
+        'CallbackEvent(callback_id: myCallbackId, name: onXyzEvent, '
+        "creation_time: 12345678, data: {'foo': 'bar'})",
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/snippet/callback_handler_base_test.py b/tests/mobly/snippet/callback_handler_base_test.py
index 0891fd5..32199b2 100644
--- a/tests/mobly/snippet/callback_handler_base_test.py
+++ b/tests/mobly/snippet/callback_handler_base_test.py
@@ -28,25 +28,34 @@
     'data': {
         'exampleData': "Here's a simple event.",
         'successful': True,
-        'secretNumber': 12
-    }
+        'secretNumber': 12,
+    },
 }
 
 
 class FakeCallbackHandler(callback_handler_base.CallbackHandlerBase):
   """Fake client class for unit tests."""
 
-  def __init__(self,
-               callback_id=None,
-               event_client=None,
-               ret_value=None,
-               method_name=None,
-               device=None,
-               rpc_max_timeout_sec=120,
-               default_timeout_sec=120):
+  def __init__(
+      self,
+      callback_id=None,
+      event_client=None,
+      ret_value=None,
+      method_name=None,
+      device=None,
+      rpc_max_timeout_sec=120,
+      default_timeout_sec=120,
+  ):
     """Initializes a fake callback handler object used for unit tests."""
-    super().__init__(callback_id, event_client, ret_value, method_name, device,
-                     rpc_max_timeout_sec, default_timeout_sec)
+    super().__init__(
+        callback_id,
+        event_client,
+        ret_value,
+        method_name,
+        device,
+        rpc_max_timeout_sec,
+        default_timeout_sec,
+    )
     self.mock_rpc_func = mock.Mock()
 
   def callEventWaitAndGetRpc(self, *args, **kwargs):
@@ -66,15 +75,18 @@
     self.assertEqual(str(actual_event), str(expected_event))
 
   def test_default_timeout_too_large(self):
-    err_msg = ('The max timeout of a single RPC must be no smaller than '
-               'the default timeout of the callback handler. '
-               'Got rpc_max_timeout_sec=10, default_timeout_sec=20.')
+    err_msg = (
+        'The max timeout of a single RPC must be no smaller than '
+        'the default timeout of the callback handler. '
+        'Got rpc_max_timeout_sec=10, default_timeout_sec=20.'
+    )
     with self.assertRaisesRegex(ValueError, err_msg):
       _ = FakeCallbackHandler(rpc_max_timeout_sec=10, default_timeout_sec=20)
 
   def test_timeout_property(self):
-    handler = FakeCallbackHandler(rpc_max_timeout_sec=20,
-                                  default_timeout_sec=10)
+    handler = FakeCallbackHandler(
+        rpc_max_timeout_sec=20, default_timeout_sec=10
+    )
     self.assertEqual(handler.rpc_max_timeout_sec, 20)
     self.assertEqual(handler.default_timeout_sec, 10)
     with self.assertRaises(AttributeError):
@@ -92,39 +104,48 @@
   def test_event_dict_to_snippet_event(self):
     handler = FakeCallbackHandler(callback_id=MOCK_CALLBACK_ID)
     handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
-        return_value=MOCK_RAW_EVENT)
+        return_value=MOCK_RAW_EVENT
+    )
 
     event = handler.waitAndGet('ha', timeout=10)
     self.assert_event_correct(event, MOCK_RAW_EVENT)
     handler.mock_rpc_func.callEventWaitAndGetRpc.assert_called_once_with(
-        MOCK_CALLBACK_ID, 'ha', 10)
+        MOCK_CALLBACK_ID, 'ha', 10
+    )
 
   def test_wait_and_get_timeout_default(self):
     handler = FakeCallbackHandler(rpc_max_timeout_sec=20, default_timeout_sec=5)
     handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
-        return_value=MOCK_RAW_EVENT)
+        return_value=MOCK_RAW_EVENT
+    )
     _ = handler.waitAndGet('ha')
     handler.mock_rpc_func.callEventWaitAndGetRpc.assert_called_once_with(
-        mock.ANY, mock.ANY, 5)
+        mock.ANY, mock.ANY, 5
+    )
 
   def test_wait_and_get_timeout_ecxeed_threshold(self):
     rpc_max_timeout_sec = 5
     big_timeout_sec = 10
-    handler = FakeCallbackHandler(rpc_max_timeout_sec=rpc_max_timeout_sec,
-                                  default_timeout_sec=rpc_max_timeout_sec)
+    handler = FakeCallbackHandler(
+        rpc_max_timeout_sec=rpc_max_timeout_sec,
+        default_timeout_sec=rpc_max_timeout_sec,
+    )
     handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
-        return_value=MOCK_RAW_EVENT)
+        return_value=MOCK_RAW_EVENT
+    )
 
     expected_msg = (
         f'Specified timeout {big_timeout_sec} is longer than max timeout '
-        f'{rpc_max_timeout_sec}.')
+        f'{rpc_max_timeout_sec}.'
+    )
     with self.assertRaisesRegex(errors.CallbackHandlerBaseError, expected_msg):
       handler.waitAndGet('ha', big_timeout_sec)
 
   def test_wait_for_event(self):
     handler = FakeCallbackHandler()
     handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
-        return_value=MOCK_RAW_EVENT)
+        return_value=MOCK_RAW_EVENT
+    )
 
     def some_condition(event):
       return event.data['successful']
@@ -135,48 +156,56 @@
   def test_wait_for_event_negative(self):
     handler = FakeCallbackHandler()
     handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
-        return_value=MOCK_RAW_EVENT)
+        return_value=MOCK_RAW_EVENT
+    )
 
     expected_msg = (
         'Timed out after 0.01s waiting for an "AsyncTaskResult" event that'
-        ' satisfies the predicate "some_condition".')
+        ' satisfies the predicate "some_condition".'
+    )
 
     def some_condition(_):
       return False
 
-    with self.assertRaisesRegex(errors.CallbackHandlerTimeoutError,
-                                expected_msg):
+    with self.assertRaisesRegex(
+        errors.CallbackHandlerTimeoutError, expected_msg
+    ):
       handler.waitForEvent('AsyncTaskResult', some_condition, 0.01)
 
   def test_wait_for_event_max_timeout(self):
     """waitForEvent should not raise the timeout exceed threshold error."""
     rpc_max_timeout_sec = 5
     big_timeout_sec = 10
-    handler = FakeCallbackHandler(rpc_max_timeout_sec=rpc_max_timeout_sec,
-                                  default_timeout_sec=rpc_max_timeout_sec)
+    handler = FakeCallbackHandler(
+        rpc_max_timeout_sec=rpc_max_timeout_sec,
+        default_timeout_sec=rpc_max_timeout_sec,
+    )
     handler.mock_rpc_func.callEventWaitAndGetRpc = mock.Mock(
-        return_value=MOCK_RAW_EVENT)
+        return_value=MOCK_RAW_EVENT
+    )
 
     def some_condition(event):
       return event.data['successful']
 
     # This line should not raise.
-    event = handler.waitForEvent('AsyncTaskResult',
-                                 some_condition,
-                                 timeout=big_timeout_sec)
+    event = handler.waitForEvent(
+        'AsyncTaskResult', some_condition, timeout=big_timeout_sec
+    )
     self.assert_event_correct(event, MOCK_RAW_EVENT)
 
   def test_get_all(self):
     handler = FakeCallbackHandler(callback_id=MOCK_CALLBACK_ID)
     handler.mock_rpc_func.callEventGetAllRpc = mock.Mock(
-        return_value=[MOCK_RAW_EVENT, MOCK_RAW_EVENT])
+        return_value=[MOCK_RAW_EVENT, MOCK_RAW_EVENT]
+    )
 
     all_events = handler.getAll('ha')
     for event in all_events:
       self.assert_event_correct(event, MOCK_RAW_EVENT)
 
     handler.mock_rpc_func.callEventGetAllRpc.assert_called_once_with(
-        MOCK_CALLBACK_ID, 'ha')
+        MOCK_CALLBACK_ID, 'ha'
+    )
 
 
 if __name__ == '__main__':
diff --git a/tests/mobly/snippet/client_base_test.py b/tests/mobly/snippet/client_base_test.py
index d9d99bd..57a3ed8 100755
--- a/tests/mobly/snippet/client_base_test.py
+++ b/tests/mobly/snippet/client_base_test.py
@@ -25,7 +25,8 @@
 
 def _generate_fix_length_rpc_response(
     response_length,
-    template='{"id": 0, "result": "%s", "error": null, "callback": null}'):
+    template='{"id": 0, "result": "%s", "error": null, "callback": null}',
+):
   """Generates an RPC response string with specified length.
 
   This function generates a random string and formats the template with the
@@ -46,9 +47,11 @@
   # '%s' in the template, of which the length is 2.
   result_length = response_length - (len(template) - 2)
   if result_length < 0:
-    raise ValueError(f'The response_length should be no smaller than '
-                     f'template_length + 2. Got response_length '
-                     f'{response_length}, template_length {len(template)}.')
+    raise ValueError(
+        'The response_length should be no smaller than '
+        'template_length + 2. Got response_length '
+        f'{response_length}, template_length {len(template)}.'
+    )
   chars = string.ascii_letters + string.digits
   return template % ''.join(random.choice(chars) for _ in range(result_length))
 
@@ -102,8 +105,9 @@
   @mock.patch.object(FakeClient, 'before_starting_server')
   @mock.patch.object(FakeClient, 'start_server')
   @mock.patch.object(FakeClient, '_make_connection')
-  def test_init_server_stage_order(self, mock_make_conn_func, mock_start_func,
-                                   mock_before_func):
+  def test_init_server_stage_order(
+      self, mock_make_conn_func, mock_start_func, mock_before_func
+  ):
     """Test that initialization runs its stages in expected order."""
     order_manager = mock.Mock()
     order_manager.attach_mock(mock_before_func, 'mock_before_func')
@@ -121,8 +125,9 @@
 
   @mock.patch.object(FakeClient, 'stop')
   @mock.patch.object(FakeClient, 'before_starting_server')
-  def test_init_server_before_starting_server_fail(self, mock_before_func,
-                                                   mock_stop_func):
+  def test_init_server_before_starting_server_fail(
+      self, mock_before_func, mock_stop_func
+  ):
     """Test before_starting_server stage of initialization fails."""
     mock_before_func.side_effect = Exception('ha')
 
@@ -142,8 +147,9 @@
 
   @mock.patch.object(FakeClient, 'stop')
   @mock.patch.object(FakeClient, '_make_connection')
-  def test_init_server_make_connection_fail(self, mock_make_conn_func,
-                                            mock_stop_func):
+  def test_init_server_make_connection_fail(
+      self, mock_make_conn_func, mock_stop_func
+  ):
     """Test _make_connection stage of initialization fails."""
     mock_make_conn_func.side_effect = Exception('ha')
 
@@ -156,9 +162,14 @@
   @mock.patch.object(FakeClient, 'send_rpc_request')
   @mock.patch.object(FakeClient, '_decode_response_string_and_validate_format')
   @mock.patch.object(FakeClient, '_handle_rpc_response')
-  def test_rpc_stage_dependencies(self, mock_handle_resp, mock_decode_resp_str,
-                                  mock_send_request, mock_gen_request,
-                                  mock_precheck):
+  def test_rpc_stage_dependencies(
+      self,
+      mock_handle_resp,
+      mock_decode_resp_str,
+      mock_send_request,
+      mock_gen_request,
+      mock_precheck,
+  ):
     """Test the internal dependencies when sending an RPC.
 
     When sending an RPC, it calls multiple functions in specific order, and
@@ -175,16 +186,19 @@
     """
     self.client.initialize()
 
-    expected_response_str = ('{"id": 0, "result": 123, "error": null, '
-                             '"callback": null}')
+    expected_response_str = (
+        '{"id": 0, "result": 123, "error": null, "callback": null}'
+    )
     expected_response_dict = {
         'id': 0,
         'result': 123,
         'error': None,
         'callback': None,
     }
-    expected_request = ('{"id": 10, "method": "some_rpc", "params": [1, 2],'
-                        '"kwargs": {"test_key": 3}')
+    expected_request = (
+        '{"id": 10, "method": "some_rpc", "params": [1, 2],'
+        '"kwargs": {"test_key": 3}'
+    )
     expected_result = 123
 
     mock_gen_request.return_value = expected_request
@@ -205,9 +219,14 @@
   @mock.patch.object(FakeClient, 'send_rpc_request')
   @mock.patch.object(FakeClient, '_decode_response_string_and_validate_format')
   @mock.patch.object(FakeClient, '_handle_rpc_response')
-  def test_rpc_precheck_fail(self, mock_handle_resp, mock_decode_resp_str,
-                             mock_send_request, mock_gen_request,
-                             mock_precheck):
+  def test_rpc_precheck_fail(
+      self,
+      mock_handle_resp,
+      mock_decode_resp_str,
+      mock_send_request,
+      mock_gen_request,
+      mock_precheck,
+  ):
     """Test when RPC precheck fails it will skip sending the RPC."""
     self.client.initialize()
     mock_precheck.side_effect = Exception('server_died')
@@ -227,8 +246,10 @@
     with all required fields.
     """
     request = self.client._gen_rpc_request(0, 'test_rpc', 1, 2, test_key=3)
-    expected_result = ('{"id": 0, "kwargs": {"test_key": 3}, '
-                       '"method": "test_rpc", "params": [1, 2]}')
+    expected_result = (
+        '{"id": 0, "kwargs": {"test_key": 3}, '
+        '"method": "test_rpc", "params": [1, 2]}'
+    )
     self.assertEqual(request, expected_result)
 
   def test_gen_request_without_kwargs(self):
@@ -243,43 +264,52 @@
 
   def test_rpc_no_response(self):
     """Test parsing an empty RPC response."""
-    with self.assertRaisesRegex(errors.ProtocolError,
-                                errors.ProtocolError.NO_RESPONSE_FROM_SERVER):
+    with self.assertRaisesRegex(
+        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_SERVER
+    ):
       self.client._decode_response_string_and_validate_format(0, '')
 
-    with self.assertRaisesRegex(errors.ProtocolError,
-                                errors.ProtocolError.NO_RESPONSE_FROM_SERVER):
+    with self.assertRaisesRegex(
+        errors.ProtocolError, errors.ProtocolError.NO_RESPONSE_FROM_SERVER
+    ):
       self.client._decode_response_string_and_validate_format(0, None)
 
   def test_rpc_response_missing_fields(self):
     """Test parsing an RPC response that misses some required fields."""
     mock_resp_without_id = '{"result": 123, "error": null, "callback": null}'
     with self.assertRaisesRegex(
-        errors.ProtocolError,
-        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'id'):
+        errors.ProtocolError, errors.ProtocolError.RESPONSE_MISSING_FIELD % 'id'
+    ):
       self.client._decode_response_string_and_validate_format(
-          10, mock_resp_without_id)
+          10, mock_resp_without_id
+      )
 
     mock_resp_without_result = '{"id": 10, "error": null, "callback": null}'
     with self.assertRaisesRegex(
         errors.ProtocolError,
-        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'result'):
+        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'result',
+    ):
       self.client._decode_response_string_and_validate_format(
-          10, mock_resp_without_result)
+          10, mock_resp_without_result
+      )
 
     mock_resp_without_error = '{"id": 10, "result": 123, "callback": null}'
     with self.assertRaisesRegex(
         errors.ProtocolError,
-        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'error'):
+        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'error',
+    ):
       self.client._decode_response_string_and_validate_format(
-          10, mock_resp_without_error)
+          10, mock_resp_without_error
+      )
 
     mock_resp_without_callback = '{"id": 10, "result": 123, "error": null}'
     with self.assertRaisesRegex(
         errors.ProtocolError,
-        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'callback'):
+        errors.ProtocolError.RESPONSE_MISSING_FIELD % 'callback',
+    ):
       self.client._decode_response_string_and_validate_format(
-          10, mock_resp_without_callback)
+          10, mock_resp_without_callback
+      )
 
   def test_rpc_response_error(self):
     """Test parsing an RPC response with a non-empty error field."""
@@ -299,15 +329,17 @@
         'id': 10,
         'result': 123,
         'error': None,
-        'callback': '1-0'
+        'callback': '1-0',
     }
-    with mock.patch.object(self.client,
-                           'handle_callback') as mock_handle_callback:
+    with mock.patch.object(
+        self.client, 'handle_callback'
+    ) as mock_handle_callback:
       expected_callback = mock.Mock()
       mock_handle_callback.return_value = expected_callback
 
-      rpc_result = self.client._handle_rpc_response('some_rpc',
-                                                    mock_resp_with_callback)
+      rpc_result = self.client._handle_rpc_response(
+          'some_rpc', mock_resp_with_callback
+      )
       mock_handle_callback.assert_called_with('1-0', 123, 'some_rpc')
       # Ensure the RPC function returns what handle_callback returned
       self.assertIs(expected_callback, rpc_result)
@@ -317,10 +349,11 @@
         'id': 10,
         'result': 123,
         'error': None,
-        'callback': None
+        'callback': None,
     }
-    with mock.patch.object(self.client,
-                           'handle_callback') as mock_handle_callback:
+    with mock.patch.object(
+        self.client, 'handle_callback'
+    ) as mock_handle_callback:
       self.client._handle_rpc_response('some_rpc', mock_resp_without_callback)
       mock_handle_callback.assert_not_called()
 
@@ -330,8 +363,9 @@
     wrong_id = 20
     resp = f'{{"id": {right_id}, "result": 1, "error": null, "callback": null}}'
 
-    with self.assertRaisesRegex(errors.ProtocolError,
-                                errors.ProtocolError.MISMATCHED_API_ID):
+    with self.assertRaisesRegex(
+        errors.ProtocolError, errors.ProtocolError.MISMATCHED_API_ID
+    ):
       self.client._decode_response_string_and_validate_format(wrong_id, resp)
 
   @mock.patch.object(FakeClient, 'send_rpc_request')
@@ -343,7 +377,8 @@
     self.client.initialize()
 
     resp = _generate_fix_length_rpc_response(
-        client_base._MAX_RPC_RESP_LOGGING_LENGTH * 2)
+        client_base._MAX_RPC_RESP_LOGGING_LENGTH * 2
+    )
     mock_send_request.return_value = resp
     self.client.some_rpc(1, 2)
     mock_log.debug.assert_called_with('Snippet received: %s', resp)
@@ -357,7 +392,8 @@
     self.client.initialize()
 
     resp = _generate_fix_length_rpc_response(
-        int(client_base._MAX_RPC_RESP_LOGGING_LENGTH // 2))
+        int(client_base._MAX_RPC_RESP_LOGGING_LENGTH // 2)
+    )
     mock_send_request.return_value = resp
     self.client.some_rpc(1, 2)
     mock_log.debug.assert_called_with('Snippet received: %s', resp)
@@ -371,7 +407,8 @@
     self.client.initialize()
 
     resp = _generate_fix_length_rpc_response(
-        client_base._MAX_RPC_RESP_LOGGING_LENGTH)
+        client_base._MAX_RPC_RESP_LOGGING_LENGTH
+    )
     mock_send_request.return_value = resp
     self.client.some_rpc(1, 2)
     mock_log.debug.assert_called_with('Snippet received: %s', resp)
@@ -390,8 +427,9 @@
     self.client.some_rpc(1, 2)
     mock_log.debug.assert_called_with(
         'Snippet received: %s... %d chars are truncated',
-        resp[:client_base._MAX_RPC_RESP_LOGGING_LENGTH],
-        len(resp) - max_len)
+        resp[: client_base._MAX_RPC_RESP_LOGGING_LENGTH],
+        len(resp) - max_len,
+    )
 
   @mock.patch.object(FakeClient, 'send_rpc_request')
   def test_rpc_call_increment_counter(self, mock_send_request):
diff --git a/tests/mobly/suite_runner_test.py b/tests/mobly/suite_runner_test.py
index dabf74f..b1023e7 100755
--- a/tests/mobly/suite_runner_test.py
+++ b/tests/mobly/suite_runner_test.py
@@ -12,7 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import inspect
 import io
 import os
 import shutil
@@ -23,8 +22,6 @@
 
 from mobly import base_suite
 from mobly import base_test
-from mobly import config_parser
-from mobly import test_runner
 from mobly import suite_runner
 from tests.lib import integration2_test
 from tests.lib import integration_test
@@ -43,53 +40,67 @@
     shutil.rmtree(self.tmp_dir)
 
   def test_select_no_args(self):
-    identifiers = suite_runner.compute_selected_tests(test_classes=[
-        integration_test.IntegrationTest, integration2_test.Integration2Test
-    ],
-                                                      selected_tests=None)
+    identifiers = suite_runner.compute_selected_tests(
+        test_classes=[
+            integration_test.IntegrationTest,
+            integration2_test.Integration2Test,
+        ],
+        selected_tests=None,
+    )
     self.assertEqual(
         {
             integration_test.IntegrationTest: None,
             integration2_test.Integration2Test: None,
-        }, identifiers)
+        },
+        identifiers,
+    )
 
   def test_select_by_class(self):
     identifiers = suite_runner.compute_selected_tests(
         test_classes=[
-            integration_test.IntegrationTest, integration2_test.Integration2Test
+            integration_test.IntegrationTest,
+            integration2_test.Integration2Test,
         ],
-        selected_tests=['IntegrationTest'])
+        selected_tests=['IntegrationTest'],
+    )
     self.assertEqual({integration_test.IntegrationTest: None}, identifiers)
 
   def test_select_by_method(self):
     identifiers = suite_runner.compute_selected_tests(
         test_classes=[
-            integration_test.IntegrationTest, integration2_test.Integration2Test
+            integration_test.IntegrationTest,
+            integration2_test.Integration2Test,
         ],
-        selected_tests=['IntegrationTest.test_a', 'IntegrationTest.test_b'])
-    self.assertEqual({integration_test.IntegrationTest: ['test_a', 'test_b']},
-                     identifiers)
+        selected_tests=['IntegrationTest.test_a', 'IntegrationTest.test_b'],
+    )
+    self.assertEqual(
+        {integration_test.IntegrationTest: ['test_a', 'test_b']}, identifiers
+    )
 
   def test_select_all_clobbers_method(self):
     identifiers = suite_runner.compute_selected_tests(
         test_classes=[
-            integration_test.IntegrationTest, integration2_test.Integration2Test
+            integration_test.IntegrationTest,
+            integration2_test.Integration2Test,
         ],
-        selected_tests=['IntegrationTest.test_a', 'IntegrationTest'])
+        selected_tests=['IntegrationTest.test_a', 'IntegrationTest'],
+    )
     self.assertEqual({integration_test.IntegrationTest: None}, identifiers)
 
     identifiers = suite_runner.compute_selected_tests(
         test_classes=[
-            integration_test.IntegrationTest, integration2_test.Integration2Test
+            integration_test.IntegrationTest,
+            integration2_test.Integration2Test,
         ],
-        selected_tests=['IntegrationTest', 'IntegrationTest.test_a'])
+        selected_tests=['IntegrationTest', 'IntegrationTest.test_a'],
+    )
     self.assertEqual({integration_test.IntegrationTest: None}, identifiers)
 
   @mock.patch('sys.exit')
   def test_run_suite(self, mock_exit):
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u"""
+      f.write("""
         TestBeds:
           # A test bed where adb will find Android devices.
           - Name: SampleTestBed
@@ -99,23 +110,25 @@
               icecream: 42
               extra_param: 'haha'
       """)
-    suite_runner.run_suite([integration_test.IntegrationTest],
-                           argv=['-c', tmp_file_path])
+    suite_runner.run_suite(
+        [integration_test.IntegrationTest], argv=['-c', tmp_file_path]
+    )
     mock_exit.assert_not_called()
 
   @mock.patch('sys.exit')
   def test_run_suite_with_failures(self, mock_exit):
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u"""
+      f.write("""
         TestBeds:
           # A test bed where adb will find Android devices.
           - Name: SampleTestBed
             Controllers:
               MagicDevice: '*'
       """)
-    suite_runner.run_suite([integration_test.IntegrationTest],
-                           argv=['-c', tmp_file_path])
+    suite_runner.run_suite(
+        [integration_test.IntegrationTest], argv=['-c', tmp_file_path]
+    )
     mock_exit.assert_called_once_with(1)
 
   @mock.patch('sys.exit')
@@ -138,7 +151,7 @@
 
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u"""
+      f.write("""
         TestBeds:
           # A test bed where adb will find Android devices.
           - Name: SampleTestBed
@@ -169,10 +182,9 @@
     mock_cls_instance = mock.MagicMock()
     mock_test_class.return_value = mock_cls_instance
     suite_runner._print_test_names([mock_test_class])
-    mock_cls_instance._pre_run.side_effect = Exception(
-        'Something went wrong.')
+    mock_cls_instance._pre_run.side_effect = Exception('Something went wrong.')
     mock_cls_instance._clean_up.assert_called_once()
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/test_runner_test.py b/tests/mobly/test_runner_test.py
index 0343e0d..bd9a8fd 100755
--- a/tests/mobly/test_runner_test.py
+++ b/tests/mobly/test_runner_test.py
@@ -17,7 +17,6 @@
 import os
 import re
 import shutil
-import sys
 import tempfile
 import unittest
 from unittest import mock
@@ -26,7 +25,6 @@
 from mobly import records
 from mobly import signals
 from mobly import test_runner
-from mobly import utils
 from tests.lib import mock_android_device
 from tests.lib import mock_controller
 from tests.lib import integration_test
@@ -49,7 +47,7 @@
     self.base_mock_test_config.controller_configs = {}
     self.base_mock_test_config.user_params = {
         'icecream': 42,
-        'extra_param': 'haha'
+        'extra_param': 'haha',
     }
     self.base_mock_test_config.log_path = self.tmp_dir
     self.log_dir = self.base_mock_test_config.log_path
@@ -59,11 +57,13 @@
     shutil.rmtree(self.tmp_dir)
 
   def _assertControllerInfoEqual(self, info, expected_info_dict):
-    self.assertEqual(expected_info_dict['Controller Name'],
-                     info.controller_name)
+    self.assertEqual(
+        expected_info_dict['Controller Name'], info.controller_name
+    )
     self.assertEqual(expected_info_dict['Test Class'], info.test_class)
-    self.assertEqual(expected_info_dict['Controller Info'],
-                     info.controller_info)
+    self.assertEqual(
+        expected_info_dict['Controller Info'], info.controller_info
+    )
 
   def test_run_twice(self):
     """Verifies that:
@@ -73,20 +73,18 @@
     """
     mock_test_config = self.base_mock_test_config.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    my_config = [{
-        'serial': 'xxxx',
-        'magic': 'Magic1'
-    }, {
-        'serial': 'xxxx',
-        'magic': 'Magic2'
-    }]
+    my_config = [
+        {'serial': 'xxxx', 'magic': 'Magic1'},
+        {'serial': 'xxxx', 'magic': 'Magic2'},
+    ]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger():
       tr.add_test_class(mock_test_config, integration_test.IntegrationTest)
       tr.run()
     self.assertTrue(
-        mock_test_config.controller_configs[mock_ctrlr_config_name][0])
+        mock_test_config.controller_configs[mock_ctrlr_config_name][0]
+    )
     with tr.mobly_logger():
       tr.run()
     results = tr.results.summary_dict()
@@ -94,24 +92,22 @@
     self.assertEqual(results['Executed'], 2)
     self.assertEqual(results['Passed'], 2)
     expected_info_dict = {
-        'Controller Info': [{
-            'MyMagic': {
-                'magic': 'Magic1'
-            }
-        }, {
-            'MyMagic': {
-                'magic': 'Magic2'
-            }
-        }],
+        'Controller Info': [
+            {'MyMagic': {'magic': 'Magic1'}},
+            {'MyMagic': {'magic': 'Magic2'}},
+        ],
         'Controller Name': 'MagicDevice',
         'Test Class': 'IntegrationTest',
     }
-    self._assertControllerInfoEqual(tr.results.controller_info[0],
-                                    expected_info_dict)
-    self._assertControllerInfoEqual(tr.results.controller_info[1],
-                                    expected_info_dict)
-    self.assertNotEqual(tr.results.controller_info[0],
-                        tr.results.controller_info[1])
+    self._assertControllerInfoEqual(
+        tr.results.controller_info[0], expected_info_dict
+    )
+    self._assertControllerInfoEqual(
+        tr.results.controller_info[1], expected_info_dict
+    )
+    self.assertNotEqual(
+        tr.results.controller_info[0], tr.results.controller_info[1]
+    )
 
   def test_summary_file_entries(self):
     """Verifies the output summary's file format.
@@ -121,40 +117,46 @@
     """
     mock_test_config = self.base_mock_test_config.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    my_config = [{
-        'serial': 'xxxx',
-        'magic': 'Magic1'
-    }, {
-        'serial': 'xxxx',
-        'magic': 'Magic2'
-    }]
+    my_config = [
+        {'serial': 'xxxx', 'magic': 'Magic1'},
+        {'serial': 'xxxx', 'magic': 'Magic2'},
+    ]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger():
       tr.add_test_class(mock_test_config, integration_test.IntegrationTest)
       tr.run()
-    summary_path = os.path.join(logging.root_output_path,
-                                records.OUTPUT_FILE_SUMMARY)
+    summary_path = os.path.join(
+        logging.root_output_path, records.OUTPUT_FILE_SUMMARY
+    )
     with io.open(summary_path, 'r', encoding='utf-8') as f:
       summary_entries = list(yaml.safe_load_all(f))
     self.assertEqual(len(summary_entries), 4)
     # Verify the first entry is the list of test names.
-    self.assertEqual(summary_entries[0]['Type'],
-                     records.TestSummaryEntryType.TEST_NAME_LIST.value)
-    self.assertEqual(summary_entries[1]['Type'],
-                     records.TestSummaryEntryType.RECORD.value)
-    self.assertEqual(summary_entries[2]['Type'],
-                     records.TestSummaryEntryType.CONTROLLER_INFO.value)
-    self.assertEqual(summary_entries[3]['Type'],
-                     records.TestSummaryEntryType.SUMMARY.value)
+    self.assertEqual(
+        summary_entries[0]['Type'],
+        records.TestSummaryEntryType.TEST_NAME_LIST.value,
+    )
+    self.assertEqual(
+        summary_entries[1]['Type'], records.TestSummaryEntryType.RECORD.value
+    )
+    self.assertEqual(
+        summary_entries[2]['Type'],
+        records.TestSummaryEntryType.CONTROLLER_INFO.value,
+    )
+    self.assertEqual(
+        summary_entries[3]['Type'], records.TestSummaryEntryType.SUMMARY.value
+    )
 
   def test_run(self):
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     self.base_mock_test_config.controller_configs[
-        mock_controller.MOBLY_CONTROLLER_CONFIG_NAME] = '*'
+        mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    ] = '*'
     with tr.mobly_logger():
-      tr.add_test_class(self.base_mock_test_config,
-                        integration_test.IntegrationTest)
+      tr.add_test_class(
+          self.base_mock_test_config, integration_test.IntegrationTest
+      )
       tr.run()
     results = tr.results.summary_dict()
     self.assertEqual(results['Requested'], 1)
@@ -167,9 +169,11 @@
   def test_run_without_mobly_logger_context(self):
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     self.base_mock_test_config.controller_configs[
-        mock_controller.MOBLY_CONTROLLER_CONFIG_NAME] = '*'
-    tr.add_test_class(self.base_mock_test_config,
-                      integration_test.IntegrationTest)
+        mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
+    ] = '*'
+    tr.add_test_class(
+        self.base_mock_test_config, integration_test.IntegrationTest
+    )
     tr.run()
     results = tr.results.summary_dict()
     self.assertEqual(results['Requested'], 1)
@@ -179,16 +183,24 @@
     record = tr.results.executed[0]
     self.assertEqual(record.test_class, 'IntegrationTest')
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy',
-              return_value=mock_android_device.MockAdbProxy(1))
-  @mock.patch('mobly.controllers.android_device_lib.fastboot.FastbootProxy',
-              return_value=mock_android_device.MockFastbootProxy(1))
-  @mock.patch('mobly.controllers.android_device.list_adb_devices',
-              return_value=['1'])
-  @mock.patch('mobly.controllers.android_device.get_all_instances',
-              return_value=mock_android_device.get_mock_ads(1))
-  def test_run_two_test_classes(self, mock_get_all, mock_list_adb,
-                                mock_fastboot, mock_adb):
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+      return_value=mock_android_device.MockFastbootProxy(1),
+  )
+  @mock.patch(
+      'mobly.controllers.android_device.list_adb_devices', return_value=['1']
+  )
+  @mock.patch(
+      'mobly.controllers.android_device.get_all_instances',
+      return_value=mock_android_device.get_mock_ads(1),
+  )
+  def test_run_two_test_classes(
+      self, mock_get_all, mock_list_adb, mock_fastboot, mock_adb
+  ):
     """Verifies that running more than one test class in one test run works
     properly.
 
@@ -197,13 +209,10 @@
     """
     mock_test_config = self.base_mock_test_config.copy()
     mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
-    my_config = [{
-        'serial': 'xxxx',
-        'magic': 'Magic1'
-    }, {
-        'serial': 'xxxx',
-        'magic': 'Magic2'
-    }]
+    my_config = [
+        {'serial': 'xxxx', 'magic': 'Magic1'},
+        {'serial': 'xxxx', 'magic': 'Magic2'},
+    ]
     mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
     mock_test_config.controller_configs['AndroidDevice'] = [{'serial': '1'}]
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
@@ -228,20 +237,18 @@
     """
     config1 = self.base_mock_test_config.copy()
     config1.controller_configs[mock_controller.MOBLY_CONTROLLER_CONFIG_NAME] = [
-        {
-            'serial': 'xxxx'
-        }
+        {'serial': 'xxxx'}
     ]
     config2 = config1.copy()
     config2.user_params['icecream'] = 10
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with tr.mobly_logger():
-      tr.add_test_class(config1,
-                        integration_test.IntegrationTest,
-                        name_suffix='FirstConfig')
-      tr.add_test_class(config2,
-                        integration_test.IntegrationTest,
-                        name_suffix='SecondConfig')
+      tr.add_test_class(
+          config1, integration_test.IntegrationTest, name_suffix='FirstConfig'
+      )
+      tr.add_test_class(
+          config2, integration_test.IntegrationTest, name_suffix='SecondConfig'
+      )
       tr.run()
     results = tr.results.summary_dict()
     self.assertEqual(results['Requested'], 2)
@@ -280,8 +287,9 @@
         logging.getLogger().handlers[0].setLevel(logging.WARNING)
         tr.run()
 
-    self.assertIn('Test received a SIGTERM. Aborting all tests.',
-                  log_output.output[0])
+    self.assertIn(
+        'Test received a SIGTERM. Aborting all tests.', log_output.output[0]
+    )
     self.assertIn('Abort all subsequent test classes', log_output.output[1])
     self.assertIn('Test received a SIGTERM.', log_output.output[1])
 
@@ -290,42 +298,52 @@
     with self.assertRaisesRegex(
         test_runner.Error,
         'TestRunner\'s log folder is "/different/log/dir", but a test '
-        r'config with a different log folder \("%s"\) was added.' %
-        re.escape(self.log_dir)):
-      tr.add_test_class(self.base_mock_test_config,
-                        integration_test.IntegrationTest)
+        r'config with a different log folder \("%s"\) was added.'
+        % re.escape(self.log_dir),
+    ):
+      tr.add_test_class(
+          self.base_mock_test_config, integration_test.IntegrationTest
+      )
 
   def test_add_test_class_mismatched_testbed_name(self):
     tr = test_runner.TestRunner(self.log_dir, 'different_test_bed')
     with self.assertRaisesRegex(
         test_runner.Error,
         'TestRunner\'s test bed is "different_test_bed", but a test '
-        r'config with a different test bed \("%s"\) was added.' %
-        self.testbed_name):
-      tr.add_test_class(self.base_mock_test_config,
-                        integration_test.IntegrationTest)
+        r'config with a different test bed \("%s"\) was added.'
+        % self.testbed_name,
+    ):
+      tr.add_test_class(
+          self.base_mock_test_config, integration_test.IntegrationTest
+      )
 
   def test_run_no_tests(self):
     tr = test_runner.TestRunner(self.log_dir, self.testbed_name)
     with self.assertRaisesRegex(test_runner.Error, 'No tests to execute.'):
       tr.run()
 
-  @mock.patch('mobly.test_runner._find_test_class',
-              return_value=type('SampleTest', (), {}))
-  @mock.patch('mobly.test_runner.config_parser.load_test_config_file',
-              return_value=[config_parser.TestRunConfig()])
+  @mock.patch(
+      'mobly.test_runner._find_test_class',
+      return_value=type('SampleTest', (), {}),
+  )
+  @mock.patch(
+      'mobly.test_runner.config_parser.load_test_config_file',
+      return_value=[config_parser.TestRunConfig()],
+  )
   @mock.patch('mobly.test_runner.TestRunner', return_value=mock.MagicMock())
   def test_main_parse_args(self, mock_test_runner, mock_config, mock_find_test):
     test_runner.main(['-c', 'some/path/foo.yaml', '-b', 'hello'])
     mock_config.assert_called_with('some/path/foo.yaml', None)
 
-  @mock.patch('mobly.test_runner._find_test_class',
-              return_value=integration_test.IntegrationTest)
+  @mock.patch(
+      'mobly.test_runner._find_test_class',
+      return_value=integration_test.IntegrationTest,
+  )
   @mock.patch('sys.exit')
   def test_main(self, mock_exit, mock_find_test):
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u"""
+      f.write("""
         TestBeds:
           # A test bed where adb will find Android devices.
           - Name: SampleTestBed
@@ -338,13 +356,15 @@
     test_runner.main(['-c', tmp_file_path])
     mock_exit.assert_not_called()
 
-  @mock.patch('mobly.test_runner._find_test_class',
-              return_value=integration_test.IntegrationTest)
+  @mock.patch(
+      'mobly.test_runner._find_test_class',
+      return_value=integration_test.IntegrationTest,
+  )
   @mock.patch('sys.exit')
   def test_main_with_failures(self, mock_exit, mock_find_test):
     tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u"""
+      f.write("""
         TestBeds:
           # A test bed where adb will find Android devices.
           - Name: SampleTestBed
@@ -382,10 +402,9 @@
     mock_cls_instance = mock.MagicMock()
     mock_test_class.return_value = mock_cls_instance
     test_runner._print_test_names(mock_test_class)
-    mock_cls_instance._pre_run.side_effect = Exception(
-        'Something went wrong.')
+    mock_cls_instance._pre_run.side_effect = Exception('Something went wrong.')
     mock_cls_instance._clean_up.assert_called_once()
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/test_suite_test.py b/tests/mobly/test_suite_test.py
index d3537f8..4eadfdb 100755
--- a/tests/mobly/test_suite_test.py
+++ b/tests/mobly/test_suite_test.py
@@ -36,16 +36,17 @@
     self.mock_test_cls_configs = config_parser.TestRunConfig()
     self.summary_file = os.path.join(self.tmp_dir, 'summary.yaml')
     self.mock_test_cls_configs.summary_writer = records.TestSummaryWriter(
-        self.summary_file)
+        self.summary_file
+    )
     self.mock_test_cls_configs.log_path = self.tmp_dir
-    self.mock_test_cls_configs.user_params = {"some_param": "hahaha"}
+    self.mock_test_cls_configs.user_params = {'some_param': 'hahaha'}
     self.mock_test_cls_configs.reporter = mock.MagicMock()
     self.base_mock_test_config = config_parser.TestRunConfig()
     self.base_mock_test_config.testbed_name = 'SampleTestBed'
     self.base_mock_test_config.controller_configs = {}
     self.base_mock_test_config.user_params = {
         'icecream': 42,
-        'extra_param': 'haha'
+        'extra_param': 'haha',
     }
     self.base_mock_test_config.log_path = self.tmp_dir
 
@@ -74,5 +75,5 @@
     self.assertIsNot(self.controller1, self.controller2)
 
 
-if __name__ == "__main__":
+if __name__ == '__main__':
   unittest.main()
diff --git a/tests/mobly/utils_test.py b/tests/mobly/utils_test.py
index 7e95718..fff3803 100755
--- a/tests/mobly/utils_test.py
+++ b/tests/mobly/utils_test.py
@@ -45,11 +45,14 @@
 def _is_process_running(pid):
   """Whether the process with given PID is running."""
   if os.name == 'nt':
-    return str(pid) in subprocess.check_output([
-        'tasklist',
-        '/fi',
-        f'PID eq {pid}',
-    ]).decode()
+    return (
+        str(pid)
+        in subprocess.check_output([
+            'tasklist',
+            '/fi',
+            f'PID eq {pid}',
+        ]).decode()
+    )
 
   try:
     # os.kill throws OSError if the process with PID pid is not running.
@@ -102,19 +105,24 @@
     else:
       return ['sleep', str(wait_secs)]
 
-  @unittest.skipIf(os.name == "nt",
-                   'collect_process_tree only available on Unix like system.')
+  @unittest.skipIf(
+      os.name == 'nt',
+      'collect_process_tree only available on Unix like system.',
+  )
   @mock.patch('subprocess.check_output')
   def test_collect_process_tree_without_child(self, mock_check_output):
-    mock_check_output.side_effect = (subprocess.CalledProcessError(
-        -1, 'fake_cmd'))
+    mock_check_output.side_effect = subprocess.CalledProcessError(
+        -1, 'fake_cmd'
+    )
 
     pid_list = utils._collect_process_tree(123)
 
     self.assertListEqual(pid_list, [])
 
-  @unittest.skipIf(os.name == "nt",
-                   'collect_process_tree only available on Unix like system.')
+  @unittest.skipIf(
+      os.name == 'nt',
+      'collect_process_tree only available on Unix like system.',
+  )
   @mock.patch('subprocess.check_output')
   def test_collect_process_tree_returns_list(self, mock_check_output):
     # Creates subprocess 777 with descendants looks like:
@@ -151,8 +159,9 @@
 
   @mock.patch.object(os, 'kill')
   @mock.patch.object(utils, '_collect_process_tree')
-  def test_kill_process_tree_on_unix_succeeds(self, mock_collect_process_tree,
-                                              mock_os_kill):
+  def test_kill_process_tree_on_unix_succeeds(
+      self, mock_collect_process_tree, mock_os_kill
+  ):
     mock_collect_process_tree.return_value = [799, 888, 890]
     mock_proc = mock.MagicMock()
     mock_proc.pid = 123
@@ -170,7 +179,8 @@
   @mock.patch.object(os, 'kill')
   @mock.patch.object(utils, '_collect_process_tree')
   def test_kill_process_tree_on_unix_kill_children_failed_throws_error(
-      self, mock_collect_process_tree, mock_os_kill):
+      self, mock_collect_process_tree, mock_os_kill
+  ):
     mock_collect_process_tree.return_value = [799, 888, 890]
     mock_os_kill.side_effect = [None, OSError(), None]
     mock_proc = mock.MagicMock()
@@ -184,7 +194,8 @@
 
   @mock.patch.object(utils, '_collect_process_tree')
   def test_kill_process_tree_on_unix_kill_proc_failed_throws_error(
-      self, mock_collect_process_tree):
+      self, mock_collect_process_tree
+  ):
     mock_collect_process_tree.return_value = []
     mock_proc = mock.MagicMock()
     mock_proc.pid = 123
@@ -262,13 +273,15 @@
     mock_proc.communicate.return_value = ('fake_out', 'fake_err')
     mock_proc.returncode = 127
 
-    out = utils.run_command(mock_command,
-                            stdout=mock_stdout,
-                            stderr=mock_stderr,
-                            shell=mock_shell,
-                            timeout=mock_timeout,
-                            env=mock_env,
-                            universal_newlines=mock_universal_newlines)
+    out = utils.run_command(
+        mock_command,
+        stdout=mock_stdout,
+        stderr=mock_stderr,
+        shell=mock_shell,
+        timeout=mock_timeout,
+        env=mock_env,
+        universal_newlines=mock_universal_newlines,
+    )
 
     self.assertEqual(out, (127, 'fake_out', 'fake_err'))
     mock_popen.assert_called_with(
@@ -283,8 +296,9 @@
     mock_timer.assert_called_with(1234, mock.ANY)
 
   def test_run_command_with_universal_newlines_false(self):
-    _, out, _ = utils.run_command(self.sleep_cmd(0.01),
-                                  universal_newlines=False)
+    _, out, _ = utils.run_command(
+        self.sleep_cmd(0.01), universal_newlines=False
+    )
 
     self.assertIsInstance(out, bytes)
 
@@ -352,19 +366,29 @@
     #   │  └─ Y (grandchild)
     #   ├─ C (child)
     #   └─ D (child)
-    process_tree_args = ('subprocess_a', [
-        ('child_b', [
-            ('grand_child_x', [
-                ('great_grand_child_1', []),
-                ('great_grand_child_2', []),
-            ]),
-            ('grand_child_y', []),
-        ]),
-        ('child_c', []),
-        ('child_d', []),
-    ])
-    subprocess_a = multiprocessing.Process(target=_fork_children_processes,
-                                           args=process_tree_args)
+    process_tree_args = (
+        'subprocess_a',
+        [
+            (
+                'child_b',
+                [
+                    (
+                        'grand_child_x',
+                        [
+                            ('great_grand_child_1', []),
+                            ('great_grand_child_2', []),
+                        ],
+                    ),
+                    ('grand_child_y', []),
+                ],
+            ),
+            ('child_c', []),
+            ('child_d', []),
+        ],
+    )
+    subprocess_a = multiprocessing.Process(
+        target=_fork_children_processes, args=process_tree_args
+    )
     subprocess_a.start()
     mock_subprocess_a_popen = mock.MagicMock()
     mock_subprocess_a_popen.pid = subprocess_a.pid
@@ -376,16 +400,17 @@
     subprocess_a.join(timeout=1)
     mock_subprocess_a_popen.wait.assert_called_once()
 
-  @unittest.skipIf(sys.version_info >= (3, 4) and sys.version_info < (3, 5),
-                   'Python 3.4 does not support `None` max_workers.')
+  @unittest.skipIf(
+      sys.version_info >= (3, 4) and sys.version_info < (3, 5),
+      'Python 3.4 does not support `None` max_workers.',
+  )
   def test_concurrent_exec_when_none_workers(self):
-
     def adder(a, b):
       return a + b
 
-    with mock.patch.object(futures,
-                           'ThreadPoolExecutor',
-                           wraps=futures.ThreadPoolExecutor) as thread_pool_spy:
+    with mock.patch.object(
+        futures, 'ThreadPoolExecutor', wraps=futures.ThreadPoolExecutor
+    ) as thread_pool_spy:
       results = utils.concurrent_exec(adder, [(1, 1), (2, 2)], max_workers=None)
 
     thread_pool_spy.assert_called_once_with(max_workers=None)
@@ -395,13 +420,12 @@
     self.assertIn(4, results)
 
   def test_concurrent_exec_when_default_max_workers(self):
-
     def adder(a, b):
       return a + b
 
-    with mock.patch.object(futures,
-                           'ThreadPoolExecutor',
-                           wraps=futures.ThreadPoolExecutor) as thread_pool_spy:
+    with mock.patch.object(
+        futures, 'ThreadPoolExecutor', wraps=futures.ThreadPoolExecutor
+    ) as thread_pool_spy:
       results = utils.concurrent_exec(adder, [(1, 1), (2, 2)])
 
     thread_pool_spy.assert_called_once_with(max_workers=30)
@@ -411,13 +435,12 @@
     self.assertIn(4, results)
 
   def test_concurrent_exec_when_custom_max_workers(self):
-
     def adder(a, b):
       return a + b
 
-    with mock.patch.object(futures,
-                           'ThreadPoolExecutor',
-                           wraps=futures.ThreadPoolExecutor) as thread_pool_spy:
+    with mock.patch.object(
+        futures, 'ThreadPoolExecutor', wraps=futures.ThreadPoolExecutor
+    ) as thread_pool_spy:
       results = utils.concurrent_exec(adder, [(1, 1), (2, 2)], max_workers=1)
 
     thread_pool_spy.assert_called_once_with(max_workers=1)
@@ -427,18 +450,20 @@
 
   def test_concurrent_exec_makes_all_calls(self):
     mock_function = mock.MagicMock()
-    _ = utils.concurrent_exec(mock_function, [
-        (1, 1),
-        (2, 2),
-        (3, 3),
-    ])
+    _ = utils.concurrent_exec(
+        mock_function,
+        [
+            (1, 1),
+            (2, 2),
+            (3, 3),
+        ],
+    )
     self.assertEqual(mock_function.call_count, 3)
     mock_function.assert_has_calls(
-        [mock.call(1, 1), mock.call(2, 2),
-         mock.call(3, 3)], any_order=True)
+        [mock.call(1, 1), mock.call(2, 2), mock.call(3, 3)], any_order=True
+    )
 
   def test_concurrent_exec_generates_results(self):
-
     def adder(a, b):
       return a + b
 
@@ -451,42 +476,54 @@
     mock_call_recorder = mock.MagicMock()
     lock_call_count = threading.Lock()
 
-    def fake_int(a,):
+    def fake_int(
+        a,
+    ):
       with lock_call_count:
         mock_call_recorder(a)
       return int(a)
 
-    utils.concurrent_exec(fake_int, [
-        (1,),
-        ('123',),
-        ('not_int',),
-        (5435,),
-    ])
+    utils.concurrent_exec(
+        fake_int,
+        [
+            (1,),
+            ('123',),
+            ('not_int',),
+            (5435,),
+        ],
+    )
 
     self.assertEqual(mock_call_recorder.call_count, 4)
-    mock_call_recorder.assert_has_calls([
-        mock.call(1),
-        mock.call('123'),
-        mock.call('not_int'),
-        mock.call(5435),
-    ],
-                                        any_order=True)
+    mock_call_recorder.assert_has_calls(
+        [
+            mock.call(1),
+            mock.call('123'),
+            mock.call('not_int'),
+            mock.call(5435),
+        ],
+        any_order=True,
+    )
 
   def test_concurrent_exec_when_exception_generates_results(self):
     mock_call_recorder = mock.MagicMock()
     lock_call_count = threading.Lock()
 
-    def fake_int(a,):
+    def fake_int(
+        a,
+    ):
       with lock_call_count:
         mock_call_recorder(a)
       return int(a)
 
-    results = utils.concurrent_exec(fake_int, [
-        (1,),
-        ('123',),
-        ('not_int',),
-        (5435,),
-    ])
+    results = utils.concurrent_exec(
+        fake_int,
+        [
+            (1,),
+            ('123',),
+            ('not_int',),
+            (5435,),
+        ],
+    )
 
     self.assertEqual(len(results), 4)
     self.assertIn(1, results)
@@ -500,42 +537,54 @@
     mock_call_recorder = mock.MagicMock()
     lock_call_count = threading.Lock()
 
-    def fake_int(a,):
+    def fake_int(
+        a,
+    ):
       with lock_call_count:
         mock_call_recorder(a)
       return int(a)
 
-    utils.concurrent_exec(fake_int, [
-        (1,),
-        ('not_int1',),
-        ('not_int2',),
-        (5435,),
-    ])
+    utils.concurrent_exec(
+        fake_int,
+        [
+            (1,),
+            ('not_int1',),
+            ('not_int2',),
+            (5435,),
+        ],
+    )
 
     self.assertEqual(mock_call_recorder.call_count, 4)
-    mock_call_recorder.assert_has_calls([
-        mock.call(1),
-        mock.call('not_int1'),
-        mock.call('not_int2'),
-        mock.call(5435),
-    ],
-                                        any_order=True)
+    mock_call_recorder.assert_has_calls(
+        [
+            mock.call(1),
+            mock.call('not_int1'),
+            mock.call('not_int2'),
+            mock.call(5435),
+        ],
+        any_order=True,
+    )
 
   def test_concurrent_exec_when_multiple_exceptions_generates_results(self):
     mock_call_recorder = mock.MagicMock()
     lock_call_count = threading.Lock()
 
-    def fake_int(a,):
+    def fake_int(
+        a,
+    ):
       with lock_call_count:
         mock_call_recorder(a)
       return int(a)
 
-    results = utils.concurrent_exec(fake_int, [
-        (1,),
-        ('not_int1',),
-        ('not_int2',),
-        (5435,),
-    ])
+    results = utils.concurrent_exec(
+        fake_int,
+        [
+            (1,),
+            ('not_int1',),
+            ('not_int2',),
+            (5435,),
+        ],
+    )
 
     self.assertEqual(len(results), 4)
     self.assertIn(1, results)
@@ -547,12 +596,12 @@
     self.assertNotEqual(exceptions[0], exceptions[1])
 
   def test_concurrent_exec_when_raising_exception_generates_results(self):
-
     def adder(a, b):
       return a + b
 
-    results = utils.concurrent_exec(adder, [(1, 1), (2, 2)],
-                                    raise_on_exception=True)
+    results = utils.concurrent_exec(
+        adder, [(1, 1), (2, 2)], raise_on_exception=True
+    )
     self.assertEqual(len(results), 2)
     self.assertIn(2, results)
     self.assertIn(4, results)
@@ -561,58 +610,74 @@
     mock_call_recorder = mock.MagicMock()
     lock_call_count = threading.Lock()
 
-    def fake_int(a,):
+    def fake_int(
+        a,
+    ):
       with lock_call_count:
         mock_call_recorder(a)
       return int(a)
 
     with self.assertRaisesRegex(RuntimeError, '.*not_int.*'):
-      _ = utils.concurrent_exec(fake_int, [
-          (1,),
-          ('123',),
-          ('not_int',),
-          (5435,),
-      ],
-                                raise_on_exception=True)
+      _ = utils.concurrent_exec(
+          fake_int,
+          [
+              (1,),
+              ('123',),
+              ('not_int',),
+              (5435,),
+          ],
+          raise_on_exception=True,
+      )
 
     self.assertEqual(mock_call_recorder.call_count, 4)
-    mock_call_recorder.assert_has_calls([
-        mock.call(1),
-        mock.call('123'),
-        mock.call('not_int'),
-        mock.call(5435),
-    ],
-                                        any_order=True)
+    mock_call_recorder.assert_has_calls(
+        [
+            mock.call(1),
+            mock.call('123'),
+            mock.call('not_int'),
+            mock.call(5435),
+        ],
+        any_order=True,
+    )
 
   def test_concurrent_exec_when_raising_multiple_exceptions_makes_all_calls(
-      self):
+      self,
+  ):
     mock_call_recorder = mock.MagicMock()
     lock_call_count = threading.Lock()
 
-    def fake_int(a,):
+    def fake_int(
+        a,
+    ):
       with lock_call_count:
         mock_call_recorder(a)
       return int(a)
 
     with self.assertRaisesRegex(
         RuntimeError,
-        r'(?m).*(not_int1(.|\s)+not_int2|not_int2(.|\s)+not_int1).*'):
-      _ = utils.concurrent_exec(fake_int, [
-          (1,),
-          ('not_int1',),
-          ('not_int2',),
-          (5435,),
-      ],
-                                raise_on_exception=True)
+        r'(?m).*(not_int1(.|\s)+not_int2|not_int2(.|\s)+not_int1).*',
+    ):
+      _ = utils.concurrent_exec(
+          fake_int,
+          [
+              (1,),
+              ('not_int1',),
+              ('not_int2',),
+              (5435,),
+          ],
+          raise_on_exception=True,
+      )
 
     self.assertEqual(mock_call_recorder.call_count, 4)
-    mock_call_recorder.assert_has_calls([
-        mock.call(1),
-        mock.call('not_int1'),
-        mock.call('not_int2'),
-        mock.call(5435),
-    ],
-                                        any_order=True)
+    mock_call_recorder.assert_has_calls(
+        [
+            mock.call(1),
+            mock.call('not_int1'),
+            mock.call('not_int2'),
+            mock.call(5435),
+        ],
+        any_order=True,
+    )
 
   def test_create_dir(self):
     new_path = os.path.join(self.tmp_dir, 'haha')
@@ -634,14 +699,17 @@
   @mock.patch(f'{ADB_MODULE_PACKAGE_NAME}.is_adb_available', return_value=False)
   @mock.patch('portpicker.pick_unused_port', return_value=MOCK_AVAILABLE_PORT)
   @mock.patch(f'{ADB_MODULE_PACKAGE_NAME}.list_occupied_adb_ports')
-  def test_get_available_port_positive_no_adb(self,
-                                              mock_list_occupied_adb_ports, *_):
+  def test_get_available_port_positive_no_adb(
+      self, mock_list_occupied_adb_ports, *_
+  ):
     self.assertEqual(utils.get_available_host_port(), MOCK_AVAILABLE_PORT)
     mock_list_occupied_adb_ports.assert_not_called()
 
   @mock.patch(f'{ADB_MODULE_PACKAGE_NAME}.is_adb_available', return_value=True)
-  @mock.patch(f'{ADB_MODULE_PACKAGE_NAME}.list_occupied_adb_ports',
-              return_value=[MOCK_AVAILABLE_PORT])
+  @mock.patch(
+      f'{ADB_MODULE_PACKAGE_NAME}.list_occupied_adb_ports',
+      return_value=[MOCK_AVAILABLE_PORT],
+  )
   @mock.patch('portpicker.pick_unused_port', return_value=MOCK_AVAILABLE_PORT)
   def test_get_available_port_negative(self, *_):
     with self.assertRaisesRegex(utils.Error, 'Failed to find.* retries'):
@@ -672,36 +740,38 @@
 
   def test_load_file_to_base64_str_reads_bytes_file_as_base64_string(self):
     tmp_file_path = os.path.join(self.tmp_dir, 'b64.bin')
-    expected_base64_encoding = u'SGVsbG93IHdvcmxkIQ=='
+    expected_base64_encoding = 'SGVsbG93IHdvcmxkIQ=='
     with io.open(tmp_file_path, 'wb') as f:
       f.write(b'Hellow world!')
-    self.assertEqual(utils.load_file_to_base64_str(tmp_file_path),
-                     expected_base64_encoding)
+    self.assertEqual(
+        utils.load_file_to_base64_str(tmp_file_path), expected_base64_encoding
+    )
 
   def test_load_file_to_base64_str_reads_text_file_as_base64_string(self):
     tmp_file_path = os.path.join(self.tmp_dir, 'b64.bin')
-    expected_base64_encoding = u'SGVsbG93IHdvcmxkIQ=='
+    expected_base64_encoding = 'SGVsbG93IHdvcmxkIQ=='
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u'Hellow world!')
-    self.assertEqual(utils.load_file_to_base64_str(tmp_file_path),
-                     expected_base64_encoding)
+      f.write('Hellow world!')
+    self.assertEqual(
+        utils.load_file_to_base64_str(tmp_file_path), expected_base64_encoding
+    )
 
   def test_load_file_to_base64_str_reads_unicode_file_as_base64_string(self):
     tmp_file_path = os.path.join(self.tmp_dir, 'b64.bin')
-    expected_base64_encoding = u'6YCa'
+    expected_base64_encoding = '6YCa'
     with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
-      f.write(u'\u901a')
-    self.assertEqual(utils.load_file_to_base64_str(tmp_file_path),
-                     expected_base64_encoding)
+      f.write('\u901a')
+    self.assertEqual(
+        utils.load_file_to_base64_str(tmp_file_path), expected_base64_encoding
+    )
 
   def test_cli_cmd_to_string(self):
     cmd = ['"adb"', 'a b', 'c//']
-    self.assertEqual(utils.cli_cmd_to_string(cmd), '\'"adb"\' \'a b\' c//')
+    self.assertEqual(utils.cli_cmd_to_string(cmd), "'\"adb\"' 'a b' c//")
     cmd = 'adb -s meme do something ab_cd'
     self.assertEqual(utils.cli_cmd_to_string(cmd), cmd)
 
   def test_get_settable_properties(self):
-
     class SomeClass:
       regular_attr = 'regular_attr'
       _foo = 'foo'
@@ -726,26 +796,31 @@
     self.assertEqual(actual, ['settable_prop'])
 
   def test_find_subclasses_in_module_when_one_subclass(self):
-    subclasses = utils.find_subclasses_in_module([base_test.BaseTestClass],
-                                                 integration_test)
+    subclasses = utils.find_subclasses_in_module(
+        [base_test.BaseTestClass], integration_test
+    )
     self.assertEqual(len(subclasses), 1)
     self.assertEqual(subclasses[0], integration_test.IntegrationTest)
 
   def test_find_subclasses_in_module_when_indirect_subclass(self):
-    subclasses = utils.find_subclasses_in_module([base_test.BaseTestClass],
-                                                 mock_instrumentation_test)
+    subclasses = utils.find_subclasses_in_module(
+        [base_test.BaseTestClass], mock_instrumentation_test
+    )
     self.assertEqual(len(subclasses), 1)
-    self.assertEqual(subclasses[0],
-                     mock_instrumentation_test.MockInstrumentationTest)
+    self.assertEqual(
+        subclasses[0], mock_instrumentation_test.MockInstrumentationTest
+    )
 
   def test_find_subclasses_in_module_when_no_subclasses(self):
-    subclasses = utils.find_subclasses_in_module([base_test.BaseTestClass],
-                                                 mock_controller)
+    subclasses = utils.find_subclasses_in_module(
+        [base_test.BaseTestClass], mock_controller
+    )
     self.assertEqual(len(subclasses), 0)
 
   def test_find_subclasses_in_module_when_multiple_subclasses(self):
-    subclasses = utils.find_subclasses_in_module([base_test.BaseTestClass],
-                                                 multiple_subclasses_module)
+    subclasses = utils.find_subclasses_in_module(
+        [base_test.BaseTestClass], multiple_subclasses_module
+    )
     self.assertEqual(len(subclasses), 2)
     self.assertIn(multiple_subclasses_module.Subclass1Test, subclasses)
     self.assertIn(multiple_subclasses_module.Subclass2Test, subclasses)
@@ -753,7 +828,8 @@
   def test_find_subclasses_in_module_when_multiple_base_classes(self):
     subclasses = utils.find_subclasses_in_module(
         [base_test.BaseTestClass, test_runner.TestRunner],
-        multiple_subclasses_module)
+        multiple_subclasses_module,
+    )
     self.assertEqual(len(subclasses), 4)
     self.assertIn(multiple_subclasses_module.Subclass1Test, subclasses)
     self.assertIn(multiple_subclasses_module.Subclass2Test, subclasses)
@@ -762,37 +838,45 @@
 
   def test_find_subclasses_in_module_when_only_some_base_classes_present(self):
     subclasses = utils.find_subclasses_in_module(
-        [signals.TestSignal, test_runner.TestRunner],
-        multiple_subclasses_module)
+        [signals.TestSignal, test_runner.TestRunner], multiple_subclasses_module
+    )
     self.assertEqual(len(subclasses), 2)
     self.assertIn(multiple_subclasses_module.Subclass1Runner, subclasses)
     self.assertIn(multiple_subclasses_module.Subclass2Runner, subclasses)
 
   def test_find_subclass_in_module_when_one_subclass(self):
-    subclass = utils.find_subclass_in_module(base_test.BaseTestClass,
-                                             integration_test)
+    subclass = utils.find_subclass_in_module(
+        base_test.BaseTestClass, integration_test
+    )
     self.assertEqual(subclass, integration_test.IntegrationTest)
 
   def test_find_subclass_in_module_when_indirect_subclass(self):
-    subclass = utils.find_subclass_in_module(base_test.BaseTestClass,
-                                             mock_instrumentation_test)
-    self.assertEqual(subclass,
-                     mock_instrumentation_test.MockInstrumentationTest)
+    subclass = utils.find_subclass_in_module(
+        base_test.BaseTestClass, mock_instrumentation_test
+    )
+    self.assertEqual(
+        subclass, mock_instrumentation_test.MockInstrumentationTest
+    )
 
   def test_find_subclass_in_module_when_no_subclasses(self):
     with self.assertRaisesRegex(
-        ValueError, '.*Expected 1 subclass of BaseTestClass per module, found'
-        r' \[\].*'):
-      _ = utils.find_subclass_in_module(base_test.BaseTestClass,
-                                        mock_controller)
+        ValueError,
+        '.*Expected 1 subclass of BaseTestClass per module, found' r' \[\].*',
+    ):
+      _ = utils.find_subclass_in_module(
+          base_test.BaseTestClass, mock_controller
+      )
 
   def test_find_subclass_in_module_when_multiple_subclasses(self):
     with self.assertRaisesRegex(
-        ValueError, '.*Expected 1 subclass of BaseTestClass per module, found'
+        ValueError,
+        '.*Expected 1 subclass of BaseTestClass per module, found'
         r' \[(\'Subclass1Test\', \'Subclass2Test\''
-        r'|\'Subclass2Test\', \'Subclass1Test\')\].*'):
-      _ = utils.find_subclass_in_module(base_test.BaseTestClass,
-                                        multiple_subclasses_module)
+        r'|\'Subclass2Test\', \'Subclass1Test\')\].*',
+    ):
+      _ = utils.find_subclass_in_module(
+          base_test.BaseTestClass, multiple_subclasses_module
+      )
 
 
 if __name__ == '__main__':
diff --git a/tools/sl4a_shell.py b/tools/sl4a_shell.py
index e8365da..6ad656e 100755
--- a/tools/sl4a_shell.py
+++ b/tools/sl4a_shell.py
@@ -51,9 +51,11 @@
 
   def _get_banner(self, serial):
     lines = [
-        'Connected to %s.' % serial, 'Call methods against:',
-        '    ad (android_device.AndroidDevice)', '    sl4a or s (SL4A)',
-        '    ed (EventDispatcher)'
+        'Connected to %s.' % serial,
+        'Call methods against:',
+        '    ad (android_device.AndroidDevice)',
+        '    sl4a or s (SL4A)',
+        '    ed (EventDispatcher)',
     ]
     return '\n'.join(lines)
 
@@ -63,7 +65,8 @@
   parser.add_argument(
       '-s',
       '--serial',
-      help='Device serial to connect to (if more than one device is connected)')
+      help='Device serial to connect to (if more than one device is connected)',
+  )
   args = parser.parse_args()
   logging.basicConfig(level=logging.INFO)
   Sl4aShell().main(args.serial)
diff --git a/tools/snippet_shell.py b/tools/snippet_shell.py
index 74e23c1..1d5fad4 100755
--- a/tools/snippet_shell.py
+++ b/tools/snippet_shell.py
@@ -46,27 +46,35 @@
 
   def _get_banner(self, serial):
     lines = [
-        'Connected to %s.' % serial, 'Call methods against:',
-        '    ad (android_device.AndroidDevice)', '    snippet or s (Snippet)'
+        'Connected to %s.' % serial,
+        'Call methods against:',
+        '    ad (android_device.AndroidDevice)',
+        '    snippet or s (Snippet)',
     ]
     return '\n'.join(lines)
 
 
 if __name__ == '__main__':
   parser = argparse.ArgumentParser(
-      description='Interactive client for Mobly code snippets.')
+      description='Interactive client for Mobly code snippets.'
+  )
   parser.add_argument(
       '-s',
       '--serial',
-      help='Device serial to connect to (if more than one device is connected)')
-  parser.add_argument('package',
-                      metavar='PACKAGE_NAME',
-                      type=str,
-                      nargs='?',
-                      help='The package name of the snippet to use.')
-  parser.add_argument('--mbs',
-                      help='Whether to connect to Mobly Bundled Snippets',
-                      action='store_true')
+      help='Device serial to connect to (if more than one device is connected)',
+  )
+  parser.add_argument(
+      'package',
+      metavar='PACKAGE_NAME',
+      type=str,
+      nargs='?',
+      help='The package name of the snippet to use.',
+  )
+  parser.add_argument(
+      '--mbs',
+      help='Whether to connect to Mobly Bundled Snippets',
+      action='store_true',
+  )
   args = parser.parse_args()
   if args.package and args.mbs:
     print('Cannot specify both --package and --mbs', file=sys.stderr)