Skip to content

Commit

Permalink
Load native libraries from assets location during test.
Browse files Browse the repository at this point in the history
Signed-off-by: Kenneth J. Shackleton <[email protected]>
  • Loading branch information
kennethshackleton committed Feb 11, 2024
1 parent 965e860 commit 3ac501a
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 11 deletions.
6 changes: 5 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ subprojects {
}
}
tasks.withType<Test>().configureEach {
systemProperty("com.bloomberg.selekt.lib.can_use_embedded", true)
systemProperty("com.bloomberg.selekt.can_use_load", true)
systemProperty(
"com.bloomberg.selekt.library_path",
layout.buildDirectory.dir("intermediates/assets/debugUnitTest").get().asFile.toString()
)
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,25 @@ package com.bloomberg.selekt.android

import com.bloomberg.selekt.ExternalSQLite
import com.bloomberg.selekt.SQLite
import com.bloomberg.selekt.commons.loadLibrary
import com.bloomberg.selekt.commons.loadEmbeddedLibrary
import com.bloomberg.selekt.externalSQLiteSingleton
import java.lang.IllegalStateException

private const val CAN_USE_EMBEDDED_PROPERTY_KEY = "com.bloomberg.selekt.lib.can_use_embedded"
private const val CAN_USE_LOAD_PROPERTY_KEY = "com.bloomberg.selekt.can_use_load"

fun loadSQLite(): ExternalSQLite = externalSQLiteSingleton {
"selekt".let {
try {
System.loadLibrary(it)
} catch (e: UnsatisfiedLinkError) {
if (System.getProperty(CAN_USE_EMBEDDED_PROPERTY_KEY, null) == "true") {
loadEmbeddedLibrary(checkNotNull(SQLite::class.java.classLoader), "jni", it)
if (System.getProperty(CAN_USE_LOAD_PROPERTY_KEY, null) == "true") {
val loader = checkNotNull(SQLite::class.java.classLoader)
try {
loadEmbeddedLibrary(loader, "jni", it)
} catch (e: IllegalStateException) {
loadLibrary("jni", it)
}
} else {
throw e
}
Expand Down
5 changes: 3 additions & 2 deletions selekt-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ android {
buildConfigField("String", "gitCommitSha1", "\"${gitCommit()}\"")
}
}
sourceSets["test"].resources.srcDir(layout.buildDirectory.dir("intermediates/libs"))
sourceSets["test"].assets.srcDir(layout.buildDirectory.dir("intermediates/libs"))
publishing {
singleVariant("release") {
withJavadocJar()
Expand Down Expand Up @@ -92,6 +92,7 @@ tasks.register<Copy>("copyJniLibs") {
fileTree(project(":Selektric").layout.buildDirectory.dir("intermediates/libs"))
)
into(layout.buildDirectory.dir("intermediates/libs/jni"))
mustRunAfter("buildNativeHost")
}

tasks.register<Task>("buildNativeHost") {
Expand All @@ -107,7 +108,7 @@ arrayOf("Debug", "Release").map { "pre${it}UnitTestBuild" }.forEach {
}
}

arrayOf("Debug", "Release").map { "process${it}UnitTestJavaRes" }.forEach {
arrayOf("Debug", "Release").map { "merge${it}UnitTestAssets" }.forEach {
tasks.whenTaskAdded {
if (it == name) {
dependsOn("copyJniLibs")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.bloomberg.selekt.android

import com.bloomberg.selekt.commons.loadEmbeddedLibrary
import com.bloomberg.selekt.commons.loadLibrary

internal object NativeFixtures {
init {
loadEmbeddedLibrary(NativeFixtures::class.java.classLoader!!, "jni", "selektric")
loadLibrary("jni", "selektric")
check(nativeInit() == 0)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.file.Files
import java.util.Locale
import kotlin.io.path.Path
import kotlin.io.path.createTempFile
import kotlin.jvm.Throws

private const val LIBRARY_PATH_KEY = "com.bloomberg.selekt.library_path"

@Suppress("Detekt.StringLiteralDuplication")
@JvmSynthetic
internal fun osNames(systemOsName: String = System.getProperty("os.name")) = systemOsName.lowercase(Locale.US).run {
Expand All @@ -50,7 +54,7 @@ internal fun libraryExtensions() = osNames().map {
}.toSet()

@JvmSynthetic
internal fun libraryResourceNames(
internal fun libraryNames(
parentDirectory: String,
name: String
) = (platformIdentifiers() * libraryExtensions()).map {
Expand All @@ -59,7 +63,7 @@ internal fun libraryResourceNames(

@Throws(IOException::class)
fun loadEmbeddedLibrary(loader: ClassLoader, parentDirectory: String, name: String) {
val url = checkNotNull(libraryResourceNames(parentDirectory, name).firstNotNullOfOrNull {
val url = checkNotNull(libraryNames(parentDirectory, name).firstNotNullOfOrNull {
loader.getResource(it)
}) { "Failed to find resource with name: $name in directory: $parentDirectory" }
@Suppress("NewApi") // Not used by Android.
Expand All @@ -74,3 +78,18 @@ fun loadEmbeddedLibrary(loader: ClassLoader, parentDirectory: String, name: Stri
file.delete()
}
}

@Suppress("NewApi")
@Throws(IOException::class)
fun loadLibrary(parentDirectory: String, name: String) {
val assetsPath = checkNotNull(System.getProperty(LIBRARY_PATH_KEY)) {
"System property $LIBRARY_PATH_KEY was not set"
}
val path = libraryNames(parentDirectory, name).map {
Path(assetsPath, it)
}.first {
Files.exists(it)
}.toAbsolutePath()
@Suppress("UnsafeDynamicallyLoadedCode")
System.load(path.toString())
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ internal class NativeResourcesKtTest {

@Test
fun commonLibraryResourceName() {
libraryResourceNames("jni", "selekt").forEach {
libraryNames("jni", "selekt").forEach {
assertTrue(it.startsWith("jni"))
}
}
Expand Down

0 comments on commit 3ac501a

Please sign in to comment.