test: add unit tests for archive paths and log redaction

This commit is contained in:
xXJsonDeruloXx committed 2026-09-27 10:52:01 -04:00
1 parent c024470cc7
commit a28aae6e4a
4 files changed
+114

No files matched your search

+3
View File
@@ -295,6 +295,9 @@ jobs:
set -o pipefail
./gradlew assembleRelease --console=plain -PndkVersion="$NDK_VERSION" 2>&1 | tee /tmp/build.log
- name: Unit tests
run: ./gradlew testReleaseUnitTest --console=plain -PndkVersion="$NDK_VERSION"
- name: Check the native dependency closure
run: |
set -euo pipefail
+7
View File
@@ -140,6 +140,11 @@ android {
buildConfig true
}
testOptions {
// Plain JVM tests: a stray android.util.Log call returns a default instead of throwing.
unitTests.returnDefaultValues = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
@@ -169,4 +174,6 @@ dependencies {
implementation 'com.flyfishxu:kadb-android:1.2.1'
// Android terminal view/emulator used by the in-session secondary-display Linux shell.
implementation 'com.termux.termux-app:terminal-view:0.118.0'
testImplementation 'junit:junit:4.13.2'
}
@@ -0,0 +1,46 @@
package com.droiddeck.launcher.core
import java.io.File
import java.nio.file.Files
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
class ArchivePathsTest {
private lateinit var root: File
private lateinit var dest: File
@Before fun setUp() {
root = Files.createTempDirectory("archive-paths").toFile()
dest = File(root, "dest").apply { mkdirs() }
}
@After fun tearDown() {
root.deleteRecursively()
}
@Test fun plainEntryLandsInside() {
assertEquals(File(dest, "usr/bin/sh").canonicalPath, ArchivePaths.inside(dest, "usr/bin/sh")!!.canonicalPath)
}
@Test fun dotEntryIsTheDestination() {
assertEquals(dest.canonicalPath, ArchivePaths.inside(dest, "./")!!.canonicalPath)
}
@Test fun parentTraversalIsRefused() {
assertNull(ArchivePaths.inside(dest, "../escape"))
assertNull(ArchivePaths.inside(dest, "usr/../../escape"))
}
@Test fun siblingWithSharedPrefixIsRefused() {
File(root, "dest-other").mkdirs()
assertNull(ArchivePaths.inside(dest, "../dest-other/x"))
}
@Test fun symlinkOutOfTheTreeIsRefused() {
Files.createSymbolicLink(File(dest, "link").toPath(), root.toPath())
assertNull(ArchivePaths.inside(dest, "link/escape"))
}
}
@@ -0,0 +1,58 @@
package com.droiddeck.launcher.core
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
class LogRedactorTest {
@Test fun labelledJwtIsRedacted() {
val out = LogRedactor.redact("Using JWT 25484942796017334")
assertFalse(out.contains("25484942796017334"))
assertTrue(out.contains("<redacted:jwt>"))
}
@Test fun secretPairKeepsItsKey() {
val out = LogRedactor.redact("GET /x?sessionid=abcdef123456 200")
assertFalse(out.contains("abcdef123456"))
assertTrue(out.contains("sessionid="))
}
@Test fun plainKeyValueSurvives() {
assertEquals("language key=english", LogRedactor.redact("language key=english"))
}
@Test fun steamIdIsMaskedNotDeleted() {
assertEquals("user 76561********1234", LogRedactor.redact("user 76561198012341234"))
}
@Test fun webApiKeyIsRedactedButDepotChunkIsKept() {
val key = "0123456789abcdef0123456789abcdef"
val chunk = "0123456789abcdef0123456789abcdef01234567"
assertFalse(LogRedactor.redact("key $key").contains(key))
assertTrue(LogRedactor.redact("chunk $chunk").contains(chunk))
}
@Test fun emailIsRedacted() {
assertEquals("login <redacted:email> ok", LogRedactor.redact("login someone@example.com ok"))
}
@Test fun clockTimeIsNotAnAddress() {
val line = "[2026-09-27 10:03:05] Startup"
assertEquals(line, LogRedactor.redact(line))
}
@Test fun redactingTwiceChangesNothing() {
val lines = listOf(
"Using JWT 25484942796017334",
"token=abcdefghijklmnop sessionid=qrstuvwxyz123",
"user 76561198012341234 [U:1:52075506]",
"external address 2607:f8b0:4005:80a::200e",
"OnLoginStateChange someaccount 2 1 0 0",
)
for (line in lines) {
val once = LogRedactor.redact(line)
assertEquals(once, LogRedactor.redact(once))
}
}
}