You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
5.3 KiB
144 lines
5.3 KiB
package cash.z.ecc.android.sdk.integration.service
|
|
|
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
import androidx.test.filters.SmallTest
|
|
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
|
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
|
import cash.z.ecc.android.sdk.exception.LightWalletException.ChangeServerException.ChainInfoNotMatching
|
|
import cash.z.ecc.android.sdk.exception.LightWalletException.ChangeServerException.StatusException
|
|
import cash.z.ecc.android.sdk.internal.block.CompactBlockDownloader
|
|
import cash.z.ecc.android.sdk.internal.block.CompactBlockStore
|
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
|
import cash.z.ecc.android.sdk.internal.service.LightWalletService
|
|
import cash.z.ecc.android.sdk.internal.twig
|
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
|
import cash.z.ecc.android.sdk.model.Mainnet
|
|
import cash.z.ecc.android.sdk.model.Testnet
|
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
|
import cash.z.ecc.android.sdk.test.ScopedTest
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.runBlocking
|
|
import org.junit.After
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertNotNull
|
|
import org.junit.Assert.assertTrue
|
|
import org.junit.Before
|
|
import org.junit.Ignore
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
import org.mockito.Mock
|
|
import org.mockito.MockitoAnnotations
|
|
import org.mockito.Spy
|
|
|
|
@MaintainedTest(TestPurpose.REGRESSION)
|
|
@RunWith(AndroidJUnit4::class)
|
|
@SmallTest
|
|
class ChangeServiceTest : ScopedTest() {
|
|
|
|
val network = ZcashNetwork.Mainnet
|
|
val lightWalletEndpoint = LightWalletEndpoint.Mainnet
|
|
private val eccEndpoint = LightWalletEndpoint("lightwalletd.electriccoin.co", 9087, true)
|
|
|
|
@Mock
|
|
lateinit var mockBlockStore: CompactBlockStore
|
|
var mockCloseable: AutoCloseable? = null
|
|
|
|
@Spy
|
|
val service = LightWalletGrpcService.new(context, lightWalletEndpoint)
|
|
|
|
lateinit var downloader: CompactBlockDownloader
|
|
lateinit var otherService: LightWalletService
|
|
|
|
@Before
|
|
fun setup() {
|
|
initMocks()
|
|
downloader = CompactBlockDownloader(service, mockBlockStore)
|
|
otherService = LightWalletGrpcService.new(context, eccEndpoint)
|
|
}
|
|
|
|
@After
|
|
fun tearDown() {
|
|
mockCloseable?.close()
|
|
}
|
|
|
|
private fun initMocks() {
|
|
mockCloseable = MockitoAnnotations.openMocks(this)
|
|
}
|
|
|
|
@Test
|
|
fun testSanityCheck() {
|
|
val result = service.getLatestBlockHeight()
|
|
assertTrue(result > network.saplingActivationHeight)
|
|
}
|
|
|
|
@Test
|
|
fun testCleanSwitch() = runBlocking {
|
|
downloader.changeService(otherService)
|
|
val result = downloader.downloadBlockRange(BlockHeight.new(network, 900_000)..BlockHeight.new(network, 901_000))
|
|
assertEquals(1_001, result)
|
|
}
|
|
|
|
/**
|
|
* Repeatedly connect to servers and download a range of blocks. Switch part way through and
|
|
* verify that the servers change over, even while actively downloading.
|
|
*/
|
|
@Test
|
|
@Ignore("This test is broken")
|
|
fun testSwitchWhileActive() = runBlocking {
|
|
val start = BlockHeight.new(ZcashNetwork.Mainnet, 900_000)
|
|
val count = 5
|
|
val differentiators = mutableListOf<String>()
|
|
var initialValue = downloader.getServerInfo().buildUser
|
|
val job = testScope.launch {
|
|
repeat(count) {
|
|
differentiators.add(downloader.getServerInfo().buildUser)
|
|
twig("downloading from ${differentiators.last()}")
|
|
downloader.downloadBlockRange(start..(start + 100 * it))
|
|
delay(10L)
|
|
}
|
|
}
|
|
delay(30)
|
|
testScope.launch {
|
|
downloader.changeService(otherService)
|
|
}
|
|
job.join()
|
|
assertTrue(differentiators.count { it == initialValue } < differentiators.size)
|
|
assertEquals(count, differentiators.size)
|
|
}
|
|
|
|
@Test
|
|
fun testSwitchToInvalidServer() = runBlocking {
|
|
var caughtException: Throwable? = null
|
|
downloader.changeService(LightWalletGrpcService.new(context, LightWalletEndpoint("invalid.lightwalletd", 9087, true))) {
|
|
caughtException = it
|
|
}
|
|
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
|
assertTrue(
|
|
"Exception was of the wrong type.",
|
|
caughtException is StatusException
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun testSwitchToTestnetFails() = runBlocking {
|
|
var caughtException: Throwable? = null
|
|
downloader.changeService(LightWalletGrpcService.new(context, LightWalletEndpoint.Testnet)) {
|
|
caughtException = it
|
|
}
|
|
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
|
assertTrue(
|
|
"Exception was of the wrong type. Expected ${ChainInfoNotMatching::class.simpleName} but was ${caughtException!!::class.simpleName}",
|
|
caughtException is ChainInfoNotMatching
|
|
)
|
|
(caughtException as ChainInfoNotMatching).propertyNames.let { props ->
|
|
arrayOf("saplingActivationHeight", "chainName").forEach {
|
|
assertTrue(
|
|
"$it should be a non-matching property but properties were [$props]",
|
|
props.contains(it, true)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|