Skip to content

Commit

Permalink
PROM-5262 | debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinFalkowski committed Feb 12, 2025
1 parent 55d9dbe commit 29cc6bf
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 115 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package pl.allegro.tech.servicemesh.envoycontrol.routing

import io.micrometer.core.instrument.MeterRegistry
import okhttp3.Response
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.RegisterExtension
import pl.allegro.tech.servicemesh.envoycontrol.chaos.api.NetworkDelay
import pl.allegro.tech.servicemesh.envoycontrol.config.EnvoyConfig
import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlExtensionBase
import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlTestApp
import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.Health
import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.SnapshotDebugResponse
import pl.allegro.tech.servicemesh.envoycontrol.services.ServicesState

class DebugTest {

companion object {
// language=yaml
private val config = """
static_resources:
listeners:
- name: egress
address: { socket_address: { address: 0.0.0.0, port_value: 5000 }}
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: e
route_config: {}
- name: ingress
address: { socket_address: { address: 0.0.0.0, port_value: 5001 }}
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: i
route_config: {}
admin:
address: { socket_address: { address: 0.0.0.0, port_value: 10000 }}
""".trimIndent()

@JvmField
@RegisterExtension
val envoy = EnvoyExtension(
envoyControl = FakeEnvoyControl(),
config = EnvoyConfig("envoy/empty.yaml", configOverride = config),
)
}

@Test
@ExtendWith
fun debug() {


}
}


private class FakeEnvoyControl : EnvoyControlExtensionBase {
override val app: EnvoyControlTestApp = object : EnvoyControlTestApp {
override val appPort: Int
get() { throw UnsupportedOperationException() }
override val grpcPort: Int = 0
override val appName: String
get() { throw UnsupportedOperationException() }

override fun run() {
throw UnsupportedOperationException()
}

override fun stop() {
throw UnsupportedOperationException()
}

override fun isHealthy(): Boolean {
throw UnsupportedOperationException()
}

override fun getState(): ServicesState {
throw UnsupportedOperationException()
}

override fun getSnapshot(nodeJson: String): SnapshotDebugResponse {
throw UnsupportedOperationException()
}

override fun getGlobalSnapshot(xds: Boolean?): SnapshotDebugResponse {
throw UnsupportedOperationException()
}

override fun getHealthStatus(): Health {
throw UnsupportedOperationException()
}

override fun postChaosFaultRequest(
username: String,
password: String,
networkDelay: NetworkDelay
): Response {
throw UnsupportedOperationException()
}

override fun getExperimentsListRequest(username: String, password: String): Response {
throw UnsupportedOperationException()
}

override fun deleteChaosFaultRequest(
username: String,
password: String,
faultId: String
): Response {
throw UnsupportedOperationException()
}

override fun meterRegistry(): MeterRegistry {
throw UnsupportedOperationException()
}
}

override fun beforeAll(context: ExtensionContext?) {}

override fun afterAll(context: ExtensionContext?) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package pl.allegro.tech.servicemesh.envoycontrol.routing

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import pl.allegro.tech.servicemesh.envoycontrol.assertions.isOk
import pl.allegro.tech.servicemesh.envoycontrol.config.RandomConfigFile
import pl.allegro.tech.servicemesh.envoycontrol.config.consul.ConsulExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.service.GenericServiceExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.service.HttpsEchoContainer
import pl.allegro.tech.servicemesh.envoycontrol.config.service.ServiceExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.service.asHttpsEchoResponse

class RoutingHeadersTest {

companion object {
private val properties = mapOf(
"envoy-control.envoy.snapshot.routing.service-tags.enabled" to true,
"envoy-control.envoy.snapshot.routing.service-tags.auto-service-tag-enabled" to true
)

@JvmField
@RegisterExtension
val consul = ConsulExtension()

@JvmField
@RegisterExtension
val envoyControl = EnvoyControlExtension(consul, properties)

@JvmField
@RegisterExtension
val echoService = GenericServiceExtension(HttpsEchoContainer())

// language=yaml
private var proxySettings = """
node:
metadata:
proxy_settings:
outgoing:
routingPolicy:
autoServiceTag: true
serviceTagPreference: ["ipsum", "lorem"]
fallbackToAnyInstance: true
dependencies:
- service: "echo"
- service: "echo-disabled"
routingPolicy:
autoServiceTag: false
- service: "echo-one-tag"
routingPolicy:
serviceTagPreference: ["one"]
- service: "echo-no-tag"
routingPolicy:
serviceTagPreference: []
""".trimIndent()

@JvmField
@RegisterExtension
val envoy = EnvoyExtension(envoyControl, config = RandomConfigFile.copy(configOverride = proxySettings))

private val allTags = listOf("ipsum", "lorem", "one")
}

@Test
fun `should add correct x-service-tag-preference header to upstream request`() {
// given
listOf("echo", "echo-disabled", "echo-one-tag", "echo-no-tag").forEach { service ->
consul.server.operations.registerService(name = service, extension = echoService, tags = allTags)
}
listOf("echo", "echo-disabled", "echo-one-tag", "echo-no-tag").forEach { service ->
waitForEndpointReady(service, echoService, envoy)
}

// when
val echoResponse = envoy.egressOperations.callService("echo").asHttpsEchoResponse()
val echoDisabledResponse = envoy.egressOperations.callService("echo-disabled").asHttpsEchoResponse()
val echoOneTagResponse = envoy.egressOperations.callService("echo-one-tag").asHttpsEchoResponse()
val echoNoTagResponse = envoy.egressOperations.callService("echo-no-tag").asHttpsEchoResponse()

// then
assertThat(echoResponse).isOk()
assertThat(echoResponse.requestHeaders).containsEntry("x-service-tag-preference", "ipsum|lorem")

assertThat(echoDisabledResponse).isOk()
assertThat(echoDisabledResponse.requestHeaders).doesNotContainKey("x-service-tag-preference")

assertThat(echoOneTagResponse).isOk()
assertThat(echoOneTagResponse.requestHeaders).containsEntry("x-service-tag-preference", "one")

assertThat(echoNoTagResponse).isOk()
assertThat(echoNoTagResponse.requestHeaders).doesNotContainKey("x-service-tag-preference")
}

@Test
fun `should not override service-tag preference header already set in the request`() {
// TODO(implement)
throw NotImplementedError("Service tag preference header already set")
}

@Test
fun `should return upstream service tags in response if service-tag preference was used`() {
// given
listOf("echo", "echo-disabled").forEach { service ->
consul.server.operations.registerService(name = service, extension = echoService, tags = allTags)
}
listOf("echo", "echo-disabled").forEach { service ->
waitForEndpointReady(service, echoService, envoy)
}

// when
val echoResponse = envoy.egressOperations.callService("echo")
val echoDisabledResponse = envoy.egressOperations.callService("echo-disabled")

// then
assertThat(echoResponse.headers("x-envoy-upstream-service-tags")).isEqualTo(listOf("""["ipsum","lorem","one"]"""))
assertThat(echoDisabledResponse.headers("x-envoy-upstream-service-tags")).isEmpty()
}

private fun waitForEndpointReady(
serviceName: String,
serviceInstance: ServiceExtension<*>,
envoy: EnvoyExtension
) {
envoy.waitForClusterEndpointHealthy(cluster = serviceName, endpointIp = serviceInstance.container().ipAddress())
}
}
Original file line number Diff line number Diff line change
@@ -1,123 +1,8 @@
package pl.allegro.tech.servicemesh.envoycontrol.routing

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import pl.allegro.tech.servicemesh.envoycontrol.assertions.isOk
import pl.allegro.tech.servicemesh.envoycontrol.config.RandomConfigFile
import pl.allegro.tech.servicemesh.envoycontrol.config.consul.ConsulExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.envoy.EnvoyExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.envoycontrol.EnvoyControlExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.service.GenericServiceExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.service.HttpsEchoContainer
import pl.allegro.tech.servicemesh.envoycontrol.config.service.ServiceExtension
import pl.allegro.tech.servicemesh.envoycontrol.config.service.asHttpsEchoResponse

class ServiceTagPreferenceTest {

companion object {
private val properties = mapOf(
"envoy-control.envoy.snapshot.routing.service-tags.enabled" to true,
"envoy-control.envoy.snapshot.routing.service-tags.auto-service-tag-enabled" to true
)

@JvmField
@RegisterExtension
val consul = ConsulExtension()

@JvmField
@RegisterExtension
val envoyControl = EnvoyControlExtension(consul, properties)

@JvmField
@RegisterExtension
val echoService = GenericServiceExtension(HttpsEchoContainer())

// language=yaml
private var proxySettings = """
node:
metadata:
proxy_settings:
outgoing:
routingPolicy:
autoServiceTag: true
serviceTagPreference: ["ipsum", "lorem"]
fallbackToAnyInstance: true
dependencies:
- service: "echo"
- service: "echo-disabled"
routingPolicy:
autoServiceTag: false
- service: "echo-one-tag"
routingPolicy:
serviceTagPreference: ["one"]
- service: "echo-no-tag"
routingPolicy:
serviceTagPreference: []
""".trimIndent()

@JvmField
@RegisterExtension
val envoy = EnvoyExtension(envoyControl, config = RandomConfigFile.copy(configOverride = proxySettings))

private val allTags = listOf("ipsum", "lorem", "one")
}

@Test
fun `should add correct x-service-tag-preference header to upstream request`() {
// given
listOf("echo", "echo-disabled", "echo-one-tag", "echo-no-tag").forEach { service ->
consul.server.operations.registerService(name = service, extension = echoService, tags = allTags)
}
listOf("echo", "echo-disabled", "echo-one-tag", "echo-no-tag").forEach { service ->
waitForEndpointReady(service, echoService, envoy)
}

// when
val echoResponse = envoy.egressOperations.callService("echo").asHttpsEchoResponse()
val echoDisabledResponse = envoy.egressOperations.callService("echo-disabled").asHttpsEchoResponse()
val echoOneTagResponse = envoy.egressOperations.callService("echo-one-tag").asHttpsEchoResponse()
val echoNoTagResponse = envoy.egressOperations.callService("echo-no-tag").asHttpsEchoResponse()

// then
assertThat(echoResponse).isOk()
assertThat(echoResponse.requestHeaders).containsEntry("x-service-tag-preference", "ipsum|lorem")

assertThat(echoDisabledResponse).isOk()
assertThat(echoDisabledResponse.requestHeaders).doesNotContainKey("x-service-tag-preference")

assertThat(echoOneTagResponse).isOk()
assertThat(echoOneTagResponse.requestHeaders).containsEntry("x-service-tag-preference", "one")

assertThat(echoNoTagResponse).isOk()
assertThat(echoNoTagResponse.requestHeaders).doesNotContainKey("x-service-tag-preference")
}

@Test
fun `should return upstream service tags in response if service-tag preference was used`() {
// given
listOf("echo", "echo-disabled").forEach { service ->
consul.server.operations.registerService(name = service, extension = echoService, tags = allTags)
}
listOf("echo", "echo-disabled").forEach { service ->
waitForEndpointReady(service, echoService, envoy)
}

// when
val echoResponse = envoy.egressOperations.callService("echo")
val echoDisabledResponse = envoy.egressOperations.callService("echo-disabled")

// then
assertThat(echoResponse.headers("x-envoy-upstream-service-tags")).isEqualTo(listOf("""["ipsum","lorem","one"]"""))
assertThat(echoDisabledResponse.headers("x-envoy-upstream-service-tags")).isEmpty()
}

private fun waitForEndpointReady(
serviceName: String,
serviceInstance: ServiceExtension<*>,
envoy: EnvoyExtension
) {
envoy.waitForClusterEndpointHealthy(cluster = serviceName, endpointIp = serviceInstance.container().ipAddress())
}
}
2 changes: 2 additions & 0 deletions envoy-control-tests/src/main/resources/envoy/empty.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# TODO: to delete
{}

0 comments on commit 29cc6bf

Please sign in to comment.