Clean up data API

Remove unused functionality and disable modification to tables that should only be written by librustzcash
This commit is contained in:
Kevin Gorham 2019-03-13 03:27:58 -04:00
parent e7108ca818
commit 359e5c0adc
9 changed files with 10 additions and 343 deletions

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}

View File

@ -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) })

View File

@ -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

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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(

View File

@ -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.*