Skip to content

Commit

Permalink
Merge branch 'fix-issues' into 'master'
Browse files Browse the repository at this point in the history
Add more unit tests

See merge request mobile/pax-app-core/app-sizer!37
  • Loading branch information
vanminh-grabtaxi committed Aug 20, 2024
2 parents 08f1877 + f8ff380 commit 7b33d4a
Show file tree
Hide file tree
Showing 7 changed files with 493 additions and 13 deletions.
10 changes: 0 additions & 10 deletions app-sizer/src/main/kotlin/com/grab/sizer/analyzer/MetricIds.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ internal const val LIB_CONTENT_METRICS_ID = "library_content"
internal const val METRICS_ID_MODULES = "module"
internal const val NOT_AVAILABLE_VALUE = "NA"

fun Report.sort(): Report {
return this.copy(
rows = this.rows.map { row ->
row.copy(
fields = row.fields.sortedBy { it.name }
)
}.sortedBy { it.name }
)
}

internal fun createRow(
name: String,
value: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ data class ApkFileInfo(
val resources: Set<RawFileInfo>,
val nativeLibs: Set<RawFileInfo>,
val assets: Set<RawFileInfo>,
val others: Set<FileInfo>,
val others: Set<RawFileInfo>,
val dexes: Set<DexFileInfo>
)
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
package com.grab.sizer.parser

import com.android.tools.apk.analyzer.ApkSizeCalculator
import com.grab.sizer.analyzer.model.FileInfo
import com.grab.sizer.analyzer.model.FileType
import com.grab.sizer.analyzer.model.RawFileInfo
import com.grab.sizer.di.AppScope
Expand Down Expand Up @@ -73,7 +72,7 @@ internal class DefaultApkFileParser @Inject constructor(
val resources = mutableSetOf<RawFileInfo>()
val assets = mutableSetOf<RawFileInfo>()
val nativeLibs = mutableSetOf<RawFileInfo>()
val others = mutableSetOf<FileInfo>()
val others = mutableSetOf<RawFileInfo>()
val dexes = mutableSetOf<DexFileInfo>()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,14 @@ class ApkAnalyzerTest {
expectNativeLibrariesRow
)
)
}

internal fun Report.sort(): Report {
return this.copy(
rows = this.rows.map { row ->
row.copy(
fields = row.fields.sortedBy { it.name }
)
}.sortedBy { it.name }
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package com.grab.sizer.parser

import org.junit.Assert.*
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import java.io.File
import java.io.InputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

class DefaultAarFileParserTest {

@get:Rule
val tempFolder = TemporaryFolder()

private lateinit var mockJarParser: MockJarStreamParser
private lateinit var aarFileParser: DefaultAarFileParser

@Before
fun setup() {
mockJarParser = MockJarStreamParser()
aarFileParser = DefaultAarFileParser(mockJarParser)
}

@Test
fun parseAarsShouldCorrectlyParseResourceFiles() {
val aar = createTestAar("test.aar", listOf("res/layout/activity_main.xml", "res/values/strings.xml"))
val result = aarFileParser.parseAars(sequenceOf(aar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals(2, aarInfo.resources.size)
assertTrue(aarInfo.resources.any { it.path == "/res/layout/activity_main.xml" })
assertTrue(aarInfo.resources.any { it.path == "/res/values/strings.xml" })
}

@Test
fun parseAarsShouldCorrectlyParseAssetFiles() {
val aar = createTestAar("test.aar", listOf("assets/fonts/roboto.ttf", "assets/images/logo.png"))
val result = aarFileParser.parseAars(sequenceOf(aar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals(2, aarInfo.assets.size)
assertTrue(aarInfo.assets.any { it.path == "/assets/fonts/roboto.ttf" })
assertTrue(aarInfo.assets.any { it.path == "/assets/images/logo.png" })
}

@Test
fun parseAarsShouldCorrectlyParseNativeLibraries() {
val aar = createTestAar("test.aar", listOf("jni/x86/libtest.so", "jni/arm64-v8a/libtest.so"))
val result = aarFileParser.parseAars(sequenceOf(aar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals(2, aarInfo.nativeLibs.size)
assertTrue(aarInfo.nativeLibs.any { it.path == "/jni/x86/libtest.so" })
assertTrue(aarInfo.nativeLibs.any { it.path == "/jni/arm64-v8a/libtest.so" })
}

@Test
fun parseAarsShouldCorrectlyParseJarFiles() {
val jarEntry = "libs/example.jar"
mockJarParser.mockJarInfo = JarFileInfo("example.jar", "libs/example.jar", emptySet(), emptySet(), emptySet())

val aar = createTestAar("test.aar", listOf(jarEntry))
val result = aarFileParser.parseAars(sequenceOf(aar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals(1, aarInfo.jars.size)
assertEquals("example.jar", aarInfo.jars.first().name)
assertEquals(jarEntry, mockJarParser.lastParsedEntry?.name)
}

@Test
fun parseAarsShouldCorrectlyParseOtherFiles() {
val aar = createTestAar("test.aar", listOf("META-INF/MANIFEST.MF", "proguard.txt"))
val result = aarFileParser.parseAars(sequenceOf(aar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals(2, aarInfo.others.size)
assertTrue(aarInfo.others.any { it.path == "/META-INF/MANIFEST.MF" })
assertTrue(aarInfo.others.any { it.path == "/proguard.txt" })
}

@Test
fun parseAarsShouldCorrectlyHandleMixedContent() {
val aar = createTestAar(
"test.aar", listOf(
"res/layout/activity_main.xml",
"assets/fonts/roboto.ttf",
"jni/x86/libtest.so",
"libs/example.jar",
"proguard.txt"
)
)

mockJarParser.mockJarInfo = JarFileInfo("example.jar", "libs/example.jar", emptySet(), emptySet(), emptySet())

val result = aarFileParser.parseAars(sequenceOf(aar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals(1, aarInfo.resources.size)
assertEquals(1, aarInfo.assets.size)
assertEquals(1, aarInfo.nativeLibs.size)
assertEquals(1, aarInfo.jars.size)
assertEquals(1, aarInfo.others.size)
}

@Test
fun parseAarsShouldCorrectlyParseMultipleAars() {
val aar1 = createTestAar("test1.aar", listOf("res/layout/activity_main.xml"))
val aar2 = createTestAar("test2.aar", listOf("jni/x86/libtest.so"))
val result = aarFileParser.parseAars(sequenceOf(aar1, aar2))

assertEquals(2, result.size)
val aarInfo1 = result.find { it.name == "test1.aar" }
val aarInfo2 = result.find { it.name == "test2.aar" }

assertNotNull(aarInfo1)
assertEquals(1, aarInfo1!!.resources.size)

assertNotNull(aarInfo2)
assertEquals(1, aarInfo2!!.nativeLibs.size)
}

@Test
fun parseAarsShouldHandleEmptyAarFiles() {
val emptyAar = createTestAar("empty.aar", listOf())
val result = aarFileParser.parseAars(sequenceOf(emptyAar))

assertEquals(1, result.size)
val aarInfo = result.first()
assertEquals("empty.aar", aarInfo.name)
assertTrue(aarInfo.resources.isEmpty())
assertTrue(aarInfo.assets.isEmpty())
assertTrue(aarInfo.nativeLibs.isEmpty())
assertTrue(aarInfo.jars.isEmpty())
assertTrue(aarInfo.others.isEmpty())
}

private fun createTestAar(name: String, entries: List<String>): File {
val aarFile = tempFolder.newFile(name)
ZipOutputStream(aarFile.outputStream()).use { zos ->
for (entry in entries) {
zos.putNextEntry(ZipEntry(entry))
zos.write("test content".toByteArray())
zos.closeEntry()
}
}
return aarFile
}

private class MockJarStreamParser : JarStreamParser {
var mockJarInfo: JarFileInfo? = null
var lastParsedEntry: ZipEntry? = null

override fun parse(jarEntry: ZipEntry, inputStream: InputStream): JarFileInfo {
lastParsedEntry = jarEntry
return mockJarInfo ?: throw IllegalStateException("MockJarInfo not set")
}
}
}
Loading

0 comments on commit 7b33d4a

Please sign in to comment.