Clean up data API
Remove unused functionality and disable modification to tables that should only be written by librustzcash
This commit is contained in:
parent
e7108ca818
commit
359e5c0adc
|
@ -1,55 +0,0 @@
|
|||
package cash.z.wallet.sdk.dao
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.room.Room
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.wallet.sdk.db.CompactBlockDb
|
||||
import cash.z.wallet.sdk.entity.CompactBlock
|
||||
import org.junit.*
|
||||
import org.junit.Assert.*
|
||||
|
||||
class ComplactBlockDaoTest {
|
||||
|
||||
@get:Rule
|
||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
private lateinit var dao: CompactBlockDao
|
||||
private lateinit var db: CompactBlockDb
|
||||
|
||||
@Before
|
||||
fun initDb() {
|
||||
db = Room.inMemoryDatabaseBuilder(
|
||||
InstrumentationRegistry.getInstrumentation().context,
|
||||
CompactBlockDb::class.java
|
||||
)
|
||||
.build()
|
||||
.apply { dao = complactBlockDao() }
|
||||
}
|
||||
|
||||
@After
|
||||
fun close() {
|
||||
db.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDbExists() {
|
||||
assertNotNull(db)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDaoExists() {
|
||||
assertNotNull(dao)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDaoInsert() {
|
||||
CompactBlock(343899, "sample".toByteArray()).let { block ->
|
||||
dao.insert(block)
|
||||
val result = dao.findById(block.height)
|
||||
assertEquals(block.height, result?.height)
|
||||
assertTrue(block.data.contentEquals(result!!.data))
|
||||
dao.delete(block)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package cash.z.wallet.sdk.dao
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.room.Room
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.wallet.sdk.db.CompactBlockDb
|
||||
import cash.z.wallet.sdk.db.DerivedDataDb
|
||||
import cash.z.wallet.sdk.entity.CompactBlock
|
||||
import cash.z.wallet.sdk.entity.Transaction
|
||||
import org.junit.*
|
||||
import org.junit.Assert.*
|
||||
|
||||
class TransactionDaoTest {
|
||||
|
||||
@get:Rule
|
||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
private lateinit var dao: TransactionDao
|
||||
private lateinit var db: DerivedDataDb
|
||||
|
||||
@Before
|
||||
fun initDb() {
|
||||
db = Room.inMemoryDatabaseBuilder(
|
||||
InstrumentationRegistry.getInstrumentation().context,
|
||||
DerivedDataDb::class.java
|
||||
)
|
||||
.build()
|
||||
.apply { dao = transactionDao() }
|
||||
}
|
||||
|
||||
@After
|
||||
fun close() {
|
||||
db.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDbExists() {
|
||||
assertNotNull(db)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDaoExists() {
|
||||
assertNotNull(dao)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDaoInsert() {
|
||||
Transaction(4L, "sample".toByteArray(), 356418, null).let { transaction ->
|
||||
dao.insert(transaction)
|
||||
val result = dao.findById(transaction.id)
|
||||
assertEquals(transaction.id, result?.id)
|
||||
assertTrue(transaction.transactionId.contentEquals(result!!.transactionId))
|
||||
dao.delete(transaction)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package cash.z.wallet.sdk.data
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import cash.z.wallet.sdk.dao.BlockDao
|
||||
import cash.z.wallet.sdk.dao.NoteDao
|
||||
import cash.z.wallet.sdk.dao.TransactionDao
|
||||
import cash.z.wallet.sdk.jni.JniConverter
|
||||
import cash.z.wallet.sdk.entity.Block
|
||||
import cash.z.wallet.sdk.entity.Note
|
||||
import cash.z.wallet.sdk.entity.Transaction
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.atLeast
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import kotlin.random.Random
|
||||
|
||||
internal class PollingTransactionRepositoryTest {
|
||||
@get:Rule
|
||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
||||
private lateinit var repository: TransactionRepository
|
||||
private lateinit var noteDao: NoteDao
|
||||
private lateinit var transactionDao: TransactionDao
|
||||
private lateinit var blockDao: BlockDao
|
||||
private val twig = TestLogTwig()
|
||||
private var ids = 0L
|
||||
private var heights: Int = 123_456
|
||||
private lateinit var balanceProvider: Iterator<Long>
|
||||
private val pollFrequency = 100L
|
||||
|
||||
private lateinit var converter: JniConverter
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
val dbName = "polling-test.db"
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
converter = mock {
|
||||
on { getBalance(any(), 0) }.thenAnswer { balanceProvider.next() }
|
||||
}
|
||||
repository = PollingTransactionRepository(context, dbName, pollFrequency, converter, twig) { db ->
|
||||
blockDao = db.blockDao()
|
||||
transactionDao = db.transactionDao()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
repository.stop()
|
||||
blockDao.deleteAll()
|
||||
|
||||
// just verify the cascading deletes are working, for sanity
|
||||
assertEquals(0, blockDao.count())
|
||||
assertEquals(0, transactionDao.count())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBalancesAreDistinct() = runBlocking<Unit> {
|
||||
val balanceList = listOf(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L)
|
||||
val iterations = balanceList.size
|
||||
balanceProvider = balanceList.iterator()
|
||||
|
||||
insert(6) {
|
||||
repository.stop()
|
||||
}
|
||||
|
||||
var distinctBalances = 0
|
||||
val balances = repository.balance()
|
||||
twig.twigTask("waiting for balance changes") {
|
||||
for (balance in balances) {
|
||||
twig.twig("found balance of $balance")
|
||||
distinctBalances++
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(iterations, blockDao.count())
|
||||
assertEquals(balanceList.distinct().size, distinctBalances)
|
||||
|
||||
// we at least requested the balance more times from the rust library than we got it in the channel
|
||||
// (meaning the duplicates were ignored)
|
||||
verify(converter, atLeast(distinctBalances + 1)).getBalance(anyString(), 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransactionsAreNotLost() = runBlocking<Unit> {
|
||||
val iterations = 10
|
||||
balanceProvider = List(iterations + 1) { it.toLong() }.iterator()
|
||||
val transactionChannel = repository.allTransactions()
|
||||
repository.start(this)
|
||||
insert(iterations) {
|
||||
repeat(iterations) {
|
||||
assertNotNull("unexpected null for transaction number $it", transactionChannel.poll())
|
||||
}
|
||||
assertNull("transactions shouldn't remain", transactionChannel.poll())
|
||||
assertEquals("incorrect number of items in DB", iterations, blockDao.count())
|
||||
repository.stop()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* insert [count] items, then run the code block.
|
||||
*/
|
||||
private fun CoroutineScope.insert(count: Int, block: suspend () -> Unit = {}) {
|
||||
repeat(count) {
|
||||
launch { insertItemDelayed(it * pollFrequency) }
|
||||
}
|
||||
launch { delay(pollFrequency * count * 2); block() }
|
||||
}
|
||||
|
||||
private suspend fun insertItemDelayed(duration: Long) {
|
||||
twig.twig("delaying $duration")
|
||||
delay(duration)
|
||||
|
||||
val block = createBlock()
|
||||
val transaction = createTransaction(block.height)
|
||||
val note = createNote(transaction.id)
|
||||
twig.twig("inserting note with value ${note.value}")
|
||||
blockDao.insert(block)
|
||||
transactionDao.insert(transaction)
|
||||
noteDao.insert(note)
|
||||
}
|
||||
|
||||
|
||||
private fun createBlock(): Block {
|
||||
return Block(heights++, System.currentTimeMillis().toInt(), byteArrayOf(heights.toByte()))
|
||||
}
|
||||
|
||||
private fun createTransaction(blockId: Int): Transaction {
|
||||
return Transaction(ids++, byteArrayOf(ids.toByte()), blockId, null)
|
||||
}
|
||||
|
||||
private fun createNote(id: Long): Note {
|
||||
return Note(
|
||||
id.toInt(),
|
||||
id.toInt(),
|
||||
value = Random.nextLong(0L, 10L)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class TestLogTwig : TroubleshootingTwig(printer = { msg: String -> Log.e("TEST_LOG", msg) })
|
|
@ -32,11 +32,6 @@ class DerivedDbIntegrationTest {
|
|||
assertNotNull(blocks)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCount_Transaction() {
|
||||
assertEquals(5, transactions.count())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCount_Block() {
|
||||
assertEquals(80101, blocks.count())
|
||||
|
@ -55,13 +50,6 @@ class DerivedDbIntegrationTest {
|
|||
assertEquals(343987, tran?.block)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBlockDaoPrepopulated() {
|
||||
val tran = blocks.findById(1)?.apply {
|
||||
assertEquals(343987, this.height)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private lateinit var transactions: TransactionDao
|
||||
private lateinit var blocks: BlockDao
|
||||
|
|
|
@ -5,27 +5,9 @@ import cash.z.wallet.sdk.entity.Block
|
|||
|
||||
@Dao
|
||||
interface BlockDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(block: Block)
|
||||
|
||||
@Query("SELECT * FROM blocks WHERE height = :height")
|
||||
fun findById(height: Int): Block?
|
||||
|
||||
@Query("DELETE FROM blocks WHERE height = :height")
|
||||
fun deleteById(height: Int)
|
||||
|
||||
@Delete
|
||||
fun delete(block: Block)
|
||||
|
||||
@Query("SELECT COUNT(height) FROM blocks")
|
||||
fun count(): Int
|
||||
|
||||
@Query("DELETE FROM blocks")
|
||||
fun deleteAll()
|
||||
|
||||
@Query("SELECT MAX(height) FROM blocks")
|
||||
fun lastScannedHeight(): Int
|
||||
|
||||
@Query("UPDATE blocks SET time=:time WHERE height = :height")
|
||||
fun updateTime(height: Int, time: Int)
|
||||
}
|
|
@ -1,26 +1,16 @@
|
|||
package cash.z.wallet.sdk.dao
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import cash.z.wallet.sdk.entity.CompactBlock
|
||||
|
||||
@Dao
|
||||
interface CompactBlockDao {
|
||||
|
||||
@Query("SELECT COUNT(height) FROM compactblocks")
|
||||
fun count(): Int
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
fun insert(block: CompactBlock)
|
||||
|
||||
@Query("SELECT * FROM compactblocks WHERE height = :height")
|
||||
fun findById(height: Int): CompactBlock?
|
||||
|
||||
@Query("DELETE FROM compactblocks WHERE height = :height")
|
||||
fun deleteById(height: Int)
|
||||
|
||||
@Delete
|
||||
fun delete(block: CompactBlock)
|
||||
|
||||
@Query("SELECT MAX(height) FROM compactblocks")
|
||||
fun latestBlockHeight(): Int
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package cash.z.wallet.sdk.dao
|
||||
|
||||
import androidx.room.*
|
||||
import cash.z.wallet.sdk.entity.Note
|
||||
|
||||
@Dao
|
||||
interface NoteDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(block: Note)
|
||||
|
||||
@Query("SELECT * FROM received_notes WHERE id_note = :id")
|
||||
fun findById(id: Int): Note?
|
||||
|
||||
@Query("DELETE FROM received_notes WHERE id_note = :id")
|
||||
fun deleteById(id: Int)
|
||||
|
||||
@Delete
|
||||
fun delete(block: Note)
|
||||
|
||||
@Query("SELECT COUNT(id_note) FROM received_notes")
|
||||
fun count(): Int
|
||||
}
|
|
@ -1,16 +1,18 @@
|
|||
package cash.z.wallet.sdk.dao
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Query
|
||||
import cash.z.wallet.sdk.entity.Transaction
|
||||
|
||||
@Dao
|
||||
interface TransactionDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(transaction: Transaction)
|
||||
|
||||
@Query("SELECT * FROM transactions WHERE id_tx = :id")
|
||||
fun findById(id: Long): Transaction?
|
||||
|
||||
@Delete
|
||||
fun delete(transaction: Transaction)
|
||||
|
||||
@Query("DELETE FROM transactions WHERE id_tx = :id")
|
||||
fun deleteById(id: Long)
|
||||
|
||||
|
@ -40,13 +42,6 @@ interface TransactionDao {
|
|||
ORDER BY block IS NOT NUll, height DESC, time DESC, txId DESC
|
||||
""")
|
||||
fun getAll(): List<WalletTransaction>
|
||||
|
||||
@Delete
|
||||
fun delete(transaction: Transaction)
|
||||
|
||||
@Query("SELECT COUNT(id_tx) FROM transactions")
|
||||
fun count(): Int
|
||||
|
||||
}
|
||||
|
||||
data class WalletTransaction(
|
||||
|
|
|
@ -3,7 +3,6 @@ package cash.z.wallet.sdk.db
|
|||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import cash.z.wallet.sdk.dao.BlockDao
|
||||
import cash.z.wallet.sdk.dao.NoteDao
|
||||
import cash.z.wallet.sdk.dao.TransactionDao
|
||||
import cash.z.wallet.sdk.entity.*
|
||||
|
||||
|
|
Loading…
Reference in New Issue