[#89] Added test for zipkin integration

This commit is contained in:
Marcin Grzejszczak
2016-01-11 17:38:24 +01:00
parent 4d3300aab6
commit 3084eab3eb
9 changed files with 355 additions and 28 deletions

View File

@@ -0,0 +1,139 @@
/*
* 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 integration;
import io.zipkin.Codec;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.JdkIdGenerator;
import org.testcontainers.containers.DockerComposeContainer;
import sample.SampleZipkinApplication;
import tools.AbstractIntegrationTest;
import tools.RequestSendingRunnable;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static org.assertj.core.api.BDDAssertions.then;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { AbstractIntegrationTest.ZipkinConfig.class, SampleZipkinApplication.class })
@WebIntegrationTest
@TestPropertySource(properties="sample.zipkin.enabled=true")
@Slf4j
public class ZipkinDockerTests extends AbstractIntegrationTest {
private static final String APP_NAME = "testsleuthzipkin";
private static int port = 3380;
private static String sampleAppUrl = "http://localhost:" + port;
@ClassRule
public static DockerComposeContainer environment =
new DockerComposeContainer(new File("src/test/resources/docker-compose.yml"))
.withExposedService("rabbitmq_1", 5672)
.withExposedService("collector_1", 9410)
.withExposedService("collector_1", 9900)
.withExposedService("mysql_1", 3306)
.withExposedService("query_1", 9411)
.withExposedService("query_1", 9901);
@Before
public void setup() {
await().until(zipkinQueryServerIsUp());
await().until(zipkinCollectorServerIsUp());
}
@Test
@SneakyThrows
public void should_propagate_spans_to_zipkin() {
String traceId = new JdkIdGenerator().generateId().toString();
httpMessageWithTraceIdInHeadersIsSuccessfullySent(sampleAppUrl + "/hi2", traceId);
await().until(() -> {
allSpansWereRegisteredInZipkinWithTraceIdEqualTo(traceId);
});
}
private void allSpansWereRegisteredInZipkinWithTraceIdEqualTo(String traceId) {
ResponseEntity<String> response = checkStateOfTheTraceId(traceId);
log.info("Response from the Zipkin query service about the trace id [{}] for trace with id [{}]", response, traceId);
then(response.getStatusCode()).isEqualTo(HttpStatus.OK);
then(response.hasBody()).isTrue();
List<io.zipkin.Span> spans = Codec.JSON.readSpans(response.getBody().getBytes());
List<String> serviceNamesNotFoundInZipkin = serviceNamesNotFoundInZipkin(spans);
List<String> spanNamesNotFoundInZipkin = annotationsNotFoundInZipkin(spans);
log.info("The following services were not found in Zipkin {}", serviceNamesNotFoundInZipkin);
log.info("The following spans were not found in Zipkin {}", spanNamesNotFoundInZipkin);
then(serviceNamesNotFoundInZipkin).isEmpty();
then(spanNamesNotFoundInZipkin).isEmpty();
log.info("Zipkin tracing is working! Sleuth is working! Let's be happy!");
}
private List<String> serviceNamesNotFoundInZipkin(List<io.zipkin.Span> spans) {
List<String> serviceNamesFoundInAnnotations = spans.stream()
.filter(span -> span.annotations != null)
.map(span -> span.annotations)
.flatMap(Collection::stream)
.filter(span -> span.endpoint != null)
.map(annotation -> annotation.endpoint)
.map(endpoint -> endpoint.serviceName)
.distinct()
.collect(Collectors.toList());
List<String> serviceNamesFoundInBinaryAnnotations = spans.stream()
.filter(span -> span.binaryAnnotations != null)
.map(span -> span.binaryAnnotations)
.flatMap(Collection::stream)
.filter(span -> span.endpoint != null)
.map(annotation -> annotation.endpoint)
.map(endpoint -> endpoint.serviceName)
.distinct()
.collect(Collectors.toList());
List<String> names = new ArrayList<>();
names.addAll(serviceNamesFoundInAnnotations);
names.addAll(serviceNamesFoundInBinaryAnnotations);
return names.contains(APP_NAME) ? Collections.EMPTY_LIST : names;
}
private List<String> annotationsNotFoundInZipkin(List<io.zipkin.Span> spans) {
String binaryAnnotationName = "random-sleep-millis";
Optional<String> names = spans.stream()
.filter(span -> span.binaryAnnotations != null)
.map(span -> span.binaryAnnotations)
.flatMap(Collection::stream)
.filter(span -> span.endpoint != null)
.map(annotation -> annotation.key)
.filter(binaryAnnotationName::equals)
.findFirst();
return names.isPresent() ? Collections.EMPTY_LIST : Collections.singletonList(binaryAnnotationName);
}
private void httpMessageWithTraceIdInHeadersIsSuccessfullySent(String endpoint, String traceId) {
new RequestSendingRunnable(restTemplate, endpoint, traceId).run();
}
}