Migrated all groovy tests from core

This commit is contained in:
Marcin Grzejszczak
2016-04-29 16:59:11 +02:00
parent 2d88f84b1d
commit 832440733e
9 changed files with 250 additions and 259 deletions

View File

@@ -203,6 +203,12 @@
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.toomuchcoding.jsonassert</groupId>
<artifactId>jsonassert</artifactId>
<version>0.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -169,6 +169,11 @@
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.toomuchcoding.jsonassert</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,32 +0,0 @@
/*
* Copyright 2013-2015 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.zookeeper.discovery
trait PollingUtils {
Closure willPass(Closure closure) {
return {
try {
closure()
} catch (Exception e) {
AssertionError assertionError = new AssertionError("Exception occurred while evaluating closure", e)
System.err.println(assertionError)
throw assertionError
}
}
}
}

View File

@@ -1,20 +0,0 @@
package org.springframework.cloud.zookeeper.discovery
import spock.lang.Specification
/**
* @author Marcin Grzejszczak
*/
class ZookeeperDiscoveryClientSpec extends Specification {
def "should return an empty list of services if service discovery is null"() {
given:
ZookeeperServiceDiscovery serviceDiscovery = Stub()
ZookeeperDiscoveryClient zookeeperDiscoveryClient = new ZookeeperDiscoveryClient(serviceDiscovery, null)
when:
List<String> services = zookeeperDiscoveryClient.getServices()
then:
assert services.empty
}
}

View File

@@ -0,0 +1,24 @@
package org.springframework.cloud.zookeeper.discovery;
import java.util.List;
import org.junit.Test;
import static org.assertj.core.api.BDDAssertions.then;
import static org.mockito.Mockito.mock;
/**
* @author Marcin Grzejszczak
*/
public class ZookeeperDiscoveryClientTests {
@Test public void should_return_an_empty_list_of_services_if_service_discovery_is_null() {
// given:
ZookeeperServiceDiscovery serviceDiscovery = mock(ZookeeperServiceDiscovery.class);
ZookeeperDiscoveryClient zookeeperDiscoveryClient = new ZookeeperDiscoveryClient(serviceDiscovery, null);
// when:
List<String> services = zookeeperDiscoveryClient.getServices();
// then:
then(services).isEmpty();
}
}

View File

@@ -1,79 +0,0 @@
package org.springframework.cloud.zookeeper.discovery
import groovy.json.JsonSlurper
import org.apache.curator.framework.CuratorFramework
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.SpringApplicationContextLoader
import org.springframework.boot.test.WebIntegrationTest
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.cloud.zookeeper.discovery.test.CommonTestConfig
import org.springframework.cloud.zookeeper.discovery.test.TestRibbonClient
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.Profile
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.ContextConfiguration
import org.springframework.web.client.RestTemplate
import spock.lang.Issue
import spock.lang.Specification
import javax.annotation.PostConstruct
import javax.annotation.PreDestroy
@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
@ActiveProfiles('nestedstructure')
@WebIntegrationTest(randomPort = true)
class ZookeeperDiscoveryHealthIndicatorWithNestedStructureISpec extends Specification implements PollingUtils {
@Autowired TestRibbonClient testRibbonClient
@Issue("#54 - ZookeeperDiscoveryHealthIndicator fails on nested structure")
def 'should return a response that app is in a healthy state when nested folders in zookeeper are present'() {
when:
String response = testRibbonClient.callService('me', 'health')
then:
twoServicesArePresentedInHealthEndpoint(response)
}
private boolean twoServicesArePresentedInHealthEndpoint(String response) {
def services = new JsonSlurper().parseText(response).zookeeperDiscovery.services
assert ['me', '/a/b/c/d/anotherservice'].every { expectedServiceName ->
services.any { service ->
expectedServiceName == service.name
}
}
return true
}
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
@Import(CommonTestConfig)
@Profile('nestedstructure')
static class Config {
@Autowired CuratorFramework curatorFramework
CustomZookeeperServiceDiscovery customZookeeperServiceDiscovery
@PostConstruct
void registerNestedDependency() {
customZookeeperServiceDiscovery = new CustomZookeeperServiceDiscovery("/a/b/c/d/anotherservice",
'/services', curatorFramework).build()
}
@PreDestroy
void unregisterServiceDiscovery() {
customZookeeperServiceDiscovery?.close()
}
@Bean
TestRibbonClient testRibbonClient(@LoadBalanced RestTemplate restTemplate,
@Value('${spring.application.name}') String springAppName) {
return new TestRibbonClient(restTemplate, springAppName)
}
}
}

View File

@@ -0,0 +1,88 @@
package org.springframework.cloud.zookeeper.discovery;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import com.toomuchcoding.jsonassert.JsonAssertion;
import org.apache.curator.framework.CuratorFramework;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.zookeeper.discovery.test.CommonTestConfig;
import org.springframework.cloud.zookeeper.discovery.test.TestRibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;
import groovy.json.JsonSlurper;
import spock.lang.Issue;
import static com.toomuchcoding.jsonassert.JsonAssertion.*;
/**
* @author Marcin Grzejszczak
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ZookeeperDiscoveryHealthIndicatorWithNestedStructureTests.Config.class)
@ActiveProfiles("nestedstructure")
@WebIntegrationTest(randomPort = true)
public class ZookeeperDiscoveryHealthIndicatorWithNestedStructureTests {
@Autowired TestRibbonClient testRibbonClient;
// Issue: #54 - ZookeeperDiscoveryHealthIndicator fails on nested structure
@Test public void should_return_a_response_that_app_is_in_a_healthy_state_when_nested_folders_in_zookeeper_are_present() {
// when:
String response = this.testRibbonClient.callService("me", "health");
// then:
twoServicesArePresentedInHealthEndpoint(response);
}
private boolean twoServicesArePresentedInHealthEndpoint(String response) {
assertThat(response).field("zookeeperDiscovery").array("services").field("name").isEqualTo("me");
assertThat(response).field("zookeeperDiscovery").array("services").field("name").isEqualTo("/a/b/c/d/anotherservice");
return true;
}
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient
@Import(CommonTestConfig.class)
@Profile("nestedstructure")
static class Config {
@Autowired CuratorFramework curatorFramework;
CustomZookeeperServiceDiscovery customZookeeperServiceDiscovery;
@PostConstruct
void registerNestedDependency() {
this.customZookeeperServiceDiscovery = new CustomZookeeperServiceDiscovery("/a/b/c/d/anotherservice",
"/services", this.curatorFramework);
this.customZookeeperServiceDiscovery.build();
}
@PreDestroy
void unregisterServiceDiscovery() {
if (this.customZookeeperServiceDiscovery != null) {
this.customZookeeperServiceDiscovery.close();
}
}
@Bean TestRibbonClient testRibbonClient(@LoadBalanced RestTemplate restTemplate,
@Value("${spring.application.name}") String springAppName) {
return new TestRibbonClient(restTemplate, springAppName);
}
}
}

View File

@@ -1,128 +0,0 @@
/*
* Copyright 2013-2015 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.zookeeper.discovery
import groovy.json.JsonSlurper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.SpringApplicationContextLoader
import org.springframework.boot.test.WebIntegrationTest
import org.springframework.cloud.client.ServiceInstance
import org.springframework.cloud.client.discovery.DiscoveryClient
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.cloud.netflix.feign.EnableFeignClients
import org.springframework.cloud.netflix.feign.FeignClient
import org.springframework.cloud.zookeeper.discovery.test.CommonTestConfig
import org.springframework.cloud.zookeeper.discovery.test.TestRibbonClient
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Controller
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.ContextConfiguration
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.client.RestTemplate
import spock.lang.Specification
import spock.util.concurrent.PollingConditions
@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
@ActiveProfiles('ribbon')
@WebIntegrationTest(randomPort = true)
class ZookeeperDiscoveryISpec extends Specification implements PollingUtils {
@Autowired TestRibbonClient testRibbonClient
@Autowired DiscoveryClient discoveryClient
@Autowired ZookeeperServiceDiscovery serviceDiscovery
@Value('${spring.application.name}') String springAppName
@Autowired IdUsingFeignClient idUsingFeignClient
PollingConditions conditions = new PollingConditions()
def 'should find the app by its name via Ribbon'() {
expect:
'UP' == registeredServiceStatusViaServiceName()
}
def 'should find a collaborator via discovery client'() {
given:
List<ServiceInstance> instances = discoveryClient.getInstances(springAppName)
ServiceInstance instance = instances.first()
expect:
'UP' == registeredServiceStatus(instance)
'testMetadataValue' == instance.metadata.get('testMetadataKey')
}
def 'should present application name as id of the service instance'() {
given:
ServiceInstance instance = discoveryClient.getLocalServiceInstance()
expect:
springAppName == instance.serviceId
}
def 'should find an instance using feign via service id'() {
expect:
conditions.eventually willPass {
assert idUsingFeignClient.beans
}
}
private String registeredServiceStatusViaServiceName() {
return new JsonSlurper().parseText(testRibbonClient.thisHealthCheck()).status
}
private String registeredServiceStatus(ServiceInstance instance) {
return new JsonSlurper().parseText(testRibbonClient.callOnUrl("${instance.host}:${instance.port}", 'health')).status
}
def 'should properly find local instance'() {
expect:
serviceDiscovery.serviceInstance.address == discoveryClient.localServiceInstance.host
}
@FeignClient("ribbonApp")
public static interface IdUsingFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/beans")
String getBeans();
}
@Configuration
@EnableAutoConfiguration
@Import(CommonTestConfig)
@EnableDiscoveryClient
@EnableFeignClients(clients = [IdUsingFeignClient])
@Profile('ribbon')
static class Config {
@Bean
TestRibbonClient testRibbonClient(@LoadBalanced RestTemplate restTemplate,
@Value('${spring.application.name}') String springAppName) {
return new TestRibbonClient(restTemplate, springAppName)
}
}
@Controller
@Profile('ribbon')
class PingController {
@RequestMapping('/ping') String ping() {
return 'pong'
}
}
}

View File

@@ -0,0 +1,127 @@
package org.springframework.cloud.zookeeper.discovery;
import java.util.List;
import java.util.concurrent.Callable;
import com.jayway.awaitility.Awaitility;
import com.toomuchcoding.jsonassert.JsonAssertion;
import com.toomuchcoding.jsonassert.JsonPath;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.zookeeper.discovery.test.CommonTestConfig;
import org.springframework.cloud.zookeeper.discovery.test.TestRibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.BDDAssertions.then;
/**
* @author Marcin Grzejszczak
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(ZookeeperDiscoveryTests.Config.class)
@ActiveProfiles("ribbon")
@WebIntegrationTest(randomPort = true)
public class ZookeeperDiscoveryTests {
@Autowired TestRibbonClient testRibbonClient;
@Autowired DiscoveryClient discoveryClient;
@Autowired ZookeeperServiceDiscovery serviceDiscovery;
@Value("${spring.application.name}") String springAppName;
@Autowired IdUsingFeignClient idUsingFeignClient;
@Test public void should_find_the_app_by_its_name_via_Ribbon() {
//expect:
then(registeredServiceStatusViaServiceName()).isEqualTo("UP");
}
@Test public void should_find_a_collaborator_via_discovery_client() {
//given:
List<ServiceInstance> instances = this.discoveryClient.getInstances(this.springAppName);
ServiceInstance instance = instances.get(0);
//expect:
then(registeredServiceStatus(instance)).isEqualTo("UP");
then(instance.getMetadata().get("testMetadataKey")).isEqualTo("testMetadataValue");
}
@Test public void should_present_application_name_as_id_of_the_service_instance() {
//given:
ServiceInstance instance = this.discoveryClient.getLocalServiceInstance();
//expect:
then(this.springAppName).isEqualTo(instance.getServiceId());
}
@Test public void should_find_an_instance_using_feign_via_service_id() {
final IdUsingFeignClient idUsingFeignClient = this.idUsingFeignClient;
//expect:
Awaitility.await().until(new Callable<Boolean>() {
@Override public Boolean call() throws Exception {
then(idUsingFeignClient.getBeans()).isNotEmpty();
return true;
}
});
}
private String registeredServiceStatusViaServiceName() {
return JsonPath.builder(this.testRibbonClient.thisHealthCheck()).field("status").read(String.class);
}
private String registeredServiceStatus(ServiceInstance instance) {
return JsonPath.builder(this.testRibbonClient.callOnUrl(instance.getHost()+":"+instance.getPort(), "health")).field("status").read(String.class);
}
@Test public void should_properly_find_local_instance() {
//expect:
then(this.serviceDiscovery.getServiceInstance().getAddress()).isEqualTo(this.discoveryClient.getLocalServiceInstance().getHost());
}
@FeignClient("ribbonApp")
public static interface IdUsingFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/beans")
String getBeans();
}
@Configuration
@EnableAutoConfiguration
@Import(CommonTestConfig.class)
@EnableDiscoveryClient
@EnableFeignClients(clients = { IdUsingFeignClient.class })
@Profile("ribbon")
static class Config {
@Bean TestRibbonClient testRibbonClient(@LoadBalanced RestTemplate restTemplate,
@Value("${spring.application.name}") String springAppName) {
return new TestRibbonClient(restTemplate, springAppName);
}
}
@Controller
@Profile("ribbon")
class PingController {
@RequestMapping("/ping") String ping() {
return "pong";
}
}
}