You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zipkin.apache.org by ad...@apache.org on 2019/06/15 13:49:58 UTC
[incubator-zipkin-brave] branch master updated: Fixes assertion by
making equals the same between lazy and real span (#927)
This is an automated email from the ASF dual-hosted git repository.
adriancole pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-zipkin-brave.git
The following commit(s) were added to refs/heads/master by this push:
new b031825 Fixes assertion by making equals the same between lazy and real span (#927)
b031825 is described below
commit b031825a60d34ff6e66aa9abc0a90388c5b4ef42
Author: Adrian Cole <ad...@users.noreply.github.com>
AuthorDate: Sat Jun 15 21:49:54 2019 +0800
Fixes assertion by making equals the same between lazy and real span (#927)
We had an assertion in `ThreadLocalSpan` which broke because our equals
comparison was one way. This fixes it.
---
brave/src/main/java/brave/LazySpan.java | 9 +--
brave/src/main/java/brave/RealSpan.java | 24 +++++--
brave/src/test/java/brave/LazySpanTest.java | 82 ++++++++++++++++++++++
brave/src/test/java/brave/RealSpanTest.java | 73 ++++++++++++++-----
.../brave/propagation/ThreadLocalSpanTest.java | 48 +++++++++++++
5 files changed, 207 insertions(+), 29 deletions(-)
diff --git a/brave/src/main/java/brave/LazySpan.java b/brave/src/main/java/brave/LazySpan.java
index 90aae26..bbf6a45 100644
--- a/brave/src/main/java/brave/LazySpan.java
+++ b/brave/src/main/java/brave/LazySpan.java
@@ -16,6 +16,8 @@ package brave;
import brave.handler.MutableSpan;
import brave.propagation.TraceContext;
+import static brave.RealSpan.isEqualToRealOrLazySpan;
+
/**
* This defers creation of a span until first public method call.
*
@@ -112,12 +114,7 @@ final class LazySpan extends Span {
*/
@Override public boolean equals(Object o) {
if (o == this) return true;
- if (o instanceof LazySpan) {
- return context.equals(((LazySpan) o).context);
- } else if (o instanceof RealSpan) {
- return context.equals(((RealSpan) o).context);
- }
- return false;
+ return isEqualToRealOrLazySpan(context, o);
}
/**
diff --git a/brave/src/main/java/brave/RealSpan.java b/brave/src/main/java/brave/RealSpan.java
index 1764517..b827ac4 100644
--- a/brave/src/main/java/brave/RealSpan.java
+++ b/brave/src/main/java/brave/RealSpan.java
@@ -28,10 +28,10 @@ final class RealSpan extends Span {
final FinishedSpanHandler finishedSpanHandler;
RealSpan(TraceContext context,
- PendingSpans pendingSpans,
- MutableSpan state,
- Clock clock,
- FinishedSpanHandler finishedSpanHandler
+ PendingSpans pendingSpans,
+ MutableSpan state,
+ Clock clock,
+ FinishedSpanHandler finishedSpanHandler
) {
this.context = context;
this.pendingSpans = pendingSpans;
@@ -164,10 +164,22 @@ final class RealSpan extends Span {
return "RealSpan(" + context + ")";
}
+ /**
+ * This also matches equals against a lazy span. The rationale is least surprise to the user, as
+ * code should not act differently given an instance of lazy or {@link RealSpan}.
+ */
@Override public boolean equals(Object o) {
if (o == this) return true;
- if (!(o instanceof RealSpan)) return false;
- return context.equals(((RealSpan) o).context);
+ return isEqualToRealOrLazySpan(context, o);
+ }
+
+ static boolean isEqualToRealOrLazySpan(TraceContext context, Object o) {
+ if (o instanceof LazySpan) {
+ return context.equals(((LazySpan) o).context);
+ } else if (o instanceof RealSpan) {
+ return context.equals(((RealSpan) o).context);
+ }
+ return false;
}
@Override public int hashCode() {
diff --git a/brave/src/test/java/brave/LazySpanTest.java b/brave/src/test/java/brave/LazySpanTest.java
new file mode 100644
index 0000000..ce41044
--- /dev/null
+++ b/brave/src/test/java/brave/LazySpanTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013-2019 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 brave;
+
+import brave.propagation.CurrentTraceContext.Scope;
+import brave.propagation.ThreadLocalCurrentTraceContext;
+import brave.propagation.TraceContext;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LazySpanTest {
+ List<zipkin2.Span> spans = new ArrayList();
+ Tracing tracing = Tracing.newBuilder()
+ .currentTraceContext(ThreadLocalCurrentTraceContext.create())
+ .spanReporter(spans::add)
+ .build();
+
+ TraceContext context = TraceContext.newBuilder().traceId(1L).spanId(1L).sampled(true).build();
+ TraceContext context2 = TraceContext.newBuilder().traceId(1L).spanId(2L).sampled(true).build();
+
+ @After public void close() {
+ tracing.close();
+ }
+
+ @Test public void equals_sameContext() {
+ Span current1, current2;
+ try (Scope ws = tracing.currentTraceContext().newScope(context)) {
+ current1 = tracing.tracer().currentSpan();
+ current2 = tracing.tracer().currentSpan();
+ }
+
+ assertThat(current1)
+ .isInstanceOf(LazySpan.class)
+ .isNotSameAs(current2)
+ .isEqualTo(current2);
+ }
+
+ @Test public void equals_notSameContext() {
+ Span current1, current2;
+ try (Scope ws = tracing.currentTraceContext().newScope(context)) {
+ current1 = tracing.tracer().currentSpan();
+ }
+ try (Scope ws = tracing.currentTraceContext().newScope(context2)) {
+ current2 = tracing.tracer().currentSpan();
+ }
+
+ assertThat(current1).isNotEqualTo(current2);
+ }
+
+ @Test public void equals_realSpan_sameContext() {
+ Span current;
+ try (Scope ws = tracing.currentTraceContext().newScope(context)) {
+ current = tracing.tracer().currentSpan();
+ }
+
+ assertThat(current).isEqualTo(tracing.tracer().toSpan(context));
+ }
+
+ @Test public void equals_realSpan_notSameContext() {
+ Span current;
+ try (Scope ws = tracing.currentTraceContext().newScope(context)) {
+ current = tracing.tracer().currentSpan();
+ }
+
+ assertThat(current).isNotEqualTo(tracing.tracer().toSpan(context2));
+ }
+}
diff --git a/brave/src/test/java/brave/RealSpanTest.java b/brave/src/test/java/brave/RealSpanTest.java
index 5d6d143..eb024e0 100644
--- a/brave/src/test/java/brave/RealSpanTest.java
+++ b/brave/src/test/java/brave/RealSpanTest.java
@@ -13,7 +13,9 @@
*/
package brave;
+import brave.propagation.CurrentTraceContext;
import brave.propagation.ThreadLocalCurrentTraceContext;
+import brave.propagation.TraceContext;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
@@ -27,9 +29,13 @@ import static org.assertj.core.api.Assertions.entry;
public class RealSpanTest {
List<zipkin2.Span> spans = new ArrayList();
Tracing tracing = Tracing.newBuilder()
- .currentTraceContext(ThreadLocalCurrentTraceContext.create())
- .spanReporter(spans::add)
- .build();
+ .currentTraceContext(ThreadLocalCurrentTraceContext.create())
+ .spanReporter(spans::add)
+ .build();
+
+ TraceContext context = TraceContext.newBuilder().traceId(1L).spanId(1L).sampled(true).build();
+ TraceContext context2 = TraceContext.newBuilder().traceId(1L).spanId(2L).sampled(true).build();
+
Span span = tracing.tracer().newTrace();
@After public void close() {
@@ -53,8 +59,8 @@ public class RealSpanTest {
span.flush();
assertThat(spans).hasSize(1).first()
- .extracting(zipkin2.Span::timestamp)
- .isNotNull();
+ .extracting(zipkin2.Span::timestamp)
+ .isNotNull();
}
@Test public void start_timestamp() {
@@ -62,8 +68,8 @@ public class RealSpanTest {
span.flush();
assertThat(spans).hasSize(1).first()
- .extracting(zipkin2.Span::timestamp)
- .isEqualTo(2L);
+ .extracting(zipkin2.Span::timestamp)
+ .isEqualTo(2L);
}
@Test public void finish() {
@@ -71,8 +77,8 @@ public class RealSpanTest {
span.finish();
assertThat(spans).hasSize(1).first()
- .extracting(zipkin2.Span::duration)
- .isNotNull();
+ .extracting(zipkin2.Span::duration)
+ .isNotNull();
}
@Test public void finish_timestamp() {
@@ -80,8 +86,8 @@ public class RealSpanTest {
span.finish(5);
assertThat(spans).hasSize(1).first()
- .extracting(zipkin2.Span::duration)
- .isEqualTo(3L);
+ .extracting(zipkin2.Span::duration)
+ .isEqualTo(3L);
}
@Test public void abandon() {
@@ -96,8 +102,8 @@ public class RealSpanTest {
span.flush();
assertThat(spans).flatExtracting(zipkin2.Span::annotations)
- .extracting(Annotation::value)
- .containsExactly("foo");
+ .extracting(Annotation::value)
+ .containsExactly("foo");
}
@Test public void remoteEndpoint_nulls() {
@@ -112,7 +118,7 @@ public class RealSpanTest {
span.flush();
assertThat(spans).flatExtracting(zipkin2.Span::annotations)
- .containsExactly(Annotation.create(2L, "foo"));
+ .containsExactly(Annotation.create(2L, "foo"));
}
@Test public void tag() {
@@ -120,7 +126,7 @@ public class RealSpanTest {
span.flush();
assertThat(spans).flatExtracting(s -> s.tags().entrySet())
- .containsExactly(entry("foo", "bar"));
+ .containsExactly(entry("foo", "bar"));
}
@Test public void finished_client_annotation() {
@@ -173,7 +179,7 @@ public class RealSpanTest {
span.flush();
assertThat(spans).flatExtracting(s -> s.tags().entrySet())
- .containsExactly(entry("error", "this cake is a lie"));
+ .containsExactly(entry("error", "this cake is a lie"));
}
@Test public void error_noMessage() {
@@ -181,6 +187,39 @@ public class RealSpanTest {
span.flush();
assertThat(spans).flatExtracting(s -> s.tags().entrySet())
- .containsExactly(entry("error", "RuntimeException"));
+ .containsOnly(entry("error", "RuntimeException"));
+ }
+
+ @Test public void equals_sameContext() {
+ Span one = tracing.tracer().toSpan(context), two = tracing.tracer().toSpan(context);
+
+ assertThat(one)
+ .isInstanceOf(RealSpan.class)
+ .isNotSameAs(two)
+ .isEqualTo(two);
+ }
+
+ @Test public void equals_notSameContext() {
+ Span one = tracing.tracer().toSpan(context), two = tracing.tracer().toSpan(context2);
+
+ assertThat(one).isNotEqualTo(two);
+ }
+
+ @Test public void equals_realSpan_sameContext() {
+ Span current;
+ try (CurrentTraceContext.Scope ws = tracing.currentTraceContext().newScope(context)) {
+ current = tracing.tracer().currentSpan();
+ }
+
+ assertThat(tracing.tracer().toSpan(context)).isEqualTo(current);
+ }
+
+ @Test public void equals_realSpan_notSameContext() {
+ Span current;
+ try (CurrentTraceContext.Scope ws = tracing.currentTraceContext().newScope(context2)) {
+ current = tracing.tracer().currentSpan();
+ }
+
+ assertThat(tracing.tracer().toSpan(context)).isNotEqualTo(current);
}
}
diff --git a/brave/src/test/java/brave/propagation/ThreadLocalSpanTest.java b/brave/src/test/java/brave/propagation/ThreadLocalSpanTest.java
new file mode 100644
index 0000000..ae9b58f
--- /dev/null
+++ b/brave/src/test/java/brave/propagation/ThreadLocalSpanTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2013-2019 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 brave.propagation;
+
+import brave.Tracing;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.After;
+import org.junit.Test;
+import zipkin2.Span;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ThreadLocalSpanTest {
+
+ List<Span> spans = new ArrayList<>();
+ Tracing tracing = Tracing.newBuilder()
+ .currentTraceContext(ThreadLocalCurrentTraceContext.create())
+ .spanReporter(spans::add)
+ .build();
+
+ ThreadLocalSpan threadLocalSpan = ThreadLocalSpan.create(tracing.tracer());
+
+ @After public void close() {
+ tracing.close();
+ }
+
+ @Test public void next() {
+ assertThat(threadLocalSpan.next())
+ .isEqualTo(threadLocalSpan.remove());
+ }
+
+ @Test public void next_extracted() {
+ assertThat(threadLocalSpan.next(TraceContextOrSamplingFlags.DEBUG))
+ .isEqualTo(threadLocalSpan.remove());
+ }
+}