Cargo2Android: add rdep tests to TEST_MAPPING
This is important because:
1. Some crates do not have their own tests enabled in presubmit.
2. As much as possible, we try to stick with one version of each
crate. This often results in using different versions of
dependencies than a crate has specified in its Cargo.toml.
Ensuring that a crate's tests continue to pass when its dependencies
are upgraded improves our confidence that the update is safe.
The underlying implementation uses the new Bazel queryview
to query modules and reverse dependencies.
Bug: 168167373
Test: Run cargo2android.py on a number of crates including rusqlite,
scopeguard, lock_api.
Change-Id: Id24f2d3267cf8d5e0369ece2442f8971d4ab1343
diff --git a/scripts/cargo2android.py b/scripts/cargo2android.py
index d1c666a..f32061e 100755
--- a/scripts/cargo2android.py
+++ b/scripts/cargo2android.py
@@ -39,14 +39,15 @@
--cargo "build --target x86_64-unknown-linux-gnu"
--cargo "build --tests --target x86_64-unknown-linux-gnu"
- Note that when there are test modules generated into Android.bp,
- corresponding test entries will also be added into the TEST_MAPPING file.
+ Note that when there are tests for this module or for its reverse
+ dependencies, these tests will be added to the TEST_MAPPING file.
If there are rustc warning messages, this script will add
a warning comment to the owner crate module in Android.bp.
"""
from __future__ import print_function
+from update_crate_tests import TestMapping
import argparse
import glob
@@ -180,36 +181,6 @@
return s.replace('"', '\\"')
-class TestMapping(object):
- """Entries for a TEST_MAPPING file."""
- # Note that this only includes device tests.
-
- def __init__(self):
- self.entries = []
-
- def add_test(self, name):
- self.entries.append(name)
-
- def is_empty(self):
- return not self.entries
-
- def dump(self, outf_name):
- """Append all entries into the output file."""
- if self.is_empty():
- return
- with open(outf_name, 'w') as outf:
- outf.write('// Generated by cargo2android.py for tests in Android.bp\n')
- outf.write('{\n "presubmit": [\n')
- is_first = True
- for name in self.entries:
- if not is_first: # add comma and '\n' after the previous entry
- outf.write(',\n')
- is_first = False
- outf.write(' {\n')
- outf.write(' "name": "' + name + '"' + '\n }')
- outf.write('\n ]\n}\n')
-
-
class Crate(object):
"""Information of a Rust crate to collect/emit for an Android.bp module."""
@@ -650,14 +621,12 @@
self.module_name = self.test_module_name()
self.decide_one_module_type(crate_type)
self.dump_one_android_module(crate_type)
- # We do not add host tests, as these are handled in the Android.bp file.
if saved_device_supported:
self.device_supported = True
self.host_supported = False
self.module_name = self.test_module_name()
self.decide_one_module_type(crate_type)
self.dump_one_android_module(crate_type)
- self.runner.add_test(self.outf_name, self.module_name)
self.host_supported = saved_host_supported
self.device_supported = saved_device_supported
self.main_src = saved_main_src
@@ -1032,7 +1001,6 @@
def __init__(self, args):
self.bp_files = set() # Remember all output Android.bp files.
- self.test_mappings = {} # Map from Android.bp file path to TestMapping.
self.root_pkg = '' # name of package in ./Cargo.toml
# Saved flags, modes, and data.
self.args = args
@@ -1184,18 +1152,11 @@
if self.dry_run:
print('Dry-run skip dump of TEST_MAPPING')
else:
- for bp_file_name in self.test_mappings:
- if bp_file_name != '/dev/null':
- name = os.path.join(os.path.dirname(bp_file_name), 'TEST_MAPPING')
- self.test_mappings[bp_file_name].dump(name)
+ test_mapping = TestMapping()
+ for bp_file_name in self.bp_files:
+ test_mapping.create_test_mapping(os.path.dirname(bp_file_name))
return self
- def add_test(self, bp_file_name, test_name):
- if bp_file_name not in self.test_mappings:
- self.test_mappings[bp_file_name] = TestMapping()
- mapping = self.test_mappings[bp_file_name]
- mapping.add_test(test_name)
-
def try_claim_module_name(self, name, owner):
"""Reserve and return True if it has not been reserved yet."""
if name not in self.name_owners or owner == self.name_owners[name]: