Skip to content

Commit

Permalink
uses docker instead of zipkin to unlock deps
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian Cole <adrian@tetrate.io>
  • Loading branch information
Adrian Cole committed Dec 11, 2023
1 parent 3dbda74 commit 62afa69
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 83 deletions.
13 changes: 10 additions & 3 deletions libthrift/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,16 @@
</dependency>

<dependency>
<groupId>io.zipkin.zipkin2</groupId>
<artifactId>zipkin-collector-scribe</artifactId>
<version>${zipkin.version}</version>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
23 changes: 0 additions & 23 deletions libthrift/src/test/java/zipkin2/collector/scribe/Access.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 The OpenZipkin Authors
* Copyright 2016-2023 The OpenZipkin 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
Expand All @@ -17,100 +17,93 @@
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.RegisterExtension;
import zipkin2.Span;
import zipkin2.codec.SpanBytesEncoder;
import zipkin2.collector.InMemoryCollectorMetrics;
import zipkin2.collector.scribe.Access;
import zipkin2.collector.scribe.ScribeCollector;
import zipkin2.storage.InMemoryStorage;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static zipkin2.TestObjects.CLIENT_SPAN;
import static zipkin2.TestObjects.LOTS_OF_SPANS;

public class ITLibthriftSender {
InMemoryStorage storage = InMemoryStorage.newBuilder().build();
InMemoryCollectorMetrics collectorMetrics = new InMemoryCollectorMetrics();
InMemoryCollectorMetrics scribeCollectorMetrics = collectorMetrics.forTransport("scribe");
ScribeCollector collector;
LibthriftSender sender;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ITLibthriftSender {
@RegisterExtension ZipkinExtension zipkin = new ZipkinExtension();

@Before public void start() {
collector = ScribeCollector.newBuilder()
.metrics(collectorMetrics)
.storage(storage)
.port(0) // use a random port so that tests don't interfere with another
.build();
collector.start();
LibthriftSender sender;

int port = Access.port(collector);
sender = LibthriftSender.newBuilder().host("127.0.0.1").port(port).build();
@BeforeEach void open() {
sender = LibthriftSender.newBuilder().
host(zipkin.host()).
port(zipkin.scribePort()).build();
}

@After public void close() {
collector.close();
@AfterEach void close() {
sender.close();
}

@Test public void sendsSpans() throws Exception {
@Test void sendsSpans() throws Exception {
send(CLIENT_SPAN);

assertThat(storage.spanStore().getTraces()).containsExactly(asList(CLIENT_SPAN));
assertThat(zipkin.get("/api/v2/trace/" + CLIENT_SPAN.traceId()).isSuccessful())
.isTrue();
}

/** This will help verify sequence ID and response parsing logic works */
@Test public void sendsSpans_multipleTimes() throws Exception {
/**
* This will help verify sequence ID and response parsing logic works
*/
@Test void sendsSpans_multipleTimes() throws Exception {
for (int i = 0; i < 5; i++) { // Have client send 5 messages
send(Arrays.copyOfRange(LOTS_OF_SPANS, i, (i * 10) + 10));
}

assertThat(storage.getTraces()).flatExtracting(l -> l)
.contains(Arrays.copyOfRange(LOTS_OF_SPANS, 0, 50));
}

@Test public void sendsSpansExpectedMetrics() throws Exception {
send(CLIENT_SPAN, CLIENT_SPAN);

assertThat(scribeCollectorMetrics.messages()).isEqualTo(1);
assertThat(scribeCollectorMetrics.messagesDropped()).isZero();
assertThat(scribeCollectorMetrics.spans()).isEqualTo(2);
assertThat(scribeCollectorMetrics.spansDropped()).isZero();
byte[] thrift = SpanBytesEncoder.THRIFT.encode(CLIENT_SPAN);

// span bytes is cumulative thrift size, not message size
assertThat(scribeCollectorMetrics.bytes()).isEqualTo(thrift.length * 2);
for (int i = 0; i < 5; i++) { // Try the last ID of each
int index = (i * 10) + 9; // not 10 because range is exclusive
assertThat(zipkin.get("/api/v2/trace/" + LOTS_OF_SPANS[index].traceId()).isSuccessful())
.isTrue();
}
}

@Test public void check_okWhenScribeIsListening() {
@Test void check_okWhenScribeIsListening() {
assertThat(sender.check().ok()).isTrue();
}

@Test public void check_notOkWhenScribeIsDown() {
collector.close();
@Test void check_notOkWhenScribeIsDown() {
sender.close();

// Reconfigure to a valid host but invalid port.
sender = LibthriftSender.newBuilder().
host(zipkin.host()).
port(zipkin.httpPort()).build();

assertThat(sender.check().ok()).isFalse();
}

@Test public void reconnects() throws Exception {
close();
@Test void reconnects() throws Exception {
sender.close();

// Reconfigure to a valid host but port that isn't listening.
sender = LibthriftSender.newBuilder().
host(zipkin.host()).
port(9999).build();

assertThatThrownBy(() -> send(CLIENT_SPAN, CLIENT_SPAN))
.isInstanceOf(IOException.class);

start();
open();

send(CLIENT_SPAN, CLIENT_SPAN);

assertThat(storage.spanStore().getTraces())
.containsExactly(asList(CLIENT_SPAN));
assertThat(zipkin.get("/api/v2/trace/" + CLIENT_SPAN.traceId()).isSuccessful())
.isTrue();
}

@Test public void illegalToSendWhenClosed() {
@Test void illegalToSendWhenClosed() {
sender.close();

assertThatThrownBy(() -> send(CLIENT_SPAN, CLIENT_SPAN))
Expand All @@ -123,12 +116,14 @@ public class ITLibthriftSender {
* exposed in logs and other monitoring tools, care should be taken to ensure the toString()
* output is a reasonable length and does not contain sensitive information.
*/
@Test public void toStringContainsOnlySenderTypeHostAndPort() {
@Test void toStringContainsOnlySenderTypeHostAndPort() {
assertThat(sender.toString())
.isEqualTo("LibthriftSender(" + sender.host + ":" + sender.port + ")");
}

/** Blocks until the callback completes to allow read-your-writes consistency during tests. */
/**
* Blocks until the callback completes to allow read-your-writes consistency during tests.
*/
void send(Span... spans) throws IOException {
List<byte[]> encodedSpans =
Stream.of(spans).map(SpanBytesEncoder.THRIFT::encode).collect(toList());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2016-2023 The OpenZipkin 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 zipkin2.reporter.libthrift;

import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.opentest4j.TestAbortedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;

import static org.testcontainers.utility.DockerImageName.parse;

class ZipkinExtension implements BeforeAllCallback, AfterAllCallback {
static final Logger LOGGER = LoggerFactory.getLogger(ZipkinExtension.class);
static final int SCRIBE_PORT = 9410;
static final int HTTP_PORT = 9411;

final ZipkinContainer container = new ZipkinContainer();

@Override public void beforeAll(ExtensionContext context) {
if (context.getRequiredTestClass().getEnclosingClass() != null) {
// Only run once in outermost scope.
return;
}

container.start();
LOGGER.info("Using scribe host and port " + host() + ":" + scribePort());
}

String host() {
return container.getHost();
}

int httpPort() {
return container.getMappedPort(HTTP_PORT);
}

int scribePort() {
return container.getMappedPort(SCRIBE_PORT);
}

OkHttpClient client = new OkHttpClient.Builder().followRedirects(true).build();

Response get(String path) throws IOException {
return client.newCall(new Request.Builder()
.url("http://" + host() + ":" + httpPort() + path).build()).execute();
}

@Override public void afterAll(ExtensionContext context) {
if (context.getRequiredTestClass().getEnclosingClass() != null) {
// Only run once in outermost scope.
return;
}
container.stop();
}

// mostly waiting for https://github.com/testcontainers/testcontainers-java/issues/3537
static final class ZipkinContainer extends GenericContainer<ZipkinContainer> {
ZipkinContainer() {
super(parse("ghcr.io/openzipkin/zipkin:2.24.4"));
if ("true".equals(System.getProperty("docker.skip"))) {
throw new TestAbortedException("${docker.skip} == true");
}
// zipkin-server disables scribe by default.
withEnv("COLLECTOR_SCRIBE_ENABLED", "true");
withExposedPorts(SCRIBE_PORT, HTTP_PORT);
waitStrategy = Wait.forHealthcheck();
withLogConsumer(new Slf4jLogConsumer(LOGGER));
}
}
}
13 changes: 13 additions & 0 deletions libthrift/src/test/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
<junit.version>4.13.2</junit.version>
<junit-jupiter.version>5.10.1</junit-jupiter.version>
<okhttp.version>3.14.9</okhttp.version>
<logback.version>1.4.14</logback.version>
<!-- use pre slf4j 2 version -->
<logback.version>1.2.13</logback.version>
<testcontainers.version>1.19.3</testcontainers.version>

<license.skip>${skipTests}</license.skip>
Expand Down

0 comments on commit 62afa69

Please sign in to comment.