From 3f90e222acb3f47950e1841af1b40e8876a8a73a Mon Sep 17 00:00:00 2001 From: wlodarcp Date: Thu, 7 Oct 2021 21:13:14 +0200 Subject: [PATCH] Fixed building k8s test resources --- .../k8s/K8sLabelBasedServiceLocator.java | 6 +- .../judged/agent/K8sServiceLocatorFT.groovy | 53 ++- .../k8s/K8sLabelBasedServiceLocatorUT.groovy | 358 ++++++++---------- 3 files changed, 195 insertions(+), 222 deletions(-) diff --git a/judge-d-agent/src/main/java/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocator.java b/judge-d-agent/src/main/java/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocator.java index 837a6dea..d3aa2445 100644 --- a/judge-d-agent/src/main/java/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocator.java +++ b/judge-d-agent/src/main/java/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocator.java @@ -42,7 +42,9 @@ public K8sLabelBasedServiceLocator( @Override public Set locateServices() { List namespacesToScan = kubernetesClient - .namespaces().list().getItems().stream().filter(excludedNamespacesFilter).filter(includedNamespacesFilter) + .namespaces().list().getItems().stream() + .filter(excludedNamespacesFilter) + .filter(includedNamespacesFilter) .map(n -> n.getMetadata().getName()) .collect(toList()); @@ -69,7 +71,7 @@ private Optional fromImage(String image) { imageVersion )); } else { - return Optional.empty(); + return Optional.empty(); } } diff --git a/judge-d-agent/src/test/functional/com/hltech/judged/agent/K8sServiceLocatorFT.groovy b/judge-d-agent/src/test/functional/com/hltech/judged/agent/K8sServiceLocatorFT.groovy index 3ae7bf25..37ff59c4 100644 --- a/judge-d-agent/src/test/functional/com/hltech/judged/agent/K8sServiceLocatorFT.groovy +++ b/judge-d-agent/src/test/functional/com/hltech/judged/agent/K8sServiceLocatorFT.groovy @@ -1,7 +1,13 @@ package com.hltech.judged.agent import com.github.tomakehurst.wiremock.junit.WireMockRule -import io.fabric8.kubernetes.api.model.* +import io.fabric8.kubernetes.api.model.ContainerBuilder +import io.fabric8.kubernetes.api.model.NamespaceListBuilder +import io.fabric8.kubernetes.api.model.PodBuilder +import io.fabric8.kubernetes.api.model.PodList +import io.fabric8.kubernetes.api.model.PodListBuilder +import io.fabric8.kubernetes.api.model.PodSpecBuilder +import io.fabric8.kubernetes.api.model.PodStatusBuilder import io.fabric8.kubernetes.client.Config import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer import org.springframework.beans.factory.annotation.Value @@ -12,7 +18,11 @@ import spock.lang.Specification import java.util.concurrent.TimeUnit -import static com.github.tomakehurst.wiremock.client.WireMock.* +import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson +import static com.github.tomakehurst.wiremock.client.WireMock.ok +import static com.github.tomakehurst.wiremock.client.WireMock.put +import static com.github.tomakehurst.wiremock.client.WireMock.putRequestedFor +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching import static org.awaitility.Awaitility.await @SpringBootTest @@ -44,23 +54,25 @@ class K8sServiceLocatorFT extends Specification { } def 'should send update services message with expected names and versions'() { - given: "expected namespaces" + given: 'expected namespaces' k8sServer.expect().get().withPath('/api/v1/namespaces') .andReturn(200, new NamespaceListBuilder() .addNewItem() .withNewMetadata() .withName('firstnamespace') + .withLabels([:]) .endMetadata() .and() .addNewItem() .withNewMetadata() .withName('secondnamespace') + .withLabels([:]) .endMetadata() .and() .build()) .always() - and: "expected pods" + and: 'expected pods' PodList expectedPodList = new PodListBuilder() .withItems( buildPod('firstnamespace', 1, '78d588f9cc'), @@ -72,23 +84,23 @@ class K8sServiceLocatorFT extends Specification { .andReturn(HttpURLConnection.HTTP_OK, expectedPodList) .always() - and: "expected message to publish" + and: 'expected message to publish' def expectedRequestBody = ''' - [ - { - "name": "test_app_1", - "version": "78d588f9cc" - }, - { - "name": "test_app_2", - "version": "54d576f9dh" - }, - { - "name": "test_app_3", - "version": "98d500g9df" - } - ] - ''' + [ + { + "name": "test_app_1", + "version": "78d588f9cc" + }, + { + "name": "test_app_2", + "version": "54d576f9dh" + }, + { + "name": "test_app_3", + "version": "98d500g9df" + } + ] + ''' wireMockRule.stubFor( put(urlPathMatching('/environments/test')) @@ -106,6 +118,7 @@ class K8sServiceLocatorFT extends Specification { new PodBuilder().withNewMetadata() .withName("pod$index") .withNamespace(namespace) + .withLabels([:]) .endMetadata() .withSpec( new PodSpecBuilder().withContainers( diff --git a/judge-d-agent/src/test/unit/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocatorUT.groovy b/judge-d-agent/src/test/unit/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocatorUT.groovy index d0e2d642..e5cdd149 100644 --- a/judge-d-agent/src/test/unit/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocatorUT.groovy +++ b/judge-d-agent/src/test/unit/com/hltech/judged/agent/k8s/K8sLabelBasedServiceLocatorUT.groovy @@ -1,243 +1,201 @@ package com.hltech.judged.agent.k8s - -import io.fabric8.kubernetes.api.model.Container -import io.fabric8.kubernetes.api.model.Initializers -import io.fabric8.kubernetes.api.model.ListMeta +import io.fabric8.kubernetes.api.model.ContainerBuilder +import io.fabric8.kubernetes.api.model.ListMetaBuilder import io.fabric8.kubernetes.api.model.Namespace import io.fabric8.kubernetes.api.model.NamespaceList import io.fabric8.kubernetes.api.model.NamespaceSpec -import io.fabric8.kubernetes.api.model.NamespaceStatus -import io.fabric8.kubernetes.api.model.ObjectMeta +import io.fabric8.kubernetes.api.model.NamespaceStatusBuilder +import io.fabric8.kubernetes.api.model.ObjectMetaBuilder import io.fabric8.kubernetes.api.model.Pod import io.fabric8.kubernetes.api.model.PodList -import io.fabric8.kubernetes.api.model.PodSpec -import io.fabric8.kubernetes.api.model.PodStatus +import io.fabric8.kubernetes.api.model.PodSpecBuilder +import io.fabric8.kubernetes.api.model.PodStatusBuilder import io.fabric8.kubernetes.client.KubernetesClient import io.fabric8.kubernetes.client.dsl.FilterWatchListMultiDeletable import io.fabric8.kubernetes.client.dsl.MixedOperation import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation import spock.lang.Specification -import static com.google.common.collect.Lists.newArrayList -import static com.google.common.collect.Maps.newHashMap import static com.google.common.collect.Sets.newHashSet class K8sLabelBasedServiceLocatorUT extends Specification { - private String label - private KubernetesClient kubernetesClient - - def setup(){ - label = "label" - kubernetesClient = Mock() - } + def label = 'label' + def kubernetesClient = Mock(KubernetesClient) - def 'should find all but excluded pods' (){ + def 'should find all but excluded pods'() { given: - def serviceLocator = new K8sLabelBasedServiceLocator(kubernetesClient, label, newHashSet("excluded"), newHashSet()) - - MixedOperation mixedOperation = Mock() - FilterWatchListMultiDeletable watchList = Mock() - PodList podList = new PodList("1.0", [ - randomPod("s1", "hltech/s1:1", "default", new HashMap()), - randomPod("s2", "hltech/s2:2", "excluded", new HashMap()), - ] as List, - "Pod", - new ListMeta("1.0", "") - ) - watchList.withLabel(label) >> watchList - watchList.list() >> podList - - mixedOperation.inAnyNamespace() >> watchList - kubernetesClient.pods() >> mixedOperation - - NonNamespaceOperation namespacesOperation = Mock() - namespacesOperation.list() >> new NamespaceList("1.0", [ - newNamespace("default"), - newNamespace("excluded") - ] as List, "Namespace", new ListMeta("1.0", "")) - kubernetesClient.namespaces() >> namespacesOperation + def serviceLocator = new K8sLabelBasedServiceLocator(kubernetesClient, label, newHashSet('excluded'), newHashSet()) + + def mixedOperation = Mock(MixedOperation) + def watchList = Mock(FilterWatchListMultiDeletable) + def podList = new PodList('1.0', [ + buildPod('s1', 'hltech/s1:1', 'default', [:]), + buildPod('s2', 'hltech/s2:2', 'excluded', [:]), + ], + 'Pod', + buildListMeta() + ) + watchList.withLabel(label) >> watchList + watchList.list() >> podList + + mixedOperation.inAnyNamespace() >> watchList + kubernetesClient.pods() >> mixedOperation + + NonNamespaceOperation namespacesOperation = Mock() + namespacesOperation.list() >> new NamespaceList('1.0', [ + newNamespace('default'), + newNamespace('excluded') + ], + 'Namespace', + buildListMeta() + ) + kubernetesClient.namespaces() >> namespacesOperation when: - def services = serviceLocator.locateServices() + def services = serviceLocator.locateServices() then: - services.size() == 1 - services.find {it.name == "s1"} .version == "1" + services.size() == 1 + services.find { it.name == 's1' }.version == '1' } - def 'should find only included pods' (){ + def 'should find only included pods'() { given: - def serviceLocator = new K8sLabelBasedServiceLocator(kubernetesClient, label, newHashSet(), newHashSet("included")) - - MixedOperation mixedOperation = Mock() - FilterWatchListMultiDeletable watchList = Mock() - PodList podList = new PodList("1.0", [ - randomPod("s1", "hltech/s1:1", "default", new HashMap()), - randomPod("s2", "hltech/s2:2", "included", new HashMap()), - ] as List, - "Pod", - new ListMeta("1.0", "") - ) - watchList.withLabel(label) >> watchList - watchList.list() >> podList - - mixedOperation.inAnyNamespace() >> watchList - kubernetesClient.pods() >> mixedOperation - - NonNamespaceOperation namespacesOperation = Mock() - namespacesOperation.list() >> new NamespaceList("1.0", [ - newNamespace("default"), - newNamespace("included") - ] as List, "Namespace", new ListMeta("1.0", "")) - kubernetesClient.namespaces() >> namespacesOperation + def serviceLocator = new K8sLabelBasedServiceLocator(kubernetesClient, label, newHashSet(), newHashSet('included')) + + def mixedOperation = Mock(MixedOperation) + def watchList = Mock(FilterWatchListMultiDeletable) + def podList = new PodList('1.0', [ + buildPod('s1', 'hltech/s1:1', 'default', [:]), + buildPod('s2', 'hltech/s2:2', 'included', [:]), + ], + 'Pod', + buildListMeta() + ) + watchList.withLabel(label) >> watchList + watchList.list() >> podList + + mixedOperation.inAnyNamespace() >> watchList + kubernetesClient.pods() >> mixedOperation + + NonNamespaceOperation namespacesOperation = Mock() + namespacesOperation.list() >> new NamespaceList('1.0', [ + newNamespace('default'), + newNamespace('included') + ], + 'Namespace', + buildListMeta() + ) + kubernetesClient.namespaces() >> namespacesOperation when: - def services = serviceLocator.locateServices() + def services = serviceLocator.locateServices() then: - services.size() == 1 - services.find {it.name == "s2"} .version == "2" + services.size() == 1 + services.find { it.name == 's2' }.version == '2' } - def 'should find all correctly configured services'(){ + def 'should find all correctly configured services'() { given: - def serviceLocator = new K8sLabelBasedServiceLocator(kubernetesClient, label, newHashSet(), newHashSet()) - def service1Name = "service1" - def service1Version = "1.0" - def service2Name = "service2" - def service2Version = "2.0" - def service3Name = "service3" - def service3Version = "3.0" - def service4Name = "service4" - def service5Name = "service5" - def service5Version = "service6" - - MixedOperation mixedOperation = Mock() - FilterWatchListMultiDeletable watchList = Mock() - PodList podList = new PodList("1.0", [ - randomPod(service1Name, "hltech/" + service1Name + ":" + service1Version, "default", new HashMap()), - randomPod(service2Name, "hltech/" + service2Name + ":" + service2Version, "default", new HashMap()), - randomPod(service3Name, service3Name + ":" + service3Version, "default", new HashMap()), - randomPod(service4Name, service4Name, "default", new HashMap()), - randomPod(service5Name, "hltech/" + service5Name + ":" + service5Version, "default", ['exclude-from-judged-jurisdiction': 'true']), - ] as List, - "Pod", - new ListMeta("1.0", "") - ) - watchList.withLabel(label) >> watchList - watchList.list() >> podList - - mixedOperation.inAnyNamespace() >> watchList - kubernetesClient.pods() >> mixedOperation - - NonNamespaceOperation namespacesOperation = Mock() - namespacesOperation.list() >> new NamespaceList("1.0", [newNamespace("default")] as List, "Namespace", new ListMeta("1.0", "")) - kubernetesClient.namespaces() >> namespacesOperation + def serviceLocator = new K8sLabelBasedServiceLocator(kubernetesClient, label, newHashSet(), newHashSet()) + def service1Name = 'service1' + def service1Version = '1.0' + def service2Name = 'service2' + def service2Version = '2.0' + def service3Name = 'service3' + def service3Version = '3.0' + def service4Name = 'service4' + def service5Name = 'service5' + def service5Version = 'service6' + + def mixedOperation = Mock(MixedOperation) + def watchList = Mock(FilterWatchListMultiDeletable) + def podList = new PodList('1.0', [ + buildPod(service1Name, 'hltech/' + service1Name + ':' + service1Version, 'default', new HashMap()), + buildPod(service2Name, 'hltech/' + service2Name + ':' + service2Version, 'default', new HashMap()), + buildPod(service3Name, service3Name + ':' + service3Version, 'default', new HashMap()), + buildPod(service4Name, service4Name, 'default', new HashMap()), + buildPod(service5Name, 'hltech/' + service5Name + ':' + service5Version, 'default', ['exclude-from-judged-jurisdiction': 'true']), + ], + 'Pod', + buildListMeta() + ) + watchList.withLabel(label) >> watchList + watchList.list() >> podList + + mixedOperation.inAnyNamespace() >> watchList + kubernetesClient.pods() >> mixedOperation + + NonNamespaceOperation namespacesOperation = Mock() + namespacesOperation.list() >> new NamespaceList('1.0', [newNamespace('default')], 'Namespace', buildListMeta()) + kubernetesClient.namespaces() >> namespacesOperation when: - def services = serviceLocator.locateServices() + def services = serviceLocator.locateServices() then: - services.size() == 3 - services.find {it.name == "service1"} .version == "1.0" - services.find {it.name == "service2"} .version == "2.0" - services.find {it.name == "service3"} .version == "3.0" + services.size() == 3 + services.find { it.name == 'service1' }.version == '1.0' + services.find { it.name == 'service2' }.version == '2.0' + services.find { it.name == 'service3' }.version == '3.0' } def newNamespace(String namespaceName) { - def meta = new ObjectMeta() - meta.setName(namespaceName) + def meta = new ObjectMetaBuilder() + .withName(namespaceName) + .withNamespace(namespaceName) + .build() return new Namespace( - "1.0", - "Namespace", + '1.0', + 'Namespace', meta, - new NamespaceSpec( - ["kubernetes"] as List - ), - new NamespaceStatus( - "Active" - ) + new NamespaceSpec(['kubernetes']), + buildNamespaceStatus('Active') ) } - def randomPod(String serviceName, String imageName, String namespace, Map podLabels) { + def buildPod(String serviceName, String imageName, String namespace, Map podLabels) { return new Pod( - "1.0", - "Pod", - new ObjectMeta( - newHashMap(), - "clusterName", - "2018", - 5, - "2018", - newArrayList(), - serviceName, - 1, - new Initializers(newArrayList(), null), - podLabels, - serviceName, - namespace, - newArrayList(), - "1.0", - "", - "" - ), - new PodSpec( - 1, - null, - true, - newArrayList( - new Container( - newArrayList(), - newArrayList(), - newArrayList(), - newArrayList(), - imageName, - "", - null, - null, - "", - newArrayList(), - null, - null, - null, - true, - true, - "", - "", - true, - newArrayList(), - "" - ) - ), - "", - newArrayList(), - true, - true, - true, - "", - newArrayList(), - newArrayList(), - "", - newHashMap(), - "always", - "", - null, - "sa", - "sa", - "com", - 10, - newArrayList(), - newArrayList() - ), - new PodStatus( - newArrayList(), - newArrayList(), - "", - newArrayList(), - "", - "running", - "", - "qosClass", - "reason", - "2018" - ) + '1.0', + 'Pod', + buildObjectMeta(serviceName, namespace, podLabels), + buildPodSpec(imageName), + buildPodStatus('running') ) } + + def buildListMeta() { + new ListMetaBuilder() + .withResourceVersion('1.0') + .build() + } + + def buildObjectMeta(String serviceName, String namespace, Map podLabels) { + new ObjectMetaBuilder() + .withName(serviceName) + .withNamespace(namespace) + .withLabels(podLabels) + .build() + } + + def buildPodSpec(String imageNme) { + new PodSpecBuilder() + .withContainers([buildContainer(imageNme)]) + .build() + } + + def buildContainer(String imageName) { + new ContainerBuilder() + .withImage(imageName) + .build() + } + + def buildPodStatus(String phase) { + new PodStatusBuilder() + .withPhase(phase) + .build() + } + + def buildNamespaceStatus(String phase) { + new NamespaceStatusBuilder() + .withPhase(phase) + .build() + } }