Merge "Add `--coverage` command-line argument to Atest." am: 89fd34aa7c

Original change: https://android-review.googlesource.com/c/platform/tools/asuite/+/2172950

Change-Id: Iaf8f898207b8ccaa0bcc78aae0db7e9b4d5c4cab
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/atest/atest.py b/atest/atest.py
index 43881b1..cc9f373 100755
--- a/atest/atest.py
+++ b/atest/atest.py
@@ -53,6 +53,7 @@
 import test_runner_handler
 
 from atest_enum import DetectType, ExitCode
+from coverage import coverage
 from metrics import metrics
 from metrics import metrics_base
 from metrics import metrics_utils
@@ -231,6 +232,7 @@
                 'annotation_filter': constants.ANNOTATION_FILTER,
                 'bazel_arg': constants.BAZEL_ARG,
                 'collect_tests_only': constants.COLLECT_TESTS_ONLY,
+                'coverage': constants.COVERAGE,
                 'custom_args': constants.CUSTOM_ARGS,
                 'device_only': constants.DEVICE_ONLY,
                 'disable_teardown': constants.DISABLE_TEARDOWN,
@@ -1049,6 +1051,11 @@
     # args.steps will be None if none of -bit set, else list of params set.
     steps = args.steps if args.steps else constants.ALL_STEPS
     if build_targets and constants.BUILD_STEP in steps:
+        # Set coverage environment variables.
+        env_vars = {}
+        if args.coverage:
+            env_vars.update(coverage.build_env_vars())
+
         # Add module-info.json target to the list of build targets to keep the
         # file up to date.
         build_targets.add(mod_info.module_info_target)
@@ -1057,6 +1064,7 @@
         build_targets |= _get_host_framework_targets(mod_info)
         build_start = time.time()
         success = atest_utils.build(build_targets, verbose=args.verbose,
+                                    env_vars=env_vars,
                                     mm_build_targets=mm_build_targets)
         build_duration = time.time() - build_start
         build_targets.update(mm_build_targets)
diff --git a/atest/atest_arg_parser.py b/atest/atest_arg_parser.py
index cc4e689..0d9c7a5 100644
--- a/atest/atest_arg_parser.py
+++ b/atest/atest_arg_parser.py
@@ -46,6 +46,8 @@
 CLEAR_CACHE = 'Wipe out the test_infos cache of the test and start a new search.'
 COLLECT_TESTS_ONLY = ('Collect a list test cases of the instrumentation tests '
                       'without testing them in real.')
+COVERAGE = ('Instrument tests with code coverage and generate a code coverage '
+            'report.')
 DEVICE_ONLY = ('Only run tests that require a device. (Note: only workable with'
                ' --test-mapping.)')
 DISABLE_TEARDOWN = 'Disable test teardown and cleanup.'
@@ -165,6 +167,7 @@
         self.add_argument('--bazel-arg', nargs='*', action='append', help=BAZEL_ARG)
         bazel_mode.add_parser_arguments(self, dest='bazel_mode_features')
 
+        self.add_argument('--coverage', action='store_true', help=COVERAGE)
         self.add_argument('-d', '--disable-teardown', action='store_true',
                           help=DISABLE_TEARDOWN)
         self.add_argument('--enable-device-preparer', action='store_true',
@@ -451,6 +454,9 @@
         --bazel-arg
             {BAZEL_ARG}
 
+        --coverage
+            {COVERAGE}
+
         --device-only
             {DEVICE_ONLY}
 
diff --git a/atest/constants_default.py b/atest/constants_default.py
index e9b06e3..b357d8f 100644
--- a/atest/constants_default.py
+++ b/atest/constants_default.py
@@ -71,6 +71,7 @@
 ENABLE_DEVICE_PREPARER = 'ENABLE_DEVICE_PREPARER'
 ANNOTATION_FILTER = 'ANNOTATION_FILTER'
 BAZEL_ARG = 'BAZEL_ARG'
+COVERAGE = 'COVERAGE'
 TEST_FILTER = 'TEST_FILTER'
 TEST_TIMEOUT = 'TEST_TIMEOUT'
 VERBOSE = 'VERBOSE'
diff --git a/atest/coverage/__init__.py b/atest/coverage/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/atest/coverage/__init__.py
diff --git a/atest/coverage/coverage.py b/atest/coverage/coverage.py
new file mode 100644
index 0000000..a23fe9d
--- /dev/null
+++ b/atest/coverage/coverage.py
@@ -0,0 +1,30 @@
+# Copyright 2022, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Code coverage instrumentation and collection class
+"""
+
+def build_env_vars():
+    """Environment variables for building with code coverage instrumentation.
+
+    Returns:
+        A dict with the environment variables to set.
+    """
+    env_vars = {
+        'CLANG_COVERAGE': 'true',
+        'NATIVE_COVERAGE_PATHS': '*',
+        'EMMA_INSTRUMENT': 'true',
+    }
+    return env_vars