blob: 733e0b7cf2514a2477203c68f1ce474481583ec3 [file] [log] [blame]
# Copyright (C) 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.
import os
import unittest
import rename_jar_services
import zipfile
class TestFile:
def __init__(self, name, content, shaded_name=None, shaded_content=None):
self._name = name
self._shaded_name = shaded_name
self._content = content
self._shaded_content = shaded_content
def name(self):
return self._name
def shaded_name(self):
return self._name if self._shaded_name is None else self._shaded_name
def content(self):
return self._content
def shaded_content(self):
return self._content if self._shaded_content is None else self._shaded_content
def get_path(name):
return os.path.join(os.getenv("TEST_TMPDIR"), name)
def write_test_data(jar_path, rules_path, rules_content, files):
with zipfile.ZipFile(jar_path, mode="w", compression=zipfile.ZIP_STORED) as archive:
for i in files:
archive.writestr(i.name(), i.content())
with open(rules_path, "w") as f:
f.write(rules_content)
def make_rules(rules):
return "\n".join(rules)
class RenameJarServicesTest(unittest.TestCase):
def setUp(self):
self.in_jar_path = get_path("test_in.jar")
self.rules_path = get_path("test_rules.txt")
self.out_jar_path = get_path("test_out.jar")
self.files = {
"service_file_full_rename": TestFile(
name="META-INF/services/com.example.ServiceProvider",
shaded_name="META-INF/services/com.android.example.ServiceProvider",
content="""
com.example.SomeClassA
com.example.SomeClassB
com.something.else.SomeClassC
""",
shaded_content="""
com.android.example.SomeClassA
com.android.example.SomeClassB
com.something.else.SomeClassC
"""),
"service_file_rename_class_only": TestFile(
name="META-INF/services/com.something.ServiceProvider",
content="""
com.example.SomeClassD
""",
shaded_content="""
com.android.example.SomeClassD
"""),
"service_file_double_rename": TestFile(
name="META-INF/services/com.something.else.foo.bar.ServiceProvider",
shaded_name="META-INF/services/com.android.something.else.bar.foo.ServiceProvider",
content="""
com.something.else.foo.bar.SomeClassE
com.something.else.foo.SomeClassF
""",
shaded_content="""
com.android.something.else.bar.foo.SomeClassE
com.something.else.foo.SomeClassF
"""),
"service_file_keep_rule": TestFile(
name="META-INF/services/com.kept.Service",
content="""
com.kept.package.SomeClassG
""",
shaded_content="""
com.kept.package.SomeClassG
"""),
"bait_class_file": TestFile(
name="com/example/BaitClass.class",
content="""
com.example.BaitClass
""")
}
self.single_rename_rule = "rule com.example.** com.android.example.@1"
self.double_rename_rule = "rule com.**.foo.bar.** com.android.@1.bar.foo.@2"
self.keep_rule = "keep com.kept.package.**"
self.zap_rule = "zap com.zap.package.**"
def assert_files_exactly(self, files):
with zipfile.ZipFile(self.out_jar_path, mode="r", compression=zipfile.ZIP_STORED) as archive:
self.assertEqual(
sorted(archive.namelist()),
sorted([i.shaded_name() for i in files]))
def assert_file_content_matches(self, files):
with zipfile.ZipFile(self.out_jar_path, mode="r", compression=zipfile.ZIP_STORED) as archive:
for test_file in files:
self.assertEqual(
archive.read(test_file.shaded_name()).decode(encoding="utf-8").strip().split("\n"),
test_file.shaded_content().strip().split("\n"))
def run_shade_services(self, rules, test_files):
write_test_data(
jar_path=self.in_jar_path,
rules_path=self.rules_path,
rules_content="\n".join(rules),
files=test_files)
rename_jar_services.shade_services(
jar_file=self.in_jar_path,
rules_file=self.rules_path,
output=self.out_jar_path)
def test_file_and_service_are_renamed(self):
test_files = [self.files["service_file_full_rename"]]
self.run_shade_services(
rules=[self.single_rename_rule],
test_files=test_files)
self.assert_files_exactly(test_files)
self.assert_file_content_matches(test_files)
def test_only_class_is_renamed(self):
test_files = [self.files["service_file_rename_class_only"]]
self.run_shade_services(
rules=[self.single_rename_rule],
test_files=test_files)
self.assert_files_exactly(test_files)
self.assert_file_content_matches(test_files)
def test_double_rename_rule(self):
test_files = [self.files["service_file_double_rename"]]
self.run_shade_services(
rules=[self.double_rename_rule],
test_files=test_files)
self.assert_files_exactly(test_files)
self.assert_file_content_matches(test_files)
def test_bait_file_not_touched(self):
test_files = [self.files["bait_class_file"]]
self.run_shade_services(
rules=[self.double_rename_rule],
test_files=test_files)
self.assert_files_exactly(test_files)
self.assert_file_content_matches(test_files)
def test_keep_rule_does_nothing(self):
test_files = [self.files["service_file_keep_rule"]]
self.run_shade_services(
rules=[self.keep_rule],
test_files=test_files)
self.assert_files_exactly(test_files)
self.assert_file_content_matches(test_files)
def test_zap_rule_fails(self):
with self.assertRaisesRegex(ValueError, "zap operation not supported"):
self.run_shade_services(
rules=[self.zap_rule],
test_files=[])
def test_full_behavior(self):
test_files = [self.files[i] for i in self.files]
self.run_shade_services(
rules=[
self.single_rename_rule,
self.double_rename_rule,
self.keep_rule
],
test_files=test_files)
self.assert_files_exactly(test_files)
self.assert_file_content_matches(test_files)
if __name__ == "__main__":
unittest.main()