Skip to content

Commit

Permalink
Refactor loadbalancer it test (14) (#1443)
Browse files Browse the repository at this point in the history
  • Loading branch information
wind57 committed Sep 20, 2023
1 parent 99a455e commit fb656dd
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,61 @@
import io.kubernetes.client.openapi.models.V1Deployment;
import io.kubernetes.client.openapi.models.V1Ingress;
import io.kubernetes.client.openapi.models.V1Service;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.testcontainers.k3s.K3sContainer;
import reactor.netty.http.client.HttpClient;
import reactor.util.retry.Retry;
import reactor.util.retry.RetryBackoffSpec;

import org.springframework.boot.test.json.BasicJsonTester;
import org.springframework.cloud.kubernetes.integration.tests.commons.Commons;
import org.springframework.cloud.kubernetes.integration.tests.commons.Phase;
import org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;

import static org.springframework.cloud.kubernetes.integration.tests.commons.native_client.Util.patchWithMerge;

/**
* @author Ryan Baxter
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class LoadBalancerIT {

private static final BasicJsonTester BASIC_JSON_TESTER = new BasicJsonTester(LoadBalancerIT.class);

private static final String BODY_FOR_MERGE = """
{
"spec": {
"template": {
"spec": {
"containers": [{
"name": "spring-cloud-kubernetes-client-loadbalancer-it",
"env": [
{
"name": "SPRING_CLOUD_KUBERNETES_LOADBALANCER_MODE",
"value": "SERVICE"
}
]
}]
}
}
}
}
""";

private static final Map<String, String> POD_LABELS = Map.of("app",
"spring-cloud-kubernetes-client-loadbalancer-it");

private static final String SERVICE_URL = "http://localhost:80/loadbalancer-it/service";

private static final String SPRING_CLOUD_K8S_LOADBALANCER_APP_NAME = "spring-cloud-kubernetes-client-loadbalancer-it";
Expand All @@ -65,10 +95,12 @@ static void beforeAll() throws Exception {
Commons.loadSpringCloudKubernetesImage(SPRING_CLOUD_K8S_LOADBALANCER_APP_NAME, K3S);
util = new Util(K3S);
util.setUp(NAMESPACE);
loadbalancerIt(Phase.CREATE);
}

@AfterAll
static void afterAll() throws Exception {
loadbalancerIt(Phase.DELETE);
Commons.cleanUp(SPRING_CLOUD_K8S_LOADBALANCER_APP_NAME, K3S);
Commons.systemPrune();
}
Expand All @@ -84,39 +116,32 @@ void afterEach() {
}

@Test
void testLoadBalancerServiceMode() {
loadbalancerIt(false, Phase.CREATE);
@Order(1)
void testLoadBalancerPodMode() {
testLoadBalancer();
loadbalancerIt(false, Phase.DELETE);
}

@Test
void testLoadBalancerPodMode() {
loadbalancerIt(true, Phase.CREATE);
@Order(2)
void testLoadBalancerServiceMode() {
patchForServiceMode("spring-cloud-kubernetes-client-loadbalancer-it-deployment", NAMESPACE);
testLoadBalancer();
loadbalancerIt(true, Phase.DELETE);
}

private void testLoadBalancer() {

WebClient.Builder builder = builder();
WebClient serviceClient = builder.baseUrl(SERVICE_URL).build();

ResolvableType resolvableType = ResolvableType.forClassWithGenerics(Map.class, String.class, Object.class);
@SuppressWarnings("unchecked")
Map<String, Object> result = (Map<String, Object>) serviceClient.method(HttpMethod.GET).retrieve()
.bodyToMono(ParameterizedTypeReference.forType(resolvableType.getType())).retryWhen(retrySpec())
.block();

Assertions.assertTrue(result.containsKey("mappings"));
Assertions.assertTrue(result.containsKey("meta"));

String result = serviceClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).block();
Assertions.assertThat(BASIC_JSON_TESTER.from(result)).extractingJsonPathArrayValue("$.mappings").isEmpty();
Assertions.assertThat(BASIC_JSON_TESTER.from(result)).extractingJsonPathNumberValue("$.meta.total")
.isEqualTo(0);
}

private void loadbalancerIt(boolean podBased, Phase phase) {
V1Deployment deployment = podBased
? (V1Deployment) util.yaml("spring-cloud-kubernetes-client-loadbalancer-pod-it-deployment.yaml")
: (V1Deployment) util.yaml("spring-cloud-kubernetes-client-loadbalancer-service-it-deployment.yaml");
private static void loadbalancerIt(Phase phase) {
V1Deployment deployment = (V1Deployment) util
.yaml("spring-cloud-kubernetes-client-loadbalancer-pod-it-deployment.yaml");
V1Service service = (V1Service) util.yaml("spring-cloud-kubernetes-client-loadbalancer-it-service.yaml");
V1Ingress ingress = (V1Ingress) util.yaml("spring-cloud-kubernetes-client-loadbalancer-it-ingress.yaml");

Expand All @@ -136,4 +161,8 @@ private RetryBackoffSpec retrySpec() {
return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull);
}

private static void patchForServiceMode(String deploymentName, String namespace) {
patchWithMerge(deploymentName, namespace, BODY_FOR_MERGE, POD_LABELS);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.kubernetes.discoveryclient.it;

import java.time.Duration;
import java.util.Objects;

import org.assertj.core.api.Assertions;
import reactor.netty.http.client.HttpClient;
import reactor.util.retry.Retry;
import reactor.util.retry.RetryBackoffSpec;

import org.springframework.boot.test.json.BasicJsonTester;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;

/**
* @author mbialkowski1
*/
final class DiscoveryClientFilterNamespaceDelegate {

private static final BasicJsonTester BASIC_JSON_TESTER = new BasicJsonTester(
DiscoveryClientFilterNamespaceDelegate.class);

static void testNamespaceDiscoveryClient() {
testLoadBalancer();
testHealth();
}

private static void testLoadBalancer() {

WebClient.Builder builder = builder();
WebClient serviceClient = builder.baseUrl("http://localhost:80/discoveryclient-it/services").build();
String result = serviceClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec())
.block();

Assertions.assertThat(BASIC_JSON_TESTER.from(result)).extractingJsonPathArrayValue("$")
.contains("service-wiremock");

// ServiceInstance
WebClient serviceInstanceClient = builder
.baseUrl("http://localhost:80/discoveryclient-it/service/service-wiremock").build();
String serviceInstances = serviceInstanceClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class)
.retryWhen(retrySpec()).block();

Assertions.assertThat(BASIC_JSON_TESTER.from(serviceInstances)).extractingJsonPathStringValue("$.[0].serviceId")
.isEqualTo("service-wiremock");

Assertions.assertThat(BASIC_JSON_TESTER.from(serviceInstances)).extractingJsonPathStringValue("$.[0].namespace")
.isEqualTo("left");
}

private static void testHealth() {
WebClient.Builder builder = builder();
WebClient serviceClient = builder.baseUrl("http://localhost:80/discoveryclient-it/actuator/health").build();

String health = serviceClient.method(HttpMethod.GET).retrieve().bodyToMono(String.class).retryWhen(retrySpec())
.block();

Assertions.assertThat(BASIC_JSON_TESTER.from(health))
.extractingJsonPathStringValue("$.components.discoveryComposite.status").isEqualTo("UP");
}

private static WebClient.Builder builder() {
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create()));
}

private static RetryBackoffSpec retrySpec() {
return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull);
}

}
Loading

0 comments on commit fb656dd

Please sign in to comment.