Add LibTest getTestDataDir to fix sled test on android

This commit is contained in:
Steve Myers 2021-06-26 18:50:58 -07:00
parent 1249a4c491
commit f5dd87b02a
17 changed files with 80 additions and 54 deletions

View File

@ -35,7 +35,7 @@ afterEvaluate {
// You can then customize attributes of the publication as shown below. // You can then customize attributes of the publication as shown below.
groupId = 'org.bitcoindevkit' groupId = 'org.bitcoindevkit'
artifactId = 'bdk' artifactId = 'bdk'
version = '0.0.1-dev' version = '0.0.1-SNAPSHOT'
} }
// Creates a Maven publication called debug. // Creates a Maven publication called debug.
debug(MavenPublication) { debug(MavenPublication) {
@ -44,14 +44,14 @@ afterEvaluate {
groupId = 'org.bitcoindevkit' groupId = 'org.bitcoindevkit'
artifactId = 'bdk-debug' artifactId = 'bdk-debug'
version = '0.0.1-dev' version = '0.0.1-SNAPSHOT'
} }
} }
} }
} }
dependencies { dependencies {
implementation (project(':jvm')) { implementation(project(':jvm')) {
exclude group: 'net.java.dev.jna', module: 'jna' exclude group: 'net.java.dev.jna', module: 'jna'
} }
@ -62,7 +62,7 @@ dependencies {
api "org.slf4j:slf4j-api:1.7.30" api "org.slf4j:slf4j-api:1.7.30"
androidTestImplementation 'com.github.tony19:logback-android:2.0.0' androidTestImplementation 'com.github.tony19:logback-android:2.0.0'
androidTestImplementation (project(':test-fixtures')) { androidTestImplementation(project(':test-fixtures')) {
exclude group: 'net.java.dev.jna', module: 'jna' exclude group: 'net.java.dev.jna', module: 'jna'
} }
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2'

View File

@ -1,11 +1,11 @@
package org.bitcoindevkit.bdk package org.bitcoindevkit.bdk
import android.app.Application
import android.content.Context.MODE_PRIVATE
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.Assert.*
/** /**
* Instrumented test, which will execute on an Android device. * Instrumented test, which will execute on an Android device.
* *
@ -13,5 +13,9 @@ import org.junit.Assert.*
*/ */
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class AndroidLibTest : LibTest() { class AndroidLibTest : LibTest() {
override fun getTestDataDir(): String {
val context = ApplicationProvider.getApplicationContext<Application>()
return context.getDir("bdk-test", MODE_PRIVATE).toString()
}
} }

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.bitcoindevkit.bdk" > package="org.bitcoindevkit.bdk">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />

View File

@ -25,7 +25,7 @@ publishing {
maven(MavenPublication) { maven(MavenPublication) {
groupId = 'org.bitcoindevkit' groupId = 'org.bitcoindevkit'
artifactId = 'bdk' artifactId = 'bdk'
version = '0.0.1-dev' version = '0.0.1-SNAPSHOT'
from components.java from components.java
} }

View File

@ -19,7 +19,7 @@ class MemoryConfig() : DatabaseConfig() {
override val databaseConfigT = libJna.new_memory_config() override val databaseConfigT = libJna.new_memory_config()
} }
class SledConfig(path: String, treeName:String) : DatabaseConfig() { class SledConfig(path: String, treeName: String) : DatabaseConfig() {
private val log: Logger = LoggerFactory.getLogger(SledConfig::class.java) private val log: Logger = LoggerFactory.getLogger(SledConfig::class.java)
override val databaseConfigT = libJna.new_sled_config(path, treeName) override val databaseConfigT = libJna.new_sled_config(path, treeName)

View File

@ -39,6 +39,6 @@ enum class JnaError {
Electrum, Electrum,
// Esplora // Esplora
// CompactFilters // CompactFilters
Sled, Sled,
} }

View File

@ -116,11 +116,11 @@ interface LibJna : Library {
// void free_blockchain_config ( // void free_blockchain_config (
// BlockchainConfig_t * blockchain_config); // BlockchainConfig_t * blockchain_config);
fun free_blockchain_config( blockchain_config: BlockchainConfig_t) fun free_blockchain_config(blockchain_config: BlockchainConfig_t)
// DatabaseConfig_t * new_memory_config (void); // DatabaseConfig_t * new_memory_config (void);
fun new_memory_config(): DatabaseConfig_t fun new_memory_config(): DatabaseConfig_t
// DatabaseConfig_t * new_sled_config ( // DatabaseConfig_t * new_sled_config (
// char const * path, // char const * path,
// char const * tree_name); // char const * tree_name);
@ -128,5 +128,5 @@ interface LibJna : Library {
// void free_database_config ( // void free_database_config (
// DatabaseConfig_t * database_config); // DatabaseConfig_t * database_config);
fun free_database_config( database_config: DatabaseConfig_t) fun free_database_config(database_config: DatabaseConfig_t)
} }

View File

@ -5,33 +5,34 @@ import com.sun.jna.PointerType
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
abstract class ResultBase<PT : PointerType, RT : Any> internal constructor(protected val resultT: PT) : abstract class ResultBase<PT : PointerType, RT : Any> internal constructor(private val pointerT: PT) :
LibBase() { LibBase() {
protected open val log: Logger = LoggerFactory.getLogger(ResultBase::class.java) protected open val log: Logger = LoggerFactory.getLogger(ResultBase::class.java)
protected abstract fun err(): Pointer? protected abstract fun err(pointerT: PT): Pointer?
protected abstract fun ok(): RT protected abstract fun ok(pointerT: PT): RT
protected abstract fun free(pointer: PT) protected abstract fun free(pointerT: PT)
private fun checkErr() { private fun checkErr(pointerT: PT) {
val errPointer = err() val errPointer = err(pointerT)
val err = errPointer?.getString(0) val err = errPointer?.getString(0)
libJna.free_string(errPointer) libJna.free_string(errPointer)
if (err != null) { if (err != null) {
log.error("JnaError: $err")
throw JnaException(JnaError.valueOf(err)) throw JnaException(JnaError.valueOf(err))
} }
} }
fun value(): RT { fun value(): RT {
checkErr() checkErr(pointerT)
return ok() return ok(pointerT)
} }
protected fun finalize() { protected fun finalize() {
free(resultT) free(pointerT)
log.debug("$resultT freed") log.debug("$pointerT freed")
} }
} }

View File

@ -9,18 +9,18 @@ class StringResult internal constructor(stringResultT: LibJna.StringResult_t) :
override val log: Logger = LoggerFactory.getLogger(StringResult::class.java) override val log: Logger = LoggerFactory.getLogger(StringResult::class.java)
override fun err(): Pointer? { override fun err(pointerT: LibJna.StringResult_t): Pointer? {
return libJna.get_string_err(resultT) return libJna.get_string_err(pointerT)
} }
override fun ok(): String { override fun ok(pointerT: LibJna.StringResult_t): String {
val okPointer = libJna.get_string_ok(resultT) val okPointer = libJna.get_string_ok(pointerT)
val ok = okPointer!!.getString(0) val ok = okPointer!!.getString(0)
libJna.free_string(okPointer) libJna.free_string(okPointer)
return ok return ok
} }
override fun free(pointer: LibJna.StringResult_t) { override fun free(pointerT: LibJna.StringResult_t) {
libJna.free_string_result(resultT) libJna.free_string_result(pointerT)
} }
} }

View File

@ -9,15 +9,15 @@ class VoidResult internal constructor(voidResultT: LibJna.VoidResult_t) :
override val log: Logger = LoggerFactory.getLogger(VoidResult::class.java) override val log: Logger = LoggerFactory.getLogger(VoidResult::class.java)
override fun err(): Pointer? { override fun err(pointerT: LibJna.VoidResult_t): Pointer? {
return libJna.get_void_err(resultT) return libJna.get_void_err(pointerT)
} }
override fun ok() { override fun ok(pointerT: LibJna.VoidResult_t) {
// Void // Void
} }
override fun free(pointer: LibJna.VoidResult_t) { override fun free(pointerT: LibJna.VoidResult_t) {
libJna.free_void_result(resultT) libJna.free_void_result(pointerT)
} }
} }

View File

@ -13,7 +13,14 @@ class Wallet constructor(
val log: Logger = LoggerFactory.getLogger(Wallet::class.java) val log: Logger = LoggerFactory.getLogger(Wallet::class.java)
private val walletResult = private val walletResult =
WalletResult(libJna.new_wallet_result(descriptor, changeDescriptor, blockchainConfig.blockchainConfigT, databaseConfig.databaseConfigT)) WalletResult(
libJna.new_wallet_result(
descriptor,
changeDescriptor,
blockchainConfig.blockchainConfigT,
databaseConfig.databaseConfigT
)
)
private val walletRefT = walletResult.value() private val walletRefT = walletResult.value()
fun sync() { fun sync() {
@ -26,7 +33,7 @@ class Wallet constructor(
return stringResult.value() return stringResult.value()
} }
protected fun finalize(pointer: LibJna.WalletResult_t) { protected fun finalize(walletRefT: LibJna.WalletRef_t) {
libJna.free_wallet_ref(walletRefT) libJna.free_wallet_ref(walletRefT)
log.debug("$walletRefT freed") log.debug("$walletRefT freed")
} }

View File

@ -9,15 +9,15 @@ class WalletResult internal constructor(walletResultT: LibJna.WalletResult_t) :
override val log: Logger = LoggerFactory.getLogger(WalletResult::class.java) override val log: Logger = LoggerFactory.getLogger(WalletResult::class.java)
override fun err(): Pointer? { override fun err(pointerT: LibJna.WalletResult_t): Pointer? {
return libJna.get_wallet_err(resultT) return libJna.get_wallet_err(pointerT)
} }
override fun ok(): LibJna.WalletRef_t { override fun ok(pointerT: LibJna.WalletResult_t): LibJna.WalletRef_t {
return libJna.get_wallet_ok(resultT)!! return libJna.get_wallet_ok(pointerT)!!
} }
override fun free(pointer: LibJna.WalletResult_t) { override fun free(pointerT: LibJna.WalletResult_t) {
libJna.free_wallet_result(resultT) libJna.free_wallet_result(pointerT)
} }
} }

View File

@ -1,9 +1,16 @@
package org.bitcoindevkit.bdk package org.bitcoindevkit.bdk
import java.nio.file.Paths
/** /**
* Library test, which will execute on linux host. * Library test, which will execute on linux host.
* *
*/ */
class JvmLibTest : LibTest() { class JvmLibTest : LibTest() {
override fun getTestDataDir(): String {
//return Files.createTempDirectory("bdk-test").toString()
return Paths.get(System.getProperty("java.io.tmpdir"), "bdk-test").toString()
}
} }

View File

@ -1,3 +1,3 @@
rootProject.name = 'bdk-kotlin' rootProject.name = 'bdk-kotlin'
include ':jvm',':android',':test-fixtures' include ':jvm', ':android', ':test-fixtures'

View File

@ -7,7 +7,7 @@ dependencies {
implementation platform('org.jetbrains.kotlin:kotlin-bom') implementation platform('org.jetbrains.kotlin:kotlin-bom')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "net.java.dev.jna:jna:5.8.0" implementation "net.java.dev.jna:jna:5.8.0"
implementation (project(':jvm')) implementation(project(':jvm'))
implementation "junit:junit:4.13.2" implementation "junit:junit:4.13.2"
//implementation "org.mockito.kotlin:mockito-kotlin:3.2.0" //implementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
api "org.slf4j:slf4j-api:1.7.30" api "org.slf4j:slf4j-api:1.7.30"

View File

@ -1,14 +1,13 @@
package org.bitcoindevkit.bdk package org.bitcoindevkit.bdk
import org.junit.*
import org.junit.Assert.* import org.junit.Assert.*
import org.junit.Test
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import javax.management.Descriptor import java.io.File
/** /**
* Library test, which will execute on linux host. * Library tests which will execute for jvm and android modules.
*
*/ */
abstract class LibTest : LibBase() { abstract class LibTest : LibBase() {
@ -20,6 +19,12 @@ abstract class LibTest : LibBase() {
val change = val change =
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)" "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
abstract fun getTestDataDir(): String
fun cleanupTestDataDir() {
File(getTestDataDir()).deleteRecursively()
}
@Test @Test
fun walletResultError() { fun walletResultError() {
val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30) val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30)
@ -46,10 +51,13 @@ abstract class LibTest : LibBase() {
@Test @Test
fun walletSync() { fun walletSync() {
val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30) val blockchainConfig = ElectrumConfig("ssl://electrum.blockstream.info:60002", null, 5, 30)
val databaseConfig = MemoryConfig() val testDataDir = getTestDataDir()
log.debug("testDataDir = $testDataDir")
val databaseConfig = SledConfig(testDataDir, "steve-test")
val wallet = Wallet(desc, change, blockchainConfig, databaseConfig) val wallet = Wallet(desc, change, blockchainConfig, databaseConfig)
assertNotNull(wallet) assertNotNull(wallet)
wallet.sync() wallet.sync()
cleanupTestDataDir()
} }
@Test @Test

View File

@ -1,3 +1,5 @@
use crate::blockchain::BlockchainConfig;
use crate::database::DatabaseConfig;
use crate::error::get_name; use crate::error::get_name;
use ::safer_ffi::prelude::*; use ::safer_ffi::prelude::*;
use bdk::bitcoin::network::constants::Network::Testnet; use bdk::bitcoin::network::constants::Network::Testnet;
@ -10,8 +12,6 @@ use bdk::wallet::AddressIndex::New;
use bdk::{Error, Wallet}; use bdk::{Error, Wallet};
use safer_ffi::boxed::Box; use safer_ffi::boxed::Box;
use safer_ffi::char_p::{char_p_boxed, char_p_ref}; use safer_ffi::char_p::{char_p_boxed, char_p_ref};
use crate::blockchain::BlockchainConfig;
use crate::database::DatabaseConfig;
#[derive_ReprC] #[derive_ReprC]
#[ReprC::opaque] #[ReprC::opaque]
@ -86,11 +86,10 @@ fn new_wallet_result(
blockchain_config: &BlockchainConfig, blockchain_config: &BlockchainConfig,
database_config: &DatabaseConfig, database_config: &DatabaseConfig,
) -> Box<WalletResult> { ) -> Box<WalletResult> {
let descriptor = descriptor.to_string(); let descriptor = descriptor.to_string();
let change_descriptor = change_descriptor.map(|s| s.to_string()); let change_descriptor = change_descriptor.map(|s| s.to_string());
let bc_config = &blockchain_config.raw; let bc_config = &blockchain_config.raw;
let db_config = &database_config.raw; let db_config = &database_config.raw;
let wallet_result = new_wallet(descriptor, change_descriptor, bc_config, db_config); let wallet_result = new_wallet(descriptor, change_descriptor, bc_config, db_config);
Box::new(WalletResult { raw: wallet_result }) Box::new(WalletResult { raw: wallet_result })
} }