Skip to content

Commit

Permalink
Add simple test to check if Diff is patched successfully
Browse files Browse the repository at this point in the history
Touches #287
  • Loading branch information
Iamlooker committed Sep 11, 2024
1 parent 93cebe4 commit 3d6c4f7
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 103 deletions.
2 changes: 0 additions & 2 deletions build-logic/structure/src/main/kotlin/AndroidLibraryPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class AndroidLibraryPlugin : Plugin<Project> {
dependencies {
add("implementation", kotlin2("stdlib", libs))
add("implementation", kotlin2("reflect", libs))
add("testImplementation", kotlin2("test", libs))
add("androidTestImplementation", kotlin2("test", libs))
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ hilt-android-testing = { group = "com.google.dagger", name = "hilt-android-testi
leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakcanary" }
junit4 = { group = "junit", name = "junit", version.ref = "junit4" }
jackson-core = { group = "com.fasterxml.jackson.core", name = "jackson-core", version.ref = "jackson" }
kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
kotlinx-coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-guava", version.ref = "kotlinxCoroutines" }
Expand Down Expand Up @@ -124,4 +125,5 @@ looker-room = { id = "looker.room", version = "unspecified" }
looker-serialization = { id = "looker.serialization", version = "unspecified" }

[bundles]
test-ui = ["androidx-test-runner", "androidx-test-rules", "androidx-test-espresso-core", "androidx-test-uiautomator"]
test-android = ["androidx-test-runner", "androidx-test-rules", "androidx-test-ext", "androidx-test-espresso-core", "kotlinx-coroutines-test", "kotlin-test"]
test-ui = ["androidx-test-runner", "androidx-test-rules", "androidx-test-espresso-core", "androidx-test-uiautomator", "kotlinx-coroutines-test", "kotlin-test"]
4 changes: 1 addition & 3 deletions sync/fdroid/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,5 @@ dependencies {
)

implementation(libs.kotlinx.coroutines.core)
testImplementation(libs.ktor.mock)
testImplementation(libs.kotlinx.coroutines.test)
testRuntimeOnly(kotlin("test"))
androidTestImplementation(libs.bundles.test.android)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.looker.sync.fdroid

import com.looker.core.common.extension.writeTo
import com.looker.network.Downloader
import com.looker.network.NetworkResponse
import com.looker.network.ProgressListener
import com.looker.network.header.HeadersBuilder
import com.looker.network.validation.FileValidator
import com.looker.sync.fdroid.common.assets
import java.io.File
import java.net.Proxy

val FakeDownloader = object : Downloader {
override fun setProxy(proxy: Proxy) {
TODO("Not yet implemented")
}

override suspend fun headCall(
url: String,
headers: HeadersBuilder.() -> Unit
): NetworkResponse {
TODO("Not yet implemented")
}

override suspend fun downloadToFile(
url: String,
target: File,
validator: FileValidator?,
headers: HeadersBuilder.() -> Unit,
block: ProgressListener?
): NetworkResponse {
return if (url.endsWith("fail")) NetworkResponse.Error.Unknown(Exception("You asked for it"))
else {
val index = when {
url.endsWith("index-v1.jar") -> assets("izzy_index_v1.jar")
url.endsWith("index-v2.json") -> assets("izzy_index_v2.json")
url.endsWith("entry.jar") -> assets("izzy_entry.jar")
url.endsWith("/diff/1725731263000.json") -> assets("izzy_diff.json")
// Just in case we try these in future
url.endsWith("index-v1.json") -> assets("izzy_index_v1.json")
url.endsWith("entry.json") -> assets("izzy_entry.json")
else -> error("Unknown URL: $url")
}
index.writeTo(target)
NetworkResponse.Success(200, null, null)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.looker.sync.fdroid

import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.looker.core.domain.model.Repo
import com.looker.sync.fdroid.common.Izzy
import com.looker.sync.fdroid.common.JsonParser
import com.looker.sync.fdroid.common.assets
import com.looker.sync.fdroid.common.memory
import com.looker.sync.fdroid.v2.EntrySyncable
import com.looker.sync.fdroid.v2.model.Entry
import com.looker.sync.fdroid.v2.model.IndexV2
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.decodeFromStream
import org.junit.Before
import org.junit.runner.RunWith
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

@RunWith(AndroidJUnit4::class)
class EntrySyncableTest {

private lateinit var dispatcher: CoroutineDispatcher
private lateinit var context: Context
private lateinit var syncable: Syncable<Entry>
private lateinit var repo: Repo
private lateinit var newIndex: IndexV2

/**
* In this particular test 1 package is removed and 36 packages are updated
*/

@OptIn(ExperimentalSerializationApi::class)
@Before
fun before() {
context = InstrumentationRegistry.getInstrumentation().context
dispatcher = StandardTestDispatcher()
syncable = EntrySyncable(context, FakeDownloader, dispatcher)
newIndex = JsonParser.parser.decodeFromStream<IndexV2>(assets("izzy_index_v2_updated.json"))
repo = Izzy
}

// Not very trustworthy
@Test
fun benchmark_sync_full() = runTest(dispatcher) {
memory("Full Benchmark") {
syncable.sync(repo)
}
memory("Diff Benchmark") {
syncable.sync(repo)
}
}

@Test
fun check_if_patch_applies() = runTest(dispatcher) {
// Downloads old index file as the index file does not exist
val (fingerprint1, index1) = syncable.sync(repo)
assert(index1 != null)
// Downloads the diff as the index file exists and is older than entry version
val (fingerprint2, index2) = syncable.sync(
repo.copy(
versionInfo = repo.versionInfo.copy(
timestamp = index1!!.repo.timestamp
)
)
)
assert(index2 != null)
// Does not download anything
val (fingerprint3, index3) = syncable.sync(
repo.copy(
versionInfo = repo.versionInfo.copy(
timestamp = index2!!.repo.timestamp
)
)
)
assert(index3 == null)

// Check if all the packages are same
assertContentEquals(newIndex.packages.keys.sorted(), index2.packages.keys.sorted())
// Check if all the version hashes are same
assertContentEquals(
newIndex.packages.values.flatMap { it.versions.keys }.sorted(),
index2.packages.values.flatMap { it.versions.keys }.sorted(),
)

// Check if repo antifeatures are same
assertContentEquals(
newIndex.repo.antiFeatures.keys.sorted(),
index2.repo.antiFeatures.keys.sorted()
)

// Check if repo categories are same
assertContentEquals(
newIndex.repo.categories.keys.sorted(),
index2.repo.categories.keys.sorted()
)

assertEquals(fingerprint1, fingerprint2)
assertEquals(fingerprint2, fingerprint3)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.looker.sync.fdroid

import com.looker.core.domain.model.Fingerprint
import java.util.jar.JarEntry

val FakeIndexValidator = object : IndexValidator {
override suspend fun validate(
jarEntry: JarEntry,
expectedFingerprint: Fingerprint?
): Fingerprint {
return expectedFingerprint ?: Fingerprint("0".repeat(64))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.looker.sync.fdroid.common

import com.looker.network.DataSize
import kotlin.time.measureTime

internal inline fun memory(
extraMessage: String? = null,
block: () -> Unit,
) {
val runtime = Runtime.getRuntime()
if (extraMessage != null) {
println("=".repeat(50))
println(extraMessage)
}
println("=".repeat(50))
val initial = runtime.freeMemory()
val time = measureTime {
block()
}
val final = runtime.freeMemory()
println("Time Taken: ${time}, Usage: ${DataSize(initial - final)} / ${DataSize(runtime.maxMemory())}")
println("=".repeat(50))
println()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import com.looker.core.domain.model.Authentication
import com.looker.core.domain.model.Fingerprint
import com.looker.core.domain.model.Repo
import com.looker.core.domain.model.VersionInfo
import kotlin.math.truncate

val Izzy = Repo(
id = 1L,
enabled = true,
address = "https://apt.izzysoft.de/fdroid/repo",
name = "IzzyOnDroid F-Droid Repo",
description = "This is a repository of apps to be used with F-Droid. Applications in this repository are official binaries built by the original application developers, taken from their resp. repositories (mostly Github, GitLab, Codeberg). Updates for the apps are usually fetched daily, and you can expect daily index updates.",
fingerprint = Fingerprint("0".repeat(64)),
fingerprint = Fingerprint("3BF0D6ABFEAE2F401707B6D966BE743BF0EEE49C2561B9BA39073711F628937A"),
authentication = Authentication("", ""),
versionInfo = VersionInfo(0L, null),
mirrors = emptyList(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.looker.sync.fdroid.common

import androidx.test.platform.app.InstrumentationRegistry
import java.io.File
import java.io.InputStream

fun getResource(name: String): File? {
val url = Thread.currentThread().contextClassLoader?.getResource(name) ?: return null
return File(url.file)
}

fun assets(name: String): InputStream {
return InstrumentationRegistry.getInstrumentation().context.assets.open(name)
}
87 changes: 0 additions & 87 deletions sync/fdroid/src/test/kotlin/com/looker/sync/fdroid/V1ParserTest.kt

This file was deleted.

This file was deleted.

0 comments on commit 3d6c4f7

Please sign in to comment.