160486c575581dcc40605ea91e1062afa30598e36Filip Pavlis/*
24a360e3a3af230badc847867c117f605367170aaFilip Pavlis * Copyright 2017 The Android Open Source Project
360486c575581dcc40605ea91e1062afa30598e36Filip Pavlis *
460486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * Licensed under the Apache License, Version 2.0 (the "License");
560486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * you may not use this file except in compliance with the License.
660486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * You may obtain a copy of the License at
760486c575581dcc40605ea91e1062afa30598e36Filip Pavlis *
84a360e3a3af230badc847867c117f605367170aaFilip Pavlis *      http://www.apache.org/licenses/LICENSE-2.0
960486c575581dcc40605ea91e1062afa30598e36Filip Pavlis *
1060486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * Unless required by applicable law or agreed to in writing, software
1160486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * distributed under the License is distributed on an "AS IS" BASIS,
1260486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1360486c575581dcc40605ea91e1062afa30598e36Filip Pavlis * See the License for the specific language governing permissions and
144a360e3a3af230badc847867c117f605367170aaFilip Pavlis * limitations under the License.
1560486c575581dcc40605ea91e1062afa30598e36Filip Pavlis */
1660486c575581dcc40605ea91e1062afa30598e36Filip Pavlis
17ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlispackage com.android.tools.build.jetifier.processor.transform.bytecode
184522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
19ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.core.config.Config
20ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.core.rule.RewriteRule
21ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.core.rule.RewriteRulesMap
22ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.core.type.JavaType
23ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.core.type.TypesMap
24ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.FileMapping
25ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.Processor
26ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.archive.Archive
27ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.archive.ArchiveFile
28ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlisimport com.android.tools.build.jetifier.processor.archive.ArchiveItemVisitor
294522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlisimport com.google.common.truth.Truth
304522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlisimport org.junit.Test
314522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlisimport java.io.File
324522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
334522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis/**
344522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis * Tests that individual files were moved properly due to their owner types rewrites.
354522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis */
364522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlisclass ClassFilesMoveTest {
374522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
384522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    companion object {
395b12e59efaab28afee6ffc712a7c8d6ecbae8144Filip Pavlis        private val TEST_CONFIG = Config.fromOptional(
40e30cfbbfc62160fa5a9aa305a2fba9b11ebbd1e8Filip Pavlis            restrictToPackagePrefixes = setOf("android/support"),
41dee52f68e1f6a3edc0cb77caa0902bc10cb50c33Filip Pavlis            reversedRestrictToPackagesPrefixes = setOf("androidx"),
42e30cfbbfc62160fa5a9aa305a2fba9b11ebbd1e8Filip Pavlis            rulesMap = RewriteRulesMap(
434522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                RewriteRule("android/support/annotation/(.*)", "ignore"),
444522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                RewriteRule("android/support/v7/preference/R(.*)", "ignore"),
454522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                RewriteRule("android/support/v4/(.*)", "ignore")
464522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            ),
47d101a9abcc701ca9a05b4870ab4703bd7ea6b0e9Filip Pavlis            slRules = listOf(
4827abf7a13cdf3ad9beba1af844c7df2de9ed1c0cFilip Pavlis                RewriteRule("android/support/annotation/(.*)", "ignore"),
4927abf7a13cdf3ad9beba1af844c7df2de9ed1c0cFilip Pavlis                RewriteRule("android/support/v7/preference/R(.*)", "ignore"),
5027abf7a13cdf3ad9beba1af844c7df2de9ed1c0cFilip Pavlis                RewriteRule("android/support/v4/(.*)", "ignore")
5127abf7a13cdf3ad9beba1af844c7df2de9ed1c0cFilip Pavlis            ),
524522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            typesMap = TypesMap(mapOf(
534522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v7/preference/Preference"
54ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/Preference",
554522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v7/preference/TwoStatePreference"
56ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/TwoStatePreference",
574522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v7/preference/PreferenceGroup"
58ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/PreferenceGroup",
594522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v7/preference/PreferenceViewHolder"
60ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/PreferenceViewHolder",
614522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v7/preference/PreferenceManager"
62ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/PreferenceManager",
634522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v14/preference/SwitchPreference"
64ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/SwitchPreference",
654522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                "android/support/v7/preference/PreferenceDataStore"
66ba381a314edcd57963ed1ac5910595e04faf29ccFilip Pavlis                        to "androidx/support/preference/PreferenceDataStore"
675b12e59efaab28afee6ffc712a7c8d6ecbae8144Filip Pavlis            ).map { JavaType(it.key) to JavaType(it.value) }.toMap())
684522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        )
694522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
704522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
714522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    /**
724522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * Tests that after rewrite of a input archive the internal classes are properly moved to new
734522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * locations (based on the rewrite rules) which is compared with the expected archive.
744522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     *
754522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * Note: The expected archive does not contain rewritten classes - they were only manually
764522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * moved. Which is fine because this test validates only files locations.
774522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     */
784522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    @Test fun fileMove_forwardRewrite_shouldMoveFilesProperly() {
794522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val inputZipPath = "/fileRenameTest/inputTestLib.zip"
804522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val expectedZipPath = "/fileRenameTest/expectedTestLib.zip"
814522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
824e29091e542d87269447fdc8b3254ce86af06845Filip Pavlis        val processor = Processor.createProcessor(TEST_CONFIG)
834522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val inputFile = File(javaClass.getResource(inputZipPath).file)
844522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
854522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val tempDir = createTempDir()
8649f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val expectedFile = File(createTempDir(), "test.zip")
8749f7010e84f8819274924817443b26fc3a117e22Filip Pavlis
8849f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val resultFiles = processor.transform(setOf(FileMapping(inputFile, expectedFile)))
894522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
9060486c575581dcc40605ea91e1062afa30598e36Filip Pavlis        Truth.assertThat(resultFiles).hasSize(1)
914a360e3a3af230badc847867c117f605367170aaFilip Pavlis        testArchivesAreSame(resultFiles.first(), File(javaClass.getResource(expectedZipPath).file))
924522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
934522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        tempDir.delete()
944522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
954522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
964522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    /**
974522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * Does exactly the same as [fileMove_forwardRewrite_nestedArchive_shouldMoveFilesProperly] but
984522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * the files are in a nested archive e.g. archive.zip/classes.jar/some files.
994522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     */
1004522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    @Test fun fileMove_forwardRewrite_nestedArchive_shouldMoveFilesProperly() {
1014522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val inputZipPath = "/fileRenameTest/inputTestLibNested.zip"
1024522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val expectedZipPath = "/fileRenameTest/expectedTestLibNested.zip"
1034522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1044e29091e542d87269447fdc8b3254ce86af06845Filip Pavlis        val processor = Processor.createProcessor(TEST_CONFIG)
1054522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val inputFile = File(javaClass.getResource(inputZipPath).file)
1064522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1074522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val tempDir = createTempDir()
10849f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val expectedFile = File(createTempDir(), "test.zip")
10949f7010e84f8819274924817443b26fc3a117e22Filip Pavlis
11049f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val resultFiles = processor.transform(setOf(FileMapping(inputFile, expectedFile)))
1114522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
11260486c575581dcc40605ea91e1062afa30598e36Filip Pavlis        Truth.assertThat(resultFiles).hasSize(1)
1134a360e3a3af230badc847867c117f605367170aaFilip Pavlis        testArchivesAreSame(resultFiles.first(), File(javaClass.getResource(expectedZipPath).file))
1144522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1154522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        tempDir.delete()
1164522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
1174522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1184522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    /**
1194522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * Rewrites the input archive and then applies reversed mode to rewrite it back. The final
1204522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * produced archive has to have the same directory structure as the input one.
1214522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     */
1224522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    @Test fun fileMove_forwardRewrite_backwardsRewrite_shouldKeepFilesProperly() {
1234522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val inputZipPath = "/fileRenameTest/inputTestLib.zip"
1244522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1254522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        // Transform forward
1264e29091e542d87269447fdc8b3254ce86af06845Filip Pavlis        val processor = Processor.createProcessor(TEST_CONFIG)
1274522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val inputFile = File(javaClass.getResource(inputZipPath).file)
12849f7010e84f8819274924817443b26fc3a117e22Filip Pavlis
1294522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val tempDir = createTempDir()
13049f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val expectedFile = File(createTempDir(), "test.zip")
13149f7010e84f8819274924817443b26fc3a117e22Filip Pavlis
13249f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val resultFiles = processor.transform(setOf(FileMapping(inputFile, expectedFile)))
1334522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1344522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        // Take previous result & reverse it
1354a360e3a3af230badc847867c117f605367170aaFilip Pavlis        val processor2 = Processor.createProcessor(
1364a360e3a3af230badc847867c117f605367170aaFilip Pavlis            TEST_CONFIG,
1374522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            rewritingSupportLib = true,
1384522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            reversedMode = true)
13949f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val expectedFile2 = File(createTempDir(), "test2.zip")
14049f7010e84f8819274924817443b26fc3a117e22Filip Pavlis        val resultFiles2 = processor2.transform(setOf(
1414a360e3a3af230badc847867c117f605367170aaFilip Pavlis            FileMapping(resultFiles.first(), expectedFile2)))
1424522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1434a360e3a3af230badc847867c117f605367170aaFilip Pavlis        testArchivesAreSame(resultFiles2.first(), File(javaClass.getResource(inputZipPath).file))
1444522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1454522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        tempDir.delete()
1464522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
1474522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1484522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    fun testArchivesAreSame(givenZip: File, expectedZip: File) {
1494522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        testArchivesAreSame(Archive.Builder.extract(givenZip), Archive.Builder.extract(expectedZip))
1504522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
1514522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1524522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    fun testArchivesAreSame(givenZip: Archive, expectedZip: Archive) {
1534522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val givenFiles = ArchiveBrowser.grabAllPathsIn(givenZip)
1544522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val expectedFiles = ArchiveBrowser.grabAllPathsIn(expectedZip)
1554522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        Truth.assertThat(givenFiles).containsExactlyElementsIn(expectedFiles)
1564522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
1574522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1584522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    /**
1594522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     * Just a helper utility to get all file paths in the archive.
1604522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis     */
1614522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    class ArchiveBrowser : ArchiveItemVisitor {
1624522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1634522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        companion object {
1644522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            fun grabAllPathsIn(archive: Archive): MutableSet<String> {
1654522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                val grabber = ArchiveBrowser()
1664522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                archive.accept(grabber)
1674522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis                return grabber.allPaths
1684522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            }
1694522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        }
1704522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1714522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        val allPaths = mutableSetOf<String>()
1724522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1734522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        override fun visit(archiveFile: ArchiveFile) {
1744522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            allPaths.add(archiveFile.relativePath.toString())
1754522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            println("Visited ${archiveFile.relativePath}")
1764522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        }
1774522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis
1784522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        override fun visit(archive: Archive) {
1794522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis            archive.files.forEach { it.accept(this) }
1804522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis        }
1814522ddeab97c3dbce39ebf739bb2352e6216db11Filip Pavlis    }
1821e5262179e35a2cecee27a8bda65b4861fc1d58dJeff Gaston}
183