ganache test

This commit is contained in:
a10zn8
2022-11-14 14:42:36 +04:00
parent 84ac73e8fa
commit d1e05b0215
5 changed files with 171 additions and 10 deletions

View File

@@ -58,6 +58,12 @@ configurations {
compile.exclude group: "org.slf4j", module: "log4j-over-slf4j"
// should be used only for generation of the stubs, the lib contains grpc classes
compile.exclude group: "com.salesforce.servicelibs", module: "reactor-grpc"
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
dependencies {
@@ -101,6 +107,11 @@ dependencies {
testImplementation libs.java.websocket
testImplementation libs.equals.verifier
testImplementation libs.groovy
testImplementation libs.bundles.testcontainers
testImplementation libs.bundles.junit
testImplementation libs.spring.boot.starter.test
testImplementation libs.grpc.testing
detektPlugins libs.detekt.formatting
}

View File

@@ -111,6 +111,14 @@ spring-security-core = { module = "org.springframework.security:spring-security-
spring-security-web = { module = "org.springframework.security:spring-security-web", version.ref = "spring-security" }
spring-security-config = { module = "org.springframework.security:spring-security-config", version.ref = "spring-security" }
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test", version.ref = "spring-boot" }
testcontainers = "org.testcontainers:testcontainers:1.17.5"
testcontainers-ganache = "io.github.ganchix:testcontainers-java-module-ganache:0.0.4"
junit-jupiter = "org.junit.jupiter:junit-jupiter:5.9.1"
assertj = "org.assertj:assertj-core:3.23.1"
[bundles]
apache-commons = ["commons-io", "apache-commons-lang3", "apache-commons-collections4"]
etherjar = ["etherjar-domain", "etherjar-hex", "etherjar-rpc-api", "etherjar-rpc-http", "etherjar-rpc-ws", "etherjar-tx", "etherjar-contract", "etherjar-erc20"]
@@ -122,6 +130,9 @@ netty = ["netty-common", "netty-transport", "netty-handler-core", "netty-handler
reactor = ["reactor-core", "reactor-netty", "reactor-extra", "reactor-kotlin"]
slf4j = ["slf4j-api", "slf4j-jul", "slf4j-jcl", "log4j-slf4j"]
spring-framework = ["spring-boot-starter", "spring-security-core", "spring-security-web", "spring-security-config"]
testcontainers = ["testcontainers", "testcontainers-ganache"]
junit = ["junit-jupiter", "assertj"]
[plugins]
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

View File

@@ -33,9 +33,11 @@ import org.springframework.boot.SpringApplication
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Profile
import org.springframework.core.env.Environment
import org.springframework.scheduling.annotation.EnableAsync
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.util.ResourceUtils
import reactor.core.scheduler.Scheduler
import reactor.core.scheduler.Schedulers
import java.io.File
@@ -47,8 +49,8 @@ import kotlin.system.exitProcess
@EnableScheduling
@EnableAsync
open class Config(
@Autowired private val env: Environment,
@Autowired private val ctx: ApplicationContext
private val env: Environment,
private val ctx: ApplicationContext
) {
companion object {
@@ -61,6 +63,7 @@ open class Config(
private var configFilePath: File? = null
init {
if (!env.activeProfiles.contains("test")) {
configFilePath = getConfigPath()
Global.version = env.getProperty("version.app", Global.version).let {
if (it.contains("SNAPSHOT")) {
@@ -71,6 +74,9 @@ open class Config(
}
Security.addProvider(BouncyCastleProvider())
} else {
configFilePath = ResourceUtils.getFile("classpath:integration/dshackle.yaml")
}
}
fun getConfigPath(): File {
@@ -95,6 +101,7 @@ open class Config(
}
@Bean
@Profile("!test")
open fun mainConfig(@Autowired fileResolver: FileResolver): MainConfig {
val f = configFilePath ?: throw IllegalStateException("Config path is not set")
log.info("Using config: ${f.absolutePath}")

View File

@@ -0,0 +1,111 @@
package io.emeraldpay.dshackle
import io.emeraldpay.api.proto.BlockchainGrpc
import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common.ChainRef
import io.emeraldpay.dshackle.config.MainConfig
import io.emeraldpay.dshackle.config.MainConfigReader
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.github.ganchix.ganache.Account
import io.github.ganchix.ganache.GanacheContainer
import io.grpc.BindableService
import io.grpc.inprocess.InProcessChannelBuilder
import io.grpc.inprocess.InProcessServerBuilder
import org.assertj.core.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.Profile
import org.springframework.test.context.ActiveProfiles
import org.springframework.util.ResourceUtils
import java.math.BigInteger
import java.net.URI
@SpringBootTest(properties = ["spring.main.allow-bean-definition-overriding=true"])
@Import(Config::class)
@ActiveProfiles("test")
class IntegrationTest {
@Autowired
lateinit var services: List<BindableService>
lateinit var stub: BlockchainGrpc.BlockchainBlockingStub
companion object {
val PRIVATE_KEY_0 = "ae020c8ddb6fbc24e167b011666639d2ce3d4aa0d9c13d02d726d6865618a781"
val PRIVATE_KEY_1 = "81ad1ba5c4da47feb0f0163c0c61a66c4d0e6a66bd839827444b1e3362016140"
var ganacheContainer: GanacheContainer<*> = GanacheContainer<Nothing>().apply {
withAccounts(
listOf(
Account.builder().privateKey(PRIVATE_KEY_0).balance(BigInteger.valueOf(2000000000000000000)).build(),
Account.builder().privateKey(PRIVATE_KEY_1).balance(BigInteger.valueOf(2000000000000000000)).build()
)
)
}
init {
ganacheContainer.start()
}
}
@BeforeEach
fun prepare() {
val serverName = InProcessServerBuilder.generateName()
val builder = InProcessServerBuilder.forName(serverName)
.directExecutor()
services.forEach { builder.addService(it) }
val managedChannel = InProcessChannelBuilder.forName(serverName).directExecutor().build()
val server = builder.build()
server.start()
stub = BlockchainGrpc.newBlockingStub(managedChannel)
}
@Test
fun test() {
val result = stub.describe(BlockchainOuterClass.DescribeRequest.newBuilder().build())
Assertions.assertThat(result.chainsCount).isEqualTo(1)
Assertions.assertThat(result.chainsList[0].chain).isEqualTo(ChainRef.CHAIN_ETHEREUM)
Assertions.assertThat(result.chainsList[0].nodesCount).isEqualTo(1)
}
@TestConfiguration
open class Config {
@Bean
@Profile("test")
open fun mainConfig(@Autowired fileResolver: FileResolver): MainConfig {
val reader = MainConfigReader(fileResolver)
val config = reader.read(
ResourceUtils.getFile("classpath:integration/dshackle.yaml")
.inputStream()
)!!
patch(config)
return config
}
private fun patch(config: MainConfig) {
config.upstreams?.upstreams?.add(
UpstreamsConfig.Upstream<UpstreamsConfig.EthereumPosConnection>().apply {
id = "ganache"
nodeId = 1
chain = "ethereum"
connection = UpstreamsConfig.EthereumPosConnection().apply {
execution = UpstreamsConfig.EthereumConnection().apply {
rpc = UpstreamsConfig.HttpEndpoint(
URI.create(
"http://" + ganacheContainer.getHost() + ":" + ganacheContainer.getMappedPort(8545) + "/"
)
)
}
}
}
)
}
}
}

View File

@@ -0,0 +1,21 @@
version: v1
host: 0.0.0.0
port: 2450
tls:
enabled: false
proxy:
host: 0.0.0.0
port: 8550
routes:
- id: eth
blockchain: ethereum
monitoring:
enabled: false
extended: true
signed-response:
enabled: false
cluster:
upstreams: