Update health chains (#740)

This commit is contained in:
KirillPamPam
2025-11-05 13:06:05 +04:00
committed by GitHub
parent 35fa52a01e
commit 63d61699b2
13 changed files with 372 additions and 154 deletions

View File

@@ -26,11 +26,11 @@ class HealthCheckSetupSpec extends Specification {
def "OK when meets availability - 1"() {
setup:
def config = new HealthConfig().tap {
it.chains[Chain.ETHEREUM__MAINNET] = new HealthConfig.ChainConfig(
Chain.ETHEREUM__MAINNET, 1
)
}
def config = new HealthConfig(
Collections.singletonMap(
Chain.ETHEREUM__MAINNET, new HealthConfig.ChainConfig(Chain.ETHEREUM__MAINNET, 1)
)
)
def up1 = Mock(Upstream)
def ethereumUpstreams = Mock(Multistream)
def multistream = Mock(MultistreamHolder)
@@ -50,11 +50,11 @@ class HealthCheckSetupSpec extends Specification {
def "OK when meets availability - 1 - bitcoin"() {
setup:
def config = new HealthConfig().tap {
it.chains[Chain.BITCOIN__MAINNET] = new HealthConfig.ChainConfig(
Chain.BITCOIN__MAINNET, 1
)
}
def config = new HealthConfig(
Collections.singletonMap(
Chain.BITCOIN__MAINNET, new HealthConfig.ChainConfig(Chain.BITCOIN__MAINNET, 1)
)
)
def up1 = Mock(Upstream)
def bitcoinUpstreams = Mock(Multistream)
def multistream = Mock(MultistreamHolder)
@@ -74,11 +74,11 @@ class HealthCheckSetupSpec extends Specification {
def "OK when meets availability - 2/3"() {
setup:
def config = new HealthConfig().tap {
it.chains[Chain.ETHEREUM__MAINNET] = new HealthConfig.ChainConfig(
Chain.ETHEREUM__MAINNET, 2
)
}
def config = new HealthConfig(
Collections.singletonMap(
Chain.ETHEREUM__MAINNET, new HealthConfig.ChainConfig(Chain.ETHEREUM__MAINNET, 1)
)
)
def up1 = Mock(Upstream)
def up2 = Mock(Upstream)
def up3 = Mock(Upstream)
@@ -102,11 +102,11 @@ class HealthCheckSetupSpec extends Specification {
def "OK when doesn't meet availability - 2/3"() {
setup:
def config = new HealthConfig().tap {
it.chains[Chain.ETHEREUM__MAINNET] = new HealthConfig.ChainConfig(
Chain.ETHEREUM__MAINNET, 2
)
}
def config = new HealthConfig(
Collections.singletonMap(
Chain.ETHEREUM__MAINNET, new HealthConfig.ChainConfig(Chain.ETHEREUM__MAINNET, 2)
)
)
def up1 = Mock(Upstream)
def up2 = Mock(Upstream)
def up3 = Mock(Upstream)
@@ -130,11 +130,11 @@ class HealthCheckSetupSpec extends Specification {
def "OK when meets availability - 2/3 - detailed"() {
setup:
def config = new HealthConfig().tap {
it.chains[Chain.ETHEREUM__MAINNET] = new HealthConfig.ChainConfig(
Chain.ETHEREUM__MAINNET, 2
)
}
def config = new HealthConfig(
Collections.singletonMap(
Chain.ETHEREUM__MAINNET, new HealthConfig.ChainConfig(Chain.ETHEREUM__MAINNET, 1)
)
)
def up1 = Mock(Upstream)
def up2 = Mock(Upstream)
def up3 = Mock(Upstream)

View File

@@ -0,0 +1,93 @@
package io.emeraldpay.dshackle.config.reload
import io.emeraldpay.dshackle.Chain
import io.emeraldpay.dshackle.Config
import io.emeraldpay.dshackle.FileResolver
import io.emeraldpay.dshackle.config.HealthConfig
import io.emeraldpay.dshackle.config.HealthConfigReader
import io.emeraldpay.dshackle.config.MainConfig
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.springframework.util.ResourceUtils
import java.io.File
class HealthReloadConfigProcessorTest {
private val fileResolver = FileResolver(File(""))
private val mainConfig = MainConfig()
private val config = mock<Config>()
private val reloadConfigService = ReloadConfigService(config, fileResolver, mainConfig)
private val processor = HealthReloadConfigProcessor(reloadConfigService)
private val healthConfigReader = HealthConfigReader()
@BeforeEach
fun setupTests() {
mainConfig.health = HealthConfig.default()
}
@Test
fun `get health processor config type`() {
assertThat(processor.configType()).isEqualTo("health config")
}
@Test
fun `cant reload config if they are equal`() {
val newConfigFile = ResourceUtils.getFile("classpath:configs/health-initial.yaml")
whenever(config.getConfigPath()).thenReturn(newConfigFile)
val initialConfigIs = ResourceUtils.getFile("classpath:configs/health-initial.yaml").inputStream()
val initialConfig = healthConfigReader.read(initialConfigIs)!!
mainConfig.health = initialConfig
val result = processor.reload()
assertThat(result).isFalse
}
@Test
fun `cant reload config if they everything is different but not blockchain list`() {
val newConfigFile = ResourceUtils.getFile("classpath:configs/health-changed-params.yaml")
whenever(config.getConfigPath()).thenReturn(newConfigFile)
val initialConfigIs = ResourceUtils.getFile("classpath:configs/health-initial.yaml").inputStream()
val initialConfig = healthConfigReader.read(initialConfigIs)!!
mainConfig.health = initialConfig
val result = processor.reload()
assertThat(result).isFalse
}
@Test
fun `reload health config`() {
val newConfigFile = ResourceUtils.getFile("classpath:configs/health-changed.yaml")
whenever(config.getConfigPath()).thenReturn(newConfigFile)
val initialConfigIs = ResourceUtils.getFile("classpath:configs/health-initial.yaml").inputStream()
val initialConfig = healthConfigReader.read(initialConfigIs)!!
mainConfig.health = initialConfig
assertThat(mainConfig.health.configs().toSet()).isEqualTo(
setOf(
HealthConfig.ChainConfig(Chain.BSC__MAINNET, 0),
),
)
val reloaded = processor.reload()
val newChains = mainConfig.health.configs()
assertThat(reloaded).isTrue
assertThat(newChains.toSet()).isEqualTo(
setOf(
HealthConfig.ChainConfig(Chain.ARBITRUM__MAINNET, 5),
HealthConfig.ChainConfig(Chain.OPTIMISM__MAINNET, 1),
HealthConfig.ChainConfig(Chain.BSC__MAINNET, 1),
),
)
}
}

View File

@@ -53,6 +53,20 @@ class ReloadConfigTest {
mainConfig.upstreams = null
}
@Test
fun `reload config and use all processors`() {
val firstProcessor = mock<ReloadConfigProcessor>()
val secondProcessor = mock<ReloadConfigProcessor>()
val reloadConfig = ReloadConfigSetup(listOf(firstProcessor, secondProcessor))
reloadConfig.handle(Signal("HUP"))
verify(firstProcessor).reload()
verify(firstProcessor).configType()
verify(secondProcessor).reload()
verify(secondProcessor).configType()
}
@Test
fun `reload upstreams changes`() {
val up1 = upstream("local1")
@@ -76,7 +90,8 @@ class ReloadConfigTest {
currentMultistreamHolder,
configuredUpstreams,
)
val reloadConfig = ReloadConfigSetup(reloadConfigService, reloadConfigUpstreamService)
val upstreamCfgReloadProcessor = UpstreamConfigReloadConfigProcessor(reloadConfigService, reloadConfigUpstreamService)
val reloadConfig = ReloadConfigSetup(listOf(upstreamCfgReloadProcessor))
val initialConfigIs = ResourceUtils.getFile("classpath:configs/upstreams-initial.yaml").inputStream()
val initialConfig = upstreamsConfigReader.read(initialConfigIs)!!
@@ -127,7 +142,8 @@ class ReloadConfigTest {
currentMultistreamHolder,
configuredUpstreams,
)
val reloadConfig = ReloadConfigSetup(reloadConfigService, reloadConfigUpstreamService)
val upstreamCfgReloadProcessor = UpstreamConfigReloadConfigProcessor(reloadConfigService, reloadConfigUpstreamService)
val reloadConfig = ReloadConfigSetup(listOf(upstreamCfgReloadProcessor))
val initialConfigIs = ResourceUtils.getFile("classpath:configs/upstreams-initial.yaml").inputStream()
val initialConfig = upstreamsConfigReader.read(initialConfigIs)!!
val newConfig = upstreamsConfigReader.read(newConfigFile.inputStream())!!
@@ -157,7 +173,8 @@ class ReloadConfigTest {
val reloadConfigUpstreamService = mock<ReloadConfigUpstreamService>()
val reloadConfig = ReloadConfigSetup(reloadConfigService, reloadConfigUpstreamService)
val upstreamCfgReloadProcessor = UpstreamConfigReloadConfigProcessor(reloadConfigService, reloadConfigUpstreamService)
val reloadConfig = ReloadConfigSetup(listOf(upstreamCfgReloadProcessor))
whenever(config.getConfigPath()).thenReturn(initialConfigFile)

View File

@@ -0,0 +1,7 @@
health:
port: 8081
host: 1.0.0.0
path: /healtha
blockchains:
- chain: bsc
min-available: 0

View File

@@ -0,0 +1,11 @@
health:
port: 8082
host: 0.0.0.0
path: /health
blockchains:
- chain: arbitrum
min-available: 5
- chain: bsc
min-available: 1
- chain: optimism
min-available: 1

View File

@@ -0,0 +1,7 @@
health:
port: 8082
host: 0.0.0.0
path: /health
blockchains:
- chain: bsc
min-available: 0