Skip to content

Commit ec6c27a

Browse files
committed
2 parents ca8edc0 + 4ab314a commit ec6c27a

File tree

7 files changed

+46
-134
lines changed
  • spring-cloud-kubernetes-integration-tests
    • spring-cloud-kubernetes-fabric8-client-catalog-watcher/src/test/java/org/springframework/cloud/kubernetes/fabric8/catalog/watch
    • spring-cloud-kubernetes-fabric8-client-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/discovery
    • spring-cloud-kubernetes-fabric8-client-istio/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/istio
  • spring-cloud-kubernetes-test-support

7 files changed

+46
-134
lines changed

spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-catalog-watcher/src/test/java/org/springframework/cloud/kubernetes/fabric8/catalog/watch/TestAssertions.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323

2424
import org.assertj.core.api.Assertions;
2525
import org.awaitility.Awaitility;
26-
import reactor.netty.http.client.HttpClient;
27-
import reactor.util.retry.Retry;
28-
import reactor.util.retry.RetryBackoffSpec;
2926

3027
import org.springframework.boot.test.system.CapturedOutput;
3128
import org.springframework.cloud.kubernetes.commons.discovery.EndpointNameAndNamespace;
@@ -34,11 +31,12 @@
3431
import org.springframework.core.ParameterizedTypeReference;
3532
import org.springframework.core.ResolvableType;
3633
import org.springframework.http.HttpMethod;
37-
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
3834
import org.springframework.web.reactive.function.client.WebClient;
3935

4036
import static org.assertj.core.api.Assertions.assertThat;
4137
import static org.awaitility.Awaitility.await;
38+
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.builder;
39+
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.retrySpec;
4240

4341
/**
4442
* @author wind57
@@ -116,12 +114,4 @@ static void invokeAndAssert(Util util, Set<String> namespaces, int port, String
116114

117115
}
118116

119-
private static WebClient.Builder builder() {
120-
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create()));
121-
}
122-
123-
private static RetryBackoffSpec retrySpec() {
124-
return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull);
125-
}
126-
127117
}

spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/discovery/TestAssertions.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,20 @@
2222
import java.util.Map;
2323
import java.util.Objects;
2424

25-
import reactor.netty.http.client.HttpClient;
26-
import reactor.util.retry.Retry;
27-
import reactor.util.retry.RetryBackoffSpec;
28-
2925
import org.springframework.boot.test.json.BasicJsonTester;
3026
import org.springframework.boot.test.system.CapturedOutput;
3127
import org.springframework.cloud.client.ServiceInstance;
3228
import org.springframework.cloud.client.discovery.DiscoveryClient;
3329
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
3430
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
3531
import org.springframework.http.HttpMethod;
36-
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
3732
import org.springframework.web.reactive.function.client.WebClient;
3833

3934
import static java.util.AbstractMap.SimpleEntry;
4035
import static java.util.Map.Entry;
4136
import static org.assertj.core.api.Assertions.assertThat;
37+
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.builder;
38+
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.retrySpec;
4239
import static org.testcontainers.shaded.org.awaitility.Awaitility.await;
4340

4441
/**
@@ -321,12 +318,4 @@ private static void waitForLogStatement(CapturedOutput output, String message) {
321318
.until(() -> output.getOut().contains(message));
322319
}
323320

324-
private static WebClient.Builder builder() {
325-
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create()));
326-
}
327-
328-
private static RetryBackoffSpec retrySpec() {
329-
return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull);
330-
}
331-
332321
}

spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-fabric8-client-istio/src/test/java/org/springframework/cloud/kubernetes/fabric8/client/istio/Fabric8IstioIT.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
package org.springframework.cloud.kubernetes.fabric8.client.istio;
1818

1919
import java.io.InputStream;
20-
import java.time.Duration;
2120
import java.util.List;
22-
import java.util.Objects;
2321

2422
import io.fabric8.kubernetes.api.model.Service;
2523
import io.fabric8.kubernetes.api.model.apps.Deployment;
@@ -31,18 +29,17 @@
3129
import org.junit.jupiter.api.Test;
3230
import org.testcontainers.containers.Container;
3331
import org.testcontainers.k3s.K3sContainer;
34-
import reactor.netty.http.client.HttpClient;
35-
import reactor.util.retry.Retry;
36-
import reactor.util.retry.RetryBackoffSpec;
3732

3833
import org.springframework.cloud.kubernetes.integration.tests.commons.Commons;
3934
import org.springframework.cloud.kubernetes.integration.tests.commons.Images;
4035
import org.springframework.cloud.kubernetes.integration.tests.commons.Phase;
4136
import org.springframework.cloud.kubernetes.integration.tests.commons.fabric8_client.Util;
4237
import org.springframework.http.HttpMethod;
43-
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
4438
import org.springframework.web.reactive.function.client.WebClient;
4539

40+
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.builder;
41+
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.retrySpec;
42+
4643
/**
4744
* @author wind57
4845
*/
@@ -133,14 +130,6 @@ private static void appManifests(Phase phase) {
133130

134131
}
135132

136-
private WebClient.Builder builder() {
137-
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create()));
138-
}
139-
140-
private RetryBackoffSpec retrySpec() {
141-
return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull);
142-
}
143-
144133
private static String istioctlPodName() {
145134
try {
146135
return K3S

spring-cloud-kubernetes-test-support/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,17 @@
2222
<groupId>org.springframework.boot</groupId>
2323
<artifactId>spring-boot-starter-test</artifactId>
2424
</dependency>
25+
26+
<dependency>
27+
<groupId>org.springframework.boot</groupId>
28+
<artifactId>spring-boot-starter-webflux</artifactId>
29+
</dependency>
30+
2531
<dependency>
2632
<groupId>io.kubernetes</groupId>
2733
<artifactId>client-java-extended</artifactId>
2834
</dependency>
35+
2936
<dependency>
3037
<groupId>io.fabric8</groupId>
3138
<artifactId>kubernetes-client</artifactId>

spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/Commons.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.time.Duration;
2727
import java.util.Arrays;
2828
import java.util.List;
29+
import java.util.Objects;
2930
import java.util.Optional;
3031
import java.util.concurrent.TimeUnit;
3132

@@ -38,10 +39,15 @@
3839
import org.junit.jupiter.api.Assertions;
3940
import org.testcontainers.containers.Container;
4041
import org.testcontainers.k3s.K3sContainer;
42+
import reactor.netty.http.client.HttpClient;
43+
import reactor.util.retry.Retry;
44+
import reactor.util.retry.RetryBackoffSpec;
4145

4246
import org.springframework.core.io.ClassPathResource;
47+
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
4348
import org.springframework.util.StreamUtils;
4449
import org.springframework.util.StringUtils;
50+
import org.springframework.web.reactive.function.client.WebClient;
4551

4652
import static org.awaitility.Awaitility.await;
4753
import static org.springframework.cloud.kubernetes.integration.tests.commons.Constants.KUBERNETES_VERSION_FILE;
@@ -264,6 +270,14 @@ public static void waitForLogStatement(String message, K3sContainer k3sContainer
264270

265271
}
266272

273+
public static WebClient.Builder builder() {
274+
return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create()));
275+
}
276+
277+
public static RetryBackoffSpec retrySpec() {
278+
return Retry.fixedDelay(15, Duration.ofSeconds(1)).filter(Objects::nonNull);
279+
}
280+
267281
private static void loadImageFromPath(String tarName, K3sContainer container) {
268282
await().atMost(Duration.ofMinutes(2)).pollInterval(Duration.ofSeconds(1)).until(() -> {
269283
Container.ExecResult result = container.execInContainer("ctr", "i", "import", TMP_IMAGES + "/" + tarName);

spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/FixedPortsK3sContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ final class FixedPortsK3sContainer extends K3sContainer {
4848
* Command to use when starting rancher. Without "server" option, traefik is not
4949
* installed
5050
*/
51-
private static final String RANCHER_COMMAND = "server";
51+
private static final String RANCHER_COMMAND = "server --disable=metric-server";
5252

5353
static final K3sContainer CONTAINER = new FixedPortsK3sContainer(DockerImageName.parse(RANCHER_VERSION))
5454
.configureFixedPorts()

spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java

Lines changed: 17 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@
2020
import java.time.Duration;
2121
import java.util.List;
2222
import java.util.Map;
23-
import java.util.Optional;
24-
import java.util.Set;
2523
import java.util.concurrent.TimeUnit;
2624

25+
import io.fabric8.kubernetes.api.model.APIService;
2726
import io.fabric8.kubernetes.api.model.ConfigMap;
2827
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
2928
import io.fabric8.kubernetes.api.model.Pod;
@@ -32,17 +31,13 @@
3231
import io.fabric8.kubernetes.api.model.Service;
3332
import io.fabric8.kubernetes.api.model.ServiceAccount;
3433
import io.fabric8.kubernetes.api.model.apps.Deployment;
35-
import io.fabric8.kubernetes.api.model.apps.DeploymentList;
3634
import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
3735
import io.fabric8.kubernetes.api.model.networking.v1.IngressLoadBalancerIngress;
38-
import io.fabric8.kubernetes.api.model.rbac.ClusterRole;
3936
import io.fabric8.kubernetes.api.model.rbac.Role;
4037
import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
4138
import io.fabric8.kubernetes.client.Config;
4239
import io.fabric8.kubernetes.client.KubernetesClient;
4340
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
44-
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
45-
import io.fabric8.kubernetes.client.dsl.base.PatchType;
4641
import io.fabric8.kubernetes.client.utils.Serialization;
4742
import jakarta.annotation.Nullable;
4843
import org.apache.commons.logging.Log;
@@ -53,7 +48,6 @@
5348
import org.springframework.cloud.kubernetes.integration.tests.commons.Phase;
5449

5550
import static org.awaitility.Awaitility.await;
56-
import static org.junit.jupiter.api.Assertions.fail;
5751
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.loadImage;
5852
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.pomVersion;
5953
import static org.springframework.cloud.kubernetes.integration.tests.commons.Commons.pullImage;
@@ -210,6 +204,22 @@ public void createNamespace(String name) {
210204

211205
public void deleteNamespace(String name) {
212206
try {
207+
208+
// sometimes we get errors like :
209+
210+
// "message": "Discovery failed for some groups,
211+
// 1 failing: unable to retrieve the complete list of server APIs:
212+
// metrics.k8s.io/v1beta1: stale GroupVersion discovery:
213+
// metrics.k8s.io/v1beta1"
214+
215+
// but even when it works OK, the finalizers are slowing down the deletion
216+
List<APIService> apiServices = client.apiServices().list().getItems();
217+
apiServices.stream()
218+
.map(apiService -> apiService.getMetadata().getName())
219+
.filter(apiServiceName -> apiServiceName.contains("metrics.k8s.io"))
220+
.findFirst()
221+
.ifPresent(apiServiceName -> client.apiServices().withName(apiServiceName).delete());
222+
213223
client.namespaces()
214224
.resource(new NamespaceBuilder().withNewMetadata().withName(name).and().build())
215225
.delete();
@@ -228,40 +238,6 @@ public void deleteNamespace(String name) {
228238

229239
}
230240

231-
public void setUpClusterWide(String serviceAccountNamespace, Set<String> namespaces) {
232-
InputStream clusterRoleBindingAsStream = inputStream("cluster/cluster-role.yaml");
233-
InputStream serviceAccountAsStream = inputStream("cluster/service-account.yaml");
234-
InputStream roleBindingAsStream = inputStream("cluster/role-binding.yaml");
235-
236-
ClusterRole clusterRole = client.rbac().clusterRoles().load(clusterRoleBindingAsStream).item();
237-
if (client.rbac().clusterRoles().withName(clusterRole.getMetadata().getName()).get() == null) {
238-
client.rbac().clusterRoles().resource(clusterRole).create();
239-
}
240-
241-
ServiceAccount serviceAccountFromStream = client.serviceAccounts().load(serviceAccountAsStream).item();
242-
serviceAccountFromStream.getMetadata().setNamespace(serviceAccountNamespace);
243-
if (client.serviceAccounts()
244-
.inNamespace(serviceAccountNamespace)
245-
.withName(serviceAccountFromStream.getMetadata().getName())
246-
.get() == null) {
247-
client.serviceAccounts().inNamespace(serviceAccountNamespace).resource(serviceAccountFromStream).create();
248-
}
249-
250-
RoleBinding roleBindingFromStream = client.rbac().roleBindings().load(roleBindingAsStream).item();
251-
namespaces.forEach(namespace -> {
252-
roleBindingFromStream.getMetadata().setNamespace(namespace);
253-
254-
if (client.rbac()
255-
.roleBindings()
256-
.inNamespace(namespace)
257-
.withName(roleBindingFromStream.getMetadata().getName())
258-
.get() == null) {
259-
client.rbac().roleBindings().inNamespace(namespace).resource(roleBindingFromStream).create();
260-
}
261-
});
262-
263-
}
264-
265241
public void createAndWait(String namespace, @Nullable ConfigMap configMap, @Nullable Secret secret) {
266242
if (configMap != null) {
267243
client.configMaps().resource(configMap).create();
@@ -469,59 +445,6 @@ public void waitForIngress(String namespace, Ingress ingress) {
469445

470446
}
471447

472-
public void patchWithReplace(String imageName, String deploymentName, String namespace, String patchBody,
473-
Map<String, String> labels) {
474-
String body = patchBody.replace("image_name_here", imageName);
475-
476-
client.apps()
477-
.deployments()
478-
.inNamespace(namespace)
479-
.withName(deploymentName)
480-
.patch(PatchContext.of(PatchType.JSON_MERGE), body);
481-
482-
waitForDeploymentAfterPatch(deploymentName, namespace, labels);
483-
}
484-
485-
private void waitForDeploymentAfterPatch(String deploymentName, String namespace, Map<String, String> labels) {
486-
try {
487-
await().pollDelay(Duration.ofSeconds(4))
488-
.pollInterval(Duration.ofSeconds(3))
489-
.atMost(60, TimeUnit.SECONDS)
490-
.until(() -> isDeploymentReadyAfterPatch(deploymentName, namespace, labels));
491-
}
492-
catch (Exception e) {
493-
throw new RuntimeException(e);
494-
}
495-
496-
}
497-
498-
private boolean isDeploymentReadyAfterPatch(String deploymentName, String namespace, Map<String, String> labels) {
499-
500-
DeploymentList deployments = client.apps().deployments().inNamespace(namespace).list();
501-
502-
if (deployments.getItems().isEmpty()) {
503-
fail("No deployment with name " + deploymentName);
504-
}
505-
506-
Deployment deployment = deployments.getItems()
507-
.stream()
508-
.filter(x -> x.getMetadata().getName().equals(deploymentName))
509-
.findFirst()
510-
.orElseThrow();
511-
// if no replicas are defined, it means only 1 is needed
512-
int replicas = Optional.ofNullable(deployment.getSpec().getReplicas()).orElse(1);
513-
514-
int numberOfPods = client.pods().inNamespace(namespace).withLabels(labels).list().getItems().size();
515-
516-
if (numberOfPods != replicas) {
517-
LOG.info("number of pods not yet stabilized");
518-
return false;
519-
}
520-
521-
return replicas == Optional.ofNullable(deployment.getStatus().getReadyReplicas()).orElse(0);
522-
523-
}
524-
525448
private void innerSetup(String namespace, InputStream serviceAccountAsStream, InputStream roleBindingAsStream,
526449
InputStream roleAsStream) {
527450
ServiceAccount serviceAccountFromStream = client.serviceAccounts()

0 commit comments

Comments
 (0)