Remove redundant groovy tests and replace useful ones with java tests (#336)

Fixes: #310
This commit is contained in:
Georgios Andrianakis
2019-02-26 18:24:05 +02:00
committed by Ryan Baxter
parent a72a4ad291
commit c9a225ed1b
13 changed files with 328 additions and 587 deletions

10
pom.xml
View File

@@ -73,7 +73,6 @@
<maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
<groovy.version>2.4.12</groovy.version>
<restassured.version>3.0.2</restassured.version>
<spock-spring.version>1.1-groovy-2.4</spock-spring.version>
@@ -152,15 +151,6 @@
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>${gmavenplus-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@@ -185,19 +185,4 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,128 +0,0 @@
/*
* Copyright 2013-2019 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
*
* http://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.config
import groovy.util.logging.Slf4j
import io.fabric8.kubernetes.api.model.ConfigMapBuilder
import io.fabric8.kubernetes.api.model.SecretBuilder
import io.fabric8.kubernetes.client.Config
import io.fabric8.kubernetes.client.KubernetesClient
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer
import spock.lang.Specification
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.core.env.Environment
import org.springframework.test.context.ContextConfiguration
@Slf4j
@ContextConfiguration(classes = [TestApplication.class])
@SpringBootTest(properties = [
"spring.application.name=testapp",
"spring.cloud.kubernetes.client.namespace=testns",
"spring.cloud.kubernetes.client.trustCerts=true",
"spring.cloud.kubernetes.config.namespace=testns",
"spring.cloud.kubernetes.secrets.enableApi=true"
])
@EnableConfigurationProperties
class CoreTest extends Specification {
private static KubernetesMockServer mockServer = new KubernetesMockServer()
private static KubernetesClient mockClient
@Autowired
Environment environment
@Autowired(required = false)
Config config
@Autowired(required = false)
KubernetesClient client
def setupSpec() {
mockServer.init()
mockClient = mockServer.createClient()
mockServer.expect().get()
.withPath("/api/v1/namespaces/testns/configmaps/testapp")
.andReturn(
200,
new ConfigMapBuilder()
.withData([
'spring.kubernetes.test.value': 'value1'])
.build())
.always()
mockServer.expect().get()
.withPath("/api/v1/namespaces/testns/secrets/testapp")
.andReturn(
200,
new SecretBuilder()
.withData([
'amq.pwd': 'MWYyZDFlMmU2N2Rm',
'amq.usr': 'YWRtaW4K'
])
.build())
.always()
//Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.
getConfiguration().getMasterUrl())
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true")
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false")
System.
setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false")
}
def cleanupSpec() {
mockServer.destroy();
}
def "Kubernetes client config bean should be present"() {
expect:
config != null
}
def "Kubernetes client config bean should be configurable via system properties"() {
expect:
config.getMasterUrl().equals(mockClient.getConfiguration().getMasterUrl())
config.getNamespace().equals("testns")
config.trustCerts
}
def "Kubernetes client bean should be present"() {
expect:
client != null
}
def "Kubernetes client should be configured from system properties"() {
expect:
client.getConfiguration().getMasterUrl().
equals(mockClient.getConfiguration().getMasterUrl())
}
def "properties should be read from config map"() {
expect:
environment.getProperty("spring.kubernetes.test.value").equals("value1")
}
def "properties should be read from secrets"() {
expect:
environment.getProperty("amq.pwd").equals("1f2d1e2e67df")
environment.getProperty("amq.usr").equals('admin');
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2013-2019 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
*
* http://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.config;
import java.util.HashMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class, properties = {
"spring.application.name=testapp",
"spring.cloud.kubernetes.client.namespace=testns",
"spring.cloud.kubernetes.client.trustCerts=true",
"spring.cloud.kubernetes.config.namespace=testns",
"spring.cloud.kubernetes.secrets.enableApi=true" })
public class CoreTest {
@ClassRule
public static KubernetesServer mockServer = new KubernetesServer();
private static KubernetesClient mockClient;
@Autowired
private Environment environment;
@Autowired(required = false)
private Config config;
@Autowired(required = false)
private KubernetesClient client;
@BeforeClass
public static void setUpBeforeClass() {
mockClient = mockServer.getClient();
mockServer.expect().get().withPath("/api/v1/namespaces/testns/configmaps/testapp")
.andReturn(200,
new ConfigMapBuilder().withData(new HashMap<String, String>() {
{
put("spring.kubernetes.test.value", "value1");
}
}).build())
.always();
mockServer.expect().get().withPath("/api/v1/namespaces/testns/secrets/testapp")
.andReturn(200,
new SecretBuilder().withData(new HashMap<String, String>() {
{
put("amq.user", "YWRtaW4K");
put("amq.pwd", "MWYyZDFlMmU2N2Rm");
}
}).build())
.always();
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
mockClient.getConfiguration().getMasterUrl());
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
"false");
}
@Test
public void kubernetesClientConfigBeanShouldBeConfigurableViaSystemProperties() {
assertThat(config).isNotNull();
assertThat(config.getMasterUrl())
.isEqualTo(mockClient.getConfiguration().getMasterUrl());
assertThat(config.getNamespace()).isEqualTo("testns");
assertThat(config.isTrustCerts()).isTrue();
}
@Test
public void kubernetesClientBeanShouldBeConfigurableViaSystemProperties() {
assertThat(client).isNotNull();
assertThat(client.getConfiguration().getMasterUrl())
.isEqualTo(mockClient.getConfiguration().getMasterUrl());
}
@Test
public void propertiesShouldBeReadFromConfigMap() {
assertThat(environment.getProperty("spring.kubernetes.test.value"))
.isEqualTo("value1");
}
@Test
public void propertiesShouldBeReadFromSecret() {
assertThat(environment.getProperty("amq.user")).isEqualTo("admin");
assertThat(environment.getProperty("amq.pwd")).isEqualTo("1f2d1e2e67df");
}
}

View File

@@ -14,15 +14,16 @@
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.config
package org.springframework.cloud.kubernetes.config;
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
class TestApplication {
public class TestApplication {
def main(String[] args) {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}

View File

@@ -83,7 +83,7 @@
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>mockwebserver</artifactId>
<artifactId>kubernetes-server-mock</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -122,19 +122,4 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,239 +0,0 @@
/*
* Copyright 2013-2019 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
*
* http://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.discovery
import io.fabric8.kubernetes.api.model.EndpointsBuilder
import io.fabric8.kubernetes.api.model.ServiceBuilder
import io.fabric8.kubernetes.api.model.ServiceListBuilder
import io.fabric8.kubernetes.client.Config
import io.fabric8.kubernetes.client.KubernetesClient
import io.fabric8.kubernetes.server.mock.KubernetesMockServer
import spock.lang.Specification
import org.springframework.cloud.client.ServiceInstance
import org.springframework.cloud.client.discovery.DiscoveryClient
import static org.assertj.core.api.Assertions.assertThat
class KubernetesDiscoveryClientTest extends Specification {
private static KubernetesMockServer mockServer = new KubernetesMockServer()
private static KubernetesClient mockClient
def setupSpec() {
mockServer.init()
mockClient = mockServer.createClient()
//Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.
getConfiguration().getMasterUrl())
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true")
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false")
System.
setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false")
}
def cleanupSpec() {
mockServer.destroy()
}
def "getInstances should be able to handle endpoints single address"() {
given:
mockServer.expect().get().
withPath("/api/v1/namespaces/test/endpoints/endpoint").
andReturn(200, new EndpointsBuilder()
.withNewMetadata()
.withName("endpoint")
.endMetadata()
.addNewSubset()
.addNewAddress()
.withIp("ip1")
.endAddress()
.addNewPort("http", 80, "TCP")
.endSubset()
.build()).once()
and:
mockServer.expect().get().
withPath("/api/v1/namespaces/test/services/endpoint").
andReturn(200, new ServiceBuilder()
.withNewMetadata()
.withName("endpoint")
.withLabels(new HashMap<String, String>() {
{
put("l", "v")
}
})
.endMetadata()
.build()).once()
final properties = new KubernetesDiscoveryProperties()
DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(
mockClient, properties, { client ->
client.services()
}, new DefaultIsServicePortSecureResolver(properties))
when:
List<ServiceInstance> instances = discoveryClient.getInstances("endpoint")
then:
instances != null
instances.size() == 1
instances.find({ s -> s.host == "ip1" && !s.secure })
}
def "getInstances should be able to handle endpoints multiple addresses"() {
given:
mockServer.expect().get().
withPath("/api/v1/namespaces/test/endpoints/endpoint").
andReturn(200, new EndpointsBuilder()
.withNewMetadata()
.withName("endpoint")
.endMetadata()
.addNewSubset()
.addNewAddress()
.withIp("ip1")
.endAddress()
.addNewAddress()
.withIp("ip2")
.endAddress()
.addNewPort("https", 443, "TCP")
.endSubset()
.build()).once()
and:
mockServer.expect().get().
withPath("/api/v1/namespaces/test/services/endpoint").
andReturn(200, new ServiceBuilder()
.withNewMetadata()
.withName("endpoint")
.withLabels(new HashMap<String, String>() {
{
put("l", "v")
}
})
.endMetadata()
.build()).once()
final properties = new KubernetesDiscoveryProperties()
DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(
mockClient, properties, { client ->
client.services()
}, new DefaultIsServicePortSecureResolver(properties))
when:
List<ServiceInstance> instances = discoveryClient.getInstances("endpoint")
then:
instances != null
instances.size() == 2
instances.find({ s -> s.host == "ip1" && s.secure })
instances.find({ s -> s.host == "ip2" && s.secure })
}
def "getServices should return all services when no labels are applied to the client"() {
given:
mockServer.expect().get().withPath("/api/v1/namespaces/test/services").
andReturn(200, new ServiceListBuilder()
.addNewItem()
.withNewMetadata()
.withName("s1")
.withLabels(new HashMap<String, String>() {
{
put("label", "value")
}
})
.endMetadata()
.endItem()
.addNewItem()
.withNewMetadata()
.withName("s2")
.withLabels(new HashMap<String, String>() {
{
put("label", "value")
put("label2", "value2")
}
})
.endMetadata()
.endItem()
.addNewItem()
.withNewMetadata()
.withName("s3")
.endMetadata()
.endItem()
.build()).once()
and:
DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(
mockClient, new KubernetesDiscoveryProperties(), { client ->
client.services()
})
when:
List<String> instances = discoveryClient.getServices()
then:
assertThat(instances).containsOnly("s1", "s2", "s3")
}
def "getServices should return only matching services when labels are applied to the client"() {
given:
// this is the URL that is created by the KubernetesClient when a a label named 'label'
// with a value of 'value' is specified
mockServer.expect().get().
withPath("/api/v1/namespaces/test/services?labelSelector=label%3Dvalue").
andReturn(200, new ServiceListBuilder()
.addNewItem()
.withNewMetadata()
.withName("s1")
.withLabels(new HashMap<String, String>() {
{
put("label", "value")
}
})
.endMetadata()
.endItem()
.addNewItem()
.withNewMetadata()
.withName("s2")
.withLabels(new HashMap<String, String>() {
{
put("label", "value")
put("label2", "value2")
}
})
.endMetadata()
.endItem()
.build()).once()
and:
DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(
mockClient,
new KubernetesDiscoveryProperties(), { client ->
client.services().withLabels(["label": "value"])
})
when:
List<String> instances = discoveryClient.getServices()
then:
assertThat(instances).containsOnly("s1", "s2")
}
}

View File

@@ -0,0 +1,176 @@
/*
* Copyright 2013-2019 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
*
* http://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.discovery;
import java.util.HashMap;
import java.util.List;
import io.fabric8.kubernetes.api.model.EndpointsBuilder;
import io.fabric8.kubernetes.api.model.ServiceBuilder;
import io.fabric8.kubernetes.api.model.ServiceListBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import static org.assertj.core.api.Assertions.assertThat;
public class KubernetesDiscoveryClientTest {
@ClassRule
public static KubernetesServer mockServer = new KubernetesServer();
private static KubernetesClient mockClient;
@Before
public void setup() {
mockClient = mockServer.getClient();
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY,
mockClient.getConfiguration().getMasterUrl());
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY,
"false");
}
@Test
public void getInstancesShouldBeAbleToHandleEndpointsSingleAddress() {
mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint")
.andReturn(200,
new EndpointsBuilder().withNewMetadata().withName("endpoint")
.endMetadata().addNewSubset().addNewAddress()
.withIp("ip1").endAddress().addNewPort("http", 80, "TCP")
.endSubset().build())
.once();
mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint")
.andReturn(200, new ServiceBuilder().withNewMetadata()
.withName("endpoint").withLabels(new HashMap<String, String>() {
{
put("l", "v");
}
}).endMetadata().build())
.once();
final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient,
properties, KubernetesClient::services,
new DefaultIsServicePortSecureResolver(properties));
final List<ServiceInstance> instances = discoveryClient.getInstances("endpoint");
assertThat(instances).hasSize(1)
.filteredOn(s -> s.getHost().equals("ip1") && !s.isSecure()).hasSize(1);
}
@Test
public void getInstancesShouldBeAbleToHandleEndpointsMultipleAddresses() {
mockServer.expect().get().withPath("/api/v1/namespaces/test/endpoints/endpoint")
.andReturn(200, new EndpointsBuilder().withNewMetadata()
.withName("endpoint").endMetadata().addNewSubset().addNewAddress()
.withIp("ip1").endAddress().addNewAddress().withIp("ip2")
.endAddress().addNewPort("https", 443, "TCP").endSubset().build())
.once();
mockServer.expect().get().withPath("/api/v1/namespaces/test/services/endpoint")
.andReturn(200, new ServiceBuilder().withNewMetadata()
.withName("endpoint").withLabels(new HashMap<String, String>() {
{
put("l", "v");
}
}).endMetadata().build())
.once();
final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient,
properties, KubernetesClient::services,
new DefaultIsServicePortSecureResolver(properties));
final List<ServiceInstance> instances = discoveryClient.getInstances("endpoint");
assertThat(instances).hasSize(2).filteredOn(ServiceInstance::isSecure)
.extracting(ServiceInstance::getHost).containsOnly("ip1", "ip2");
}
@Test
public void getServicesShouldReturnAllServicesWhenNoLabelsAreAppliedToTheClient() {
mockServer.expect().get().withPath("/api/v1/namespaces/test/services")
.andReturn(200, new ServiceListBuilder().addNewItem().withNewMetadata()
.withName("s1").withLabels(new HashMap<String, String>() {
{
put("label", "value");
}
}).endMetadata().endItem().addNewItem().withNewMetadata()
.withName("s2").withLabels(new HashMap<String, String>() {
{
put("label", "value");
put("label2", "value2");
}
}).endMetadata().endItem().addNewItem().withNewMetadata()
.withName("s3").endMetadata().endItem().build())
.once();
final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient,
properties, KubernetesClient::services,
new DefaultIsServicePortSecureResolver(properties));
final List<String> services = discoveryClient.getServices();
assertThat(services).containsOnly("s1", "s2", "s3");
}
@Test
public void getServicesShouldReturnOnlyMatchingServicesWhenLabelsAreAppliedToTheClient() {
mockServer.expect().get()
.withPath("/api/v1/namespaces/test/services?labelSelector=label%3Dvalue")
.andReturn(200, new ServiceListBuilder().addNewItem().withNewMetadata()
.withName("s1").withLabels(new HashMap<String, String>() {
{
put("label", "value");
}
}).endMetadata().endItem().addNewItem().withNewMetadata()
.withName("s2").withLabels(new HashMap<String, String>() {
{
put("label", "value");
put("label2", "value2");
}
}).endMetadata().endItem().build())
.once();
final KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties();
final DiscoveryClient discoveryClient = new KubernetesDiscoveryClient(mockClient,
properties,
client -> client.services().withLabels(new HashMap<String, String>() {
{
put("label", "value");
}
}), new DefaultIsServicePortSecureResolver(properties));
final List<String> services = discoveryClient.getServices();
assertThat(services).containsOnly("s1", "s2");
}
}

View File

@@ -75,8 +75,18 @@
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>mockwebserver</artifactId>
<artifactId>kubernetes-server-mock</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
@@ -93,17 +103,6 @@
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>

View File

@@ -1,112 +0,0 @@
/*
* Copyright 2013-2019 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
*
* http://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.ribbon.test
import io.fabric8.kubernetes.api.model.EndpointsBuilder
import io.fabric8.kubernetes.client.Config
import io.fabric8.kubernetes.client.KubernetesClient
import io.fabric8.kubernetes.server.mock.KubernetesMockServer
import spock.lang.Specification
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor
import org.springframework.cloud.kubernetes.ribbon.KubernetesRibbonClientConfiguration
import org.springframework.cloud.netflix.ribbon.RibbonClient
import org.springframework.test.context.ContextConfiguration
import org.springframework.web.client.RestTemplate
@EnableAutoConfiguration
@ContextConfiguration(classes = [TestApplication.class])
@SpringBootTest(properties =
[
"spring.application.name=testapp",
"spring.cloud.kubernetes.client.namespace=testns",
"spring.cloud.kubernetes.client.trustCerts=true",
"spring.cloud.kubernetes.config.namespace=testns"
])
@RibbonClient(name = "testapp", configuration = KubernetesRibbonClientConfiguration.class)
class RibbonTest extends Specification {
private static KubernetesMockServer mockServer = new KubernetesMockServer()
private static KubernetesMockServer mockEndpointA = new KubernetesMockServer(false)
private static KubernetesMockServer mockEndpointB = new KubernetesMockServer(false)
private static KubernetesClient mockClient;
@Autowired
RestTemplate restTemplate;
@Autowired
LoadBalancerInterceptor interceptor;
def setupSpec() {
mockServer.init()
mockEndpointA.init()
mockEndpointB.init()
mockClient = mockServer.createClient()
//Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.
getConfiguration().getMasterUrl())
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true")
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false")
System.
setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false")
//Configured
mockServer.expect().get().withPath("/api/v1/namespaces/testns/endpoints/testapp").
andReturn(200, new EndpointsBuilder()
.withNewMetadata()
.withName("testapp-a")
.endMetadata()
.addNewSubset()
.addNewAddress().withIp(mockEndpointA.getServer().hostName).endAddress()
.addNewPort("http", mockEndpointA.getServer().port, "http")
.endSubset()
.addNewSubset()
.addNewAddress().withIp(mockEndpointB.getServer().hostName).endAddress()
.addNewPort("http", mockEndpointB.getServer().port, "http")
.endSubset()
.build()).always()
mockEndpointA.expect().get().withPath("/greeting").andReturn(200, "Hello from A").
always()
mockEndpointB.expect().get().withPath("/greeting").andReturn(200, "Hello from B").
always()
}
def cleanupSpec() {
mockServer.destroy()
mockEndpointA.destroy()
mockEndpointB.destroy()
}
def "A ribbon rest template should round robin over the available kubernetes endpoints"() {
given:
List<String> grettings = new ArrayList<>()
when:
for (int i = 0; i < 2; i++) {
grettings.add(restTemplate.
getForObject("http://testapp/greeting", String.class))
}
then:
grettings.contains("Hello from A")
grettings.contains("Hello from B")
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2013-2019 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
*
* http://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.ribbon.test
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.context.annotation.Bean
import org.springframework.web.client.RestTemplate
@SpringBootApplication
class TestApplication {
def main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@LoadBalanced
@Bean
def RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@@ -22,7 +22,7 @@ import java.util.List;
import io.fabric8.kubernetes.api.model.EndpointsBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.server.mock.KubernetesServer;
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
@@ -35,6 +35,8 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Charles Moulliard
*/
@@ -57,13 +59,13 @@ public class RibbonTest {
@ClassRule
public static KubernetesServer mockEndpointB = new KubernetesServer(false);
public static KubernetesClient mockClient;
private static KubernetesClient mockClient;
@Autowired
RestTemplate restTemplate;
private RestTemplate restTemplate;
@BeforeClass
public static void setUpBefore() throws Exception {
public static void setUpBefore() {
mockClient = server.getClient();
// Configure the kubernetes master url to point to the mock server
@@ -99,13 +101,13 @@ public class RibbonTest {
@Test
public void testGreetingEndpoint() {
List<String> greetings = new ArrayList<>();
for (int i = 0; i < 2; i++) {
greetings.add(this.restTemplate.getForObject("http://testapp/greeting",
String.class));
}
greetings.contains("Hello from A");
greetings.contains("Hello from B");
final List<String> greetings = new ArrayList<>();
greetings.add(
this.restTemplate.getForObject("http://testapp/greeting", String.class));
greetings.add(
this.restTemplate.getForObject("http://testapp/greeting", String.class));
assertThat(greetings).containsOnly("Hello from A", "Hello from B");
}
}

View File

@@ -18,7 +18,6 @@ package org.springframework.cloud.kubernetes.ribbon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@@ -26,7 +25,6 @@ import org.springframework.web.client.RestTemplate;
/**
* @author Charles Moulliard
*/
@EnableAutoConfiguration
@SpringBootConfiguration
public class TestApplication {