diff options
Diffstat (limited to 'api/src/test')
80 files changed, 9123 insertions, 0 deletions
diff --git a/api/src/test/java/io/opencensus/common/DurationTest.java b/api/src/test/java/io/opencensus/common/DurationTest.java new file mode 100644 index 00000000..ea636ca0 --- /dev/null +++ b/api/src/test/java/io/opencensus/common/DurationTest.java @@ -0,0 +1,152 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Duration}. */ +@RunWith(JUnit4.class) +public class DurationTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testDurationCreate() { + assertThat(Duration.create(24, 42).getSeconds()).isEqualTo(24); + assertThat(Duration.create(24, 42).getNanos()).isEqualTo(42); + assertThat(Duration.create(-24, -42).getSeconds()).isEqualTo(-24); + assertThat(Duration.create(-24, -42).getNanos()).isEqualTo(-42); + assertThat(Duration.create(315576000000L, 999999999).getSeconds()).isEqualTo(315576000000L); + assertThat(Duration.create(315576000000L, 999999999).getNanos()).isEqualTo(999999999); + assertThat(Duration.create(-315576000000L, -999999999).getSeconds()).isEqualTo(-315576000000L); + assertThat(Duration.create(-315576000000L, -999999999).getNanos()).isEqualTo(-999999999); + } + + @Test + public void create_SecondsTooLow() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is less than minimum (-315576000000): -315576000001"); + Duration.create(-315576000001L, 0); + } + + @Test + public void create_SecondsTooHigh() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is greater than maximum (315576000000): 315576000001"); + Duration.create(315576000001L, 0); + } + + @Test + public void create_NanosTooLow() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'nanos' is less than minimum (-999999999): -1000000000"); + Duration.create(0, -1000000000); + } + + @Test + public void create_NanosTooHigh() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'nanos' is greater than maximum (999999999): 1000000000"); + Duration.create(0, 1000000000); + } + + @Test + public void create_NegativeSecondsPositiveNanos() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' and 'nanos' have inconsistent sign: seconds=-1, nanos=1"); + Duration.create(-1, 1); + } + + @Test + public void create_PositiveSecondsNegativeNanos() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' and 'nanos' have inconsistent sign: seconds=1, nanos=-1"); + Duration.create(1, -1); + } + + @Test + public void testDurationFromMillis() { + assertThat(Duration.fromMillis(0)).isEqualTo(Duration.create(0, 0)); + assertThat(Duration.fromMillis(987)).isEqualTo(Duration.create(0, 987000000)); + assertThat(Duration.fromMillis(3456)).isEqualTo(Duration.create(3, 456000000)); + } + + @Test + public void testDurationFromMillisNegative() { + assertThat(Duration.fromMillis(-1)).isEqualTo(Duration.create(0, -1000000)); + assertThat(Duration.fromMillis(-999)).isEqualTo(Duration.create(0, -999000000)); + assertThat(Duration.fromMillis(-1000)).isEqualTo(Duration.create(-1, 0)); + assertThat(Duration.fromMillis(-3456)).isEqualTo(Duration.create(-3, -456000000)); + } + + @Test + public void fromMillis_TooLow() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is less than minimum (-315576000000): -315576000001"); + Duration.fromMillis(-315576000001000L); + } + + @Test + public void fromMillis_TooHigh() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is greater than maximum (315576000000): 315576000001"); + Duration.fromMillis(315576000001000L); + } + + @Test + public void duration_CompareLength() { + assertThat(Duration.create(0, 0).compareTo(Duration.create(0, 0))).isEqualTo(0); + assertThat(Duration.create(24, 42).compareTo(Duration.create(24, 42))).isEqualTo(0); + assertThat(Duration.create(-24, -42).compareTo(Duration.create(-24, -42))).isEqualTo(0); + assertThat(Duration.create(25, 42).compareTo(Duration.create(24, 42))).isEqualTo(1); + assertThat(Duration.create(24, 45).compareTo(Duration.create(24, 42))).isEqualTo(1); + assertThat(Duration.create(24, 42).compareTo(Duration.create(25, 42))).isEqualTo(-1); + assertThat(Duration.create(24, 42).compareTo(Duration.create(24, 45))).isEqualTo(-1); + assertThat(Duration.create(-24, -45).compareTo(Duration.create(-24, -42))).isEqualTo(-1); + assertThat(Duration.create(-24, -42).compareTo(Duration.create(-25, -42))).isEqualTo(1); + assertThat(Duration.create(24, 42).compareTo(Duration.create(-24, -42))).isEqualTo(1); + } + + @Test + public void testDurationEqual() { + // Positive tests. + assertThat(Duration.create(0, 0)).isEqualTo(Duration.create(0, 0)); + assertThat(Duration.create(24, 42)).isEqualTo(Duration.create(24, 42)); + assertThat(Duration.create(-24, -42)).isEqualTo(Duration.create(-24, -42)); + // Negative tests. + assertThat(Duration.create(25, 42)).isNotEqualTo(Duration.create(24, 42)); + assertThat(Duration.create(24, 43)).isNotEqualTo(Duration.create(24, 42)); + assertThat(Duration.create(-25, -42)).isNotEqualTo(Duration.create(-24, -42)); + assertThat(Duration.create(-24, -43)).isNotEqualTo(Duration.create(-24, -42)); + } + + @Test + public void toMillis() { + assertThat(Duration.create(10, 0).toMillis()).isEqualTo(10000L); + assertThat(Duration.create(10, 1000).toMillis()).isEqualTo(10000L); + assertThat(Duration.create(0, (int) 1e6).toMillis()).isEqualTo(1L); + assertThat(Duration.create(0, 0).toMillis()).isEqualTo(0L); + assertThat(Duration.create(-10, 0).toMillis()).isEqualTo(-10000L); + assertThat(Duration.create(-10, -1000).toMillis()).isEqualTo(-10000L); + assertThat(Duration.create(0, -(int) 1e6).toMillis()).isEqualTo(-1L); + } +} diff --git a/api/src/test/java/io/opencensus/common/FunctionsTest.java b/api/src/test/java/io/opencensus/common/FunctionsTest.java new file mode 100644 index 00000000..55d58d4d --- /dev/null +++ b/api/src/test/java/io/opencensus/common/FunctionsTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Functions}. */ +@RunWith(JUnit4.class) +public class FunctionsTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testReturnNull() { + assertThat(Functions.returnNull().apply("ignored")).isNull(); + } + + @Test + public void testReturnConstant() { + assertThat(Functions.returnConstant(123).apply("ignored")).isEqualTo(123); + } + + @Test + public void testReturnToString() { + assertThat(Functions.returnToString().apply("input")).isEqualTo("input"); + assertThat(Functions.returnToString().apply(Boolean.FALSE)).isEqualTo("false"); + assertThat(Functions.returnToString().apply(Double.valueOf(123.45))).isEqualTo("123.45"); + assertThat(Functions.returnToString().apply(null)).isEqualTo(null); + } + + @Test + public void testThrowIllegalArgumentException() { + Function<Object, Void> f = Functions.throwIllegalArgumentException(); + thrown.expect(IllegalArgumentException.class); + f.apply("ignored"); + } + + @Test + public void testThrowAssertionError() { + Function<Object, Void> f = Functions.throwAssertionError(); + thrown.handleAssertionErrors(); + thrown.expect(AssertionError.class); + f.apply("ignored"); + } +} diff --git a/api/src/test/java/io/opencensus/common/ServerStatsEncodingTest.java b/api/src/test/java/io/opencensus/common/ServerStatsEncodingTest.java new file mode 100644 index 00000000..6db14a79 --- /dev/null +++ b/api/src/test/java/io/opencensus/common/ServerStatsEncodingTest.java @@ -0,0 +1,155 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ServerStatsEncoding}. */ +@RunWith(JUnit4.class) +public class ServerStatsEncodingTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void encodeDecodeTest() throws ServerStatsDeserializationException { + ServerStats serverStatsToBeEncoded = null; + ServerStats serverStatsDecoded = null; + byte[] serialized = null; + + serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1); + serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded); + serverStatsDecoded = ServerStatsEncoding.parseBytes(serialized); + assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded); + + serverStatsToBeEncoded = ServerStats.create(0, 22, (byte) 0); + serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded); + serverStatsDecoded = ServerStatsEncoding.parseBytes(serialized); + assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded); + + serverStatsToBeEncoded = ServerStats.create(450, 0, (byte) 0); + serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded); + serverStatsDecoded = ServerStatsEncoding.parseBytes(serialized); + assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded); + } + + @Test + public void skipUnknownFieldTest() throws ServerStatsDeserializationException { + ServerStats serverStatsToBeEncoded = null; + ServerStats serverStatsDecoded = null; + byte[] serialized = null; + + serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1); + serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded); + + // Add new field at the end. + byte[] serializedExpanded = new byte[serialized.length + 9]; + System.arraycopy(serialized, 0, serializedExpanded, 0, serialized.length); + final ByteBuffer bb = ByteBuffer.wrap(serializedExpanded); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.position(serialized.length); + bb.put((byte) 255); + bb.putLong(0L); + byte[] newSerialized = bb.array(); + + serverStatsDecoded = ServerStatsEncoding.parseBytes(newSerialized); + assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded); + } + + @Test + public void negativeLbLatencyValueTest() throws ServerStatsDeserializationException { + ServerStats serverStatsToBeEncoded = null; + ServerStats serverStatsDecoded = null; + byte[] serialized = null; + + serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1); + serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded); + + // update serialized byte[] with negative value for lbLatency. + final ByteBuffer bb = ByteBuffer.wrap(serialized); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.position(2); + bb.putLong(-100L); + + byte[] newSerialized = bb.array(); + thrown.expect(ServerStatsDeserializationException.class); + thrown.expectMessage("Serialized ServiceStats contains invalid values"); + ServerStatsEncoding.parseBytes(newSerialized); + } + + @Test + public void negativeServerLatencyValueTest() throws ServerStatsDeserializationException { + ServerStats serverStatsToBeEncoded = null; + ServerStats serverStatsDecoded = null; + byte[] serialized = null; + + serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1); + serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded); + + // update serialized byte[] with negative value for serviceLatency. + final ByteBuffer bb = ByteBuffer.wrap(serialized); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.position(11); + bb.putLong(-101L); + + byte[] newSerialized = bb.array(); + thrown.expect(ServerStatsDeserializationException.class); + thrown.expectMessage("Serialized ServiceStats contains invalid values"); + ServerStatsEncoding.parseBytes(newSerialized); + } + + @Test + public void emptySerializedBuffer() throws ServerStatsDeserializationException { + final ByteBuffer bb = ByteBuffer.allocate(0); + bb.order(ByteOrder.LITTLE_ENDIAN); + + byte[] newSerialized = bb.array(); + thrown.expect(ServerStatsDeserializationException.class); + thrown.expectMessage("Serialized ServerStats buffer is empty"); + ServerStatsEncoding.parseBytes(newSerialized); + } + + @Test + public void invalidNegativeVersion() throws ServerStatsDeserializationException { + final ByteBuffer bb = ByteBuffer.allocate(10); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.put((byte) -1); + byte[] newSerialized = bb.array(); + thrown.expect(ServerStatsDeserializationException.class); + thrown.expectMessage("Invalid ServerStats version: -1"); + ServerStatsEncoding.parseBytes(newSerialized); + } + + @Test + public void invalidCompatibleVersion() throws ServerStatsDeserializationException { + final ByteBuffer bb = ByteBuffer.allocate(10); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.put((byte) (ServerStatsEncoding.CURRENT_VERSION + 1)); + byte[] newSerialized = bb.array(); + thrown.expect(ServerStatsDeserializationException.class); + thrown.expectMessage( + "Invalid ServerStats version: " + (ServerStatsEncoding.CURRENT_VERSION + 1)); + ServerStatsEncoding.parseBytes(newSerialized); + } +} diff --git a/api/src/test/java/io/opencensus/common/ServerStatsFieldEnumsTest.java b/api/src/test/java/io/opencensus/common/ServerStatsFieldEnumsTest.java new file mode 100644 index 00000000..ed786f6c --- /dev/null +++ b/api/src/test/java/io/opencensus/common/ServerStatsFieldEnumsTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.ServerStatsFieldEnums.Id; +import io.opencensus.common.ServerStatsFieldEnums.Size; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ServerStatsFieldEnums}. */ +@RunWith(JUnit4.class) +public class ServerStatsFieldEnumsTest { + + @Test + public void enumIdValueOfTest() { + assertThat(Id.valueOf(0)).isEqualTo(Id.SERVER_STATS_LB_LATENCY_ID); + assertThat(Id.valueOf(1)).isEqualTo(Id.SERVER_STATS_SERVICE_LATENCY_ID); + assertThat(Id.valueOf(2)).isEqualTo(Id.SERVER_STATS_TRACE_OPTION_ID); + } + + @Test + public void enumIdInvalidValueOfTest() { + assertThat(Id.valueOf(-1)).isNull(); + assertThat(Id.valueOf(Id.values().length)).isNull(); + assertThat(Id.valueOf(Id.values().length + 1)).isNull(); + } + + @Test + public void enumSizeValueTest() { + assertThat(Size.SERVER_STATS_LB_LATENCY_SIZE.value()).isEqualTo(8); + assertThat(Size.SERVER_STATS_SERVICE_LATENCY_SIZE.value()).isEqualTo(8); + assertThat(Size.SERVER_STATS_TRACE_OPTION_SIZE.value()).isEqualTo(1); + } + + @Test + public void totalSizeTest() { + assertThat(ServerStatsFieldEnums.getTotalSize()).isEqualTo(20); + } +} diff --git a/api/src/test/java/io/opencensus/common/ServerStatsTest.java b/api/src/test/java/io/opencensus/common/ServerStatsTest.java new file mode 100644 index 00000000..620bbb4f --- /dev/null +++ b/api/src/test/java/io/opencensus/common/ServerStatsTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ServerStats}. */ +@RunWith(JUnit4.class) +public class ServerStatsTest { + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void serverStatsCreate() { + ServerStats serverStats = null; + + serverStats = ServerStats.create(31, 22, (byte) 0); + assertThat(serverStats.getLbLatencyNs()).isEqualTo(31); + assertThat(serverStats.getServiceLatencyNs()).isEqualTo(22); + assertThat(serverStats.getTraceOption()).isEqualTo((byte) 0); + + serverStats = ServerStats.create(1000011L, 900022L, (byte) 1); + assertThat(serverStats.getLbLatencyNs()).isEqualTo(1000011L); + assertThat(serverStats.getServiceLatencyNs()).isEqualTo(900022L); + assertThat(serverStats.getTraceOption()).isEqualTo((byte) 1); + + serverStats = ServerStats.create(0, 22, (byte) 0); + assertThat(serverStats.getLbLatencyNs()).isEqualTo(0); + assertThat(serverStats.getServiceLatencyNs()).isEqualTo(22); + assertThat(serverStats.getTraceOption()).isEqualTo((byte) 0); + + serverStats = ServerStats.create(1010, 0, (byte) 0); + assertThat(serverStats.getLbLatencyNs()).isEqualTo(1010); + assertThat(serverStats.getServiceLatencyNs()).isEqualTo(0); + assertThat(serverStats.getTraceOption()).isEqualTo((byte) 0); + } + + @Test + public void create_LbLatencyNegative() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'getLbLatencyNs' is less than zero"); + ServerStats.create(-1L, 100, (byte) 0); + } + + @Test + public void create_ServerLatencyNegative() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'getServiceLatencyNs' is less than zero"); + ServerStats.create(100L, -1L, (byte) 0); + } + + @Test + public void create_LbLatencyAndServerLatencyNegative() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'getLbLatencyNs' is less than zero"); + ServerStats.create(-100L, -1L, (byte) 0); + } +} diff --git a/api/src/test/java/io/opencensus/common/TimeUtilsTest.java b/api/src/test/java/io/opencensus/common/TimeUtilsTest.java new file mode 100644 index 00000000..d6228566 --- /dev/null +++ b/api/src/test/java/io/opencensus/common/TimeUtilsTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TimeUtils}. */ +@RunWith(JUnit4.class) +public final class TimeUtilsTest { + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void compareLongs() { + assertThat(TimeUtils.compareLongs(-1L, 1L)).isLessThan(0); + assertThat(TimeUtils.compareLongs(10L, 10L)).isEqualTo(0); + assertThat(TimeUtils.compareLongs(1L, 0L)).isGreaterThan(0); + } + + @Test + public void checkedAdd_TooLow() { + thrown.expect(ArithmeticException.class); + thrown.expectMessage("Long sum overflow: x=-9223372036854775807, y=-2"); + TimeUtils.checkedAdd(Long.MIN_VALUE + 1, -2); + } + + @Test + public void checkedAdd_TooHigh() { + thrown.expect(ArithmeticException.class); + thrown.expectMessage("Long sum overflow: x=9223372036854775806, y=2"); + TimeUtils.checkedAdd(Long.MAX_VALUE - 1, 2); + } + + @Test + public void checkedAdd_Valid() { + assertThat(TimeUtils.checkedAdd(1, 2)).isEqualTo(3); + assertThat(TimeUtils.checkedAdd(Integer.MAX_VALUE, Integer.MAX_VALUE)) + .isEqualTo(2L * Integer.MAX_VALUE); + } +} diff --git a/api/src/test/java/io/opencensus/common/TimestampTest.java b/api/src/test/java/io/opencensus/common/TimestampTest.java new file mode 100644 index 00000000..b193b3c8 --- /dev/null +++ b/api/src/test/java/io/opencensus/common/TimestampTest.java @@ -0,0 +1,217 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.common; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Timestamp}. */ +@RunWith(JUnit4.class) +public class TimestampTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void timestampCreate() { + assertThat(Timestamp.create(24, 42).getSeconds()).isEqualTo(24); + assertThat(Timestamp.create(24, 42).getNanos()).isEqualTo(42); + assertThat(Timestamp.create(-24, 42).getSeconds()).isEqualTo(-24); + assertThat(Timestamp.create(-24, 42).getNanos()).isEqualTo(42); + assertThat(Timestamp.create(315576000000L, 999999999).getSeconds()).isEqualTo(315576000000L); + assertThat(Timestamp.create(315576000000L, 999999999).getNanos()).isEqualTo(999999999); + assertThat(Timestamp.create(-315576000000L, 999999999).getSeconds()).isEqualTo(-315576000000L); + assertThat(Timestamp.create(-315576000000L, 999999999).getNanos()).isEqualTo(999999999); + } + + @Test + public void create_SecondsTooLow() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is less than minimum (-315576000000): -315576000001"); + Timestamp.create(-315576000001L, 0); + } + + @Test + public void create_SecondsTooHigh() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is greater than maximum (315576000000): 315576000001"); + Timestamp.create(315576000001L, 0); + } + + @Test + public void create_NanosTooLow_PositiveTime() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'nanos' is less than zero: -1"); + Timestamp.create(1, -1); + } + + @Test + public void create_NanosTooHigh_PositiveTime() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'nanos' is greater than maximum (999999999): 1000000000"); + Timestamp.create(1, 1000000000); + } + + @Test + public void create_NanosTooLow_NegativeTime() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'nanos' is less than zero: -1"); + Timestamp.create(-1, -1); + } + + @Test + public void create_NanosTooHigh_NegativeTime() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'nanos' is greater than maximum (999999999): 1000000000"); + Timestamp.create(-1, 1000000000); + } + + @Test + public void timestampFromMillis() { + assertThat(Timestamp.fromMillis(0)).isEqualTo(Timestamp.create(0, 0)); + assertThat(Timestamp.fromMillis(987)).isEqualTo(Timestamp.create(0, 987000000)); + assertThat(Timestamp.fromMillis(3456)).isEqualTo(Timestamp.create(3, 456000000)); + } + + @Test + public void timestampFromMillis_Negative() { + assertThat(Timestamp.fromMillis(-1)).isEqualTo(Timestamp.create(-1, 999000000)); + assertThat(Timestamp.fromMillis(-999)).isEqualTo(Timestamp.create(-1, 1000000)); + assertThat(Timestamp.fromMillis(-3456)).isEqualTo(Timestamp.create(-4, 544000000)); + } + + @Test + public void fromMillis_TooLow() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is less than minimum (-315576000000): -315576000001"); + Timestamp.fromMillis(-315576000001000L); + } + + @Test + public void fromMillis_TooHigh() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("'seconds' is greater than maximum (315576000000): 315576000001"); + Timestamp.fromMillis(315576000001000L); + } + + @Test + public void timestampAddNanos() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.addNanos(0)).isEqualTo(timestamp); + assertThat(timestamp.addNanos(999999777)).isEqualTo(Timestamp.create(1235, 0)); + assertThat(timestamp.addNanos(1300200500)).isEqualTo(Timestamp.create(1235, 300200723)); + assertThat(timestamp.addNanos(1999999777)).isEqualTo(Timestamp.create(1236, 0)); + assertThat(timestamp.addNanos(9876543789L)).isEqualTo(Timestamp.create(1243, 876544012)); + assertThat(timestamp.addNanos(Long.MAX_VALUE)) + .isEqualTo(Timestamp.create(1234L + 9223372036L, 223 + 854775807)); + } + + @Test + public void timestampAddNanos_Negative() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.addNanos(-223)).isEqualTo(Timestamp.create(1234, 0)); + assertThat(timestamp.addNanos(-1000000223)).isEqualTo(Timestamp.create(1233, 0)); + assertThat(timestamp.addNanos(-1300200500)).isEqualTo(Timestamp.create(1232, 699799723)); + assertThat(timestamp.addNanos(-4123456213L)).isEqualTo(Timestamp.create(1229, 876544010)); + assertThat(timestamp.addNanos(Long.MIN_VALUE)) + .isEqualTo(Timestamp.create(1234L - 9223372036L - 1, 223 + 145224192)); + } + + @Test + public void timestampAddDuration() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.addDuration(Duration.create(1, 0))).isEqualTo(Timestamp.create(1235, 223)); + assertThat(timestamp.addDuration(Duration.create(0, 1))).isEqualTo(Timestamp.create(1234, 224)); + assertThat(timestamp.addDuration(Duration.create(1, 1))).isEqualTo(Timestamp.create(1235, 224)); + assertThat(timestamp.addDuration(Duration.create(1, 999999900))) + .isEqualTo(Timestamp.create(1236, 123)); + } + + @Test + public void timestampAddDuration_Negative() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.addDuration(Duration.create(-1234, -223))) + .isEqualTo(Timestamp.create(0, 0)); + assertThat(timestamp.addDuration(Duration.create(-1, 0))) + .isEqualTo(Timestamp.create(1233, 223)); + assertThat(timestamp.addDuration(Duration.create(-1, -1))) + .isEqualTo(Timestamp.create(1233, 222)); + assertThat(timestamp.addDuration(Duration.create(-1, -323))) + .isEqualTo(Timestamp.create(1232, 999999900)); + assertThat(timestamp.addDuration(Duration.create(-33, -999999999))) + .isEqualTo(Timestamp.create(1200, 224)); + } + + @Test + public void timestampSubtractTimestamp() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.subtractTimestamp(Timestamp.create(0, 0))) + .isEqualTo(Duration.create(1234, 223)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1233, 223))) + .isEqualTo(Duration.create(1, 0)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1233, 222))) + .isEqualTo(Duration.create(1, 1)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1232, 999999900))) + .isEqualTo(Duration.create(1, 323)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1200, 224))) + .isEqualTo(Duration.create(33, 999999999)); + } + + @Test + public void timestampSubtractTimestamp_NegativeResult() { + Timestamp timestamp = Timestamp.create(1234, 223); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1235, 223))) + .isEqualTo(Duration.create(-1, 0)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1234, 224))) + .isEqualTo(Duration.create(0, -1)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1235, 224))) + .isEqualTo(Duration.create(-1, -1)); + assertThat(timestamp.subtractTimestamp(Timestamp.create(1236, 123))) + .isEqualTo(Duration.create(-1, -999999900)); + } + + @Test + public void timestamp_CompareTo() { + assertThat(Timestamp.create(0, 0).compareTo(Timestamp.create(0, 0))).isEqualTo(0); + assertThat(Timestamp.create(24, 42).compareTo(Timestamp.create(24, 42))).isEqualTo(0); + assertThat(Timestamp.create(-24, 42).compareTo(Timestamp.create(-24, 42))).isEqualTo(0); + assertThat(Timestamp.create(25, 42).compareTo(Timestamp.create(24, 42))).isEqualTo(1); + assertThat(Timestamp.create(24, 45).compareTo(Timestamp.create(24, 42))).isEqualTo(1); + assertThat(Timestamp.create(24, 42).compareTo(Timestamp.create(25, 42))).isEqualTo(-1); + assertThat(Timestamp.create(24, 42).compareTo(Timestamp.create(24, 45))).isEqualTo(-1); + assertThat(Timestamp.create(-25, 42).compareTo(Timestamp.create(-24, 42))).isEqualTo(-1); + assertThat(Timestamp.create(-24, 45).compareTo(Timestamp.create(-24, 42))).isEqualTo(1); + assertThat(Timestamp.create(-24, 42).compareTo(Timestamp.create(-25, 42))).isEqualTo(1); + assertThat(Timestamp.create(-24, 42).compareTo(Timestamp.create(-24, 45))).isEqualTo(-1); + } + + @Test + public void timestamp_Equal() { + // Positive tests. + assertThat(Timestamp.create(0, 0)).isEqualTo(Timestamp.create(0, 0)); + assertThat(Timestamp.create(24, 42)).isEqualTo(Timestamp.create(24, 42)); + assertThat(Timestamp.create(-24, 42)).isEqualTo(Timestamp.create(-24, 42)); + // Negative tests. + assertThat(Timestamp.create(25, 42)).isNotEqualTo(Timestamp.create(24, 42)); + assertThat(Timestamp.create(24, 43)).isNotEqualTo(Timestamp.create(24, 42)); + assertThat(Timestamp.create(-25, 42)).isNotEqualTo(Timestamp.create(-24, 42)); + assertThat(Timestamp.create(-24, 43)).isNotEqualTo(Timestamp.create(-24, 42)); + } +} diff --git a/api/src/test/java/io/opencensus/internal/ProviderTest.java b/api/src/test/java/io/opencensus/internal/ProviderTest.java new file mode 100644 index 00000000..1f4c33fa --- /dev/null +++ b/api/src/test/java/io/opencensus/internal/ProviderTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.internal; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.ServiceConfigurationError; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Provider}. */ +@RunWith(JUnit4.class) +public class ProviderTest { + static class GoodClass { + public GoodClass() {} + } + + static class PrivateConstructorClass { + private PrivateConstructorClass() {} + } + + static class NoDefaultConstructorClass { + public NoDefaultConstructorClass(int arg) {} + } + + private static class PrivateClass {} + + static interface MyInterface {} + + static class MyInterfaceImpl implements MyInterface { + public MyInterfaceImpl() {} + } + + @Test(expected = ServiceConfigurationError.class) + public void createInstance_ThrowsErrorWhenClassIsPrivate() throws ClassNotFoundException { + Provider.createInstance( + Class.forName( + "io.opencensus.internal.ProviderTest$PrivateClass", + true, + ProviderTest.class.getClassLoader()), + PrivateClass.class); + } + + @Test(expected = ServiceConfigurationError.class) + public void createInstance_ThrowsErrorWhenClassHasPrivateConstructor() + throws ClassNotFoundException { + Provider.createInstance( + Class.forName( + "io.opencensus.internal.ProviderTest$PrivateConstructorClass", + true, + ProviderTest.class.getClassLoader()), + PrivateConstructorClass.class); + } + + @Test(expected = ServiceConfigurationError.class) + public void createInstance_ThrowsErrorWhenClassDoesNotHaveDefaultConstructor() + throws ClassNotFoundException { + Provider.createInstance( + Class.forName( + "io.opencensus.internal.ProviderTest$NoDefaultConstructorClass", + true, + ProviderTest.class.getClassLoader()), + NoDefaultConstructorClass.class); + } + + @Test(expected = ServiceConfigurationError.class) + public void createInstance_ThrowsErrorWhenClassIsNotASubclass() throws ClassNotFoundException { + Provider.createInstance( + Class.forName( + "io.opencensus.internal.ProviderTest$GoodClass", + true, + ProviderTest.class.getClassLoader()), + MyInterface.class); + } + + @Test + public void createInstance_GoodClass() throws ClassNotFoundException { + assertThat( + Provider.createInstance( + Class.forName( + "io.opencensus.internal.ProviderTest$GoodClass", + true, + ProviderTest.class.getClassLoader()), + GoodClass.class)) + .isNotNull(); + } + + @Test + public void createInstance_GoodSubclass() throws ClassNotFoundException { + assertThat( + Provider.createInstance( + Class.forName( + "io.opencensus.internal.ProviderTest$MyInterfaceImpl", + true, + ProviderTest.class.getClassLoader()), + MyInterface.class)) + .isNotNull(); + } +} diff --git a/api/src/test/java/io/opencensus/internal/StringUtilsTest.java b/api/src/test/java/io/opencensus/internal/StringUtilsTest.java new file mode 100644 index 00000000..5e866940 --- /dev/null +++ b/api/src/test/java/io/opencensus/internal/StringUtilsTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.internal; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link StringUtils}. */ +@RunWith(JUnit4.class) +public final class StringUtilsTest { + + @Test + public void isPrintableString() { + assertTrue(StringUtils.isPrintableString("abcd")); + assertFalse(StringUtils.isPrintableString("\2ab\3cd")); + } +} diff --git a/api/src/test/java/io/opencensus/internal/UtilsTest.java b/api/src/test/java/io/opencensus/internal/UtilsTest.java new file mode 100644 index 00000000..608a8fe0 --- /dev/null +++ b/api/src/test/java/io/opencensus/internal/UtilsTest.java @@ -0,0 +1,144 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.internal; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Date; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Utils}. */ +@RunWith(JUnit4.class) +public final class UtilsTest { + private static final String TEST_MESSAGE = "test message"; + private static final String TEST_MESSAGE_TEMPLATE = "I ate %s eggs."; + private static final int TEST_MESSAGE_VALUE = 2; + private static final String FORMATED_SIMPLE_TEST_MESSAGE = "I ate 2 eggs."; + private static final String FORMATED_COMPLEX_TEST_MESSAGE = "I ate 2 eggs. [2]"; + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void checkArgument() { + Utils.checkArgument(true, TEST_MESSAGE); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(TEST_MESSAGE); + Utils.checkArgument(false, TEST_MESSAGE); + } + + @Test + public void checkArgument_NullErrorMessage() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("null"); + Utils.checkArgument(false, null); + } + + @Test + public void checkArgument_WithSimpleFormat() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(FORMATED_SIMPLE_TEST_MESSAGE); + Utils.checkArgument(false, TEST_MESSAGE_TEMPLATE, TEST_MESSAGE_VALUE); + } + + @Test + public void checkArgument_WithComplexFormat() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(FORMATED_COMPLEX_TEST_MESSAGE); + Utils.checkArgument(false, TEST_MESSAGE_TEMPLATE, TEST_MESSAGE_VALUE, TEST_MESSAGE_VALUE); + } + + @Test + public void checkState() { + Utils.checkNotNull(true, TEST_MESSAGE); + thrown.expect(IllegalStateException.class); + thrown.expectMessage(TEST_MESSAGE); + Utils.checkState(false, TEST_MESSAGE); + } + + @Test + public void checkState_NullErrorMessage() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("null"); + Utils.checkState(false, null); + } + + @Test + public void checkNotNull() { + Utils.checkNotNull(new Object(), TEST_MESSAGE); + thrown.expect(NullPointerException.class); + thrown.expectMessage(TEST_MESSAGE); + Utils.checkNotNull(null, TEST_MESSAGE); + } + + @Test + public void checkNotNull_NullErrorMessage() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("null"); + Utils.checkNotNull(null, null); + } + + @Test + public void checkIndex_Valid() { + Utils.checkIndex(1, 2); + } + + @Test + public void checkIndex_NegativeSize() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Negative size: -1"); + Utils.checkIndex(0, -1); + } + + @Test + public void checkIndex_NegativeIndex() { + thrown.expect(IndexOutOfBoundsException.class); + thrown.expectMessage("Index out of bounds: size=10, index=-2"); + Utils.checkIndex(-2, 10); + } + + @Test + public void checkIndex_IndexEqualToSize() { + thrown.expect(IndexOutOfBoundsException.class); + thrown.expectMessage("Index out of bounds: size=5, index=5"); + Utils.checkIndex(5, 5); + } + + @Test + public void checkIndex_IndexGreaterThanSize() { + thrown.expect(IndexOutOfBoundsException.class); + thrown.expectMessage("Index out of bounds: size=10, index=11"); + Utils.checkIndex(11, 10); + } + + @Test + public void equalsObjects_Equal() { + assertTrue(Utils.equalsObjects(null, null)); + assertTrue(Utils.equalsObjects(new Date(1L), new Date(1L))); + } + + @Test + public void equalsObjects_Unequal() { + assertFalse(Utils.equalsObjects(null, new Object())); + assertFalse(Utils.equalsObjects(new Object(), null)); + assertFalse(Utils.equalsObjects(new Object(), new Object())); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/DerivedDoubleGaugeTest.java b/api/src/test/java/io/opencensus/metrics/DerivedDoubleGaugeTest.java new file mode 100644 index 00000000..dbae3c49 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/DerivedDoubleGaugeTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import io.opencensus.common.ToDoubleFunction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DerivedDoubleGauge}. */ +// TODO(mayurkale): Add more tests, once DerivedDoubleGauge plugs-in into the registry. +@RunWith(JUnit4.class) +public class DerivedDoubleGaugeTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String UNIT = "1"; + private static final List<LabelKey> LABEL_KEY = + Collections.singletonList(LabelKey.create("key", "key description")); + private static final List<LabelValue> LABEL_VALUES = + Collections.singletonList(LabelValue.create("value")); + private static final List<LabelValue> EMPTY_LABEL_VALUES = new ArrayList<LabelValue>(); + + private final DerivedDoubleGauge derivedDoubleGauge = + DerivedDoubleGauge.newNoopDerivedDoubleGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + private static final ToDoubleFunction<Object> doubleFunction = + new ToDoubleFunction<Object>() { + @Override + public double applyAsDouble(Object value) { + return 5.0; + } + }; + + @Test + public void noopCreateTimeSeries_WithNullLabelValues() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + derivedDoubleGauge.createTimeSeries(null, null, doubleFunction); + } + + @Test + public void noopCreateTimeSeries_WithNullElement() { + List<LabelValue> labelValues = Collections.singletonList(null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValue element should not be null."); + derivedDoubleGauge.createTimeSeries(labelValues, null, doubleFunction); + } + + @Test + public void noopCreateTimeSeries_WithInvalidLabelSize() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Incorrect number of labels."); + derivedDoubleGauge.createTimeSeries(EMPTY_LABEL_VALUES, null, doubleFunction); + } + + @Test + public void createTimeSeries_WithNullFunction() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("function"); + derivedDoubleGauge.createTimeSeries(LABEL_VALUES, null, null); + } + + @Test + public void noopRemoveTimeSeries_WithNullLabelValues() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + derivedDoubleGauge.removeTimeSeries(null); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/DerivedLongGaugeTest.java b/api/src/test/java/io/opencensus/metrics/DerivedLongGaugeTest.java new file mode 100644 index 00000000..6a462881 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/DerivedLongGaugeTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import io.opencensus.common.ToLongFunction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DerivedLongGauge}. */ +// TODO(mayurkale): Add more tests, once DerivedLongGauge plugs-in into the registry. +@RunWith(JUnit4.class) +public class DerivedLongGaugeTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String UNIT = "1"; + private static final List<LabelKey> LABEL_KEY = + Collections.singletonList(LabelKey.create("key", "key description")); + private static final List<LabelValue> LABEL_VALUES = + Collections.singletonList(LabelValue.create("value")); + private static final List<LabelValue> EMPTY_LABEL_VALUES = new ArrayList<LabelValue>(); + + private final DerivedLongGauge derivedLongGauge = + DerivedLongGauge.newNoopDerivedLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + private static final ToLongFunction<Object> longFunction = + new ToLongFunction<Object>() { + @Override + public long applyAsLong(Object value) { + return 5; + } + }; + + @Test + public void noopCreateTimeSeries_WithNullLabelValues() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + derivedLongGauge.createTimeSeries(null, null, longFunction); + } + + @Test + public void noopCreateTimeSeries_WithNullElement() { + List<LabelValue> labelValues = Collections.singletonList(null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValue element should not be null."); + derivedLongGauge.createTimeSeries(labelValues, null, longFunction); + } + + @Test + public void noopCreateTimeSeries_WithInvalidLabelSize() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Incorrect number of labels."); + derivedLongGauge.createTimeSeries(EMPTY_LABEL_VALUES, null, longFunction); + } + + @Test + public void createTimeSeries_WithNullFunction() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("function"); + derivedLongGauge.createTimeSeries(LABEL_VALUES, null, null); + } + + @Test + public void noopRemoveTimeSeries_WithNullLabelValues() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + derivedLongGauge.removeTimeSeries(null); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/DoubleGaugeTest.java b/api/src/test/java/io/opencensus/metrics/DoubleGaugeTest.java new file mode 100644 index 00000000..b0cdea7c --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/DoubleGaugeTest.java @@ -0,0 +1,88 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link DoubleGauge}. */ +@RunWith(JUnit4.class) +public class DoubleGaugeTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String UNIT = "1"; + private static final List<LabelKey> LABEL_KEY = + Collections.singletonList(LabelKey.create("key", "key description")); + private static final List<LabelValue> LABEL_VALUES = + Collections.singletonList(LabelValue.create("value")); + private static final List<LabelKey> EMPTY_LABEL_KEYS = new ArrayList<LabelKey>(); + private static final List<LabelValue> EMPTY_LABEL_VALUES = new ArrayList<LabelValue>(); + + // TODO(mayurkale): Add more tests, once DoubleGauge plugs-in into the registry. + + @Test + public void noopGetOrCreateTimeSeries_WithNullLabelValues() { + DoubleGauge doubleGauge = + DoubleGauge.newNoopDoubleGauge(NAME, DESCRIPTION, UNIT, EMPTY_LABEL_KEYS); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + doubleGauge.getOrCreateTimeSeries(null); + } + + @Test + public void noopGetOrCreateTimeSeries_WithNullElement() { + List<LabelValue> labelValues = Collections.singletonList(null); + DoubleGauge doubleGauge = DoubleGauge.newNoopDoubleGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValue element should not be null."); + doubleGauge.getOrCreateTimeSeries(labelValues); + } + + @Test + public void noopGetOrCreateTimeSeries_WithInvalidLabelSize() { + DoubleGauge doubleGauge = DoubleGauge.newNoopDoubleGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Incorrect number of labels."); + doubleGauge.getOrCreateTimeSeries(EMPTY_LABEL_VALUES); + } + + @Test + public void noopRemoveTimeSeries_WithNullLabelValues() { + DoubleGauge doubleGauge = DoubleGauge.newNoopDoubleGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + doubleGauge.removeTimeSeries(null); + } + + @Test + public void noopSameAs() { + DoubleGauge doubleGauge = DoubleGauge.newNoopDoubleGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + assertThat(doubleGauge.getDefaultTimeSeries()).isSameAs(doubleGauge.getDefaultTimeSeries()); + assertThat(doubleGauge.getDefaultTimeSeries()) + .isSameAs(doubleGauge.getOrCreateTimeSeries(LABEL_VALUES)); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/LabelKeyTest.java b/api/src/test/java/io/opencensus/metrics/LabelKeyTest.java new file mode 100644 index 00000000..83f2b59a --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/LabelKeyTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link LabelKey}. */ +@RunWith(JUnit4.class) +public class LabelKeyTest { + + private static final LabelKey KEY = LabelKey.create("key", "description"); + + @Test + public void testGetKey() { + assertThat(KEY.getKey()).isEqualTo("key"); + } + + @Test + public void testGetDescription() { + assertThat(KEY.getDescription()).isEqualTo("description"); + } + + @Test + public void create_NoLengthConstraint() { + // We have a length constraint of 256-characters for TagKey. That constraint doesn't apply to + // LabelKey. + char[] chars = new char[300]; + Arrays.fill(chars, 'k'); + String key = new String(chars); + assertThat(LabelKey.create(key, "").getKey()).isEqualTo(key); + } + + @Test + public void create_WithUnprintableChars() { + String key = "\2ab\3cd"; + String description = "\4ef\5gh"; + LabelKey labelKey = LabelKey.create(key, description); + assertThat(labelKey.getKey()).isEqualTo(key); + assertThat(labelKey.getDescription()).isEqualTo(description); + } + + @Test + public void create_WithNonAsciiChars() { + String key = "键"; + String description = "测试用键"; + LabelKey nonAsciiKey = LabelKey.create(key, description); + assertThat(nonAsciiKey.getKey()).isEqualTo(key); + assertThat(nonAsciiKey.getDescription()).isEqualTo(description); + } + + @Test + public void create_Empty() { + LabelKey emptyKey = LabelKey.create("", ""); + assertThat(emptyKey.getKey()).isEmpty(); + assertThat(emptyKey.getDescription()).isEmpty(); + } + + @Test + public void testLabelKeyEquals() { + new EqualsTester() + .addEqualityGroup(LabelKey.create("foo", ""), LabelKey.create("foo", "")) + .addEqualityGroup(LabelKey.create("foo", "description")) + .addEqualityGroup(LabelKey.create("bar", "")) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/LabelValueTest.java b/api/src/test/java/io/opencensus/metrics/LabelValueTest.java new file mode 100644 index 00000000..e5526b2f --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/LabelValueTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link LabelValue}. */ +@RunWith(JUnit4.class) +public class LabelValueTest { + + private static final LabelValue VALUE = LabelValue.create("value"); + private static final LabelValue UNSET = LabelValue.create(null); + private static final LabelValue EMPTY = LabelValue.create(""); + + @Test + public void testGetValue() { + assertThat(VALUE.getValue()).isEqualTo("value"); + assertThat(UNSET.getValue()).isNull(); + assertThat(EMPTY.getValue()).isEmpty(); + } + + @Test + public void create_NoLengthConstraint() { + // We have a length constraint of 256-characters for TagValue. That constraint doesn't apply to + // LabelValue. + char[] chars = new char[300]; + Arrays.fill(chars, 'v'); + String value = new String(chars); + assertThat(LabelValue.create(value).getValue()).isEqualTo(value); + } + + @Test + public void create_WithUnprintableChars() { + String value = "\2ab\3cd"; + assertThat(LabelValue.create(value).getValue()).isEqualTo(value); + } + + @Test + public void create_WithNonAsciiChars() { + String value = "值"; + LabelValue nonAsciiValue = LabelValue.create(value); + assertThat(nonAsciiValue.getValue()).isEqualTo(value); + } + + @Test + public void testLabelValueEquals() { + new EqualsTester() + .addEqualityGroup(LabelValue.create("foo"), LabelValue.create("foo")) + .addEqualityGroup(UNSET) + .addEqualityGroup(EMPTY) + .addEqualityGroup(LabelValue.create("bar")) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/LongGaugeTest.java b/api/src/test/java/io/opencensus/metrics/LongGaugeTest.java new file mode 100644 index 00000000..eedb287c --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/LongGaugeTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link LongGauge}. */ +@RunWith(JUnit4.class) +public class LongGaugeTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + private static final String NAME = "name"; + private static final String DESCRIPTION = "description"; + private static final String UNIT = "1"; + private static final List<LabelKey> LABEL_KEY = + Collections.singletonList(LabelKey.create("key", "key description")); + private static final List<LabelValue> LABEL_VALUES = + Collections.singletonList(LabelValue.create("value")); + private static final List<LabelKey> EMPTY_LABEL_KEYS = new ArrayList<LabelKey>(); + private static final List<LabelValue> EMPTY_LABEL_VALUES = new ArrayList<LabelValue>(); + + // TODO(mayurkale): Add more tests, once LongGauge plugs-in into the registry. + + @Test + public void noopGetOrCreateTimeSeries_WithNullLabelValues() { + LongGauge longGauge = LongGauge.newNoopLongGauge(NAME, DESCRIPTION, UNIT, EMPTY_LABEL_KEYS); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + longGauge.getOrCreateTimeSeries(null); + } + + @Test + public void noopGetOrCreateTimeSeries_WithNullElement() { + List<LabelValue> labelValues = Collections.singletonList(null); + LongGauge longGauge = LongGauge.newNoopLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValue element should not be null."); + longGauge.getOrCreateTimeSeries(labelValues); + } + + @Test + public void noopGetOrCreateTimeSeries_WithInvalidLabelSize() { + LongGauge longGauge = LongGauge.newNoopLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Incorrect number of labels."); + longGauge.getOrCreateTimeSeries(EMPTY_LABEL_VALUES); + } + + @Test + public void noopRemoveTimeSeries_WithNullLabelValues() { + LongGauge longGauge = LongGauge.newNoopLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelValues"); + longGauge.removeTimeSeries(null); + } + + @Test + public void noopSameAs() { + LongGauge longGauge = LongGauge.newNoopLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + assertThat(longGauge.getDefaultTimeSeries()).isSameAs(longGauge.getDefaultTimeSeries()); + assertThat(longGauge.getDefaultTimeSeries()) + .isSameAs(longGauge.getOrCreateTimeSeries(LABEL_VALUES)); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/MetricRegistryTest.java b/api/src/test/java/io/opencensus/metrics/MetricRegistryTest.java new file mode 100644 index 00000000..d8a26cc8 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/MetricRegistryTest.java @@ -0,0 +1,220 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link MetricRegistry}. */ +@RunWith(JUnit4.class) +public class MetricRegistryTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + private static final String NAME = "name"; + private static final String NAME_2 = "name2"; + private static final String NAME_3 = "name3"; + private static final String NAME_4 = "name4"; + private static final String DESCRIPTION = "description"; + private static final String UNIT = "1"; + private static final List<LabelKey> LABEL_KEY = + Collections.singletonList(LabelKey.create("key", "key description")); + private static final List<LabelValue> LABEL_VALUES = + Collections.singletonList(LabelValue.create("value")); + private final MetricRegistry metricRegistry = + MetricsComponent.newNoopMetricsComponent().getMetricRegistry(); + + @Test + public void noopAddLongGauge_NullName() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("name"); + metricRegistry.addLongGauge(null, DESCRIPTION, UNIT, LABEL_KEY); + } + + @Test + public void noopAddLongGauge_NullDescription() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("description"); + metricRegistry.addLongGauge(NAME, null, UNIT, LABEL_KEY); + } + + @Test + public void noopAddLongGauge_NullUnit() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("unit"); + metricRegistry.addLongGauge(NAME, DESCRIPTION, null, LABEL_KEY); + } + + @Test + public void noopAddLongGauge_NullLabels() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKeys"); + metricRegistry.addLongGauge(NAME, DESCRIPTION, UNIT, null); + } + + @Test + public void noopAddLongGauge_WithNullElement() { + List<LabelKey> labelKeys = Collections.singletonList(null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKey element should not be null."); + metricRegistry.addLongGauge(NAME, DESCRIPTION, UNIT, labelKeys); + } + + @Test + public void noopAddDoubleGauge_NullName() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("name"); + metricRegistry.addDoubleGauge(null, DESCRIPTION, UNIT, LABEL_KEY); + } + + @Test + public void noopAddDoubleGauge_NullDescription() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("description"); + metricRegistry.addDoubleGauge(NAME_2, null, UNIT, LABEL_KEY); + } + + @Test + public void noopAddDoubleGauge_NullUnit() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("unit"); + metricRegistry.addDoubleGauge(NAME_2, DESCRIPTION, null, LABEL_KEY); + } + + @Test + public void noopAddDoubleGauge_NullLabels() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKeys"); + metricRegistry.addDoubleGauge(NAME_2, DESCRIPTION, UNIT, null); + } + + @Test + public void noopAddDoubleGauge_WithNullElement() { + List<LabelKey> labelKeys = Collections.singletonList(null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKey element should not be null."); + metricRegistry.addDoubleGauge(NAME_2, DESCRIPTION, UNIT, labelKeys); + } + + @Test + public void noopAddDerivedLongGauge_NullName() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("name"); + metricRegistry.addDerivedLongGauge(null, DESCRIPTION, UNIT, LABEL_KEY); + } + + @Test + public void noopAddDerivedLongGauge_NullDescription() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("description"); + metricRegistry.addDerivedLongGauge(NAME_3, null, UNIT, LABEL_KEY); + } + + @Test + public void noopAddDerivedLongGauge_NullUnit() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("unit"); + metricRegistry.addDerivedLongGauge(NAME_3, DESCRIPTION, null, LABEL_KEY); + } + + @Test + public void noopAddDerivedLongGauge_NullLabels() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKeys"); + metricRegistry.addDerivedLongGauge(NAME_3, DESCRIPTION, UNIT, null); + } + + @Test + public void noopAddDerivedLongGauge_WithNullElement() { + List<LabelKey> labelKeys = Collections.singletonList(null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKey element should not be null."); + metricRegistry.addDerivedLongGauge(NAME_3, DESCRIPTION, UNIT, labelKeys); + } + + @Test + public void noopAddDerivedDoubleGauge_NullName() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("name"); + metricRegistry.addDerivedDoubleGauge(null, DESCRIPTION, UNIT, LABEL_KEY); + } + + @Test + public void noopAddDerivedDoubleGauge_NullDescription() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("description"); + metricRegistry.addDerivedDoubleGauge(NAME_4, null, UNIT, LABEL_KEY); + } + + @Test + public void noopAddDerivedDoubleGauge_NullUnit() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("unit"); + metricRegistry.addDerivedDoubleGauge(NAME_4, DESCRIPTION, null, LABEL_KEY); + } + + @Test + public void noopAddDerivedDoubleGauge_NullLabels() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKeys"); + metricRegistry.addDerivedDoubleGauge(NAME_4, DESCRIPTION, UNIT, null); + } + + @Test + public void noopAddDerivedDoubleGauge_WithNullElement() { + List<LabelKey> labelKeys = Collections.singletonList(null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("labelKey element should not be null."); + metricRegistry.addDerivedDoubleGauge(NAME_4, DESCRIPTION, UNIT, labelKeys); + } + + @Test + public void noopSameAs() { + LongGauge longGauge = metricRegistry.addLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY); + assertThat(longGauge.getDefaultTimeSeries()).isSameAs(longGauge.getDefaultTimeSeries()); + assertThat(longGauge.getDefaultTimeSeries()) + .isSameAs(longGauge.getOrCreateTimeSeries(LABEL_VALUES)); + + DoubleGauge doubleGauge = metricRegistry.addDoubleGauge(NAME_2, DESCRIPTION, UNIT, LABEL_KEY); + assertThat(doubleGauge.getDefaultTimeSeries()).isSameAs(doubleGauge.getDefaultTimeSeries()); + assertThat(doubleGauge.getDefaultTimeSeries()) + .isSameAs(doubleGauge.getOrCreateTimeSeries(LABEL_VALUES)); + } + + @Test + public void noopInstanceOf() { + assertThat(metricRegistry.addLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY)) + .isInstanceOf(LongGauge.newNoopLongGauge(NAME, DESCRIPTION, UNIT, LABEL_KEY).getClass()); + assertThat(metricRegistry.addDoubleGauge(NAME_2, DESCRIPTION, UNIT, LABEL_KEY)) + .isInstanceOf( + DoubleGauge.newNoopDoubleGauge(NAME_2, DESCRIPTION, UNIT, LABEL_KEY).getClass()); + assertThat(metricRegistry.addDerivedLongGauge(NAME_3, DESCRIPTION, UNIT, LABEL_KEY)) + .isInstanceOf( + DerivedLongGauge.newNoopDerivedLongGauge(NAME_3, DESCRIPTION, UNIT, LABEL_KEY) + .getClass()); + assertThat(metricRegistry.addDerivedDoubleGauge(NAME_4, DESCRIPTION, UNIT, LABEL_KEY)) + .isInstanceOf( + DerivedDoubleGauge.newNoopDerivedDoubleGauge(NAME_4, DESCRIPTION, UNIT, LABEL_KEY) + .getClass()); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/MetricsComponentTest.java b/api/src/test/java/io/opencensus/metrics/MetricsComponentTest.java new file mode 100644 index 00000000..1c4e70f7 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/MetricsComponentTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.metrics.export.ExportComponent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link MetricsComponent}. */ +@RunWith(JUnit4.class) +public class MetricsComponentTest { + @Test + public void defaultExportComponent() { + assertThat(MetricsComponent.newNoopMetricsComponent().getExportComponent()) + .isInstanceOf(ExportComponent.newNoopExportComponent().getClass()); + } + + @Test + public void defaultMetricRegistry() { + assertThat(MetricsComponent.newNoopMetricsComponent().getMetricRegistry()) + .isInstanceOf(MetricRegistry.newNoopMetricRegistry().getClass()); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/MetricsTest.java b/api/src/test/java/io/opencensus/metrics/MetricsTest.java new file mode 100644 index 00000000..9e0eee1f --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/MetricsTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.metrics.export.ExportComponent; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Metrics}. */ +@RunWith(JUnit4.class) +public class MetricsTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void loadMetricsComponent_UsesProvidedClassLoader() { + final RuntimeException toThrow = new RuntimeException("UseClassLoader"); + thrown.expect(RuntimeException.class); + thrown.expectMessage("UseClassLoader"); + Metrics.loadMetricsComponent( + new ClassLoader() { + @Override + public Class<?> loadClass(String name) { + throw toThrow; + } + }); + } + + @Test + public void loadMetricsComponent_IgnoresMissingClasses() { + ClassLoader classLoader = + new ClassLoader() { + @Override + public Class<?> loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }; + assertThat(Metrics.loadMetricsComponent(classLoader).getClass().getName()) + .isEqualTo("io.opencensus.metrics.MetricsComponent$NoopMetricsComponent"); + } + + @Test + public void defaultExportComponent() { + assertThat(Metrics.getExportComponent()) + .isInstanceOf(ExportComponent.newNoopExportComponent().getClass()); + } + + @Test + public void defaultMetricRegistry() { + assertThat(Metrics.getMetricRegistry()) + .isInstanceOf(MetricRegistry.newNoopMetricRegistry().getClass()); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/DistributionTest.java b/api/src/test/java/io/opencensus/metrics/export/DistributionTest.java new file mode 100644 index 00000000..85b31498 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/DistributionTest.java @@ -0,0 +1,331 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; +import io.opencensus.metrics.export.Distribution.Bucket; +import io.opencensus.metrics.export.Distribution.BucketOptions; +import io.opencensus.metrics.export.Distribution.BucketOptions.ExplicitOptions; +import io.opencensus.metrics.export.Distribution.Exemplar; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Distribution}. */ +@RunWith(JUnit4.class) +public class DistributionTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + private static final Timestamp TIMESTAMP = Timestamp.create(1, 0); + private static final Map<String, String> ATTACHMENTS = Collections.singletonMap("key", "value"); + private static final double TOLERANCE = 1e-6; + + @Test + public void createAndGet_Bucket() { + Bucket bucket = Bucket.create(98); + assertThat(bucket.getCount()).isEqualTo(98); + assertThat(bucket.getExemplar()).isNull(); + } + + @Test + public void createAndGet_BucketWithExemplar() { + Exemplar exemplar = Exemplar.create(12.2, TIMESTAMP, ATTACHMENTS); + Bucket bucket = Bucket.create(7, exemplar); + assertThat(bucket.getCount()).isEqualTo(7); + assertThat(bucket.getExemplar()).isEqualTo(exemplar); + } + + @Test + public void createBucket_preventNullExemplar() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("exemplar"); + Bucket.create(1, null); + } + + @Test + public void createAndGet_Exemplar() { + Exemplar exemplar = Exemplar.create(-9.9, TIMESTAMP, ATTACHMENTS); + assertThat(exemplar.getValue()).isWithin(TOLERANCE).of(-9.9); + assertThat(exemplar.getTimestamp()).isEqualTo(TIMESTAMP); + assertThat(exemplar.getAttachments()).isEqualTo(ATTACHMENTS); + } + + @Test + public void createAndGet_ExplicitBuckets() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 3.0); + + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + final List<Double> actual = new ArrayList<Double>(); + bucketOptions.match( + new Function<ExplicitOptions, Object>() { + @Override + public Object apply(ExplicitOptions arg) { + actual.addAll(arg.getBucketBoundaries()); + return null; + } + }, + Functions.throwAssertionError()); + + assertThat(actual).containsExactlyElementsIn(bucketBounds).inOrder(); + } + + @Test + public void createAndGet_ExplicitBucketsNegativeBounds() { + List<Double> bucketBounds = Collections.singletonList(-1.0); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("bucket boundary should be > 0"); + BucketOptions.explicitOptions(bucketBounds); + } + + @Test + public void createAndGet_PreventNullExplicitBuckets() { + thrown.expect(NullPointerException.class); + BucketOptions.explicitOptions(Arrays.asList(1.0, null, 3.0)); + } + + @Test + public void createAndGet_ExplicitBucketsEmptyBounds() { + List<Double> bucketBounds = new ArrayList<Double>(); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + + final List<Double> actual = new ArrayList<Double>(); + bucketOptions.match( + new Function<ExplicitOptions, Object>() { + @Override + public Object apply(ExplicitOptions arg) { + actual.addAll(arg.getBucketBoundaries()); + return null; + } + }, + Functions.throwAssertionError()); + + assertThat(actual).isEmpty(); + } + + @Test + public void createBucketOptions_UnorderedBucketBounds() { + List<Double> bucketBounds = Arrays.asList(1.0, 5.0, 2.0); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("bucket boundaries not sorted."); + BucketOptions.explicitOptions(bucketBounds); + } + + @Test + public void createAndGet_PreventNullBucketOptions() { + thrown.expect(NullPointerException.class); + BucketOptions.explicitOptions(null); + } + + @Test + public void createAndGet_Distribution() { + Exemplar exemplar = Exemplar.create(15.0, TIMESTAMP, ATTACHMENTS); + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + List<Bucket> buckets = + Arrays.asList( + Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4, exemplar)); + Distribution distribution = Distribution.create(10, 6.6, 678.54, bucketOptions, buckets); + assertThat(distribution.getCount()).isEqualTo(10); + assertThat(distribution.getSum()).isWithin(TOLERANCE).of(6.6); + assertThat(distribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(678.54); + + final List<Double> actual = new ArrayList<Double>(); + distribution + .getBucketOptions() + .match( + new Function<ExplicitOptions, Object>() { + @Override + public Object apply(ExplicitOptions arg) { + actual.addAll(arg.getBucketBoundaries()); + return null; + } + }, + Functions.throwAssertionError()); + + assertThat(actual).containsExactlyElementsIn(bucketBounds).inOrder(); + + assertThat(distribution.getBuckets()).containsExactlyElementsIn(buckets).inOrder(); + } + + @Test + public void createBucket_NegativeCount() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("bucket count should be non-negative."); + Bucket.create(-5); + } + + @Test + public void createExemplar_PreventNullAttachments() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("attachments"); + Exemplar.create(15, TIMESTAMP, null); + } + + @Test + public void createExemplar_PreventNullAttachmentKey() { + Map<String, String> attachments = Collections.singletonMap(null, "value"); + thrown.expect(NullPointerException.class); + thrown.expectMessage("key of attachment"); + Exemplar.create(15, TIMESTAMP, attachments); + } + + @Test + public void createExemplar_PreventNullAttachmentValue() { + Map<String, String> attachments = Collections.singletonMap("key", null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("value of attachment"); + Exemplar.create(15, TIMESTAMP, attachments); + } + + @Test + public void createDistribution_NegativeCount() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + + List<Bucket> buckets = + Arrays.asList(Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("count should be non-negative."); + Distribution.create(-10, 6.6, 678.54, bucketOptions, buckets); + } + + @Test + public void createDistribution_NegativeSumOfSquaredDeviations() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + + List<Bucket> buckets = + Arrays.asList(Bucket.create(0), Bucket.create(0), Bucket.create(0), Bucket.create(0)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum of squared deviations should be non-negative."); + Distribution.create(0, 6.6, -678.54, bucketOptions, buckets); + } + + @Test + public void createDistribution_ZeroCountAndPositiveMean() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + + List<Bucket> buckets = + Arrays.asList(Bucket.create(0), Bucket.create(0), Bucket.create(0), Bucket.create(0)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum should be 0 if count is 0."); + Distribution.create(0, 6.6, 0, bucketOptions, buckets); + } + + @Test + public void createDistribution_ZeroCountAndSumOfSquaredDeviations() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + List<Bucket> buckets = + Arrays.asList(Bucket.create(0), Bucket.create(0), Bucket.create(0), Bucket.create(0)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum of squared deviations should be 0 if count is 0."); + Distribution.create(0, 0, 678.54, bucketOptions, buckets); + } + + @Test + public void createDistribution_NullBucketBoundaries() { + List<Bucket> buckets = + Arrays.asList(Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)); + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketBoundaries"); + Distribution.create(10, 6.6, 678.54, BucketOptions.explicitOptions(null), buckets); + } + + @Test + public void createDistribution_NullBucketBoundary() { + List<Bucket> buckets = + Arrays.asList(Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)); + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketBoundary"); + Distribution.create( + 10, 6.6, 678.54, BucketOptions.explicitOptions(Arrays.asList(2.5, null)), buckets); + } + + @Test + public void createDistribution_NullBucketOptions() { + List<Bucket> buckets = + Arrays.asList(Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)); + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketOptions"); + Distribution.create(10, 6.6, 678.54, null, buckets); + } + + @Test + public void createDistribution_NullBucketList() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + thrown.expect(NullPointerException.class); + thrown.expectMessage("buckets"); + Distribution.create(10, 6.6, 678.54, bucketOptions, null); + } + + @Test + public void createDistribution_NullBucket() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 5.0); + BucketOptions bucketOptions = BucketOptions.explicitOptions(bucketBounds); + List<Bucket> buckets = + Arrays.asList(Bucket.create(3), Bucket.create(1), null, Bucket.create(4)); + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucket"); + Distribution.create(10, 6.6, 678.54, bucketOptions, buckets); + } + + @Test + public void testEquals() { + List<Double> bucketBounds = Arrays.asList(1.0, 2.0, 2.5); + new EqualsTester() + .addEqualityGroup( + Distribution.create( + 10, + 10, + 1, + BucketOptions.explicitOptions(bucketBounds), + Arrays.asList( + Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4))), + Distribution.create( + 10, + 10, + 1, + BucketOptions.explicitOptions(bucketBounds), + Arrays.asList( + Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)))) + .addEqualityGroup( + Distribution.create( + 7, + 10, + 23.456, + BucketOptions.explicitOptions(bucketBounds), + Arrays.asList( + Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)))) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java b/api/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java new file mode 100644 index 00000000..15c6e883 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ExportComponent}. */ +@RunWith(JUnit4.class) +public class ExportComponentTest { + @Test + public void defaultMetricExporter() { + assertThat(ExportComponent.newNoopExportComponent().getMetricProducerManager()) + .isInstanceOf(MetricProducerManager.class); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/MetricDescriptorTest.java b/api/src/test/java/io/opencensus/metrics/export/MetricDescriptorTest.java new file mode 100644 index 00000000..502170c6 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/MetricDescriptorTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.metrics.LabelKey; +import io.opencensus.metrics.export.MetricDescriptor.Type; +import java.util.Arrays; +import java.util.List; +import org.hamcrest.CoreMatchers; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link MetricDescriptor}. */ +@RunWith(JUnit4.class) +public class MetricDescriptorTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + private static final String METRIC_NAME_1 = "metric1"; + private static final String METRIC_NAME_2 = "metric2"; + private static final String DESCRIPTION = "Metric description."; + private static final String UNIT = "kb/s"; + private static final LabelKey KEY_1 = LabelKey.create("key1", "some key"); + private static final LabelKey KEY_2 = LabelKey.create("key2", "some other key"); + + @Test + public void testGet() { + MetricDescriptor metricDescriptor = + MetricDescriptor.create( + METRIC_NAME_1, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, Arrays.asList(KEY_1, KEY_2)); + assertThat(metricDescriptor.getName()).isEqualTo(METRIC_NAME_1); + assertThat(metricDescriptor.getDescription()).isEqualTo(DESCRIPTION); + assertThat(metricDescriptor.getUnit()).isEqualTo(UNIT); + assertThat(metricDescriptor.getType()).isEqualTo(Type.GAUGE_DOUBLE); + assertThat(metricDescriptor.getLabelKeys()).containsExactly(KEY_1, KEY_2).inOrder(); + } + + @Test + public void preventNullLabelKeyList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("labelKeys")); + MetricDescriptor.create(METRIC_NAME_1, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, null); + } + + @Test + public void preventNullLabelKey() { + List<LabelKey> keys = Arrays.asList(KEY_1, null); + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("labelKey")); + MetricDescriptor.create(METRIC_NAME_1, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, keys); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + MetricDescriptor.create( + METRIC_NAME_1, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, Arrays.asList(KEY_1, KEY_2)), + MetricDescriptor.create( + METRIC_NAME_1, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, Arrays.asList(KEY_1, KEY_2))) + .addEqualityGroup( + MetricDescriptor.create( + METRIC_NAME_2, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, Arrays.asList(KEY_1, KEY_2))) + .addEqualityGroup( + MetricDescriptor.create( + METRIC_NAME_2, DESCRIPTION, UNIT, Type.GAUGE_INT64, Arrays.asList(KEY_1, KEY_2))) + .addEqualityGroup( + MetricDescriptor.create( + METRIC_NAME_1, + DESCRIPTION, + UNIT, + Type.CUMULATIVE_DISTRIBUTION, + Arrays.asList(KEY_1, KEY_2))) + .addEqualityGroup( + MetricDescriptor.create( + METRIC_NAME_1, + DESCRIPTION, + UNIT, + Type.CUMULATIVE_DISTRIBUTION, + Arrays.asList(KEY_1))) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java b/api/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java new file mode 100644 index 00000000..1025427f --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link MetricProducerManager}. */ +@RunWith(JUnit4.class) +public class MetricProducerManagerTest { + private final MetricProducerManager metricProducerManager = + MetricProducerManager.newNoopMetricProducerManager(); + @Mock private MetricProducer metricProducer; + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void add_DisallowsNull() { + thrown.expect(NullPointerException.class); + metricProducerManager.add(null); + } + + @Test + public void add() { + metricProducerManager.add(metricProducer); + assertThat(metricProducerManager.getAllMetricProducer()).isEmpty(); + } + + @Test + public void addAndRemove() { + metricProducerManager.add(metricProducer); + assertThat(metricProducerManager.getAllMetricProducer()).isEmpty(); + metricProducerManager.remove(metricProducer); + assertThat(metricProducerManager.getAllMetricProducer()).isEmpty(); + } + + @Test + public void remove_DisallowsNull() { + thrown.expect(NullPointerException.class); + metricProducerManager.remove(null); + } + + @Test + public void remove_FromEmpty() { + metricProducerManager.remove(metricProducer); + assertThat(metricProducerManager.getAllMetricProducer()).isEmpty(); + } + + @Test + public void getAllMetricProducer_empty() { + assertThat(metricProducerManager.getAllMetricProducer()).isEmpty(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/MetricTest.java b/api/src/test/java/io/opencensus/metrics/export/MetricTest.java new file mode 100644 index 00000000..ed205289 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/MetricTest.java @@ -0,0 +1,180 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Timestamp; +import io.opencensus.metrics.LabelKey; +import io.opencensus.metrics.LabelValue; +import io.opencensus.metrics.export.MetricDescriptor.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Metric}. */ +@RunWith(JUnit4.class) +public class MetricTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + private static final String METRIC_NAME_1 = "metric1"; + private static final String METRIC_NAME_2 = "metric2"; + private static final String DESCRIPTION = "Metric description."; + private static final String UNIT = "kb/s"; + private static final LabelKey KEY_1 = LabelKey.create("key1", "some key"); + private static final LabelKey KEY_2 = LabelKey.create("key1", "some other key"); + private static final MetricDescriptor METRIC_DESCRIPTOR_1 = + MetricDescriptor.create( + METRIC_NAME_1, DESCRIPTION, UNIT, Type.GAUGE_DOUBLE, Arrays.asList(KEY_1, KEY_2)); + private static final MetricDescriptor METRIC_DESCRIPTOR_2 = + MetricDescriptor.create( + METRIC_NAME_2, + DESCRIPTION, + UNIT, + Type.CUMULATIVE_INT64, + Collections.singletonList(KEY_1)); + private static final LabelValue LABEL_VALUE_1 = LabelValue.create("value1"); + private static final LabelValue LABEL_VALUE_2 = LabelValue.create("value1"); + private static final LabelValue LABEL_VALUE_EMPTY = LabelValue.create(""); + private static final Value VALUE_LONG = Value.longValue(12345678); + private static final Value VALUE_DOUBLE_1 = Value.doubleValue(-345.77); + private static final Value VALUE_DOUBLE_2 = Value.doubleValue(133.79); + private static final Timestamp TIMESTAMP_1 = Timestamp.fromMillis(1000); + private static final Timestamp TIMESTAMP_2 = Timestamp.fromMillis(2000); + private static final Timestamp TIMESTAMP_3 = Timestamp.fromMillis(3000); + private static final Point POINT_1 = Point.create(VALUE_DOUBLE_1, TIMESTAMP_2); + private static final Point POINT_2 = Point.create(VALUE_DOUBLE_2, TIMESTAMP_3); + private static final Point POINT_3 = Point.create(VALUE_LONG, TIMESTAMP_3); + private static final TimeSeries GAUGE_TIME_SERIES_1 = + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Collections.singletonList(POINT_1), null); + private static final TimeSeries GAUGE_TIME_SERIES_2 = + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Collections.singletonList(POINT_2), null); + private static final TimeSeries CUMULATIVE_TIME_SERIES = + TimeSeries.create( + Collections.singletonList(LABEL_VALUE_EMPTY), + Collections.singletonList(POINT_3), + TIMESTAMP_1); + + @Test + public void testGet() { + Metric metric = + Metric.create(METRIC_DESCRIPTOR_1, Arrays.asList(GAUGE_TIME_SERIES_1, GAUGE_TIME_SERIES_2)); + assertThat(metric.getMetricDescriptor()).isEqualTo(METRIC_DESCRIPTOR_1); + assertThat(metric.getTimeSeriesList()) + .containsExactly(GAUGE_TIME_SERIES_1, GAUGE_TIME_SERIES_2) + .inOrder(); + } + + @Test + public void typeMismatch_GaugeDouble_Long() { + typeMismatch( + METRIC_DESCRIPTOR_1, + Collections.singletonList(CUMULATIVE_TIME_SERIES), + String.format("Type mismatch: %s, %s.", Type.GAUGE_DOUBLE, "ValueLong")); + } + + @Test + public void typeMismatch_CumulativeInt64_Double() { + typeMismatch( + METRIC_DESCRIPTOR_2, + Collections.singletonList(GAUGE_TIME_SERIES_1), + String.format("Type mismatch: %s, %s.", Type.CUMULATIVE_INT64, "ValueDouble")); + } + + private void typeMismatch( + MetricDescriptor metricDescriptor, List<TimeSeries> timeSeriesList, String errorMessage) { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(errorMessage); + Metric.create(metricDescriptor, timeSeriesList); + } + + @Test + public void create_WithNullMetricDescriptor() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("metricDescriptor"); + Metric.create(null, Collections.<TimeSeries>emptyList()); + } + + @Test + public void create_WithNullTimeSeriesList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("timeSeriesList"); + Metric.create(METRIC_DESCRIPTOR_1, null); + } + + @Test + public void create_WithNullTimeSeries() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("timeSeries"); + Metric.create(METRIC_DESCRIPTOR_1, Arrays.asList(GAUGE_TIME_SERIES_1, null)); + } + + @Test + public void immutableTimeSeriesList() { + List<TimeSeries> timeSeriesList = new ArrayList<TimeSeries>(); + timeSeriesList.add(GAUGE_TIME_SERIES_1); + Metric metric = Metric.create(METRIC_DESCRIPTOR_1, timeSeriesList); + timeSeriesList.add(GAUGE_TIME_SERIES_2); + assertThat(metric.getTimeSeriesList()).containsExactly(GAUGE_TIME_SERIES_1); + } + + @Test + public void createWithOneTimeSeries_WithNullTimeSeries() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("timeSeries"); + Metric.createWithOneTimeSeries(METRIC_DESCRIPTOR_1, null); + } + + @Test + public void createWithOneTimeSeries_WithNullMetricDescriptor() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("metricDescriptor"); + Metric.createWithOneTimeSeries(null, GAUGE_TIME_SERIES_1); + } + + @Test + public void testGet_WithOneTimeSeries() { + Metric metric = Metric.createWithOneTimeSeries(METRIC_DESCRIPTOR_1, GAUGE_TIME_SERIES_1); + assertThat(metric.getMetricDescriptor()).isEqualTo(METRIC_DESCRIPTOR_1); + assertThat(metric.getTimeSeriesList()).containsExactly(GAUGE_TIME_SERIES_1); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + Metric.create( + METRIC_DESCRIPTOR_1, Arrays.asList(GAUGE_TIME_SERIES_1, GAUGE_TIME_SERIES_2)), + Metric.create( + METRIC_DESCRIPTOR_1, Arrays.asList(GAUGE_TIME_SERIES_1, GAUGE_TIME_SERIES_2))) + .addEqualityGroup(Metric.create(METRIC_DESCRIPTOR_1, Collections.<TimeSeries>emptyList())) + .addEqualityGroup( + Metric.createWithOneTimeSeries(METRIC_DESCRIPTOR_2, CUMULATIVE_TIME_SERIES)) + .addEqualityGroup(Metric.create(METRIC_DESCRIPTOR_2, Collections.<TimeSeries>emptyList())) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/PointTest.java b/api/src/test/java/io/opencensus/metrics/export/PointTest.java new file mode 100644 index 00000000..cdfc7792 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/PointTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Timestamp; +import io.opencensus.metrics.export.Distribution.Bucket; +import io.opencensus.metrics.export.Distribution.BucketOptions; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Point}. */ +@RunWith(JUnit4.class) +public class PointTest { + + private static final Value DOUBLE_VALUE = Value.doubleValue(55.5); + private static final Value LONG_VALUE = Value.longValue(9876543210L); + private static final Value DISTRIBUTION_VALUE = + Value.distributionValue( + Distribution.create( + 10, + 6.6, + 678.54, + BucketOptions.explicitOptions(Arrays.asList(1.0, 2.0, 5.0)), + Arrays.asList( + Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4)))); + private static final Timestamp TIMESTAMP_1 = Timestamp.create(1, 2); + private static final Timestamp TIMESTAMP_2 = Timestamp.create(3, 4); + private static final Timestamp TIMESTAMP_3 = Timestamp.create(5, 6); + + @Test + public void testGet() { + Point point = Point.create(DOUBLE_VALUE, TIMESTAMP_1); + assertThat(point.getValue()).isEqualTo(DOUBLE_VALUE); + assertThat(point.getTimestamp()).isEqualTo(TIMESTAMP_1); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + Point.create(DOUBLE_VALUE, TIMESTAMP_1), Point.create(DOUBLE_VALUE, TIMESTAMP_1)) + .addEqualityGroup(Point.create(LONG_VALUE, TIMESTAMP_1)) + .addEqualityGroup(Point.create(LONG_VALUE, TIMESTAMP_2)) + .addEqualityGroup( + Point.create(DISTRIBUTION_VALUE, TIMESTAMP_2), + Point.create(DISTRIBUTION_VALUE, TIMESTAMP_2)) + .addEqualityGroup(Point.create(DISTRIBUTION_VALUE, TIMESTAMP_3)) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/SummaryTest.java b/api/src/test/java/io/opencensus/metrics/export/SummaryTest.java new file mode 100644 index 00000000..c10df043 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/SummaryTest.java @@ -0,0 +1,189 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.metrics.export.Summary.Snapshot; +import io.opencensus.metrics.export.Summary.Snapshot.ValueAtPercentile; +import java.util.Collections; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Summary}. */ +@RunWith(JUnit4.class) +public class SummaryTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + private static final double TOLERANCE = 1e-6; + + @Test + public void createAndGet_ValueAtPercentile() { + ValueAtPercentile valueAtPercentile = ValueAtPercentile.create(99.5, 10.2); + assertThat(valueAtPercentile.getPercentile()).isWithin(TOLERANCE).of(99.5); + assertThat(valueAtPercentile.getValue()).isWithin(TOLERANCE).of(10.2); + } + + @Test + public void createValueAtPercentile_InvalidValueAtPercentileInterval() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("percentile must be in the interval (0.0, 100.0]"); + ValueAtPercentile.create(100.1, 10.2); + } + + @Test + public void createValueAtPercentile_NegativeValue() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("value must be non-negative"); + ValueAtPercentile.create(99.5, -10.2); + } + + @Test + public void createAndGet_Snapshot() { + Snapshot snapshot = + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))); + assertThat(snapshot.getCount()).isEqualTo(10); + assertThat(snapshot.getSum()).isWithin(TOLERANCE).of(87.07); + assertThat(snapshot.getValueAtPercentiles()) + .containsExactly(ValueAtPercentile.create(99.5, 10.2)); + } + + @Test + public void createAndGet_Snapshot_WithNullCountAndSum() { + Snapshot snapshot = + Snapshot.create( + null, null, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))); + assertThat(snapshot.getCount()).isNull(); + assertThat(snapshot.getSum()).isNull(); + assertThat(snapshot.getValueAtPercentiles()) + .containsExactly(ValueAtPercentile.create(99.5, 10.2)); + } + + @Test + public void createSnapshot_NegativeCount() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("count must be non-negative"); + Snapshot.create(-10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))); + } + + @Test + public void createSnapshot_NegativeSum() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum must be non-negative"); + Snapshot.create(10L, -87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))); + } + + @Test + public void createSnapshot_ZeroCountAndNonZeroSum() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum must be 0 if count is 0"); + Snapshot.create(0L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))); + } + + @Test + public void createSnapshot_NullValueAtPercentilesList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("valueAtPercentiles"); + Snapshot.create(10L, 87.07, null); + } + + @Test + public void createSnapshot_OneNullValueAtPercentile() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("value in valueAtPercentiles"); + Snapshot.create(10L, 87.07, Collections.<ValueAtPercentile>singletonList(null)); + } + + @Test + public void createAndGet_Summary() { + Snapshot snapshot = + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))); + Summary summary = Summary.create(10L, 6.6, snapshot); + assertThat(summary.getCount()).isEqualTo(10); + assertThat(summary.getSum()).isWithin(TOLERANCE).of(6.6); + assertThat(summary.getSnapshot()).isEqualTo(snapshot); + } + + @Test + public void createSummary_NegativeCount() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("count must be non-negative"); + Summary.create( + -10L, 6.6, Snapshot.create(null, null, Collections.<ValueAtPercentile>emptyList())); + } + + @Test + public void createSummary_NegativeSum() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum must be non-negative"); + Summary.create( + 10L, -6.6, Snapshot.create(null, null, Collections.<ValueAtPercentile>emptyList())); + } + + @Test + public void createSummary_ZeroCountAndNonZeroSum() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("sum must be 0 if count is 0"); + Summary.create( + 0L, 6.6, Snapshot.create(null, null, Collections.<ValueAtPercentile>emptyList())); + } + + @Test + public void createSummary_NullSnapshot() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("snapshot"); + Summary.create(10L, 6.6, null); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + Summary.create( + 10L, + 10.0, + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2)))), + Summary.create( + 10L, + 10.0, + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))))) + .addEqualityGroup( + Summary.create( + 7L, + 10.0, + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))))) + .addEqualityGroup( + Summary.create( + 10L, + 7.0, + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(99.5, 10.2))))) + .addEqualityGroup( + Summary.create( + 10L, 10.0, Snapshot.create(null, null, Collections.<ValueAtPercentile>emptyList()))) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/TimeSeriesTest.java b/api/src/test/java/io/opencensus/metrics/export/TimeSeriesTest.java new file mode 100644 index 00000000..92a2c8cf --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/TimeSeriesTest.java @@ -0,0 +1,151 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Timestamp; +import io.opencensus.metrics.LabelValue; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.hamcrest.CoreMatchers; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TimeSeries}. */ +@RunWith(JUnit4.class) +public class TimeSeriesTest { + + @Rule public ExpectedException thrown = ExpectedException.none(); + + private static final LabelValue LABEL_VALUE_1 = LabelValue.create("value1"); + private static final LabelValue LABEL_VALUE_2 = LabelValue.create("value2"); + private static final Value VALUE_LONG = Value.longValue(12345678); + private static final Value VALUE_DOUBLE = Value.doubleValue(-345.77); + private static final Timestamp TIMESTAMP_1 = Timestamp.fromMillis(1000); + private static final Timestamp TIMESTAMP_2 = Timestamp.fromMillis(2000); + private static final Timestamp TIMESTAMP_3 = Timestamp.fromMillis(3000); + private static final Point POINT_1 = Point.create(VALUE_DOUBLE, TIMESTAMP_2); + private static final Point POINT_2 = Point.create(VALUE_LONG, TIMESTAMP_3); + + @Test + public void testGet_TimeSeries() { + TimeSeries cumulativeTimeSeries = + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Arrays.asList(POINT_1), TIMESTAMP_1); + assertThat(cumulativeTimeSeries.getStartTimestamp()).isEqualTo(TIMESTAMP_1); + assertThat(cumulativeTimeSeries.getLabelValues()) + .containsExactly(LABEL_VALUE_1, LABEL_VALUE_2) + .inOrder(); + assertThat(cumulativeTimeSeries.getPoints()).containsExactly(POINT_1).inOrder(); + } + + @Test + public void create_WithNullLabelValueList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("labelValues")); + TimeSeries.create(null, Collections.<Point>emptyList(), TIMESTAMP_1); + } + + @Test + public void create_WithNullLabelValue() { + List<LabelValue> labelValues = Arrays.asList(LABEL_VALUE_1, null); + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("labelValue")); + TimeSeries.create(labelValues, Collections.<Point>emptyList(), TIMESTAMP_1); + } + + @Test + public void create_WithNullPointList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("points")); + TimeSeries.create(Collections.<LabelValue>emptyList(), null, TIMESTAMP_1); + } + + @Test + public void create_WithNullPoint() { + List<Point> points = Arrays.asList(POINT_1, null); + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("point")); + TimeSeries.create(Collections.<LabelValue>emptyList(), points, TIMESTAMP_1); + } + + @Test + public void testGet_WithOnePointTimeSeries() { + TimeSeries cumulativeTimeSeries = + TimeSeries.createWithOnePoint( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), POINT_1, TIMESTAMP_1); + assertThat(cumulativeTimeSeries.getStartTimestamp()).isEqualTo(TIMESTAMP_1); + assertThat(cumulativeTimeSeries.getLabelValues()) + .containsExactly(LABEL_VALUE_1, LABEL_VALUE_2) + .inOrder(); + assertThat(cumulativeTimeSeries.getPoints()).containsExactly(POINT_1).inOrder(); + } + + @Test + public void createWithOnePoint_WithNullLabelValueList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("labelValues")); + TimeSeries.createWithOnePoint(null, POINT_1, TIMESTAMP_1); + } + + @Test + public void createWithOnePoint_WithNullLabelValue() { + List<LabelValue> labelValues = Arrays.asList(LABEL_VALUE_1, null); + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("labelValue")); + TimeSeries.createWithOnePoint(labelValues, POINT_1, TIMESTAMP_1); + } + + @Test + public void createWithOnePoint_WithNullPointList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage(CoreMatchers.equalTo("point")); + TimeSeries.createWithOnePoint(Collections.<LabelValue>emptyList(), null, TIMESTAMP_1); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup( + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Arrays.asList(POINT_1), TIMESTAMP_1), + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Arrays.asList(POINT_1), TIMESTAMP_1)) + .addEqualityGroup( + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Arrays.asList(POINT_1), null), + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Arrays.asList(POINT_1), null)) + .addEqualityGroup( + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1, LABEL_VALUE_2), Arrays.asList(POINT_1), TIMESTAMP_2)) + .addEqualityGroup( + TimeSeries.create(Arrays.asList(LABEL_VALUE_1), Arrays.asList(POINT_1), TIMESTAMP_2)) + .addEqualityGroup( + TimeSeries.create(Arrays.asList(LABEL_VALUE_1), Arrays.asList(POINT_2), TIMESTAMP_2)) + .addEqualityGroup( + TimeSeries.create( + Arrays.asList(LABEL_VALUE_1), Arrays.asList(POINT_1, POINT_2), TIMESTAMP_2)) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/metrics/export/ValueTest.java b/api/src/test/java/io/opencensus/metrics/export/ValueTest.java new file mode 100644 index 00000000..bf947692 --- /dev/null +++ b/api/src/test/java/io/opencensus/metrics/export/ValueTest.java @@ -0,0 +1,168 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.metrics.export.Distribution.Bucket; +import io.opencensus.metrics.export.Distribution.BucketOptions; +import io.opencensus.metrics.export.Distribution.BucketOptions.ExplicitOptions; +import io.opencensus.metrics.export.Summary.Snapshot; +import io.opencensus.metrics.export.Summary.Snapshot.ValueAtPercentile; +import io.opencensus.metrics.export.Value.ValueDistribution; +import io.opencensus.metrics.export.Value.ValueDouble; +import io.opencensus.metrics.export.Value.ValueLong; +import io.opencensus.metrics.export.Value.ValueSummary; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Value}. */ +@RunWith(JUnit4.class) +public class ValueTest { + private static final double TOLERANCE = 1e-6; + + private static final Distribution DISTRIBUTION = + Distribution.create( + 10, + 10, + 1, + BucketOptions.explicitOptions(Arrays.asList(1.0, 2.0, 5.0)), + Arrays.asList(Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4))); + private static final Summary SUMMARY = + Summary.create( + 10L, + 10.0, + Snapshot.create( + 10L, 87.07, Collections.singletonList(ValueAtPercentile.create(0.98, 10.2)))); + + @Test + public void createAndGet_ValueDouble() { + Value value = Value.doubleValue(-34.56); + assertThat(value).isInstanceOf(ValueDouble.class); + assertThat(((ValueDouble) value).getValue()).isWithin(TOLERANCE).of(-34.56); + } + + @Test + public void createAndGet_ValueLong() { + Value value = Value.longValue(123456789); + assertThat(value).isInstanceOf(ValueLong.class); + assertThat(((ValueLong) value).getValue()).isEqualTo(123456789); + } + + @Test + public void createAndGet_ValueDistribution() { + Value value = Value.distributionValue(DISTRIBUTION); + assertThat(value).isInstanceOf(ValueDistribution.class); + assertThat(((ValueDistribution) value).getValue()).isEqualTo(DISTRIBUTION); + } + + @Test + public void createAndGet_ValueSummary() { + Value value = Value.summaryValue(SUMMARY); + assertThat(value).isInstanceOf(ValueSummary.class); + assertThat(((ValueSummary) value).getValue()).isEqualTo(SUMMARY); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(Value.doubleValue(1.0), Value.doubleValue(1.0)) + .addEqualityGroup(Value.doubleValue(2.0)) + .addEqualityGroup(Value.longValue(1L)) + .addEqualityGroup(Value.longValue(2L)) + .addEqualityGroup( + Value.distributionValue( + Distribution.create( + 7, + 10, + 23.456, + BucketOptions.explicitOptions(Arrays.asList(1.0, 2.0, 5.0)), + Arrays.asList( + Bucket.create(3), Bucket.create(1), Bucket.create(2), Bucket.create(4))))) + .testEquals(); + } + + @Test + public void testMatch() { + List<Value> values = + Arrays.asList( + ValueDouble.create(1.0), + ValueLong.create(-1), + ValueDistribution.create(DISTRIBUTION), + ValueSummary.create(SUMMARY)); + List<Number> expected = + Arrays.<Number>asList(1.0, -1L, 10.0, 10L, 1.0, 1.0, 2.0, 5.0, 3L, 1L, 2L, 4L); + final List<Number> actual = new ArrayList<Number>(); + for (Value value : values) { + value.match( + new Function<Double, Object>() { + @Override + public Object apply(Double arg) { + actual.add(arg); + return null; + } + }, + new Function<Long, Object>() { + @Override + public Object apply(Long arg) { + actual.add(arg); + return null; + } + }, + new Function<Distribution, Object>() { + @Override + public Object apply(Distribution arg) { + actual.add(arg.getSum()); + actual.add(arg.getCount()); + actual.add(arg.getSumOfSquaredDeviations()); + + arg.getBucketOptions() + .match( + new Function<ExplicitOptions, Object>() { + @Override + public Object apply(ExplicitOptions arg) { + actual.addAll(arg.getBucketBoundaries()); + return null; + } + }, + Functions.throwAssertionError()); + + for (Bucket bucket : arg.getBuckets()) { + actual.add(bucket.getCount()); + } + return null; + } + }, + new Function<Summary, Object>() { + @Override + public Object apply(Summary arg) { + return null; + } + }, + Functions.throwAssertionError()); + } + assertThat(actual).containsExactlyElementsIn(expected).inOrder(); + } +} diff --git a/api/src/test/java/io/opencensus/stats/AggregationDataTest.java b/api/src/test/java/io/opencensus/stats/AggregationDataTest.java new file mode 100644 index 00000000..a6d6d1de --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/AggregationDataTest.java @@ -0,0 +1,231 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.DistributionData; +import io.opencensus.stats.AggregationData.DistributionData.Exemplar; +import io.opencensus.stats.AggregationData.LastValueDataDouble; +import io.opencensus.stats.AggregationData.LastValueDataLong; +import io.opencensus.stats.AggregationData.MeanData; +import io.opencensus.stats.AggregationData.SumDataDouble; +import io.opencensus.stats.AggregationData.SumDataLong; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.stats.AggregationData}. */ +@RunWith(JUnit4.class) +public class AggregationDataTest { + + private static final double TOLERANCE = 1e-6; + private static final Timestamp TIMESTAMP_1 = Timestamp.create(1, 0); + private static final Timestamp TIMESTAMP_2 = Timestamp.create(2, 0); + private static final Map<String, String> ATTACHMENTS = Collections.singletonMap("key", "value"); + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testCreateDistributionData() { + DistributionData distributionData = + DistributionData.create(7.7, 10, 1.1, 9.9, 32.2, Arrays.asList(4L, 1L, 5L)); + assertThat(distributionData.getMean()).isWithin(TOLERANCE).of(7.7); + assertThat(distributionData.getCount()).isEqualTo(10); + assertThat(distributionData.getMin()).isWithin(TOLERANCE).of(1.1); + assertThat(distributionData.getMax()).isWithin(TOLERANCE).of(9.9); + assertThat(distributionData.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(32.2); + assertThat(distributionData.getBucketCounts()).containsExactly(4L, 1L, 5L).inOrder(); + } + + @Test + public void testCreateDistributionDataWithExemplar() { + Exemplar exemplar1 = Exemplar.create(4, TIMESTAMP_2, ATTACHMENTS); + Exemplar exemplar2 = Exemplar.create(1, TIMESTAMP_1, ATTACHMENTS); + DistributionData distributionData = + DistributionData.create( + 7.7, 10, 1.1, 9.9, 32.2, Arrays.asList(4L, 1L), Arrays.asList(exemplar1, exemplar2)); + assertThat(distributionData.getExemplars()).containsExactly(exemplar1, exemplar2).inOrder(); + } + + @Test + public void testExemplar() { + Exemplar exemplar = Exemplar.create(15.0, TIMESTAMP_1, ATTACHMENTS); + assertThat(exemplar.getValue()).isEqualTo(15.0); + assertThat(exemplar.getTimestamp()).isEqualTo(TIMESTAMP_1); + assertThat(exemplar.getAttachments()).isEqualTo(ATTACHMENTS); + } + + @Test + public void testExemplar_PreventNullAttachments() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("attachments"); + Exemplar.create(15, TIMESTAMP_1, null); + } + + @Test + public void testExemplar_PreventNullAttachmentKey() { + Map<String, String> attachments = Collections.singletonMap(null, "value"); + thrown.expect(NullPointerException.class); + thrown.expectMessage("key of attachment"); + Exemplar.create(15, TIMESTAMP_1, attachments); + } + + @Test + public void testExemplar_PreventNullAttachmentValue() { + Map<String, String> attachments = Collections.singletonMap("key", null); + thrown.expect(NullPointerException.class); + thrown.expectMessage("value of attachment"); + Exemplar.create(15, TIMESTAMP_1, attachments); + } + + @Test + public void preventNullBucketCountList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketCounts"); + DistributionData.create(1, 1, 1, 1, 0, null); + } + + @Test + public void preventNullBucket() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucket"); + DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 1L, null)); + } + + @Test + public void preventNullExemplarList() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("exemplar list should not be null."); + DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 1L), null); + } + + @Test + public void preventNullExemplar() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("exemplar"); + DistributionData.create( + 1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 1L), Collections.<Exemplar>singletonList(null)); + } + + @Test + public void preventMinIsGreaterThanMax() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("max should be greater or equal to min."); + DistributionData.create(1, 1, 10, 1, 0, Arrays.asList(0L, 1L, 0L)); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(SumDataDouble.create(10.0), SumDataDouble.create(10.0)) + .addEqualityGroup(SumDataDouble.create(20.0), SumDataDouble.create(20.0)) + .addEqualityGroup(SumDataLong.create(20), SumDataLong.create(20)) + .addEqualityGroup(CountData.create(40), CountData.create(40)) + .addEqualityGroup(CountData.create(80), CountData.create(80)) + .addEqualityGroup( + DistributionData.create(10, 10, 1, 1, 0, Arrays.asList(0L, 10L, 0L)), + DistributionData.create(10, 10, 1, 1, 0, Arrays.asList(0L, 10L, 0L))) + .addEqualityGroup(DistributionData.create(10, 10, 1, 1, 0, Arrays.asList(0L, 10L, 100L))) + .addEqualityGroup(DistributionData.create(110, 10, 1, 1, 0, Arrays.asList(0L, 10L, 0L))) + .addEqualityGroup(DistributionData.create(10, 110, 1, 1, 0, Arrays.asList(0L, 10L, 0L))) + .addEqualityGroup(DistributionData.create(10, 10, -1, 1, 0, Arrays.asList(0L, 10L, 0L))) + .addEqualityGroup(DistributionData.create(10, 10, 1, 5, 0, Arrays.asList(0L, 10L, 0L))) + .addEqualityGroup(DistributionData.create(10, 10, 1, 1, 55.5, Arrays.asList(0L, 10L, 0L))) + .addEqualityGroup(MeanData.create(5.0, 1), MeanData.create(5.0, 1)) + .addEqualityGroup(MeanData.create(-5.0, 1), MeanData.create(-5.0, 1)) + .addEqualityGroup(LastValueDataDouble.create(20.0), LastValueDataDouble.create(20.0)) + .addEqualityGroup(LastValueDataLong.create(20), LastValueDataLong.create(20)) + .testEquals(); + } + + @Test + public void testMatchAndGet() { + List<AggregationData> aggregations = + Arrays.asList( + SumDataDouble.create(10.0), + SumDataLong.create(100000000), + CountData.create(40), + DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 10L, 0L)), + LastValueDataDouble.create(20.0), + LastValueDataLong.create(200000000L)); + + final List<Object> actual = new ArrayList<Object>(); + for (AggregationData aggregation : aggregations) { + aggregation.match( + new Function<SumDataDouble, Void>() { + @Override + public Void apply(SumDataDouble arg) { + actual.add(arg.getSum()); + return null; + } + }, + new Function<SumDataLong, Void>() { + @Override + public Void apply(SumDataLong arg) { + actual.add(arg.getSum()); + return null; + } + }, + new Function<CountData, Void>() { + @Override + public Void apply(CountData arg) { + actual.add(arg.getCount()); + return null; + } + }, + new Function<DistributionData, Void>() { + @Override + public Void apply(DistributionData arg) { + actual.add(arg.getBucketCounts()); + return null; + } + }, + new Function<LastValueDataDouble, Void>() { + @Override + public Void apply(LastValueDataDouble arg) { + actual.add(arg.getLastValue()); + return null; + } + }, + new Function<LastValueDataLong, Void>() { + @Override + public Void apply(LastValueDataLong arg) { + actual.add(arg.getLastValue()); + return null; + } + }, + Functions.<Void>throwIllegalArgumentException()); + } + + assertThat(actual) + .containsExactly(10.0, 100000000L, 40L, Arrays.asList(0L, 10L, 0L), 20.0, 200000000L) + .inOrder(); + } +} diff --git a/api/src/test/java/io/opencensus/stats/AggregationTest.java b/api/src/test/java/io/opencensus/stats/AggregationTest.java new file mode 100644 index 00000000..cf337030 --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/AggregationTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Functions; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Distribution; +import io.opencensus.stats.Aggregation.LastValue; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Sum; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.stats.Aggregation}. */ +@RunWith(JUnit4.class) +public class AggregationTest { + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testCreateDistribution() { + BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(0.1, 2.2, 33.3)); + Distribution distribution = Distribution.create(bucketBoundaries); + assertThat(distribution.getBucketBoundaries()).isEqualTo(bucketBoundaries); + } + + @Test + public void testNullBucketBoundaries() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("bucketBoundaries"); + Distribution.create(null); + } + + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(Sum.create(), Sum.create()) + .addEqualityGroup(Count.create(), Count.create()) + .addEqualityGroup( + Distribution.create(BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0))), + Distribution.create(BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0)))) + .addEqualityGroup( + Distribution.create(BucketBoundaries.create(Arrays.asList(0.0, 1.0, 5.0))), + Distribution.create(BucketBoundaries.create(Arrays.asList(0.0, 1.0, 5.0)))) + .addEqualityGroup(Mean.create(), Mean.create()) + .addEqualityGroup(LastValue.create(), LastValue.create()) + .testEquals(); + } + + @Test + public void testMatch() { + List<Aggregation> aggregations = + Arrays.asList( + Sum.create(), + Count.create(), + Mean.create(), + Distribution.create(BucketBoundaries.create(Arrays.asList(-10.0, 1.0, 5.0))), + LastValue.create()); + + List<String> actual = new ArrayList<String>(); + for (Aggregation aggregation : aggregations) { + actual.add( + aggregation.match( + Functions.returnConstant("SUM"), + Functions.returnConstant("COUNT"), + Functions.returnConstant("DISTRIBUTION"), + Functions.returnConstant("LASTVALUE"), + Functions.returnConstant("UNKNOWN"))); + } + + assertThat(actual) + .isEqualTo(Arrays.asList("SUM", "COUNT", "UNKNOWN", "DISTRIBUTION", "LASTVALUE")); + } +} diff --git a/api/src/test/java/io/opencensus/stats/BucketBoundariesTest.java b/api/src/test/java/io/opencensus/stats/BucketBoundariesTest.java new file mode 100644 index 00000000..36f2edb4 --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/BucketBoundariesTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.stats.BucketBoundaries}. */ +@RunWith(JUnit4.class) +public class BucketBoundariesTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void testConstructBoundaries() { + List<Double> buckets = Arrays.asList(0.0, 1.0, 2.0); + BucketBoundaries bucketBoundaries = BucketBoundaries.create(buckets); + assertThat(bucketBoundaries.getBoundaries()).isEqualTo(buckets); + } + + @Test + public void testBoundariesDoesNotChangeWithOriginalList() { + List<Double> original = new ArrayList<Double>(); + original.add(0.0); + original.add(1.0); + original.add(2.0); + BucketBoundaries bucketBoundaries = BucketBoundaries.create(original); + original.set(2, 3.0); + original.add(4.0); + List<Double> expected = Arrays.asList(0.0, 1.0, 2.0); + assertThat(bucketBoundaries.getBoundaries()).isNotEqualTo(original); + assertThat(bucketBoundaries.getBoundaries()).isEqualTo(expected); + } + + @Test + public void testNullBoundaries() throws Exception { + thrown.expect(NullPointerException.class); + BucketBoundaries.create(null); + } + + @Test + public void testUnsortedBoundaries() throws Exception { + List<Double> buckets = Arrays.asList(0.0, 1.0, 1.0); + thrown.expect(IllegalArgumentException.class); + BucketBoundaries.create(buckets); + } + + @Test + public void testNoBoundaries() { + List<Double> buckets = Arrays.asList(); + BucketBoundaries bucketBoundaries = BucketBoundaries.create(buckets); + assertThat(bucketBoundaries.getBoundaries()).isEqualTo(buckets); + } + + @Test + public void testBucketBoundariesEquals() { + new EqualsTester() + .addEqualityGroup( + BucketBoundaries.create(Arrays.asList(-1.0, 2.0)), + BucketBoundaries.create(Arrays.asList(-1.0, 2.0))) + .addEqualityGroup(BucketBoundaries.create(Arrays.asList(-1.0))) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/stats/MeasureTest.java b/api/src/test/java/io/opencensus/stats/MeasureTest.java new file mode 100644 index 00000000..a9302425 --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/MeasureTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.Measure.MeasureLong; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Measure}. */ +@RunWith(JUnit4.class) +public final class MeasureTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void testConstants() { + assertThat(Measure.NAME_MAX_LENGTH).isEqualTo(255); + } + + @Test + public void preventTooLongMeasureName() { + char[] chars = new char[Measure.NAME_MAX_LENGTH + 1]; + Arrays.fill(chars, 'a'); + String longName = String.valueOf(chars); + thrown.expect(IllegalArgumentException.class); + Measure.MeasureDouble.create(longName, "description", "1"); + } + + @Test + public void preventNonPrintableMeasureName() { + thrown.expect(IllegalArgumentException.class); + Measure.MeasureDouble.create("\2", "description", "1"); + } + + @Test + public void testMeasureDoubleComponents() { + Measure measurement = Measure.MeasureDouble.create("Foo", "The description of Foo", "Mbit/s"); + assertThat(measurement.getName()).isEqualTo("Foo"); + assertThat(measurement.getDescription()).isEqualTo("The description of Foo"); + assertThat(measurement.getUnit()).isEqualTo("Mbit/s"); + } + + @Test + public void testMeasureLongComponents() { + Measure measurement = Measure.MeasureLong.create("Bar", "The description of Bar", "1"); + assertThat(measurement.getName()).isEqualTo("Bar"); + assertThat(measurement.getDescription()).isEqualTo("The description of Bar"); + assertThat(measurement.getUnit()).isEqualTo("1"); + } + + @Test + public void testMeasureDoubleEquals() { + new EqualsTester() + .addEqualityGroup( + Measure.MeasureDouble.create("name", "description", "bit/s"), + Measure.MeasureDouble.create("name", "description", "bit/s")) + .addEqualityGroup(Measure.MeasureDouble.create("name", "description 2", "bit/s")) + .testEquals(); + } + + @Test + public void testMeasureLongEquals() { + new EqualsTester() + .addEqualityGroup( + Measure.MeasureLong.create("name", "description", "bit/s"), + Measure.MeasureLong.create("name", "description", "bit/s")) + .addEqualityGroup(Measure.MeasureLong.create("name", "description 2", "bit/s")) + .testEquals(); + } + + @Test + public void testMatch() { + List<Measure> measures = + Arrays.asList( + MeasureDouble.create("measure1", "description", "1"), + MeasureLong.create("measure2", "description", "1")); + List<String> outputs = Lists.newArrayList(); + for (Measure measure : measures) { + outputs.add( + measure.match( + new Function<MeasureDouble, String>() { + @Override + public String apply(MeasureDouble arg) { + return "double"; + } + }, + new Function<MeasureLong, String>() { + @Override + public String apply(MeasureLong arg) { + return "long"; + } + }, + Functions.<String>throwAssertionError())); + } + assertThat(outputs).containsExactly("double", "long").inOrder(); + } + + @Test + public void testMeasureDoubleIsNotEqualToMeasureLong() { + assertThat(Measure.MeasureDouble.create("name", "description", "bit/s")) + .isNotEqualTo(Measure.MeasureLong.create("name", "description", "bit/s")); + } +} diff --git a/api/src/test/java/io/opencensus/stats/NoopStatsTest.java b/api/src/test/java/io/opencensus/stats/NoopStatsTest.java new file mode 100644 index 00000000..4bae14a6 --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/NoopStatsTest.java @@ -0,0 +1,133 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; +import java.util.Collections; +import java.util.Iterator; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Unit tests for {@link NoopStats}. Tests for {@link NoopStats#newNoopViewManager} are in {@link + * NoopViewManagerTest} + */ +@RunWith(JUnit4.class) +public final class NoopStatsTest { + private static final Tag TAG = Tag.create(TagKey.create("key"), TagValue.create("value")); + private static final MeasureDouble MEASURE = + Measure.MeasureDouble.create("my measure", "description", "s"); + + private final TagContext tagContext = + new TagContext() { + + @Override + protected Iterator<Tag> getIterator() { + return Collections.<Tag>singleton(TAG).iterator(); + } + }; + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void noopStatsComponent() { + assertThat(NoopStats.newNoopStatsComponent().getStatsRecorder()) + .isSameAs(NoopStats.getNoopStatsRecorder()); + assertThat(NoopStats.newNoopStatsComponent().getViewManager()) + .isInstanceOf(NoopStats.newNoopViewManager().getClass()); + } + + @Test + public void noopStatsComponent_GetState() { + assertThat(NoopStats.newNoopStatsComponent().getState()) + .isEqualTo(StatsCollectionState.DISABLED); + } + + @Test + @SuppressWarnings("deprecation") + public void noopStatsComponent_SetState_IgnoresInput() { + StatsComponent noopStatsComponent = NoopStats.newNoopStatsComponent(); + noopStatsComponent.setState(StatsCollectionState.ENABLED); + assertThat(noopStatsComponent.getState()).isEqualTo(StatsCollectionState.DISABLED); + } + + @Test + @SuppressWarnings("deprecation") + public void noopStatsComponent_SetState_DisallowsNull() { + StatsComponent noopStatsComponent = NoopStats.newNoopStatsComponent(); + thrown.expect(NullPointerException.class); + noopStatsComponent.setState(null); + } + + @Test + @SuppressWarnings("deprecation") + public void noopStatsComponent_DisallowsSetStateAfterGetState() { + StatsComponent noopStatsComponent = NoopStats.newNoopStatsComponent(); + noopStatsComponent.setState(StatsCollectionState.DISABLED); + noopStatsComponent.getState(); + thrown.expect(IllegalStateException.class); + thrown.expectMessage("State was already read, cannot set state."); + noopStatsComponent.setState(StatsCollectionState.ENABLED); + } + + @Test + public void noopStatsRecorder_PutAttachmentNullKey() { + MeasureMap measureMap = NoopStats.getNoopStatsRecorder().newMeasureMap(); + thrown.expect(NullPointerException.class); + thrown.expectMessage("key"); + measureMap.putAttachment(null, "value"); + } + + @Test + public void noopStatsRecorder_PutAttachmentNullValue() { + MeasureMap measureMap = NoopStats.getNoopStatsRecorder().newMeasureMap(); + thrown.expect(NullPointerException.class); + thrown.expectMessage("value"); + measureMap.putAttachment("key", null); + } + + // The NoopStatsRecorder should do nothing, so this test just checks that record doesn't throw an + // exception. + @Test + public void noopStatsRecorder_Record() { + NoopStats.getNoopStatsRecorder().newMeasureMap().put(MEASURE, 5).record(tagContext); + } + + // The NoopStatsRecorder should do nothing, so this test just checks that record doesn't throw an + // exception. + @Test + public void noopStatsRecorder_RecordWithCurrentContext() { + NoopStats.getNoopStatsRecorder().newMeasureMap().put(MEASURE, 6).record(); + } + + @Test + public void noopStatsRecorder_Record_DisallowNullTagContext() { + MeasureMap measureMap = NoopStats.getNoopStatsRecorder().newMeasureMap(); + thrown.expect(NullPointerException.class); + thrown.expectMessage("tags"); + measureMap.record(null); + } +} diff --git a/api/src/test/java/io/opencensus/stats/NoopViewManagerTest.java b/api/src/test/java/io/opencensus/stats/NoopViewManagerTest.java new file mode 100644 index 00000000..44c7626f --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/NoopViewManagerTest.java @@ -0,0 +1,186 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.Duration; +import io.opencensus.common.Timestamp; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.View.AggregationWindow.Cumulative; +import io.opencensus.stats.View.AggregationWindow.Interval; +import io.opencensus.stats.View.Name; +import io.opencensus.stats.ViewData.AggregationWindowData.CumulativeData; +import io.opencensus.stats.ViewData.AggregationWindowData.IntervalData; +import io.opencensus.tags.TagKey; +import java.util.Arrays; +import java.util.Set; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link NoopStats#newNoopViewManager}. */ +@RunWith(JUnit4.class) +public final class NoopViewManagerTest { + private static final MeasureDouble MEASURE = + Measure.MeasureDouble.create("my measure", "description", "s"); + private static final TagKey KEY = TagKey.create("KEY"); + private static final Name VIEW_NAME = Name.create("my view"); + private static final String VIEW_DESCRIPTION = "view description"; + private static final Sum AGGREGATION = Sum.create(); + private static final Cumulative CUMULATIVE = Cumulative.create(); + private static final Duration TEN_SECONDS = Duration.create(10, 0); + private static final Interval INTERVAL = Interval.create(TEN_SECONDS); + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void noopViewManager_RegisterView_DisallowRegisteringDifferentViewWithSameName() { + final View view1 = + View.create( + VIEW_NAME, "description 1", MEASURE, AGGREGATION, Arrays.asList(KEY), CUMULATIVE); + final View view2 = + View.create( + VIEW_NAME, "description 2", MEASURE, AGGREGATION, Arrays.asList(KEY), CUMULATIVE); + ViewManager viewManager = NoopStats.newNoopViewManager(); + viewManager.registerView(view1); + + try { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("A different view with the same name already exists."); + viewManager.registerView(view2); + } finally { + assertThat(viewManager.getView(VIEW_NAME).getView()).isEqualTo(view1); + } + } + + @Test + public void noopViewManager_RegisterView_AllowRegisteringSameViewTwice() { + View view = + View.create( + VIEW_NAME, VIEW_DESCRIPTION, MEASURE, AGGREGATION, Arrays.asList(KEY), CUMULATIVE); + ViewManager viewManager = NoopStats.newNoopViewManager(); + viewManager.registerView(view); + viewManager.registerView(view); + } + + @Test + public void noopViewManager_RegisterView_DisallowNull() { + ViewManager viewManager = NoopStats.newNoopViewManager(); + thrown.expect(NullPointerException.class); + viewManager.registerView(null); + } + + @Test + public void noopViewManager_GetView_GettingNonExistentViewReturnsNull() { + ViewManager viewManager = NoopStats.newNoopViewManager(); + assertThat(viewManager.getView(VIEW_NAME)).isNull(); + } + + @Test + public void noopViewManager_GetView_Cumulative() { + View view = + View.create( + VIEW_NAME, VIEW_DESCRIPTION, MEASURE, AGGREGATION, Arrays.asList(KEY), CUMULATIVE); + ViewManager viewManager = NoopStats.newNoopViewManager(); + viewManager.registerView(view); + + ViewData viewData = viewManager.getView(VIEW_NAME); + assertThat(viewData.getView()).isEqualTo(view); + assertThat(viewData.getAggregationMap()).isEmpty(); + assertThat(viewData.getStart()).isEqualTo(Timestamp.create(0, 0)); + assertThat(viewData.getEnd()).isEqualTo(Timestamp.create(0, 0)); + assertThat(viewData.getWindowData()) + .isEqualTo(CumulativeData.create(Timestamp.create(0, 0), Timestamp.create(0, 0))); + } + + @Test + public void noopViewManager_GetView_Interval() { + View view = + View.create( + VIEW_NAME, VIEW_DESCRIPTION, MEASURE, AGGREGATION, Arrays.asList(KEY), INTERVAL); + ViewManager viewManager = NoopStats.newNoopViewManager(); + viewManager.registerView(view); + + ViewData viewData = viewManager.getView(VIEW_NAME); + assertThat(viewData.getView()).isEqualTo(view); + assertThat(viewData.getAggregationMap()).isEmpty(); + assertThat(viewData.getWindowData()).isEqualTo(IntervalData.create(Timestamp.create(0, 0))); + } + + @Test + public void noopViewManager_GetView_DisallowNull() { + ViewManager viewManager = NoopStats.newNoopViewManager(); + thrown.expect(NullPointerException.class); + viewManager.getView(null); + } + + @Test + public void getAllExportedViews() { + ViewManager viewManager = NoopStats.newNoopViewManager(); + assertThat(viewManager.getAllExportedViews()).isEmpty(); + View cumulativeView1 = + View.create( + View.Name.create("View 1"), + VIEW_DESCRIPTION, + MEASURE, + AGGREGATION, + Arrays.asList(KEY), + CUMULATIVE); + View cumulativeView2 = + View.create( + View.Name.create("View 2"), + VIEW_DESCRIPTION, + MEASURE, + AGGREGATION, + Arrays.asList(KEY), + CUMULATIVE); + View intervalView = + View.create( + View.Name.create("View 3"), + VIEW_DESCRIPTION, + MEASURE, + AGGREGATION, + Arrays.asList(KEY), + INTERVAL); + viewManager.registerView(cumulativeView1); + viewManager.registerView(cumulativeView2); + viewManager.registerView(intervalView); + + // Only cumulative views should be exported. + assertThat(viewManager.getAllExportedViews()).containsExactly(cumulativeView1, cumulativeView2); + } + + @Test + public void getAllExportedViews_ResultIsUnmodifiable() { + ViewManager viewManager = NoopStats.newNoopViewManager(); + View view1 = + View.create( + View.Name.create("View 1"), VIEW_DESCRIPTION, MEASURE, AGGREGATION, Arrays.asList(KEY)); + viewManager.registerView(view1); + Set<View> exported = viewManager.getAllExportedViews(); + + View view2 = + View.create( + View.Name.create("View 2"), VIEW_DESCRIPTION, MEASURE, AGGREGATION, Arrays.asList(KEY)); + thrown.expect(UnsupportedOperationException.class); + exported.add(view2); + } +} diff --git a/api/src/test/java/io/opencensus/stats/StatsTest.java b/api/src/test/java/io/opencensus/stats/StatsTest.java new file mode 100644 index 00000000..4219173a --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/StatsTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Stats}. */ +@RunWith(JUnit4.class) +public final class StatsTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void loadStatsManager_UsesProvidedClassLoader() { + final RuntimeException toThrow = new RuntimeException("UseClassLoader"); + thrown.expect(RuntimeException.class); + thrown.expectMessage("UseClassLoader"); + Stats.loadStatsComponent( + new ClassLoader() { + @Override + public Class<?> loadClass(String name) { + throw toThrow; + } + }); + } + + @Test + public void loadStatsManager_IgnoresMissingClasses() { + ClassLoader classLoader = + new ClassLoader() { + @Override + public Class<?> loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }; + + assertThat(Stats.loadStatsComponent(classLoader).getClass().getName()) + .isEqualTo("io.opencensus.stats.NoopStats$NoopStatsComponent"); + } + + @Test + public void defaultValues() { + assertThat(Stats.getStatsRecorder()).isEqualTo(NoopStats.getNoopStatsRecorder()); + assertThat(Stats.getViewManager()).isInstanceOf(NoopStats.newNoopViewManager().getClass()); + } + + @Test + public void getState() { + assertThat(Stats.getState()).isEqualTo(StatsCollectionState.DISABLED); + } + + @Test + @SuppressWarnings("deprecation") + public void setState_IgnoresInput() { + Stats.setState(StatsCollectionState.ENABLED); + assertThat(Stats.getState()).isEqualTo(StatsCollectionState.DISABLED); + } + + @Test + @SuppressWarnings("deprecation") + public void setState_DisallowsNull() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("state"); + Stats.setState(null); + } +} diff --git a/api/src/test/java/io/opencensus/stats/ViewDataTest.java b/api/src/test/java/io/opencensus/stats/ViewDataTest.java new file mode 100644 index 00000000..0120ffea --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/ViewDataTest.java @@ -0,0 +1,301 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; + +import com.google.common.collect.ImmutableMap; +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Duration; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; +import io.opencensus.stats.Aggregation.Count; +import io.opencensus.stats.Aggregation.Distribution; +import io.opencensus.stats.Aggregation.LastValue; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.Aggregation.Sum; +import io.opencensus.stats.AggregationData.CountData; +import io.opencensus.stats.AggregationData.DistributionData; +import io.opencensus.stats.AggregationData.LastValueDataDouble; +import io.opencensus.stats.AggregationData.LastValueDataLong; +import io.opencensus.stats.AggregationData.SumDataDouble; +import io.opencensus.stats.AggregationData.SumDataLong; +import io.opencensus.stats.View.AggregationWindow; +import io.opencensus.stats.View.AggregationWindow.Cumulative; +import io.opencensus.stats.View.AggregationWindow.Interval; +import io.opencensus.stats.ViewData.AggregationWindowData; +import io.opencensus.stats.ViewData.AggregationWindowData.CumulativeData; +import io.opencensus.stats.ViewData.AggregationWindowData.IntervalData; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.TagValue; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for class {@link ViewData}. */ +@RunWith(JUnit4.class) +public final class ViewDataTest { + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testCumulativeViewData() { + View view = View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE); + Timestamp start = Timestamp.fromMillis(1000); + Timestamp end = Timestamp.fromMillis(2000); + AggregationWindowData windowData = CumulativeData.create(start, end); + ViewData viewData = ViewData.create(view, ENTRIES, windowData); + assertThat(viewData.getView()).isEqualTo(view); + assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES); + assertThat(viewData.getWindowData()).isEqualTo(windowData); + } + + @Test + public void testIntervalViewData() { + View view = + View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR); + Timestamp end = Timestamp.fromMillis(2000); + AggregationWindowData windowData = IntervalData.create(end); + ViewData viewData = ViewData.create(view, ENTRIES, windowData); + assertThat(viewData.getView()).isEqualTo(view); + assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES); + assertThat(viewData.getWindowData()).isEqualTo(windowData); + } + + @Test + public void testViewDataEquals() { + View cumulativeView = + View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE); + View intervalView = + View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR); + + new EqualsTester() + .addEqualityGroup( + ViewData.create( + cumulativeView, + ENTRIES, + CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))), + ViewData.create( + cumulativeView, + ENTRIES, + CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)))) + .addEqualityGroup( + ViewData.create( + cumulativeView, + ENTRIES, + CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(3000)))) + .addEqualityGroup( + ViewData.create(intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000))), + ViewData.create(intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000)))) + .addEqualityGroup( + ViewData.create( + intervalView, + Collections.<List<TagValue>, AggregationData>emptyMap(), + IntervalData.create(Timestamp.fromMillis(2000)))) + .testEquals(); + } + + @Test + public void testAggregationWindowDataMatch() { + final Timestamp start = Timestamp.fromMillis(1000); + final Timestamp end = Timestamp.fromMillis(2000); + final AggregationWindowData windowData1 = CumulativeData.create(start, end); + final AggregationWindowData windowData2 = IntervalData.create(end); + windowData1.match( + new Function<CumulativeData, Void>() { + @Override + public Void apply(CumulativeData windowData) { + assertThat(windowData.getStart()).isEqualTo(start); + assertThat(windowData.getEnd()).isEqualTo(end); + return null; + } + }, + new Function<IntervalData, Void>() { + @Override + public Void apply(IntervalData windowData) { + fail("CumulativeData expected."); + return null; + } + }, + Functions.<Void>throwIllegalArgumentException()); + windowData2.match( + new Function<CumulativeData, Void>() { + @Override + public Void apply(CumulativeData windowData) { + fail("IntervalData expected."); + return null; + } + }, + new Function<IntervalData, Void>() { + @Override + public Void apply(IntervalData windowData) { + assertThat(windowData.getEnd()).isEqualTo(end); + return null; + } + }, + Functions.<Void>throwIllegalArgumentException()); + } + + @Test + public void preventWindowAndAggregationWindowDataMismatch() { + CumulativeData cumulativeData = + CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage( + "AggregationWindow and AggregationWindowData types mismatch. " + + "AggregationWindow: " + + INTERVAL_HOUR.getClass().getSimpleName() + + " AggregationWindowData: " + + cumulativeData.getClass().getSimpleName()); + ViewData.create( + View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR), + ENTRIES, + cumulativeData); + } + + @Test + public void preventWindowAndAggregationWindowDataMismatch2() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("AggregationWindow and AggregationWindowData types mismatch. "); + ViewData.create( + View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE), + ENTRIES, + IntervalData.create(Timestamp.fromMillis(1000))); + } + + @Test + public void preventStartTimeLaterThanEndTime() { + thrown.expect(IllegalArgumentException.class); + CumulativeData.create(Timestamp.fromMillis(3000), Timestamp.fromMillis(2000)); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_SumDouble_SumLong() { + aggregationAndAggregationDataMismatch( + createView(Sum.create(), MEASURE_DOUBLE), + ImmutableMap.<List<TagValue>, AggregationData>of( + Arrays.asList(V1, V2), SumDataLong.create(100))); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_SumLong_SumDouble() { + aggregationAndAggregationDataMismatch( + createView(Sum.create(), MEASURE_LONG), + ImmutableMap.<List<TagValue>, AggregationData>of( + Arrays.asList(V1, V2), SumDataDouble.create(100))); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_Count_Distribution() { + aggregationAndAggregationDataMismatch(createView(Count.create()), ENTRIES); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_Mean_Distribution() { + aggregationAndAggregationDataMismatch(createView(Mean.create()), ENTRIES); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_Distribution_Count() { + aggregationAndAggregationDataMismatch( + createView(DISTRIBUTION), ImmutableMap.of(Arrays.asList(V10, V20), CountData.create(100))); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_LastValueDouble_LastValueLong() { + aggregationAndAggregationDataMismatch( + createView(LastValue.create(), MEASURE_DOUBLE), + ImmutableMap.<List<TagValue>, AggregationData>of( + Arrays.asList(V1, V2), LastValueDataLong.create(100))); + } + + @Test + public void preventAggregationAndAggregationDataMismatch_LastValueLong_LastValueDouble() { + aggregationAndAggregationDataMismatch( + createView(LastValue.create(), MEASURE_LONG), + ImmutableMap.<List<TagValue>, AggregationData>of( + Arrays.asList(V1, V2), LastValueDataDouble.create(100))); + } + + private static View createView(Aggregation aggregation) { + return createView(aggregation, MEASURE_DOUBLE); + } + + private static View createView(Aggregation aggregation, Measure measure) { + return View.create(NAME, DESCRIPTION, measure, aggregation, TAG_KEYS, CUMULATIVE); + } + + private void aggregationAndAggregationDataMismatch( + View view, Map<List<TagValue>, ? extends AggregationData> entries) { + CumulativeData cumulativeData = + CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000)); + Aggregation aggregation = view.getAggregation(); + AggregationData aggregationData = entries.values().iterator().next(); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage( + "Aggregation and AggregationData types mismatch. " + + "Aggregation: " + + aggregation.getClass().getSimpleName() + + " AggregationData: " + + aggregationData.getClass().getSimpleName()); + ViewData.create(view, entries, cumulativeData); + } + + // tag keys + private static final TagKey K1 = TagKey.create("k1"); + private static final TagKey K2 = TagKey.create("k2"); + private static final List<TagKey> TAG_KEYS = Arrays.asList(K1, K2); + + // tag values + private static final TagValue V1 = TagValue.create("v1"); + private static final TagValue V2 = TagValue.create("v2"); + private static final TagValue V10 = TagValue.create("v10"); + private static final TagValue V20 = TagValue.create("v20"); + + private static final AggregationWindow CUMULATIVE = Cumulative.create(); + private static final AggregationWindow INTERVAL_HOUR = Interval.create(Duration.create(3600, 0)); + + private static final BucketBoundaries BUCKET_BOUNDARIES = + BucketBoundaries.create(Arrays.asList(10.0, 20.0, 30.0, 40.0)); + + private static final Aggregation DISTRIBUTION = Distribution.create(BUCKET_BOUNDARIES); + + private static final ImmutableMap<List<TagValue>, DistributionData> ENTRIES = + ImmutableMap.of( + Arrays.asList(V1, V2), + DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 0L)), + Arrays.asList(V10, V20), + DistributionData.create(-5, 6, -20, 5, 100.1, Arrays.asList(5L, 0L, 1L))); + + // name + private static final View.Name NAME = View.Name.create("test-view"); + // description + private static final String DESCRIPTION = "test-view-descriptor description"; + // measure + private static final Measure MEASURE_DOUBLE = + Measure.MeasureDouble.create("measure1", "measure description", "1"); + private static final Measure MEASURE_LONG = + Measure.MeasureLong.create("measure2", "measure description", "1"); +} diff --git a/api/src/test/java/io/opencensus/stats/ViewTest.java b/api/src/test/java/io/opencensus/stats/ViewTest.java new file mode 100644 index 00000000..afba1bc0 --- /dev/null +++ b/api/src/test/java/io/opencensus/stats/ViewTest.java @@ -0,0 +1,164 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.stats; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Duration; +import io.opencensus.stats.Aggregation.Mean; +import io.opencensus.stats.View.AggregationWindow.Cumulative; +import io.opencensus.stats.View.AggregationWindow.Interval; +import io.opencensus.tags.TagKey; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link View}. */ +@RunWith(JUnit4.class) +public final class ViewTest { + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void testConstants() { + assertThat(View.NAME_MAX_LENGTH).isEqualTo(255); + } + + @Test + public void sortTagKeys() { + final View view = + View.create( + NAME, + DESCRIPTION, + MEASURE, + MEAN, + Arrays.asList( + TagKey.create("ab"), TagKey.create("a"), TagKey.create("A"), TagKey.create("b"))); + assertThat(view.getColumns()) + .containsExactly( + TagKey.create("A"), TagKey.create("a"), TagKey.create("ab"), TagKey.create("b")) + .inOrder(); + } + + @Test + public void testDistributionView() { + final View view = View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS); + assertThat(view.getName()).isEqualTo(NAME); + assertThat(view.getDescription()).isEqualTo(DESCRIPTION); + assertThat(view.getMeasure().getName()).isEqualTo(MEASURE.getName()); + assertThat(view.getAggregation()).isEqualTo(MEAN); + assertThat(view.getColumns()).containsExactly(BAR, FOO).inOrder(); + assertThat(view.getWindow()).isEqualTo(Cumulative.create()); + } + + @Test + public void testIntervalView() { + final View view = View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS, Interval.create(MINUTE)); + assertThat(view.getName()).isEqualTo(NAME); + assertThat(view.getDescription()).isEqualTo(DESCRIPTION); + assertThat(view.getMeasure().getName()).isEqualTo(MEASURE.getName()); + assertThat(view.getAggregation()).isEqualTo(MEAN); + assertThat(view.getColumns()).containsExactly(BAR, FOO).inOrder(); + assertThat(view.getWindow()).isEqualTo(Interval.create(MINUTE)); + } + + @Test + public void testViewEquals() { + new EqualsTester() + .addEqualityGroup( + View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS), + View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS, Cumulative.create())) + .addEqualityGroup( + View.create(NAME, DESCRIPTION + 2, MEASURE, MEAN, KEYS, Cumulative.create())) + .addEqualityGroup( + View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS, Interval.create(MINUTE)), + View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS, Interval.create(MINUTE))) + .addEqualityGroup( + View.create(NAME, DESCRIPTION, MEASURE, MEAN, KEYS, Interval.create(TWO_MINUTES))) + .testEquals(); + } + + @Test + public void preventDuplicateColumns() { + TagKey key1 = TagKey.create("duplicate"); + TagKey key2 = TagKey.create("duplicate"); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Columns have duplicate."); + View.create(NAME, DESCRIPTION, MEASURE, MEAN, Arrays.asList(key1, key2)); + } + + @Test(expected = NullPointerException.class) + public void preventNullViewName() { + View.create(null, DESCRIPTION, MEASURE, MEAN, KEYS); + } + + @Test + public void preventTooLongViewName() { + char[] chars = new char[View.NAME_MAX_LENGTH + 1]; + Arrays.fill(chars, 'a'); + String longName = String.valueOf(chars); + thrown.expect(IllegalArgumentException.class); + View.Name.create(longName); + } + + @Test + public void preventNonPrintableViewName() { + thrown.expect(IllegalArgumentException.class); + View.Name.create("\2"); + } + + @Test + public void testViewName() { + assertThat(View.Name.create("my name").asString()).isEqualTo("my name"); + } + + @Test(expected = NullPointerException.class) + public void preventNullNameString() { + View.Name.create(null); + } + + @Test(expected = IllegalArgumentException.class) + public void preventNegativeIntervalDuration() { + Interval.create(NEG_TEN_SECONDS); + } + + @Test + public void testViewNameEquals() { + new EqualsTester() + .addEqualityGroup(View.Name.create("view-1"), View.Name.create("view-1")) + .addEqualityGroup(View.Name.create("view-2")) + .testEquals(); + } + + private static final View.Name NAME = View.Name.create("test-view-name"); + private static final String DESCRIPTION = "test-view-name description"; + private static final Measure MEASURE = + Measure.MeasureDouble.create("measure", "measure description", "1"); + private static final TagKey FOO = TagKey.create("foo"); + private static final TagKey BAR = TagKey.create("bar"); + private static final List<TagKey> KEYS = Collections.unmodifiableList(Arrays.asList(FOO, BAR)); + private static final Mean MEAN = Mean.create(); + private static final Duration MINUTE = Duration.create(60, 0); + private static final Duration TWO_MINUTES = Duration.create(120, 0); + private static final Duration NEG_TEN_SECONDS = Duration.create(-10, 0); +} diff --git a/api/src/test/java/io/opencensus/tags/InternalUtilsTest.java b/api/src/test/java/io/opencensus/tags/InternalUtilsTest.java new file mode 100644 index 00000000..65482de1 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/InternalUtilsTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link InternalUtils}. */ +@RunWith(JUnit4.class) +public final class InternalUtilsTest { + + @Test + public void getTags() { + final Iterator<Tag> iterator = + Lists.<Tag>newArrayList(Tag.create(TagKey.create("k"), TagValue.create("v"))).iterator(); + TagContext ctx = + new TagContext() { + @Override + protected Iterator<Tag> getIterator() { + return iterator; + } + }; + assertThat(InternalUtils.getTags(ctx)).isSameAs(iterator); + } +} diff --git a/api/src/test/java/io/opencensus/tags/NoopTagsTest.java b/api/src/test/java/io/opencensus/tags/NoopTagsTest.java new file mode 100644 index 00000000..db07520e --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/NoopTagsTest.java @@ -0,0 +1,179 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.opencensus.internal.NoopScope; +import io.opencensus.tags.propagation.TagContextBinarySerializer; +import io.opencensus.tags.propagation.TagContextDeserializationException; +import io.opencensus.tags.propagation.TagContextSerializationException; +import java.util.Arrays; +import java.util.Iterator; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link NoopTags}. */ +@RunWith(JUnit4.class) +public final class NoopTagsTest { + private static final TagKey KEY = TagKey.create("key"); + private static final TagValue VALUE = TagValue.create("value"); + + private static final TagContext TAG_CONTEXT = + new TagContext() { + + @Override + protected Iterator<Tag> getIterator() { + return Arrays.<Tag>asList(Tag.create(KEY, VALUE)).iterator(); + } + }; + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void noopTagsComponent() { + assertThat(NoopTags.newNoopTagsComponent().getTagger()).isSameAs(NoopTags.getNoopTagger()); + assertThat(NoopTags.newNoopTagsComponent().getTagPropagationComponent()) + .isSameAs(NoopTags.getNoopTagPropagationComponent()); + } + + @Test + @SuppressWarnings("deprecation") + public void noopTagsComponent_SetState_DisallowsNull() { + TagsComponent noopTagsComponent = NoopTags.newNoopTagsComponent(); + thrown.expect(NullPointerException.class); + noopTagsComponent.setState(null); + } + + @Test + @SuppressWarnings("deprecation") + public void preventSettingStateAfterGettingState_DifferentState() { + TagsComponent noopTagsComponent = NoopTags.newNoopTagsComponent(); + noopTagsComponent.setState(TaggingState.DISABLED); + noopTagsComponent.getState(); + thrown.expect(IllegalStateException.class); + thrown.expectMessage("State was already read, cannot set state."); + noopTagsComponent.setState(TaggingState.ENABLED); + } + + @Test + @SuppressWarnings("deprecation") + public void preventSettingStateAfterGettingState_SameState() { + TagsComponent noopTagsComponent = NoopTags.newNoopTagsComponent(); + noopTagsComponent.setState(TaggingState.DISABLED); + noopTagsComponent.getState(); + thrown.expect(IllegalStateException.class); + thrown.expectMessage("State was already read, cannot set state."); + noopTagsComponent.setState(TaggingState.DISABLED); + } + + @Test + public void noopTagger() { + Tagger noopTagger = NoopTags.getNoopTagger(); + assertThat(noopTagger.empty()).isSameAs(NoopTags.getNoopTagContext()); + assertThat(noopTagger.getCurrentTagContext()).isSameAs(NoopTags.getNoopTagContext()); + assertThat(noopTagger.emptyBuilder()).isSameAs(NoopTags.getNoopTagContextBuilder()); + assertThat(noopTagger.toBuilder(TAG_CONTEXT)).isSameAs(NoopTags.getNoopTagContextBuilder()); + assertThat(noopTagger.currentBuilder()).isSameAs(NoopTags.getNoopTagContextBuilder()); + assertThat(noopTagger.withTagContext(TAG_CONTEXT)).isSameAs(NoopScope.getInstance()); + } + + @Test + public void noopTagger_ToBuilder_DisallowsNull() { + Tagger noopTagger = NoopTags.getNoopTagger(); + thrown.expect(NullPointerException.class); + noopTagger.toBuilder(null); + } + + @Test + public void noopTagger_WithTagContext_DisallowsNull() { + Tagger noopTagger = NoopTags.getNoopTagger(); + thrown.expect(NullPointerException.class); + noopTagger.withTagContext(null); + } + + @Test + public void noopTagContextBuilder() { + assertThat(NoopTags.getNoopTagContextBuilder().build()).isSameAs(NoopTags.getNoopTagContext()); + assertThat(NoopTags.getNoopTagContextBuilder().put(KEY, VALUE).build()) + .isSameAs(NoopTags.getNoopTagContext()); + assertThat(NoopTags.getNoopTagContextBuilder().buildScoped()).isSameAs(NoopScope.getInstance()); + assertThat(NoopTags.getNoopTagContextBuilder().put(KEY, VALUE).buildScoped()) + .isSameAs(NoopScope.getInstance()); + } + + @Test + public void noopTagContextBuilder_Put_DisallowsNullKey() { + TagContextBuilder noopBuilder = NoopTags.getNoopTagContextBuilder(); + thrown.expect(NullPointerException.class); + noopBuilder.put(null, VALUE); + } + + @Test + public void noopTagContextBuilder_Put_DisallowsNullValue() { + TagContextBuilder noopBuilder = NoopTags.getNoopTagContextBuilder(); + thrown.expect(NullPointerException.class); + noopBuilder.put(KEY, null); + } + + @Test + public void noopTagContextBuilder_Remove_DisallowsNullKey() { + TagContextBuilder noopBuilder = NoopTags.getNoopTagContextBuilder(); + thrown.expect(NullPointerException.class); + noopBuilder.remove(null); + } + + @Test + public void noopTagContext() { + assertThat(Lists.newArrayList(NoopTags.getNoopTagContext().getIterator())).isEmpty(); + } + + @Test + public void noopTagPropagationComponent() { + assertThat(NoopTags.getNoopTagPropagationComponent().getBinarySerializer()) + .isSameAs(NoopTags.getNoopTagContextBinarySerializer()); + } + + @Test + public void noopTagContextBinarySerializer() + throws TagContextDeserializationException, TagContextSerializationException { + assertThat(NoopTags.getNoopTagContextBinarySerializer().toByteArray(TAG_CONTEXT)) + .isEqualTo(new byte[0]); + assertThat(NoopTags.getNoopTagContextBinarySerializer().fromByteArray(new byte[5])) + .isEqualTo(NoopTags.getNoopTagContext()); + } + + @Test + public void noopTagContextBinarySerializer_ToByteArray_DisallowsNull() + throws TagContextSerializationException { + TagContextBinarySerializer noopSerializer = NoopTags.getNoopTagContextBinarySerializer(); + thrown.expect(NullPointerException.class); + noopSerializer.toByteArray(null); + } + + @Test + public void noopTagContextBinarySerializer_FromByteArray_DisallowsNull() + throws TagContextDeserializationException { + TagContextBinarySerializer noopSerializer = NoopTags.getNoopTagContextBinarySerializer(); + thrown.expect(NullPointerException.class); + noopSerializer.fromByteArray(null); + } +} diff --git a/api/src/test/java/io/opencensus/tags/TagContextTest.java b/api/src/test/java/io/opencensus/tags/TagContextTest.java new file mode 100644 index 00000000..025c7bae --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/TagContextTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import com.google.common.testing.EqualsTester; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import javax.annotation.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagContext}. */ +@RunWith(JUnit4.class) +public final class TagContextTest { + private static final Tag TAG1 = Tag.create(TagKey.create("key"), TagValue.create("val")); + private static final Tag TAG2 = Tag.create(TagKey.create("key2"), TagValue.create("val")); + + @Test + public void equals_IgnoresTagOrderAndTagContextClass() { + new EqualsTester() + .addEqualityGroup( + new SimpleTagContext(TAG1, TAG2), + new SimpleTagContext(TAG1, TAG2), + new SimpleTagContext(TAG2, TAG1), + new TagContext() { + @Override + protected Iterator<Tag> getIterator() { + return Lists.newArrayList(TAG1, TAG2).iterator(); + } + }) + .testEquals(); + } + + @Test + public void equals_HandlesNullIterator() { + new EqualsTester() + .addEqualityGroup( + new SimpleTagContext((List<Tag>) null), + new SimpleTagContext((List<Tag>) null), + new SimpleTagContext()) + .testEquals(); + } + + @Test + public void equals_DoesNotIgnoreNullTags() { + new EqualsTester() + .addEqualityGroup(new SimpleTagContext(TAG1)) + .addEqualityGroup(new SimpleTagContext(TAG1, null), new SimpleTagContext(null, TAG1)) + .addEqualityGroup(new SimpleTagContext(TAG1, null, null)) + .testEquals(); + } + + @Test + public void equals_DoesNotIgnoreDuplicateTags() { + new EqualsTester() + .addEqualityGroup(new SimpleTagContext(TAG1)) + .addEqualityGroup(new SimpleTagContext(TAG1, TAG1)) + .testEquals(); + } + + @Test + public void testToString() { + assertThat(new SimpleTagContext().toString()).isEqualTo("TagContext"); + assertThat(new SimpleTagContext(TAG1, TAG2).toString()).isEqualTo("TagContext"); + } + + private static final class SimpleTagContext extends TagContext { + @Nullable private final List<Tag> tags; + + SimpleTagContext(Tag... tags) { + this(Lists.newArrayList(tags)); + } + + SimpleTagContext(List<Tag> tags) { + this.tags = tags == null ? null : Collections.unmodifiableList(Lists.newArrayList(tags)); + } + + @Override + @Nullable + protected Iterator<Tag> getIterator() { + return tags == null ? null : tags.iterator(); + } + } +} diff --git a/api/src/test/java/io/opencensus/tags/TagKeyTest.java b/api/src/test/java/io/opencensus/tags/TagKeyTest.java new file mode 100644 index 00000000..48cf9fd4 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/TagKeyTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Arrays; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagKey}. */ +@RunWith(JUnit4.class) +public final class TagKeyTest { + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void testMaxLength() { + assertThat(TagKey.MAX_LENGTH).isEqualTo(255); + } + + @Test + public void testGetName() { + assertThat(TagKey.create("foo").getName()).isEqualTo("foo"); + } + + @Test + public void create_AllowTagKeyNameWithMaxLength() { + char[] chars = new char[TagKey.MAX_LENGTH]; + Arrays.fill(chars, 'k'); + String key = new String(chars); + assertThat(TagKey.create(key).getName()).isEqualTo(key); + } + + @Test + public void create_DisallowTagKeyNameOverMaxLength() { + char[] chars = new char[TagKey.MAX_LENGTH + 1]; + Arrays.fill(chars, 'k'); + String key = new String(chars); + thrown.expect(IllegalArgumentException.class); + TagKey.create(key); + } + + @Test + public void create_DisallowUnprintableChars() { + thrown.expect(IllegalArgumentException.class); + TagKey.create("\2ab\3cd"); + } + + @Test + public void createString_DisallowEmpty() { + thrown.expect(IllegalArgumentException.class); + TagKey.create(""); + } + + @Test + public void testTagKeyEquals() { + new EqualsTester() + .addEqualityGroup(TagKey.create("foo"), TagKey.create("foo")) + .addEqualityGroup(TagKey.create("bar")) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/tags/TagTest.java b/api/src/test/java/io/opencensus/tags/TagTest.java new file mode 100644 index 00000000..3c899e65 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/TagTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Tag}. */ +@RunWith(JUnit4.class) +public final class TagTest { + + @Test + public void testGetKey() { + assertThat(Tag.create(TagKey.create("k"), TagValue.create("v")).getKey()) + .isEqualTo(TagKey.create("k")); + } + + @Test + public void testTagEquals() { + new EqualsTester() + .addEqualityGroup( + Tag.create(TagKey.create("Key"), TagValue.create("foo")), + Tag.create(TagKey.create("Key"), TagValue.create("foo"))) + .addEqualityGroup(Tag.create(TagKey.create("Key"), TagValue.create("bar"))) + .addEqualityGroup(Tag.create(TagKey.create("Key2"), TagValue.create("foo"))) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/tags/TagValueTest.java b/api/src/test/java/io/opencensus/tags/TagValueTest.java new file mode 100644 index 00000000..9aa42c8c --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/TagValueTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Arrays; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TagValue}. */ +@RunWith(JUnit4.class) +public final class TagValueTest { + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void testMaxLength() { + assertThat(TagValue.MAX_LENGTH).isEqualTo(255); + } + + @Test + public void testAsString() { + assertThat(TagValue.create("foo").asString()).isEqualTo("foo"); + } + + @Test + public void create_AllowTagValueWithMaxLength() { + char[] chars = new char[TagValue.MAX_LENGTH]; + Arrays.fill(chars, 'v'); + String value = new String(chars); + assertThat(TagValue.create(value).asString()).isEqualTo(value); + } + + @Test + public void create_DisallowTagValueOverMaxLength() { + char[] chars = new char[TagValue.MAX_LENGTH + 1]; + Arrays.fill(chars, 'v'); + String value = new String(chars); + thrown.expect(IllegalArgumentException.class); + TagValue.create(value); + } + + @Test + public void disallowTagValueWithUnprintableChars() { + String value = "\2ab\3cd"; + thrown.expect(IllegalArgumentException.class); + TagValue.create(value); + } + + @Test + public void testTagValueEquals() { + new EqualsTester() + .addEqualityGroup(TagValue.create("foo"), TagValue.create("foo")) + .addEqualityGroup(TagValue.create("bar")) + .testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/tags/TagsTest.java b/api/src/test/java/io/opencensus/tags/TagsTest.java new file mode 100644 index 00000000..dee517b6 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/TagsTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Tags}. */ +@RunWith(JUnit4.class) +public class TagsTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void loadTagsComponent_UsesProvidedClassLoader() { + final RuntimeException toThrow = new RuntimeException("UseClassLoader"); + thrown.expect(RuntimeException.class); + thrown.expectMessage("UseClassLoader"); + Tags.loadTagsComponent( + new ClassLoader() { + @Override + public Class<?> loadClass(String name) { + throw toThrow; + } + }); + } + + @Test + public void loadTagsComponent_IgnoresMissingClasses() { + ClassLoader classLoader = + new ClassLoader() { + @Override + public Class<?> loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }; + assertThat(Tags.loadTagsComponent(classLoader).getClass().getName()) + .isEqualTo("io.opencensus.tags.NoopTags$NoopTagsComponent"); + } + + // There is only one test that modifies tagging state in the Tags class, since the state is + // global, and it could affect other tests. NoopTagsTest has more thorough tests for tagging + // state. + @Test + @SuppressWarnings("deprecation") + public void testState() { + // Test that setState ignores its input. + Tags.setState(TaggingState.ENABLED); + assertThat(Tags.getState()).isEqualTo(TaggingState.DISABLED); + + // Test that setState cannot be called after getState. + thrown.expect(IllegalStateException.class); + thrown.expectMessage("State was already read, cannot set state."); + Tags.setState(TaggingState.ENABLED); + } + + @Test + public void defaultTagger() { + assertThat(Tags.getTagger()).isEqualTo(NoopTags.getNoopTagger()); + } + + @Test + public void defaultTagContextSerializer() { + assertThat(Tags.getTagPropagationComponent()) + .isEqualTo(NoopTags.getNoopTagPropagationComponent()); + } +} diff --git a/api/src/test/java/io/opencensus/tags/propagation/TagContextDeserializationExceptionTest.java b/api/src/test/java/io/opencensus/tags/propagation/TagContextDeserializationExceptionTest.java new file mode 100644 index 00000000..750d5d45 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/propagation/TagContextDeserializationExceptionTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.IOException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TagContextDeserializationException}. */ +@RunWith(JUnit4.class) +public final class TagContextDeserializationExceptionTest { + + @Test + public void createWithMessage() { + assertThat(new TagContextDeserializationException("my message").getMessage()) + .isEqualTo("my message"); + } + + @Test + public void createWithMessageAndCause() { + IOException cause = new IOException(); + TagContextDeserializationException exception = + new TagContextDeserializationException("my message", cause); + assertThat(exception.getMessage()).isEqualTo("my message"); + assertThat(exception.getCause()).isEqualTo(cause); + } +} diff --git a/api/src/test/java/io/opencensus/tags/propagation/TagContextSerializationExceptionTest.java b/api/src/test/java/io/opencensus/tags/propagation/TagContextSerializationExceptionTest.java new file mode 100644 index 00000000..54e9fab6 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/propagation/TagContextSerializationExceptionTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.IOException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TagContextSerializationException}. */ +@RunWith(JUnit4.class) +public final class TagContextSerializationExceptionTest { + + @Test + public void createWithMessage() { + assertThat(new TagContextSerializationException("my message").getMessage()) + .isEqualTo("my message"); + } + + @Test + public void createWithMessageAndCause() { + IOException cause = new IOException(); + TagContextSerializationException exception = + new TagContextSerializationException("my message", cause); + assertThat(exception.getMessage()).isEqualTo("my message"); + assertThat(exception.getCause()).isEqualTo(cause); + } +} diff --git a/api/src/test/java/io/opencensus/tags/unsafe/ContextUtilsTest.java b/api/src/test/java/io/opencensus/tags/unsafe/ContextUtilsTest.java new file mode 100644 index 00000000..c35c5dc4 --- /dev/null +++ b/api/src/test/java/io/opencensus/tags/unsafe/ContextUtilsTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.tags.unsafe; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.grpc.Context; +import io.opencensus.tags.InternalUtils; +import io.opencensus.tags.Tag; +import io.opencensus.tags.TagContext; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ContextUtils}. */ +@RunWith(JUnit4.class) +public final class ContextUtilsTest { + @Test + public void testContextKeyName() { + // Context.Key.toString() returns the name. + assertThat(ContextUtils.TAG_CONTEXT_KEY.toString()).isEqualTo("opencensus-tag-context-key"); + } + + @Test + public void testGetCurrentTagContext_DefaultContext() { + TagContext tags = ContextUtils.TAG_CONTEXT_KEY.get(); + assertThat(tags).isNotNull(); + assertThat(asList(tags)).isEmpty(); + } + + @Test + public void testGetCurrentTagContext_ContextSetToNull() { + Context orig = Context.current().withValue(ContextUtils.TAG_CONTEXT_KEY, null).attach(); + try { + TagContext tags = ContextUtils.TAG_CONTEXT_KEY.get(); + assertThat(tags).isNotNull(); + assertThat(asList(tags)).isEmpty(); + } finally { + Context.current().detach(orig); + } + } + + private static List<Tag> asList(TagContext tags) { + return Lists.newArrayList(InternalUtils.getTags(tags)); + } +} diff --git a/api/src/test/java/io/opencensus/trace/AnnotationTest.java b/api/src/test/java/io/opencensus/trace/AnnotationTest.java new file mode 100644 index 00000000..0db5d93c --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/AnnotationTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Link}. */ +@RunWith(JUnit4.class) +public class AnnotationTest { + @Test(expected = NullPointerException.class) + public void fromDescription_NullDescription() { + Annotation.fromDescription(null); + } + + @Test + public void fromDescription() { + Annotation annotation = Annotation.fromDescription("MyAnnotationText"); + assertThat(annotation.getDescription()).isEqualTo("MyAnnotationText"); + assertThat(annotation.getAttributes().size()).isEqualTo(0); + } + + @Test(expected = NullPointerException.class) + public void fromDescriptionAndAttributes_NullDescription() { + Annotation.fromDescriptionAndAttributes(null, Collections.<String, AttributeValue>emptyMap()); + } + + @Test(expected = NullPointerException.class) + public void fromDescriptionAndAttributes_NullAttributes() { + Annotation.fromDescriptionAndAttributes("", null); + } + + @Test + public void fromDescriptionAndAttributes() { + Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>(); + attributes.put( + "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue")); + Annotation annotation = Annotation.fromDescriptionAndAttributes("MyAnnotationText", attributes); + assertThat(annotation.getDescription()).isEqualTo("MyAnnotationText"); + assertThat(annotation.getAttributes()).isEqualTo(attributes); + } + + @Test + public void fromDescriptionAndAttributes_EmptyAttributes() { + Annotation annotation = + Annotation.fromDescriptionAndAttributes( + "MyAnnotationText", Collections.<String, AttributeValue>emptyMap()); + assertThat(annotation.getDescription()).isEqualTo("MyAnnotationText"); + assertThat(annotation.getAttributes().size()).isEqualTo(0); + } + + @Test + public void annotation_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>(); + attributes.put( + "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue")); + tester + .addEqualityGroup( + Annotation.fromDescription("MyAnnotationText"), + Annotation.fromDescriptionAndAttributes( + "MyAnnotationText", Collections.<String, AttributeValue>emptyMap())) + .addEqualityGroup( + Annotation.fromDescriptionAndAttributes("MyAnnotationText", attributes), + Annotation.fromDescriptionAndAttributes("MyAnnotationText", attributes)) + .addEqualityGroup(Annotation.fromDescription("MyAnnotationText2")); + tester.testEquals(); + } + + @Test + public void annotation_ToString() { + Annotation annotation = Annotation.fromDescription("MyAnnotationText"); + assertThat(annotation.toString()).contains("MyAnnotationText"); + Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>(); + attributes.put( + "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue")); + annotation = Annotation.fromDescriptionAndAttributes("MyAnnotationText2", attributes); + assertThat(annotation.toString()).contains("MyAnnotationText2"); + assertThat(annotation.toString()).contains(attributes.toString()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/AttributeValueTest.java b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java new file mode 100644 index 00000000..05ef43c0 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/AttributeValueTest.java @@ -0,0 +1,233 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import javax.annotation.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link AttributeValue}. */ +@RunWith(JUnit4.class) +public class AttributeValueTest { + @Test + public void stringAttributeValue() { + AttributeValue attribute = AttributeValue.stringAttributeValue("MyStringAttributeValue"); + attribute.match( + new Function<String, Object>() { + @Override + @Nullable + public Object apply(String stringValue) { + assertThat(stringValue).isEqualTo("MyStringAttributeValue"); + return null; + } + }, + new Function<Boolean, Object>() { + @Override + @Nullable + public Object apply(Boolean booleanValue) { + fail("Expected a String"); + return null; + } + }, + new Function<Long, Object>() { + @Override + @Nullable + public Object apply(Long longValue) { + fail("Expected a String"); + return null; + } + }, + Functions.throwIllegalArgumentException()); + } + + @Test + public void booleanAttributeValue() { + AttributeValue attribute = AttributeValue.booleanAttributeValue(true); + attribute.match( + new Function<String, Object>() { + @Override + @Nullable + public Object apply(String stringValue) { + fail("Expected a Boolean"); + return null; + } + }, + new Function<Boolean, Object>() { + @Override + @Nullable + public Object apply(Boolean booleanValue) { + assertThat(booleanValue).isTrue(); + return null; + } + }, + new Function<Long, Object>() { + @Override + @Nullable + public Object apply(Long longValue) { + fail("Expected a Boolean"); + return null; + } + }, + Functions.throwIllegalArgumentException()); + } + + @Test + public void longAttributeValue() { + AttributeValue attribute = AttributeValue.longAttributeValue(123456L); + attribute.match( + new Function<String, Object>() { + @Override + @Nullable + public Object apply(String stringValue) { + fail("Expected a Long"); + return null; + } + }, + new Function<Boolean, Object>() { + @Override + @Nullable + public Object apply(Boolean booleanValue) { + fail("Expected a Long"); + return null; + } + }, + new Function<Long, Object>() { + @Override + @Nullable + public Object apply(Long longValue) { + assertThat(longValue).isEqualTo(123456L); + return null; + } + }, + Functions.throwIllegalArgumentException()); + } + + @Test + public void doubleAttributeValue() { + AttributeValue attribute = AttributeValue.doubleAttributeValue(1.23456); + attribute.match( + new Function<String, Object>() { + @Override + @Nullable + public Object apply(String stringValue) { + fail("Expected a Double"); + return null; + } + }, + new Function<Boolean, Object>() { + @Override + @Nullable + public Object apply(Boolean booleanValue) { + fail("Expected a Double"); + return null; + } + }, + new Function<Long, Object>() { + @Override + @Nullable + public Object apply(Long longValue) { + fail("Expected a Double"); + return null; + } + }, + new Function<Double, Object>() { + @Override + @Nullable + public Object apply(Double doubleValue) { + assertThat(doubleValue).isEqualTo(1.23456); + return null; + } + }, + Functions.throwIllegalArgumentException()); + } + + @Test + public void doubleAttributeValue_DeprecatedMatchFunction() { + AttributeValue attribute = AttributeValue.doubleAttributeValue(1.23456); + attribute.match( + new Function<String, Object>() { + @Override + @Nullable + public Object apply(String stringValue) { + fail("Expected a Double"); + return null; + } + }, + new Function<Boolean, Object>() { + @Override + @Nullable + public Object apply(Boolean booleanValue) { + fail("Expected a Double"); + return null; + } + }, + new Function<Long, Object>() { + @Override + @Nullable + public Object apply(Long longValue) { + fail("Expected a Double"); + return null; + } + }, + new Function<Object, Object>() { + @Override + @Nullable + public Object apply(Object value) { + assertThat(value).isEqualTo(1.23456); + return null; + } + }); + } + + @Test + public void attributeValue_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup( + AttributeValue.stringAttributeValue("MyStringAttributeValue"), + AttributeValue.stringAttributeValue("MyStringAttributeValue")); + tester.addEqualityGroup(AttributeValue.stringAttributeValue("MyStringAttributeDiffValue")); + tester.addEqualityGroup( + AttributeValue.booleanAttributeValue(true), AttributeValue.booleanAttributeValue(true)); + tester.addEqualityGroup(AttributeValue.booleanAttributeValue(false)); + tester.addEqualityGroup( + AttributeValue.longAttributeValue(123456L), AttributeValue.longAttributeValue(123456L)); + tester.addEqualityGroup(AttributeValue.longAttributeValue(1234567L)); + tester.addEqualityGroup( + AttributeValue.doubleAttributeValue(1.23456), AttributeValue.doubleAttributeValue(1.23456)); + tester.addEqualityGroup(AttributeValue.doubleAttributeValue(1.234567)); + tester.testEquals(); + } + + @Test + public void attributeValue_ToString() { + AttributeValue attribute = AttributeValue.stringAttributeValue("MyStringAttributeValue"); + assertThat(attribute.toString()).contains("MyStringAttributeValue"); + attribute = AttributeValue.booleanAttributeValue(true); + assertThat(attribute.toString()).contains("true"); + attribute = AttributeValue.longAttributeValue(123456L); + assertThat(attribute.toString()).contains("123456"); + attribute = AttributeValue.doubleAttributeValue(1.23456); + assertThat(attribute.toString()).contains("1.23456"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/BlankSpanTest.java b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java new file mode 100644 index 00000000..185a5acd --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/BlankSpanTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link BlankSpan}. */ +@RunWith(JUnit4.class) +public class BlankSpanTest { + @Test + public void hasInvalidContextAndDefaultSpanOptions() { + assertThat(BlankSpan.INSTANCE.getContext()).isEqualTo(SpanContext.INVALID); + assertThat(BlankSpan.INSTANCE.getOptions().isEmpty()).isTrue(); + } + + @Test + public void doNotCrash() { + Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>(); + attributes.put( + "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue")); + Map<String, AttributeValue> multipleAttributes = new HashMap<String, AttributeValue>(); + multipleAttributes.put( + "MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue")); + multipleAttributes.put("MyBooleanAttributeKey", AttributeValue.booleanAttributeValue(true)); + multipleAttributes.put("MyLongAttributeKey", AttributeValue.longAttributeValue(123)); + // Tests only that all the methods are not crashing/throwing errors. + BlankSpan.INSTANCE.putAttribute( + "MyStringAttributeKey2", AttributeValue.stringAttributeValue("MyStringAttributeValue2")); + BlankSpan.INSTANCE.addAttributes(attributes); + BlankSpan.INSTANCE.addAttributes(multipleAttributes); + BlankSpan.INSTANCE.addAnnotation("MyAnnotation"); + BlankSpan.INSTANCE.addAnnotation("MyAnnotation", attributes); + BlankSpan.INSTANCE.addAnnotation("MyAnnotation", multipleAttributes); + BlankSpan.INSTANCE.addAnnotation(Annotation.fromDescription("MyAnnotation")); + BlankSpan.INSTANCE.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).build()); + BlankSpan.INSTANCE.addMessageEvent(MessageEvent.builder(MessageEvent.Type.SENT, 1L).build()); + BlankSpan.INSTANCE.addLink( + Link.fromSpanContext(SpanContext.INVALID, Link.Type.CHILD_LINKED_SPAN)); + BlankSpan.INSTANCE.setStatus(Status.OK); + BlankSpan.INSTANCE.end(EndSpanOptions.DEFAULT); + BlankSpan.INSTANCE.end(); + } + + @Test + public void blankSpan_ToString() { + assertThat(BlankSpan.INSTANCE.toString()).isEqualTo("BlankSpan"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java new file mode 100644 index 00000000..6b16c3d0 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/CurrentSpanUtilsTest.java @@ -0,0 +1,294 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import io.grpc.Context; +import io.opencensus.common.Scope; +import io.opencensus.trace.unsafe.ContextUtils; +import java.util.concurrent.Callable; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link CurrentSpanUtils}. */ +@RunWith(JUnit4.class) +public class CurrentSpanUtilsTest { + @Mock private Span span; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + // TODO(bdrutu): When update to junit 4.13 use assertThrows instead of this. + private void executeRunnableAndExpectError(Runnable runnable, Throwable error) { + boolean called = false; + try { + CurrentSpanUtils.withSpan(span, true, runnable).run(); + } catch (Throwable e) { + assertThat(e).isEqualTo(error); + called = true; + } + assertThat(called).isTrue(); + } + + // TODO(bdrutu): When update to junit 4.13 use assertThrows instead of this. + private void executeCallableAndExpectError(Callable<Object> callable, Throwable error) { + boolean called = false; + try { + CurrentSpanUtils.withSpan(span, true, callable).call(); + } catch (Throwable e) { + assertThat(e).isEqualTo(error); + called = true; + } + assertThat(called).isTrue(); + } + + @Test + public void getCurrentSpan_WhenNoContext() { + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void getCurrentSpan() { + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Context origContext = Context.current().withValue(ContextUtils.CONTEXT_SPAN_KEY, span).attach(); + // Make sure context is detached even if test fails. + try { + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + } finally { + Context.current().detach(origContext); + } + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpan_CloseDetaches() { + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Scope ws = CurrentSpanUtils.withSpan(span, false); + try { + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + } finally { + ws.close(); + } + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + verifyZeroInteractions(span); + } + + @Test + public void withSpan_CloseDetachesAndEndsSpan() { + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Scope ss = CurrentSpanUtils.withSpan(span, true); + try { + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + } finally { + ss.close(); + } + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + verify(span).end(same(EndSpanOptions.DEFAULT)); + } + + @Test + public void withSpanRunnable() { + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Runnable runnable = + new Runnable() { + @Override + public void run() { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + } + }; + CurrentSpanUtils.withSpan(span, false, runnable).run(); + verifyZeroInteractions(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanRunnable_EndSpan() { + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Runnable runnable = + new Runnable() { + @Override + public void run() { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + } + }; + CurrentSpanUtils.withSpan(span, true, runnable).run(); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanRunnable_WithError() { + final AssertionError error = new AssertionError("MyError"); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Runnable runnable = + new Runnable() { + @Override + public void run() { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + throw error; + } + }; + executeRunnableAndExpectError(runnable, error); + verify(span).setStatus(Status.UNKNOWN.withDescription("MyError")); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanRunnable_WithErrorNoMessage() { + final AssertionError error = new AssertionError(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Runnable runnable = + new Runnable() { + @Override + public void run() { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + throw error; + } + }; + executeRunnableAndExpectError(runnable, error); + verify(span).setStatus(Status.UNKNOWN.withDescription("AssertionError")); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanCallable() throws Exception { + final Object ret = new Object(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Callable<Object> callable = + new Callable<Object>() { + @Override + public Object call() throws Exception { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + return ret; + } + }; + assertThat(CurrentSpanUtils.withSpan(span, false, callable).call()).isEqualTo(ret); + verifyZeroInteractions(span); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanCallable_EndSpan() throws Exception { + final Object ret = new Object(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Callable<Object> callable = + new Callable<Object>() { + @Override + public Object call() throws Exception { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + return ret; + } + }; + assertThat(CurrentSpanUtils.withSpan(span, true, callable).call()).isEqualTo(ret); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanCallable_WithException() { + final Exception exception = new Exception("MyException"); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Callable<Object> callable = + new Callable<Object>() { + @Override + public Object call() throws Exception { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + throw exception; + } + }; + executeCallableAndExpectError(callable, exception); + verify(span).setStatus(Status.UNKNOWN.withDescription("MyException")); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanCallable_WithExceptionNoMessage() { + final Exception exception = new Exception(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Callable<Object> callable = + new Callable<Object>() { + @Override + public Object call() throws Exception { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + throw exception; + } + }; + executeCallableAndExpectError(callable, exception); + verify(span).setStatus(Status.UNKNOWN.withDescription("Exception")); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanCallable_WithError() { + final AssertionError error = new AssertionError("MyError"); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Callable<Object> callable = + new Callable<Object>() { + @Override + public Object call() throws Exception { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + throw error; + } + }; + executeCallableAndExpectError(callable, error); + verify(span).setStatus(Status.UNKNOWN.withDescription("MyError")); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } + + @Test + public void withSpanCallable_WithErrorNoMessage() { + final AssertionError error = new AssertionError(); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + Callable<Object> callable = + new Callable<Object>() { + @Override + public Object call() throws Exception { + // When we run the runnable we will have the span in the current Context. + assertThat(CurrentSpanUtils.getCurrentSpan()).isSameAs(span); + throw error; + } + }; + executeCallableAndExpectError(callable, error); + verify(span).setStatus(Status.UNKNOWN.withDescription("AssertionError")); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(CurrentSpanUtils.getCurrentSpan()).isNull(); + } +} diff --git a/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java new file mode 100644 index 00000000..b6ab8e0e --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/EndSpanOptionsTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link EndSpanOptions}. */ +@RunWith(JUnit4.class) +public class EndSpanOptionsTest { + @Test + public void endSpanOptions_DefaultOptions() { + assertThat(EndSpanOptions.DEFAULT.getStatus()).isNull(); + assertThat(EndSpanOptions.DEFAULT.getSampleToLocalSpanStore()).isFalse(); + } + + @Test + public void setStatus_Ok() { + EndSpanOptions endSpanOptions = EndSpanOptions.builder().setStatus(Status.OK).build(); + assertThat(endSpanOptions.getStatus()).isEqualTo(Status.OK); + } + + @Test + public void setStatus_Error() { + EndSpanOptions endSpanOptions = + EndSpanOptions.builder() + .setStatus(Status.CANCELLED.withDescription("ThisIsAnError")) + .build(); + assertThat(endSpanOptions.getStatus()) + .isEqualTo(Status.CANCELLED.withDescription("ThisIsAnError")); + } + + @Test + public void setSampleToLocalSpanStore() { + EndSpanOptions endSpanOptions = + EndSpanOptions.builder().setSampleToLocalSpanStore(true).build(); + assertThat(endSpanOptions.getSampleToLocalSpanStore()).isTrue(); + } + + @Test + public void endSpanOptions_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup( + EndSpanOptions.builder() + .setStatus(Status.CANCELLED.withDescription("ThisIsAnError")) + .build(), + EndSpanOptions.builder() + .setStatus(Status.CANCELLED.withDescription("ThisIsAnError")) + .build()); + tester.addEqualityGroup(EndSpanOptions.builder().build(), EndSpanOptions.DEFAULT); + tester.testEquals(); + } + + @Test + public void endSpanOptions_ToString() { + EndSpanOptions endSpanOptions = + EndSpanOptions.builder() + .setStatus(Status.CANCELLED.withDescription("ThisIsAnError")) + .build(); + assertThat(endSpanOptions.toString()).contains("ThisIsAnError"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/LinkTest.java b/api/src/test/java/io/opencensus/trace/LinkTest.java new file mode 100644 index 00000000..5c1ebf5d --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/LinkTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.trace.Link.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Link}. */ +@RunWith(JUnit4.class) +public class LinkTest { + private final Map<String, AttributeValue> attributesMap = new HashMap<String, AttributeValue>(); + private final Random random = new Random(1234); + private final SpanContext spanContext = + SpanContext.create( + TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); + + @Before + public void setUp() { + attributesMap.put("MyAttributeKey0", AttributeValue.stringAttributeValue("MyStringAttribute")); + attributesMap.put("MyAttributeKey1", AttributeValue.longAttributeValue(10)); + attributesMap.put("MyAttributeKey2", AttributeValue.booleanAttributeValue(true)); + } + + @Test + public void fromSpanContext_ChildLink() { + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN); + assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(link.getType()).isEqualTo(Type.CHILD_LINKED_SPAN); + } + + @Test + public void fromSpanContext_ChildLink_WithAttributes() { + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN, attributesMap); + assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(link.getType()).isEqualTo(Type.CHILD_LINKED_SPAN); + assertThat(link.getAttributes()).isEqualTo(attributesMap); + } + + @Test + public void fromSpanContext_ParentLink() { + Link link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN); + assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(link.getType()).isEqualTo(Type.PARENT_LINKED_SPAN); + } + + @Test + public void fromSpanContext_ParentLink_WithAttributes() { + Link link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap); + assertThat(link.getTraceId()).isEqualTo(spanContext.getTraceId()); + assertThat(link.getSpanId()).isEqualTo(spanContext.getSpanId()); + assertThat(link.getType()).isEqualTo(Type.PARENT_LINKED_SPAN); + assertThat(link.getAttributes()).isEqualTo(attributesMap); + } + + @Test + public void link_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester + .addEqualityGroup( + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN), + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN)) + .addEqualityGroup( + Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN), + Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN)) + .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.CHILD_LINKED_SPAN)) + .addEqualityGroup(Link.fromSpanContext(SpanContext.INVALID, Type.PARENT_LINKED_SPAN)) + .addEqualityGroup( + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap), + Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap)); + tester.testEquals(); + } + + @Test + public void link_ToString() { + Link link = Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN, attributesMap); + assertThat(link.toString()).contains(spanContext.getTraceId().toString()); + assertThat(link.toString()).contains(spanContext.getSpanId().toString()); + assertThat(link.toString()).contains("CHILD_LINKED_SPAN"); + assertThat(link.toString()).contains(attributesMap.toString()); + link = Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN, attributesMap); + assertThat(link.toString()).contains(spanContext.getTraceId().toString()); + assertThat(link.toString()).contains(spanContext.getSpanId().toString()); + assertThat(link.toString()).contains("PARENT_LINKED_SPAN"); + assertThat(link.toString()).contains(attributesMap.toString()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/LowerCaseBase16EncodingTest.java b/api/src/test/java/io/opencensus/trace/LowerCaseBase16EncodingTest.java new file mode 100644 index 00000000..3444d2b3 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/LowerCaseBase16EncodingTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import java.nio.charset.Charset; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link io.opencensus.trace.LowerCaseBase16Encoding}. */ +@RunWith(JUnit4.class) +public class LowerCaseBase16EncodingTest { + private static final Charset CHARSET = Charset.forName("UTF-8"); + + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void valid_EncodeDecode() { + testEncoding("", ""); + testEncoding("f", "66"); + testEncoding("fo", "666f"); + testEncoding("foo", "666f6f"); + testEncoding("foob", "666f6f62"); + testEncoding("fooba", "666f6f6261"); + testEncoding("foobar", "666f6f626172"); + } + + @Test + public void invalidDecodings_UnrecongnizedCharacters() { + // These contain bytes not in the decoding. + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Invalid character g"); + LowerCaseBase16Encoding.decodeToBytes("efhg"); + } + + @Test + public void invalidDecodings_InvalidInputLength() { + // Valid base16 strings always have an even length. + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Invalid input length 3"); + LowerCaseBase16Encoding.decodeToBytes("abc"); + } + + @Test + public void invalidDecodings_InvalidInputLengthAndCharacter() { + // These have a combination of invalid length and unrecognized characters. + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Invalid input length 1"); + LowerCaseBase16Encoding.decodeToBytes("?"); + } + + private static void testEncoding(String decoded, String encoded) { + testEncodes(decoded, encoded); + testDecodes(encoded, decoded); + } + + private static void testEncodes(String decoded, String encoded) { + assertThat(LowerCaseBase16Encoding.encodeToString(decoded.getBytes(CHARSET))) + .isEqualTo(encoded); + } + + private static void testDecodes(String encoded, String decoded) { + assertThat(LowerCaseBase16Encoding.decodeToBytes(encoded)).isEqualTo(decoded.getBytes(CHARSET)); + } +} diff --git a/api/src/test/java/io/opencensus/trace/MessageEventTest.java b/api/src/test/java/io/opencensus/trace/MessageEventTest.java new file mode 100644 index 00000000..fde32fe6 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/MessageEventTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link MessageEvent}. */ +@RunWith(JUnit4.class) +public class MessageEventTest { + @Test(expected = NullPointerException.class) + public void buildMessageEvent_NullType() { + MessageEvent.builder(null, 1L).build(); + } + + @Test + public void buildMessageEvent_WithRequiredFields() { + MessageEvent messageEvent = MessageEvent.builder(MessageEvent.Type.SENT, 1L).build(); + assertThat(messageEvent.getType()).isEqualTo(MessageEvent.Type.SENT); + assertThat(messageEvent.getMessageId()).isEqualTo(1L); + assertThat(messageEvent.getUncompressedMessageSize()).isEqualTo(0L); + } + + @Test + public void buildMessageEvent_WithUncompressedMessageSize() { + MessageEvent messageEvent = + MessageEvent.builder(MessageEvent.Type.SENT, 1L).setUncompressedMessageSize(123L).build(); + assertThat(messageEvent.getType()).isEqualTo(MessageEvent.Type.SENT); + assertThat(messageEvent.getMessageId()).isEqualTo(1L); + assertThat(messageEvent.getUncompressedMessageSize()).isEqualTo(123L); + } + + @Test + public void buildMessageEvent_WithCompressedMessageSize() { + MessageEvent messageEvent = + MessageEvent.builder(MessageEvent.Type.SENT, 1L).setCompressedMessageSize(123L).build(); + assertThat(messageEvent.getType()).isEqualTo(MessageEvent.Type.SENT); + assertThat(messageEvent.getMessageId()).isEqualTo(1L); + assertThat(messageEvent.getCompressedMessageSize()).isEqualTo(123L); + } + + @Test + public void buildMessageEvent_WithAllValues() { + MessageEvent messageEvent = + MessageEvent.builder(MessageEvent.Type.RECEIVED, 1L) + .setUncompressedMessageSize(123L) + .setCompressedMessageSize(63L) + .build(); + assertThat(messageEvent.getType()).isEqualTo(MessageEvent.Type.RECEIVED); + assertThat(messageEvent.getMessageId()).isEqualTo(1L); + assertThat(messageEvent.getUncompressedMessageSize()).isEqualTo(123L); + assertThat(messageEvent.getCompressedMessageSize()).isEqualTo(63L); + } + + @Test + public void messageEvent_ToString() { + MessageEvent messageEvent = + MessageEvent.builder(MessageEvent.Type.SENT, 1L) + .setUncompressedMessageSize(123L) + .setCompressedMessageSize(63L) + .build(); + assertThat(messageEvent.toString()).contains("type=SENT"); + assertThat(messageEvent.toString()).contains("messageId=1"); + assertThat(messageEvent.toString()).contains("compressedMessageSize=63"); + assertThat(messageEvent.toString()).contains("uncompressedMessageSize=123"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/NetworkEventTest.java b/api/src/test/java/io/opencensus/trace/NetworkEventTest.java new file mode 100644 index 00000000..8c132377 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/NetworkEventTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.common.Timestamp; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link NetworkEvent}. */ +@RunWith(JUnit4.class) +public class NetworkEventTest { + @Test(expected = NullPointerException.class) + public void buildNetworkEvent_NullType() { + NetworkEvent.builder(null, 1L).build(); + } + + @Test + public void buildNetworkEvent_WithRequiredFields() { + NetworkEvent networkEvent = NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).build(); + assertThat(networkEvent.getType()).isEqualTo(NetworkEvent.Type.SENT); + assertThat(networkEvent.getMessageId()).isEqualTo(1L); + assertThat(networkEvent.getKernelTimestamp()).isNull(); + assertThat(networkEvent.getUncompressedMessageSize()).isEqualTo(0L); + } + + @Test + public void buildNetworkEvent_WithTimestamp() { + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1L) + .setKernelTimestamp(Timestamp.fromMillis(123456L)) + .build(); + assertThat(networkEvent.getKernelTimestamp()).isEqualTo(Timestamp.fromMillis(123456L)); + assertThat(networkEvent.getType()).isEqualTo(NetworkEvent.Type.SENT); + assertThat(networkEvent.getMessageId()).isEqualTo(1L); + assertThat(networkEvent.getUncompressedMessageSize()).isEqualTo(0L); + } + + @Test + public void buildNetworkEvent_WithUncompressedMessageSize() { + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).setUncompressedMessageSize(123L).build(); + assertThat(networkEvent.getKernelTimestamp()).isNull(); + assertThat(networkEvent.getType()).isEqualTo(NetworkEvent.Type.SENT); + assertThat(networkEvent.getMessageId()).isEqualTo(1L); + assertThat(networkEvent.getUncompressedMessageSize()).isEqualTo(123L); + assertThat(networkEvent.getMessageSize()).isEqualTo(123L); + } + + @Test + public void buildNetworkEvent_WithMessageSize() { + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).setMessageSize(123L).build(); + assertThat(networkEvent.getKernelTimestamp()).isNull(); + assertThat(networkEvent.getType()).isEqualTo(NetworkEvent.Type.SENT); + assertThat(networkEvent.getMessageId()).isEqualTo(1L); + assertThat(networkEvent.getMessageSize()).isEqualTo(123L); + assertThat(networkEvent.getUncompressedMessageSize()).isEqualTo(123L); + } + + @Test + public void buildNetworkEvent_WithCompressedMessageSize() { + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).setCompressedMessageSize(123L).build(); + assertThat(networkEvent.getKernelTimestamp()).isNull(); + assertThat(networkEvent.getType()).isEqualTo(NetworkEvent.Type.SENT); + assertThat(networkEvent.getMessageId()).isEqualTo(1L); + assertThat(networkEvent.getCompressedMessageSize()).isEqualTo(123L); + } + + @Test + public void buildNetworkEvent_WithAllValues() { + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.RECV, 1L) + .setKernelTimestamp(Timestamp.fromMillis(123456L)) + .setUncompressedMessageSize(123L) + .setCompressedMessageSize(63L) + .build(); + assertThat(networkEvent.getKernelTimestamp()).isEqualTo(Timestamp.fromMillis(123456L)); + assertThat(networkEvent.getType()).isEqualTo(NetworkEvent.Type.RECV); + assertThat(networkEvent.getMessageId()).isEqualTo(1L); + assertThat(networkEvent.getUncompressedMessageSize()).isEqualTo(123L); + // Test that getMessageSize returns same as getUncompressedMessageSize(); + assertThat(networkEvent.getMessageSize()).isEqualTo(123L); + assertThat(networkEvent.getCompressedMessageSize()).isEqualTo(63L); + } + + @Test + public void networkEvent_ToString() { + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1L) + .setKernelTimestamp(Timestamp.fromMillis(123456L)) + .setUncompressedMessageSize(123L) + .setCompressedMessageSize(63L) + .build(); + assertThat(networkEvent.toString()).contains(Timestamp.fromMillis(123456L).toString()); + assertThat(networkEvent.toString()).contains("type=SENT"); + assertThat(networkEvent.toString()).contains("messageId=1"); + assertThat(networkEvent.toString()).contains("compressedMessageSize=63"); + assertThat(networkEvent.toString()).contains("uncompressedMessageSize=123"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/NoopSpan.java b/api/src/test/java/io/opencensus/trace/NoopSpan.java new file mode 100644 index 00000000..a21a8aac --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/NoopSpan.java @@ -0,0 +1,69 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import io.opencensus.internal.Utils; +import java.util.EnumSet; +import java.util.Map; +import javax.annotation.Nullable; + +/** + * Class to be used in tests where an implementation for the Span is needed. + * + * <p>Not final to allow Mockito to "spy" this class. + */ +public class NoopSpan extends Span { + + /** Creates a new {@code NoopSpan}. */ + public NoopSpan(SpanContext context, @Nullable EnumSet<Options> options) { + super(Utils.checkNotNull(context, "context"), options); + } + + @Override + public void putAttributes(Map<String, AttributeValue> attributes) { + Utils.checkNotNull(attributes, "attributes"); + } + + @Override + public void addAnnotation(String description, Map<String, AttributeValue> attributes) { + Utils.checkNotNull(description, "description"); + Utils.checkNotNull(attributes, "attributes"); + } + + @Override + public void addAnnotation(Annotation annotation) { + Utils.checkNotNull(annotation, "annotation"); + } + + @Override + public void addNetworkEvent(NetworkEvent networkEvent) {} + + @Override + public void addMessageEvent(MessageEvent messageEvent) { + Utils.checkNotNull(messageEvent, "messageEvent"); + } + + @Override + public void addLink(Link link) { + Utils.checkNotNull(link, "link"); + } + + @Override + public void end(EndSpanOptions options) { + Utils.checkNotNull(options, "options"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java new file mode 100644 index 00000000..839c8945 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/SpanBuilderTest.java @@ -0,0 +1,104 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.opencensus.common.Scope; +import io.opencensus.trace.Span.Kind; +import io.opencensus.trace.samplers.Samplers; +import java.util.Collections; +import java.util.concurrent.Callable; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link SpanBuilder}. */ +@RunWith(JUnit4.class) +// Need to suppress warnings for MustBeClosed because Java-6 does not support try-with-resources. +@SuppressWarnings("MustBeClosedChecker") +public class SpanBuilderTest { + private final Tracer tracer = Tracing.getTracer(); + @Mock private SpanBuilder spanBuilder; + @Mock private Span span; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(spanBuilder.startSpan()).thenReturn(span); + } + + @Test + public void startScopedSpan() { + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + Scope scope = spanBuilder.startScopedSpan(); + try { + assertThat(tracer.getCurrentSpan()).isSameAs(span); + } finally { + scope.close(); + } + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void startSpanAndRun() { + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + spanBuilder.startSpanAndRun( + new Runnable() { + @Override + public void run() { + assertThat(tracer.getCurrentSpan()).isSameAs(span); + } + }); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void startSpanAndCall() throws Exception { + final Object ret = new Object(); + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + assertThat( + spanBuilder.startSpanAndCall( + new Callable<Object>() { + @Override + public Object call() throws Exception { + assertThat(tracer.getCurrentSpan()).isSameAs(span); + return ret; + } + })) + .isEqualTo(ret); + verify(span).end(EndSpanOptions.DEFAULT); + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void doNotCrash_NoopImplementation() throws Exception { + SpanBuilder spanBuilder = tracer.spanBuilder("MySpanName"); + spanBuilder.setParentLinks(Collections.<Span>emptyList()); + spanBuilder.setRecordEvents(true); + spanBuilder.setSampler(Samplers.alwaysSample()); + spanBuilder.setSpanKind(Kind.SERVER); + assertThat(spanBuilder.startSpan()).isSameAs(BlankSpan.INSTANCE); + } +} diff --git a/api/src/test/java/io/opencensus/trace/SpanContextTest.java b/api/src/test/java/io/opencensus/trace/SpanContextTest.java new file mode 100644 index 00000000..54e188c8 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/SpanContextTest.java @@ -0,0 +1,133 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link SpanContext}. */ +@RunWith(JUnit4.class) +public class SpanContextTest { + private static final byte[] firstTraceIdBytes = + new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'a'}; + private static final byte[] secondTraceIdBytes = + new byte[] {0, 0, 0, 0, 0, 0, 0, '0', 0, 0, 0, 0, 0, 0, 0, 0}; + private static final byte[] firstSpanIdBytes = new byte[] {0, 0, 0, 0, 0, 0, 0, 'a'}; + private static final byte[] secondSpanIdBytes = new byte[] {'0', 0, 0, 0, 0, 0, 0, 0}; + private static final Tracestate firstTracestate = Tracestate.builder().set("foo", "bar").build(); + private static final Tracestate secondTracestate = Tracestate.builder().set("foo", "baz").build(); + private static final SpanContext first = + SpanContext.create( + TraceId.fromBytes(firstTraceIdBytes), + SpanId.fromBytes(firstSpanIdBytes), + TraceOptions.DEFAULT, + firstTracestate); + private static final SpanContext second = + SpanContext.create( + TraceId.fromBytes(secondTraceIdBytes), + SpanId.fromBytes(secondSpanIdBytes), + TraceOptions.builder().setIsSampled(true).build(), + secondTracestate); + + @Test + public void invalidSpanContext() { + assertThat(SpanContext.INVALID.getTraceId()).isEqualTo(TraceId.INVALID); + assertThat(SpanContext.INVALID.getSpanId()).isEqualTo(SpanId.INVALID); + assertThat(SpanContext.INVALID.getTraceOptions()).isEqualTo(TraceOptions.DEFAULT); + } + + @Test + public void isValid() { + assertThat(SpanContext.INVALID.isValid()).isFalse(); + assertThat( + SpanContext.create( + TraceId.fromBytes(firstTraceIdBytes), SpanId.INVALID, TraceOptions.DEFAULT) + .isValid()) + .isFalse(); + assertThat( + SpanContext.create( + TraceId.INVALID, SpanId.fromBytes(firstSpanIdBytes), TraceOptions.DEFAULT) + .isValid()) + .isFalse(); + assertThat(first.isValid()).isTrue(); + assertThat(second.isValid()).isTrue(); + } + + @Test + public void getTraceId() { + assertThat(first.getTraceId()).isEqualTo(TraceId.fromBytes(firstTraceIdBytes)); + assertThat(second.getTraceId()).isEqualTo(TraceId.fromBytes(secondTraceIdBytes)); + } + + @Test + public void getSpanId() { + assertThat(first.getSpanId()).isEqualTo(SpanId.fromBytes(firstSpanIdBytes)); + assertThat(second.getSpanId()).isEqualTo(SpanId.fromBytes(secondSpanIdBytes)); + } + + @Test + public void getTraceOptions() { + assertThat(first.getTraceOptions()).isEqualTo(TraceOptions.DEFAULT); + assertThat(second.getTraceOptions()) + .isEqualTo(TraceOptions.builder().setIsSampled(true).build()); + } + + @Test + public void getTracestate() { + assertThat(first.getTracestate()).isEqualTo(firstTracestate); + assertThat(second.getTracestate()).isEqualTo(secondTracestate); + } + + @Test + public void spanContext_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup( + first, + SpanContext.create( + TraceId.fromBytes(firstTraceIdBytes), + SpanId.fromBytes(firstSpanIdBytes), + TraceOptions.DEFAULT), + SpanContext.create( + TraceId.fromBytes(firstTraceIdBytes), + SpanId.fromBytes(firstSpanIdBytes), + TraceOptions.builder().setIsSampled(false).build(), + firstTracestate)); + tester.addEqualityGroup( + second, + SpanContext.create( + TraceId.fromBytes(secondTraceIdBytes), + SpanId.fromBytes(secondSpanIdBytes), + TraceOptions.builder().setIsSampled(true).build(), + secondTracestate)); + tester.testEquals(); + } + + @Test + public void spanContext_ToString() { + assertThat(first.toString()).contains(TraceId.fromBytes(firstTraceIdBytes).toString()); + assertThat(first.toString()).contains(SpanId.fromBytes(firstSpanIdBytes).toString()); + assertThat(first.toString()).contains(TraceOptions.DEFAULT.toString()); + assertThat(second.toString()).contains(TraceId.fromBytes(secondTraceIdBytes).toString()); + assertThat(second.toString()).contains(SpanId.fromBytes(secondSpanIdBytes).toString()); + assertThat(second.toString()) + .contains(TraceOptions.builder().setIsSampled(true).build().toString()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/SpanIdTest.java b/api/src/test/java/io/opencensus/trace/SpanIdTest.java new file mode 100644 index 00000000..4a5bc2ae --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/SpanIdTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link SpanId}. */ +@RunWith(JUnit4.class) +public class SpanIdTest { + private static final byte[] firstBytes = new byte[] {0, 0, 0, 0, 0, 0, 0, 'a'}; + private static final byte[] secondBytes = new byte[] {(byte) 0xFF, 0, 0, 0, 0, 0, 0, 'A'}; + private static final SpanId first = SpanId.fromBytes(firstBytes); + private static final SpanId second = SpanId.fromBytes(secondBytes); + + @Test + public void invalidSpanId() { + assertThat(SpanId.INVALID.getBytes()).isEqualTo(new byte[8]); + } + + @Test + public void isValid() { + assertThat(SpanId.INVALID.isValid()).isFalse(); + assertThat(first.isValid()).isTrue(); + assertThat(second.isValid()).isTrue(); + } + + @Test + public void fromLowerBase16() { + assertThat(SpanId.fromLowerBase16("0000000000000000")).isEqualTo(SpanId.INVALID); + assertThat(SpanId.fromLowerBase16("0000000000000061")).isEqualTo(first); + assertThat(SpanId.fromLowerBase16("ff00000000000041")).isEqualTo(second); + } + + @Test + public void toLowerBase16() { + assertThat(SpanId.INVALID.toLowerBase16()).isEqualTo("0000000000000000"); + assertThat(first.toLowerBase16()).isEqualTo("0000000000000061"); + assertThat(second.toLowerBase16()).isEqualTo("ff00000000000041"); + } + + @Test + public void getBytes() { + assertThat(first.getBytes()).isEqualTo(firstBytes); + assertThat(second.getBytes()).isEqualTo(secondBytes); + } + + @Test + public void traceId_CompareTo() { + assertThat(first.compareTo(second)).isGreaterThan(0); + assertThat(second.compareTo(first)).isLessThan(0); + assertThat(first.compareTo(SpanId.fromBytes(firstBytes))).isEqualTo(0); + } + + @Test + public void traceId_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup(SpanId.INVALID, SpanId.INVALID); + tester.addEqualityGroup(first, SpanId.fromBytes(Arrays.copyOf(firstBytes, firstBytes.length))); + tester.addEqualityGroup( + second, SpanId.fromBytes(Arrays.copyOf(secondBytes, secondBytes.length))); + tester.testEquals(); + } + + @Test + public void traceId_ToString() { + assertThat(SpanId.INVALID.toString()).contains("0000000000000000"); + assertThat(first.toString()).contains("0000000000000061"); + assertThat(second.toString()).contains("ff00000000000041"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/SpanTest.java b/api/src/test/java/io/opencensus/trace/SpanTest.java new file mode 100644 index 00000000..f7546ca4 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/SpanTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.verify; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.Random; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mockito; + +/** Unit tests for {@link Span}. */ +@RunWith(JUnit4.class) +public class SpanTest { + private Random random; + private SpanContext spanContext; + private SpanContext notSampledSpanContext; + private EnumSet<Span.Options> spanOptions; + + @Before + public void setUp() { + random = new Random(1234); + spanContext = + SpanContext.create( + TraceId.generateRandomId(random), + SpanId.generateRandomId(random), + TraceOptions.builder().setIsSampled(true).build()); + notSampledSpanContext = + SpanContext.create( + TraceId.generateRandomId(random), + SpanId.generateRandomId(random), + TraceOptions.DEFAULT); + spanOptions = EnumSet.of(Span.Options.RECORD_EVENTS); + } + + @Test(expected = NullPointerException.class) + public void newSpan_WithNullContext() { + new NoopSpan(null, null); + } + + @Test(expected = IllegalArgumentException.class) + public void newSpan_SampledContextAndNullOptions() { + new NoopSpan(spanContext, null); + } + + @Test(expected = IllegalArgumentException.class) + public void newSpan_SampledContextAndEmptyOptions() { + new NoopSpan(spanContext, EnumSet.noneOf(Span.Options.class)); + } + + @Test + public void getOptions_WhenNullOptions() { + Span span = new NoopSpan(notSampledSpanContext, null); + assertThat(span.getOptions()).isEmpty(); + } + + @Test + public void getContextAndOptions() { + Span span = new NoopSpan(spanContext, spanOptions); + assertThat(span.getContext()).isEqualTo(spanContext); + assertThat(span.getOptions()).isEqualTo(spanOptions); + } + + @Test + public void putAttributeCallsAddAttributesByDefault() { + Span span = Mockito.spy(new NoopSpan(spanContext, spanOptions)); + span.putAttribute("MyKey", AttributeValue.booleanAttributeValue(true)); + span.end(); + verify(span) + .putAttributes( + eq(Collections.singletonMap("MyKey", AttributeValue.booleanAttributeValue(true)))); + } + + @Test + public void endCallsEndWithDefaultOptions() { + Span span = Mockito.spy(new NoopSpan(spanContext, spanOptions)); + span.end(); + verify(span).end(same(EndSpanOptions.DEFAULT)); + } + + @Test + public void addMessageEventDefaultImplementation() { + Span mockSpan = Mockito.mock(Span.class); + MessageEvent messageEvent = + MessageEvent.builder(MessageEvent.Type.SENT, 123) + .setUncompressedMessageSize(456) + .setCompressedMessageSize(789) + .build(); + NetworkEvent networkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 123) + .setUncompressedMessageSize(456) + .setCompressedMessageSize(789) + .build(); + Mockito.doCallRealMethod().when(mockSpan).addMessageEvent(messageEvent); + mockSpan.addMessageEvent(messageEvent); + verify(mockSpan).addNetworkEvent(eq(networkEvent)); + } +} diff --git a/api/src/test/java/io/opencensus/trace/StatusTest.java b/api/src/test/java/io/opencensus/trace/StatusTest.java new file mode 100644 index 00000000..108db2d2 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/StatusTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Status}. */ +@RunWith(JUnit4.class) +public class StatusTest { + @Test + public void status_Ok() { + assertThat(Status.OK.getCanonicalCode()).isEqualTo(Status.CanonicalCode.OK); + assertThat(Status.OK.getDescription()).isNull(); + assertThat(Status.OK.isOk()).isTrue(); + } + + @Test + public void createStatus_WithDescription() { + Status status = Status.UNKNOWN.withDescription("This is an error."); + assertThat(status.getCanonicalCode()).isEqualTo(Status.CanonicalCode.UNKNOWN); + assertThat(status.getDescription()).isEqualTo("This is an error."); + assertThat(status.isOk()).isFalse(); + } + + @Test + public void status_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup(Status.OK, Status.OK.withDescription(null)); + tester.addEqualityGroup( + Status.CANCELLED.withDescription("ThisIsAnError"), + Status.CANCELLED.withDescription("ThisIsAnError")); + tester.addEqualityGroup(Status.UNKNOWN.withDescription("This is an error.")); + tester.testEquals(); + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceComponentTest.java b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java new file mode 100644 index 00000000..1c3f07d5 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/TraceComponentTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.internal.ZeroTimeClock; +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceComponent}. */ +@RunWith(JUnit4.class) +public class TraceComponentTest { + @Test + public void defaultTracer() { + assertThat(TraceComponent.newNoopTraceComponent().getTracer()).isSameAs(Tracer.getNoopTracer()); + } + + @Test + public void defaultBinaryPropagationHandler() { + assertThat(TraceComponent.newNoopTraceComponent().getPropagationComponent()) + .isSameAs(PropagationComponent.getNoopPropagationComponent()); + } + + @Test + public void defaultClock() { + assertThat(TraceComponent.newNoopTraceComponent().getClock()).isInstanceOf(ZeroTimeClock.class); + } + + @Test + public void defaultTraceExporter() { + assertThat(TraceComponent.newNoopTraceComponent().getExportComponent()) + .isInstanceOf(ExportComponent.newNoopExportComponent().getClass()); + } + + @Test + public void defaultTraceConfig() { + assertThat(TraceComponent.newNoopTraceComponent().getTraceConfig()) + .isSameAs(TraceConfig.getNoopTraceConfig()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceIdTest.java b/api/src/test/java/io/opencensus/trace/TraceIdTest.java new file mode 100644 index 00000000..c8b5dc8f --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/TraceIdTest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import java.util.Arrays; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceId}. */ +@RunWith(JUnit4.class) +public class TraceIdTest { + private static final byte[] firstBytes = + new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'a'}; + private static final byte[] secondBytes = + new byte[] {(byte) 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'A'}; + private static final TraceId first = TraceId.fromBytes(firstBytes); + private static final TraceId second = TraceId.fromBytes(secondBytes); + + @Test + public void invalidTraceId() { + assertThat(TraceId.INVALID.getBytes()).isEqualTo(new byte[16]); + } + + @Test + public void isValid() { + assertThat(TraceId.INVALID.isValid()).isFalse(); + assertThat(first.isValid()).isTrue(); + assertThat(second.isValid()).isTrue(); + } + + @Test + public void getBytes() { + assertThat(first.getBytes()).isEqualTo(firstBytes); + assertThat(second.getBytes()).isEqualTo(secondBytes); + } + + @Test + public void fromLowerBase16() { + assertThat(TraceId.fromLowerBase16("00000000000000000000000000000000")) + .isEqualTo(TraceId.INVALID); + assertThat(TraceId.fromLowerBase16("00000000000000000000000000000061")).isEqualTo(first); + assertThat(TraceId.fromLowerBase16("ff000000000000000000000000000041")).isEqualTo(second); + } + + @Test + public void toLowerBase16() { + assertThat(TraceId.INVALID.toLowerBase16()).isEqualTo("00000000000000000000000000000000"); + assertThat(first.toLowerBase16()).isEqualTo("00000000000000000000000000000061"); + assertThat(second.toLowerBase16()).isEqualTo("ff000000000000000000000000000041"); + } + + @Test + public void traceId_CompareTo() { + assertThat(first.compareTo(second)).isGreaterThan(0); + assertThat(second.compareTo(first)).isLessThan(0); + assertThat(first.compareTo(TraceId.fromBytes(firstBytes))).isEqualTo(0); + } + + @Test + public void traceId_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup(TraceId.INVALID, TraceId.INVALID); + tester.addEqualityGroup(first, TraceId.fromBytes(Arrays.copyOf(firstBytes, firstBytes.length))); + tester.addEqualityGroup( + second, TraceId.fromBytes(Arrays.copyOf(secondBytes, secondBytes.length))); + tester.testEquals(); + } + + @Test + public void traceId_ToString() { + assertThat(TraceId.INVALID.toString()).contains("00000000000000000000000000000000"); + assertThat(first.toString()).contains("00000000000000000000000000000061"); + assertThat(second.toString()).contains("ff000000000000000000000000000041"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java b/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java new file mode 100644 index 00000000..3c46d097 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/TraceOptionsTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceOptions}. */ +@RunWith(JUnit4.class) +public class TraceOptionsTest { + private static final byte FIRST_BYTE = (byte) 0xff; + private static final byte SECOND_BYTE = 1; + private static final byte THIRD_BYTE = 6; + + @Test + public void getOptions() { + assertThat(TraceOptions.DEFAULT.getOptions()).isEqualTo(0); + assertThat(TraceOptions.builder().setIsSampled(false).build().getOptions()).isEqualTo(0); + assertThat(TraceOptions.builder().setIsSampled(true).build().getOptions()).isEqualTo(1); + assertThat(TraceOptions.builder().setIsSampled(true).setIsSampled(false).build().getOptions()) + .isEqualTo(0); + assertThat(TraceOptions.fromByte(FIRST_BYTE).getOptions()).isEqualTo(-1); + assertThat(TraceOptions.fromByte(SECOND_BYTE).getOptions()).isEqualTo(1); + assertThat(TraceOptions.fromByte(THIRD_BYTE).getOptions()).isEqualTo(6); + } + + @Test + public void isSampled() { + assertThat(TraceOptions.DEFAULT.isSampled()).isFalse(); + assertThat(TraceOptions.builder().setIsSampled(true).build().isSampled()).isTrue(); + } + + @Test + public void toFromByte() { + assertThat(TraceOptions.fromByte(FIRST_BYTE).getByte()).isEqualTo(FIRST_BYTE); + assertThat(TraceOptions.fromByte(SECOND_BYTE).getByte()).isEqualTo(SECOND_BYTE); + assertThat(TraceOptions.fromByte(THIRD_BYTE).getByte()).isEqualTo(THIRD_BYTE); + } + + @Test + @SuppressWarnings("deprecation") + public void deprecated_fromBytes() { + assertThat(TraceOptions.fromBytes(new byte[] {FIRST_BYTE}).getByte()).isEqualTo(FIRST_BYTE); + assertThat(TraceOptions.fromBytes(new byte[] {1, FIRST_BYTE}, 1).getByte()) + .isEqualTo(FIRST_BYTE); + } + + @Test + @SuppressWarnings("deprecation") + public void deprecated_getBytes() { + assertThat(TraceOptions.fromByte(FIRST_BYTE).getBytes()).isEqualTo(new byte[] {FIRST_BYTE}); + } + + @Test + public void builder_FromOptions() { + assertThat( + TraceOptions.builder(TraceOptions.fromByte(THIRD_BYTE)) + .setIsSampled(true) + .build() + .getOptions()) + .isEqualTo(6 | 1); + } + + @Test + public void traceOptions_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup(TraceOptions.DEFAULT); + tester.addEqualityGroup( + TraceOptions.fromByte(SECOND_BYTE), TraceOptions.builder().setIsSampled(true).build()); + tester.addEqualityGroup(TraceOptions.fromByte(FIRST_BYTE)); + tester.testEquals(); + } + + @Test + public void traceOptions_ToString() { + assertThat(TraceOptions.DEFAULT.toString()).contains("sampled=false"); + assertThat(TraceOptions.builder().setIsSampled(true).build().toString()) + .contains("sampled=true"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/TracerTest.java b/api/src/test/java/io/opencensus/trace/TracerTest.java new file mode 100644 index 00000000..58dd4bbe --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/TracerTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import io.opencensus.common.Scope; +import java.util.concurrent.Callable; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link Tracer}. */ +@RunWith(JUnit4.class) +// Need to suppress warnings for MustBeClosed because Java-6 does not support try-with-resources. +@SuppressWarnings("MustBeClosedChecker") +public class TracerTest { + private static final Tracer noopTracer = Tracer.getNoopTracer(); + private static final String SPAN_NAME = "MySpanName"; + @Mock private Tracer tracer; + @Mock private SpanBuilder spanBuilder; + @Mock private Span span; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void defaultGetCurrentSpan() { + assertThat(noopTracer.getCurrentSpan()).isEqualTo(BlankSpan.INSTANCE); + } + + @Test(expected = NullPointerException.class) + public void withSpan_NullSpan() { + noopTracer.withSpan(null); + } + + @Test + public void getCurrentSpan_WithSpan() { + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + Scope ws = noopTracer.withSpan(span); + try { + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); + } finally { + ws.close(); + } + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void wrapRunnable() { + Runnable runnable; + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + runnable = + tracer.withSpan( + span, + new Runnable() { + @Override + public void run() { + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); + } + }); + // When we run the runnable we will have the span in the current Context. + runnable.run(); + verifyZeroInteractions(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void wrapCallable() throws Exception { + final Object ret = new Object(); + Callable<Object> callable; + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + callable = + tracer.withSpan( + span, + new Callable<Object>() { + @Override + public Object call() throws Exception { + assertThat(noopTracer.getCurrentSpan()).isSameAs(span); + return ret; + } + }); + // When we call the callable we will have the span in the current Context. + assertThat(callable.call()).isEqualTo(ret); + verifyZeroInteractions(span); + assertThat(noopTracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test(expected = NullPointerException.class) + public void spanBuilderWithName_NullName() { + noopTracer.spanBuilder(null); + } + + @Test + public void defaultSpanBuilderWithName() { + assertThat(noopTracer.spanBuilder(SPAN_NAME).startSpan()).isSameAs(BlankSpan.INSTANCE); + } + + @Test(expected = NullPointerException.class) + public void spanBuilderWithParentAndName_NullName() { + noopTracer.spanBuilderWithExplicitParent(null, null); + } + + @Test + public void defaultSpanBuilderWithParentAndName() { + assertThat(noopTracer.spanBuilderWithExplicitParent(SPAN_NAME, null).startSpan()) + .isSameAs(BlankSpan.INSTANCE); + } + + @Test(expected = NullPointerException.class) + public void spanBuilderWithRemoteParent_NullName() { + noopTracer.spanBuilderWithRemoteParent(null, null); + } + + @Test + public void defaultSpanBuilderWithRemoteParent_NullParent() { + assertThat(noopTracer.spanBuilderWithRemoteParent(SPAN_NAME, null).startSpan()) + .isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void defaultSpanBuilderWithRemoteParent() { + assertThat(noopTracer.spanBuilderWithRemoteParent(SPAN_NAME, SpanContext.INVALID).startSpan()) + .isSameAs(BlankSpan.INSTANCE); + } + + @Test + public void startSpanWithParentFromContext() { + Scope ws = tracer.withSpan(span); + try { + assertThat(tracer.getCurrentSpan()).isSameAs(span); + when(tracer.spanBuilderWithExplicitParent(same(SPAN_NAME), same(span))) + .thenReturn(spanBuilder); + assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); + } finally { + ws.close(); + } + } + + @Test + public void startSpanWithInvalidParentFromContext() { + Scope ws = tracer.withSpan(BlankSpan.INSTANCE); + try { + assertThat(tracer.getCurrentSpan()).isSameAs(BlankSpan.INSTANCE); + when(tracer.spanBuilderWithExplicitParent(same(SPAN_NAME), same(BlankSpan.INSTANCE))) + .thenReturn(spanBuilder); + assertThat(tracer.spanBuilder(SPAN_NAME)).isSameAs(spanBuilder); + } finally { + ws.close(); + } + } +} diff --git a/api/src/test/java/io/opencensus/trace/TracestateTest.java b/api/src/test/java/io/opencensus/trace/TracestateTest.java new file mode 100644 index 00000000..3374eb75 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/TracestateTest.java @@ -0,0 +1,235 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.trace.Tracestate.Entry; +import java.util.Arrays; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Tracestate}. */ +@RunWith(JUnit4.class) +public class TracestateTest { + private static final String FIRST_KEY = "key_1"; + private static final String SECOND_KEY = "key_2"; + private static final String FIRST_VALUE = "value.1"; + private static final String SECOND_VALUE = "value.2"; + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + private static final Tracestate EMPTY = Tracestate.builder().build(); + private final Tracestate firstTracestate = EMPTY.toBuilder().set(FIRST_KEY, FIRST_VALUE).build(); + private final Tracestate secondTracestate = + EMPTY.toBuilder().set(SECOND_KEY, SECOND_VALUE).build(); + private final Tracestate multiValueTracestate = + EMPTY.toBuilder().set(FIRST_KEY, FIRST_VALUE).set(SECOND_KEY, SECOND_VALUE).build(); + + @Test + public void get() { + assertThat(firstTracestate.get(FIRST_KEY)).isEqualTo(FIRST_VALUE); + assertThat(secondTracestate.get(SECOND_KEY)).isEqualTo(SECOND_VALUE); + assertThat(multiValueTracestate.get(FIRST_KEY)).isEqualTo(FIRST_VALUE); + assertThat(multiValueTracestate.get(SECOND_KEY)).isEqualTo(SECOND_VALUE); + } + + @Test + public void getEntries() { + assertThat(firstTracestate.getEntries()).containsExactly(Entry.create(FIRST_KEY, FIRST_VALUE)); + assertThat(secondTracestate.getEntries()) + .containsExactly(Entry.create(SECOND_KEY, SECOND_VALUE)); + assertThat(multiValueTracestate.getEntries()) + .containsExactly( + Entry.create(FIRST_KEY, FIRST_VALUE), Entry.create(SECOND_KEY, SECOND_VALUE)); + } + + @Test + public void disallowsNullKey() { + thrown.expect(NullPointerException.class); + EMPTY.toBuilder().set(null, FIRST_VALUE).build(); + } + + @Test + public void invalidFirstKeyCharacter() { + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set("1_key", FIRST_VALUE).build(); + } + + @Test + public void invalidKeyCharacters() { + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set("kEy_1", FIRST_VALUE).build(); + } + + @Test + public void invalidKeySize() { + char[] chars = new char[257]; + Arrays.fill(chars, 'a'); + String longKey = new String(chars); + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set(longKey, FIRST_VALUE).build(); + } + + @Test + public void allAllowedKeyCharacters() { + StringBuilder stringBuilder = new StringBuilder(); + for (char c = 'a'; c <= 'z'; c++) { + stringBuilder.append(c); + } + for (char c = '0'; c <= '9'; c++) { + stringBuilder.append(c); + } + stringBuilder.append('_'); + stringBuilder.append('-'); + stringBuilder.append('*'); + stringBuilder.append('/'); + String allowedKey = stringBuilder.toString(); + assertThat(EMPTY.toBuilder().set(allowedKey, FIRST_VALUE).build().get(allowedKey)) + .isEqualTo(FIRST_VALUE); + } + + @Test + public void disallowsNullValue() { + thrown.expect(NullPointerException.class); + EMPTY.toBuilder().set(FIRST_KEY, null).build(); + } + + @Test + public void valueCannotContainEqual() { + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set(FIRST_KEY, "my_vakue=5").build(); + } + + @Test + public void valueCannotContainComma() { + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set(FIRST_KEY, "first,second").build(); + } + + @Test + public void valueCannotContainTrailingSpaces() { + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set(FIRST_KEY, "first ").build(); + } + + @Test + public void invalidValueSize() { + char[] chars = new char[257]; + Arrays.fill(chars, 'a'); + String longValue = new String(chars); + thrown.expect(IllegalArgumentException.class); + EMPTY.toBuilder().set(FIRST_KEY, longValue).build(); + } + + @Test + public void allAllowedValueCharacters() { + StringBuilder stringBuilder = new StringBuilder(); + for (char c = ' ' /* '\u0020' */; c <= '~' /* '\u007E' */; c++) { + if (c == ',' || c == '=') { + continue; + } + stringBuilder.append(c); + } + String allowedValue = stringBuilder.toString(); + assertThat(EMPTY.toBuilder().set(FIRST_KEY, allowedValue).build().get(FIRST_KEY)) + .isEqualTo(allowedValue); + } + + @Test + public void addEntry() { + assertThat(firstTracestate.toBuilder().set(SECOND_KEY, SECOND_VALUE).build()) + .isEqualTo(multiValueTracestate); + } + + @Test + public void updateEntry() { + assertThat(firstTracestate.toBuilder().set(FIRST_KEY, SECOND_VALUE).build().get(FIRST_KEY)) + .isEqualTo(SECOND_VALUE); + Tracestate updatedMultiValueTracestate = + multiValueTracestate.toBuilder().set(FIRST_KEY, SECOND_VALUE).build(); + assertThat(updatedMultiValueTracestate.get(FIRST_KEY)).isEqualTo(SECOND_VALUE); + assertThat(updatedMultiValueTracestate.get(SECOND_KEY)).isEqualTo(SECOND_VALUE); + } + + @Test + public void addAndUpdateEntry() { + assertThat( + firstTracestate + .toBuilder() + .set(FIRST_KEY, SECOND_VALUE) // update the existing entry + .set(SECOND_KEY, FIRST_VALUE) // add a new entry + .build() + .getEntries()) + .containsExactly( + Entry.create(FIRST_KEY, SECOND_VALUE), Entry.create(SECOND_KEY, FIRST_VALUE)); + } + + @Test + public void addSameKey() { + assertThat( + EMPTY + .toBuilder() + .set(FIRST_KEY, SECOND_VALUE) // update the existing entry + .set(FIRST_KEY, FIRST_VALUE) // add a new entry + .build() + .getEntries()) + .containsExactly(Entry.create(FIRST_KEY, FIRST_VALUE)); + } + + @Test + public void remove() { + assertThat(multiValueTracestate.toBuilder().remove(SECOND_KEY).build()) + .isEqualTo(firstTracestate); + } + + @Test + public void addAndRemoveEntry() { + assertThat( + EMPTY + .toBuilder() + .set(FIRST_KEY, SECOND_VALUE) // update the existing entry + .remove(FIRST_KEY) // add a new entry + .build()) + .isEqualTo(EMPTY); + } + + @Test + public void remove_NullNotAllowed() { + thrown.expect(NullPointerException.class); + multiValueTracestate.toBuilder().remove(null).build(); + } + + @Test + public void tracestate_EqualsAndHashCode() { + EqualsTester tester = new EqualsTester(); + tester.addEqualityGroup(EMPTY, EMPTY); + tester.addEqualityGroup(firstTracestate, EMPTY.toBuilder().set(FIRST_KEY, FIRST_VALUE).build()); + tester.addEqualityGroup( + secondTracestate, EMPTY.toBuilder().set(SECOND_KEY, SECOND_VALUE).build()); + tester.testEquals(); + } + + @Test + public void tracestate_ToString() { + assertThat(EMPTY.toString()).isEqualTo("Tracestate{entries=[]}"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/TracingTest.java b/api/src/test/java/io/opencensus/trace/TracingTest.java new file mode 100644 index 00000000..e7c93a95 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/TracingTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016-17, OpenCensus 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 io.opencensus.trace; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.config.TraceConfig; +import io.opencensus.trace.export.ExportComponent; +import io.opencensus.trace.propagation.PropagationComponent; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Tracing}. */ +@RunWith(JUnit4.class) +public class TracingTest { + @Rule public ExpectedException thrown = ExpectedException.none(); + + @Test + public void loadTraceComponent_UsesProvidedClassLoader() { + final RuntimeException toThrow = new RuntimeException("UseClassLoader"); + thrown.expect(RuntimeException.class); + thrown.expectMessage("UseClassLoader"); + Tracing.loadTraceComponent( + new ClassLoader() { + @Override + public Class<?> loadClass(String name) { + throw toThrow; + } + }); + } + + @Test + public void loadTraceComponent_IgnoresMissingClasses() { + ClassLoader classLoader = + new ClassLoader() { + @Override + public Class<?> loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + }; + assertThat(Tracing.loadTraceComponent(classLoader).getClass().getName()) + .isEqualTo("io.opencensus.trace.TraceComponent$NoopTraceComponent"); + } + + @Test + public void defaultTracer() { + assertThat(Tracing.getTracer()).isSameAs(Tracer.getNoopTracer()); + } + + @Test + public void defaultBinaryPropagationHandler() { + assertThat(Tracing.getPropagationComponent()) + .isSameAs(PropagationComponent.getNoopPropagationComponent()); + } + + @Test + public void defaultTraceExporter() { + assertThat(Tracing.getExportComponent()) + .isInstanceOf(ExportComponent.newNoopExportComponent().getClass()); + } + + @Test + public void defaultTraceConfig() { + assertThat(Tracing.getTraceConfig()).isSameAs(TraceConfig.getNoopTraceConfig()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java b/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java new file mode 100644 index 00000000..d48e0894 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/config/TraceConfigTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.config; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.samplers.Samplers; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceConfig}. */ +@RunWith(JUnit4.class) +public class TraceConfigTest { + TraceConfig traceConfig = TraceConfig.getNoopTraceConfig(); + + @Test + public void activeTraceParams_NoOpImplementation() { + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); + } + + @Test + public void updateActiveTraceParams_NoOpImplementation() { + TraceParams traceParams = + TraceParams.DEFAULT + .toBuilder() + .setSampler(Samplers.alwaysSample()) + .setMaxNumberOfAttributes(8) + .setMaxNumberOfAnnotations(9) + .setMaxNumberOfNetworkEvents(10) + .setMaxNumberOfMessageEvents(10) + .setMaxNumberOfLinks(11) + .build(); + traceConfig.updateActiveTraceParams(traceParams); + assertThat(traceConfig.getActiveTraceParams()).isEqualTo(TraceParams.DEFAULT); + } +} diff --git a/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java b/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java new file mode 100644 index 00000000..bdf07d53 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/config/TraceParamsTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.config; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.samplers.Samplers; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TraceParams}. */ +@RunWith(JUnit4.class) +public class TraceParamsTest { + @Test + public void defaultTraceParams() { + assertThat(TraceParams.DEFAULT.getSampler()).isEqualTo(Samplers.probabilitySampler(1e-4)); + assertThat(TraceParams.DEFAULT.getMaxNumberOfAttributes()).isEqualTo(32); + assertThat(TraceParams.DEFAULT.getMaxNumberOfAnnotations()).isEqualTo(32); + assertThat(TraceParams.DEFAULT.getMaxNumberOfNetworkEvents()).isEqualTo(128); + assertThat(TraceParams.DEFAULT.getMaxNumberOfMessageEvents()).isEqualTo(128); + assertThat(TraceParams.DEFAULT.getMaxNumberOfLinks()).isEqualTo(32); + } + + @Test(expected = NullPointerException.class) + public void updateTraceParams_NullSampler() { + TraceParams.DEFAULT.toBuilder().setSampler(null).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void updateTraceParams_NonPositiveMaxNumberOfAttributes() { + TraceParams.DEFAULT.toBuilder().setMaxNumberOfAttributes(0).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void updateTraceParams_NonPositiveMaxNumberOfAnnotations() { + TraceParams.DEFAULT.toBuilder().setMaxNumberOfAnnotations(0).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void updateTraceParams_NonPositiveMaxNumberOfNetworkEvents() { + TraceParams.DEFAULT.toBuilder().setMaxNumberOfNetworkEvents(0).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void updateTraceParams_NonPositiveMaxNumberOfMessageEvents() { + TraceParams.DEFAULT.toBuilder().setMaxNumberOfMessageEvents(0).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void updateTraceParams_NonPositiveMaxNumberOfLinks() { + TraceParams.DEFAULT.toBuilder().setMaxNumberOfLinks(0).build(); + } + + @Test + public void updateTraceParams_All() { + TraceParams traceParams = + TraceParams.DEFAULT + .toBuilder() + .setSampler(Samplers.alwaysSample()) + .setMaxNumberOfAttributes(8) + .setMaxNumberOfAnnotations(9) + .setMaxNumberOfMessageEvents(10) + .setMaxNumberOfLinks(11) + .build(); + assertThat(traceParams.getSampler()).isEqualTo(Samplers.alwaysSample()); + assertThat(traceParams.getMaxNumberOfAttributes()).isEqualTo(8); + assertThat(traceParams.getMaxNumberOfAnnotations()).isEqualTo(9); + // test maxNumberOfNetworkEvent can be set via maxNumberOfMessageEvent + assertThat(traceParams.getMaxNumberOfNetworkEvents()).isEqualTo(10); + assertThat(traceParams.getMaxNumberOfMessageEvents()).isEqualTo(10); + assertThat(traceParams.getMaxNumberOfLinks()).isEqualTo(11); + } + + @Test + public void updateTraceParams_maxNumberOfNetworkEvents() { + TraceParams traceParams = + TraceParams.DEFAULT.toBuilder().setMaxNumberOfNetworkEvents(10).build(); + assertThat(traceParams.getMaxNumberOfNetworkEvents()).isEqualTo(10); + // test maxNumberOfMessageEvent can be set via maxNumberOfNetworkEvent + assertThat(traceParams.getMaxNumberOfMessageEvents()).isEqualTo(10); + } +} diff --git a/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java new file mode 100644 index 00000000..d7f385d0 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/export/ExportComponentTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ExportComponent}. */ +@RunWith(JUnit4.class) +public class ExportComponentTest { + private final ExportComponent exportComponent = ExportComponent.newNoopExportComponent(); + + @Test + public void implementationOfSpanExporter() { + assertThat(exportComponent.getSpanExporter()).isEqualTo(SpanExporter.getNoopSpanExporter()); + } + + @Test + public void implementationOfActiveSpans() { + assertThat(exportComponent.getRunningSpanStore()) + .isEqualTo(RunningSpanStore.getNoopRunningSpanStore()); + } + + @Test + public void implementationOfSampledSpanStore() { + assertThat(exportComponent.getSampledSpanStore()) + .isInstanceOf(SampledSpanStore.newNoopSampledSpanStore().getClass()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/export/NoopRunningSpanStoreTest.java b/api/src/test/java/io/opencensus/trace/export/NoopRunningSpanStoreTest.java new file mode 100644 index 00000000..960da27c --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/export/NoopRunningSpanStoreTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import java.util.Collection; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link NoopRunningSpanStore}. */ +@RunWith(JUnit4.class) +public final class NoopRunningSpanStoreTest { + + private final RunningSpanStore runningSpanStore = + ExportComponent.newNoopExportComponent().getRunningSpanStore(); + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void noopRunningSpanStore_GetSummary() { + RunningSpanStore.Summary summary = runningSpanStore.getSummary(); + assertThat(summary.getPerSpanNameSummary()).isEmpty(); + } + + @Test + public void noopRunningSpanStore_GetRunningSpans_DisallowsNull() { + thrown.expect(NullPointerException.class); + runningSpanStore.getRunningSpans(null); + } + + @Test + public void noopRunningSpanStore_GetRunningSpans() { + Collection<SpanData> runningSpans = + runningSpanStore.getRunningSpans(RunningSpanStore.Filter.create("TestSpan", 0)); + assertThat(runningSpans).isEmpty(); + } +} diff --git a/api/src/test/java/io/opencensus/trace/export/NoopSampledSpanStoreTest.java b/api/src/test/java/io/opencensus/trace/export/NoopSampledSpanStoreTest.java new file mode 100644 index 00000000..6e9c7b0f --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/export/NoopSampledSpanStoreTest.java @@ -0,0 +1,94 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.Lists; +import io.opencensus.trace.Status.CanonicalCode; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link NoopSampledSpanStore}. */ +@RunWith(JUnit4.class) +public final class NoopSampledSpanStoreTest { + + private static final SampledSpanStore.PerSpanNameSummary EMPTY_PER_SPAN_NAME_SUMMARY = + SampledSpanStore.PerSpanNameSummary.create( + Collections.<SampledSpanStore.LatencyBucketBoundaries, Integer>emptyMap(), + Collections.<CanonicalCode, Integer>emptyMap()); + + @Test + public void noopSampledSpanStore_RegisterUnregisterAndGetSummary() { + // should return empty before register + SampledSpanStore sampledSpanStore = + ExportComponent.newNoopExportComponent().getSampledSpanStore(); + SampledSpanStore.Summary summary = sampledSpanStore.getSummary(); + assertThat(summary.getPerSpanNameSummary()).isEmpty(); + + // should return non-empty summaries with zero latency/error sampled spans after register + sampledSpanStore.registerSpanNamesForCollection( + Collections.unmodifiableList(Lists.newArrayList("TestSpan1", "TestSpan2", "TestSpan3"))); + summary = sampledSpanStore.getSummary(); + assertThat(summary.getPerSpanNameSummary()) + .containsExactly( + "TestSpan1", EMPTY_PER_SPAN_NAME_SUMMARY, + "TestSpan2", EMPTY_PER_SPAN_NAME_SUMMARY, + "TestSpan3", EMPTY_PER_SPAN_NAME_SUMMARY); + + // should unregister specific spanNames + sampledSpanStore.unregisterSpanNamesForCollection( + Collections.unmodifiableList(Lists.newArrayList("TestSpan1", "TestSpan3"))); + summary = sampledSpanStore.getSummary(); + assertThat(summary.getPerSpanNameSummary()) + .containsExactly("TestSpan2", EMPTY_PER_SPAN_NAME_SUMMARY); + } + + @Test + public void noopSampledSpanStore_GetLatencySampledSpans() { + SampledSpanStore sampledSpanStore = + ExportComponent.newNoopExportComponent().getSampledSpanStore(); + Collection<SpanData> latencySampledSpans = + sampledSpanStore.getLatencySampledSpans( + SampledSpanStore.LatencyFilter.create("TestLatencyFilter", 0, 0, 0)); + assertThat(latencySampledSpans).isEmpty(); + } + + @Test + public void noopSampledSpanStore_GetErrorSampledSpans() { + SampledSpanStore sampledSpanStore = + ExportComponent.newNoopExportComponent().getSampledSpanStore(); + Collection<SpanData> errorSampledSpans = + sampledSpanStore.getErrorSampledSpans( + SampledSpanStore.ErrorFilter.create("TestErrorFilter", null, 0)); + assertThat(errorSampledSpans).isEmpty(); + } + + @Test + public void noopSampledSpanStore_GetRegisteredSpanNamesForCollection() { + SampledSpanStore sampledSpanStore = + ExportComponent.newNoopExportComponent().getSampledSpanStore(); + sampledSpanStore.registerSpanNamesForCollection( + Collections.unmodifiableList(Lists.newArrayList("TestSpan3", "TestSpan4"))); + Set<String> registeredSpanNames = sampledSpanStore.getRegisteredSpanNamesForCollection(); + assertThat(registeredSpanNames).containsExactly("TestSpan3", "TestSpan4"); + } +} diff --git a/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java new file mode 100644 index 00000000..b991d145 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/export/SpanDataTest.java @@ -0,0 +1,321 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.export; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.EqualsTester; +import io.opencensus.common.Timestamp; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Link; +import io.opencensus.trace.Link.Type; +import io.opencensus.trace.MessageEvent; +import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.Span.Kind; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.export.SpanData.Attributes; +import io.opencensus.trace.export.SpanData.Links; +import io.opencensus.trace.export.SpanData.TimedEvent; +import io.opencensus.trace.export.SpanData.TimedEvents; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link SpanData}. */ +@RunWith(JUnit4.class) +public class SpanDataTest { + private static final Timestamp startTimestamp = Timestamp.create(123, 456); + private static final Timestamp eventTimestamp1 = Timestamp.create(123, 457); + private static final Timestamp eventTimestamp2 = Timestamp.create(123, 458); + private static final Timestamp eventTimestamp3 = Timestamp.create(123, 459); + private static final Timestamp endTimestamp = Timestamp.create(123, 460); + private static final String SPAN_NAME = "MySpanName"; + private static final String ANNOTATION_TEXT = "MyAnnotationText"; + private static final Annotation annotation = Annotation.fromDescription(ANNOTATION_TEXT); + private static final NetworkEvent recvNetworkEvent = + NetworkEvent.builder(NetworkEvent.Type.RECV, 1).build(); + private static final NetworkEvent sentNetworkEvent = + NetworkEvent.builder(NetworkEvent.Type.SENT, 1).build(); + private static final MessageEvent recvMessageEvent = + MessageEvent.builder(MessageEvent.Type.RECEIVED, 1).build(); + private static final MessageEvent sentMessageEvent = + MessageEvent.builder(MessageEvent.Type.SENT, 1).build(); + private static final Status status = Status.DEADLINE_EXCEEDED.withDescription("TooSlow"); + private static final int CHILD_SPAN_COUNT = 13; + private final Random random = new Random(1234); + private final SpanContext spanContext = + SpanContext.create( + TraceId.generateRandomId(random), SpanId.generateRandomId(random), TraceOptions.DEFAULT); + private final SpanId parentSpanId = SpanId.generateRandomId(random); + private final Map<String, AttributeValue> attributesMap = new HashMap<String, AttributeValue>(); + private final List<TimedEvent<Annotation>> annotationsList = + new ArrayList<TimedEvent<Annotation>>(); + private final List<TimedEvent<NetworkEvent>> networkEventsList = + new ArrayList<SpanData.TimedEvent<NetworkEvent>>(); + private final List<TimedEvent<MessageEvent>> messageEventsList = + new ArrayList<SpanData.TimedEvent<MessageEvent>>(); + private final List<Link> linksList = new ArrayList<Link>(); + + private Attributes attributes; + private TimedEvents<Annotation> annotations; + private TimedEvents<NetworkEvent> networkEvents; + private TimedEvents<MessageEvent> messageEvents; + private Links links; + + @Before + public void setUp() { + attributesMap.put("MyAttributeKey1", AttributeValue.longAttributeValue(10)); + attributesMap.put("MyAttributeKey2", AttributeValue.booleanAttributeValue(true)); + attributes = Attributes.create(attributesMap, 1); + annotationsList.add(SpanData.TimedEvent.create(eventTimestamp1, annotation)); + annotationsList.add(SpanData.TimedEvent.create(eventTimestamp3, annotation)); + annotations = TimedEvents.create(annotationsList, 2); + networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp1, recvNetworkEvent)); + networkEventsList.add(SpanData.TimedEvent.create(eventTimestamp2, sentNetworkEvent)); + networkEvents = TimedEvents.create(networkEventsList, 3); + messageEventsList.add(SpanData.TimedEvent.create(eventTimestamp1, recvMessageEvent)); + messageEventsList.add(SpanData.TimedEvent.create(eventTimestamp2, sentMessageEvent)); + messageEvents = TimedEvents.create(messageEventsList, 3); + linksList.add(Link.fromSpanContext(spanContext, Type.CHILD_LINKED_SPAN)); + links = Links.create(linksList, 0); + } + + @Test + public void spanData_AllValues() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + true, + SPAN_NAME, + Kind.SERVER, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + assertThat(spanData.getContext()).isEqualTo(spanContext); + assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isTrue(); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getKind()).isEqualTo(Kind.SERVER); + assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); + assertThat(spanData.getAttributes()).isEqualTo(attributes); + assertThat(spanData.getAnnotations()).isEqualTo(annotations); + assertThat(spanData.getNetworkEvents()).isEqualTo(networkEvents); + assertThat(spanData.getMessageEvents()).isEqualTo(messageEvents); + assertThat(spanData.getLinks()).isEqualTo(links); + assertThat(spanData.getChildSpanCount()).isEqualTo(CHILD_SPAN_COUNT); + assertThat(spanData.getStatus()).isEqualTo(status); + assertThat(spanData.getEndTimestamp()).isEqualTo(endTimestamp); + } + + @Test + public void spanData_Create_Compatibility() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + true, + SPAN_NAME, + null, + startTimestamp, + attributes, + annotations, + networkEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + assertThat(spanData.getContext()).isEqualTo(spanContext); + assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isTrue(); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); + assertThat(spanData.getAttributes()).isEqualTo(attributes); + assertThat(spanData.getAnnotations()).isEqualTo(annotations); + assertThat(spanData.getNetworkEvents()).isEqualTo(networkEvents); + assertThat(spanData.getMessageEvents()).isEqualTo(messageEvents); + assertThat(spanData.getLinks()).isEqualTo(links); + assertThat(spanData.getChildSpanCount()).isEqualTo(CHILD_SPAN_COUNT); + assertThat(spanData.getStatus()).isEqualTo(status); + assertThat(spanData.getEndTimestamp()).isEqualTo(endTimestamp); + } + + @Test + public void spanData_RootActiveSpan() { + SpanData spanData = + SpanData.create( + spanContext, + null, + null, + SPAN_NAME, + null, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + null, + null, + null); + assertThat(spanData.getContext()).isEqualTo(spanContext); + assertThat(spanData.getParentSpanId()).isNull(); + assertThat(spanData.getHasRemoteParent()).isNull(); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); + assertThat(spanData.getAttributes()).isEqualTo(attributes); + assertThat(spanData.getAnnotations()).isEqualTo(annotations); + assertThat(spanData.getNetworkEvents()).isEqualTo(networkEvents); + assertThat(spanData.getMessageEvents()).isEqualTo(messageEvents); + assertThat(spanData.getLinks()).isEqualTo(links); + assertThat(spanData.getChildSpanCount()).isNull(); + assertThat(spanData.getStatus()).isNull(); + assertThat(spanData.getEndTimestamp()).isNull(); + } + + @Test + public void spanData_AllDataEmpty() { + SpanData spanData = + SpanData.create( + spanContext, + parentSpanId, + false, + SPAN_NAME, + null, + startTimestamp, + Attributes.create(Collections.<String, AttributeValue>emptyMap(), 0), + TimedEvents.create(Collections.<SpanData.TimedEvent<Annotation>>emptyList(), 0), + TimedEvents.create(Collections.<SpanData.TimedEvent<MessageEvent>>emptyList(), 0), + Links.create(Collections.<Link>emptyList(), 0), + 0, + status, + endTimestamp); + assertThat(spanData.getContext()).isEqualTo(spanContext); + assertThat(spanData.getParentSpanId()).isEqualTo(parentSpanId); + assertThat(spanData.getHasRemoteParent()).isFalse(); + assertThat(spanData.getName()).isEqualTo(SPAN_NAME); + assertThat(spanData.getStartTimestamp()).isEqualTo(startTimestamp); + assertThat(spanData.getAttributes().getAttributeMap().isEmpty()).isTrue(); + assertThat(spanData.getAnnotations().getEvents().isEmpty()).isTrue(); + assertThat(spanData.getNetworkEvents().getEvents().isEmpty()).isTrue(); + assertThat(spanData.getMessageEvents().getEvents().isEmpty()).isTrue(); + assertThat(spanData.getLinks().getLinks().isEmpty()).isTrue(); + assertThat(spanData.getChildSpanCount()).isEqualTo(0); + assertThat(spanData.getStatus()).isEqualTo(status); + assertThat(spanData.getEndTimestamp()).isEqualTo(endTimestamp); + } + + @Test + public void spanDataEquals() { + SpanData allSpanData1 = + SpanData.create( + spanContext, + parentSpanId, + false, + SPAN_NAME, + Kind.CLIENT, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + SpanData allSpanData2 = + SpanData.create( + spanContext, + parentSpanId, + false, + SPAN_NAME, + Kind.CLIENT, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp); + SpanData emptySpanData = + SpanData.create( + spanContext, + parentSpanId, + false, + SPAN_NAME, + null, + startTimestamp, + Attributes.create(Collections.<String, AttributeValue>emptyMap(), 0), + TimedEvents.create(Collections.<SpanData.TimedEvent<Annotation>>emptyList(), 0), + TimedEvents.create(Collections.<SpanData.TimedEvent<MessageEvent>>emptyList(), 0), + Links.create(Collections.<Link>emptyList(), 0), + 0, + status, + endTimestamp); + new EqualsTester() + .addEqualityGroup(allSpanData1, allSpanData2) + .addEqualityGroup(emptySpanData) + .testEquals(); + } + + @Test + public void spanData_ToString() { + String spanDataString = + SpanData.create( + spanContext, + parentSpanId, + false, + SPAN_NAME, + Kind.CLIENT, + startTimestamp, + attributes, + annotations, + messageEvents, + links, + CHILD_SPAN_COUNT, + status, + endTimestamp) + .toString(); + assertThat(spanDataString).contains(spanContext.toString()); + assertThat(spanDataString).contains(parentSpanId.toString()); + assertThat(spanDataString).contains(SPAN_NAME); + assertThat(spanDataString).contains(Kind.CLIENT.toString()); + assertThat(spanDataString).contains(startTimestamp.toString()); + assertThat(spanDataString).contains(attributes.toString()); + assertThat(spanDataString).contains(annotations.toString()); + assertThat(spanDataString).contains(messageEvents.toString()); + assertThat(spanDataString).contains(links.toString()); + assertThat(spanDataString).contains(status.toString()); + assertThat(spanDataString).contains(endTimestamp.toString()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/internal/BaseMessageEventUtilsTest.java b/api/src/test/java/io/opencensus/trace/internal/BaseMessageEventUtilsTest.java new file mode 100644 index 00000000..4f8c8508 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/internal/BaseMessageEventUtilsTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018, OpenCensus 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 io.opencensus.trace.internal; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.MessageEvent; +import io.opencensus.trace.NetworkEvent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link BaseMessageEventUtils}. */ +@RunWith(JUnit4.class) +public class BaseMessageEventUtilsTest { + private static final long SENT_EVENT_ID = 12345L; + private static final long RECV_EVENT_ID = 67890L; + private static final long UNCOMPRESSED_SIZE = 100; + private static final long COMPRESSED_SIZE = 99; + + private static final MessageEvent SENT_MESSAGE_EVENT = + MessageEvent.builder(MessageEvent.Type.SENT, SENT_EVENT_ID) + .setUncompressedMessageSize(UNCOMPRESSED_SIZE) + .setCompressedMessageSize(COMPRESSED_SIZE) + .build(); + private static final MessageEvent RECV_MESSAGE_EVENT = + MessageEvent.builder(MessageEvent.Type.RECEIVED, RECV_EVENT_ID) + .setUncompressedMessageSize(UNCOMPRESSED_SIZE) + .setCompressedMessageSize(COMPRESSED_SIZE) + .build(); + private static final NetworkEvent SENT_NETWORK_EVENT = + NetworkEvent.builder(NetworkEvent.Type.SENT, SENT_EVENT_ID) + .setUncompressedMessageSize(UNCOMPRESSED_SIZE) + .setCompressedMessageSize(COMPRESSED_SIZE) + .build(); + private static final NetworkEvent RECV_NETWORK_EVENT = + NetworkEvent.builder(NetworkEvent.Type.RECV, RECV_EVENT_ID) + .setUncompressedMessageSize(UNCOMPRESSED_SIZE) + .setCompressedMessageSize(COMPRESSED_SIZE) + .build(); + + @Test + public void networkEventToMessageEvent() { + assertThat(BaseMessageEventUtils.asMessageEvent(SENT_NETWORK_EVENT)) + .isEqualTo(SENT_MESSAGE_EVENT); + assertThat(BaseMessageEventUtils.asMessageEvent(RECV_NETWORK_EVENT)) + .isEqualTo(RECV_MESSAGE_EVENT); + } + + @Test + public void messageEventToNetworkEvent() { + assertThat(BaseMessageEventUtils.asNetworkEvent(SENT_MESSAGE_EVENT)) + .isEqualTo(SENT_NETWORK_EVENT); + assertThat(BaseMessageEventUtils.asNetworkEvent(RECV_MESSAGE_EVENT)) + .isEqualTo(RECV_NETWORK_EVENT); + } +} diff --git a/api/src/test/java/io/opencensus/trace/propagation/BinaryFormatTest.java b/api/src/test/java/io/opencensus/trace/propagation/BinaryFormatTest.java new file mode 100644 index 00000000..64544ffe --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/propagation/BinaryFormatTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.SpanContext; +import java.text.ParseException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link BinaryFormat}. */ +@RunWith(JUnit4.class) +public class BinaryFormatTest { + private static final BinaryFormat binaryFormat = BinaryFormat.getNoopBinaryFormat(); + + @Test(expected = NullPointerException.class) + public void toBinaryValue_NullSpanContext() { + binaryFormat.toBinaryValue(null); + } + + @Test + public void toBinaryValue_NotNullSpanContext() { + assertThat(binaryFormat.toBinaryValue(SpanContext.INVALID)).isEqualTo(new byte[0]); + } + + @Test(expected = NullPointerException.class) + public void toByteArray_NullSpanContext() { + binaryFormat.toByteArray(null); + } + + @Test + public void toByteArray_NotNullSpanContext() { + assertThat(binaryFormat.toByteArray(SpanContext.INVALID)).isEqualTo(new byte[0]); + } + + @Test(expected = NullPointerException.class) + public void fromBinaryValue_NullInput() throws ParseException { + binaryFormat.fromBinaryValue(null); + } + + @Test + public void fromBinaryValue_NotNullInput() throws ParseException { + assertThat(binaryFormat.fromBinaryValue(new byte[0])).isEqualTo(SpanContext.INVALID); + } + + @Test(expected = NullPointerException.class) + public void fromByteArray_NullInput() throws SpanContextParseException { + binaryFormat.fromByteArray(null); + } + + @Test + public void fromByteArray_NotNullInput() throws SpanContextParseException { + assertThat(binaryFormat.fromByteArray(new byte[0])).isEqualTo(SpanContext.INVALID); + } +} diff --git a/api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java b/api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java new file mode 100644 index 00000000..ba64e98e --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/propagation/PropagationComponentTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link PropagationComponent}. */ +@RunWith(JUnit4.class) +public class PropagationComponentTest { + private final PropagationComponent propagationComponent = + PropagationComponent.getNoopPropagationComponent(); + + @Test + public void implementationOfBinaryFormat() { + assertThat(propagationComponent.getBinaryFormat()) + .isEqualTo(BinaryFormat.getNoopBinaryFormat()); + } +} diff --git a/api/src/test/java/io/opencensus/trace/propagation/SpanContextParseExceptionTest.java b/api/src/test/java/io/opencensus/trace/propagation/SpanContextParseExceptionTest.java new file mode 100644 index 00000000..92efb35d --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/propagation/SpanContextParseExceptionTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.IOException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link SpanContextParseException}. */ +@RunWith(JUnit4.class) +public class SpanContextParseExceptionTest { + + @Test + public void createWithMessage() { + assertThat(new SpanContextParseException("my message").getMessage()).isEqualTo("my message"); + } + + @Test + public void createWithMessageAndCause() { + IOException cause = new IOException(); + SpanContextParseException parseException = new SpanContextParseException("my message", cause); + assertThat(parseException.getMessage()).isEqualTo("my message"); + assertThat(parseException.getCause()).isEqualTo(cause); + } +} diff --git a/api/src/test/java/io/opencensus/trace/propagation/TextFormatTest.java b/api/src/test/java/io/opencensus/trace/propagation/TextFormatTest.java new file mode 100644 index 00000000..c2e6e127 --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/propagation/TextFormatTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.propagation; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.propagation.TextFormat.Getter; +import io.opencensus.trace.propagation.TextFormat.Setter; +import javax.annotation.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link TextFormat}. */ +@RunWith(JUnit4.class) +public class TextFormatTest { + private static final TextFormat textFormat = TextFormat.getNoopTextFormat(); + + @Test(expected = NullPointerException.class) + public void inject_NullSpanContext() { + textFormat.inject( + null, + new Object(), + new Setter<Object>() { + @Override + public void put(Object carrier, String key, String value) {} + }); + } + + @Test + public void inject_NotNullSpanContext_DoesNotFail() { + textFormat.inject( + SpanContext.INVALID, + new Object(), + new Setter<Object>() { + @Override + public void put(Object carrier, String key, String value) {} + }); + } + + @Test(expected = NullPointerException.class) + public void fromHeaders_NullGetter() throws SpanContextParseException { + textFormat.extract(new Object(), null); + } + + @Test + public void fromHeaders_NotNullGetter() throws SpanContextParseException { + assertThat( + textFormat.extract( + new Object(), + new Getter<Object>() { + @Nullable + @Override + public String get(Object carrier, String key) { + return null; + } + })) + .isSameAs(SpanContext.INVALID); + } +} diff --git a/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java new file mode 100644 index 00000000..7a46e97a --- /dev/null +++ b/api/src/test/java/io/opencensus/trace/samplers/SamplersTest.java @@ -0,0 +1,281 @@ +/* + * Copyright 2017, OpenCensus 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 io.opencensus.trace.samplers; + +import static com.google.common.truth.Truth.assertThat; + +import io.opencensus.trace.NoopSpan; +import io.opencensus.trace.Sampler; +import io.opencensus.trace.Span; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Random; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Samplers}. */ +@RunWith(JUnit4.class) +public class SamplersTest { + private static final String SPAN_NAME = "MySpanName"; + private static final int NUM_SAMPLE_TRIES = 1000; + private final Random random = new Random(1234); + private final TraceId traceId = TraceId.generateRandomId(random); + private final SpanId parentSpanId = SpanId.generateRandomId(random); + private final SpanId spanId = SpanId.generateRandomId(random); + private final SpanContext sampledSpanContext = + SpanContext.create(traceId, parentSpanId, TraceOptions.builder().setIsSampled(true).build()); + private final SpanContext notSampledSpanContext = + SpanContext.create(traceId, parentSpanId, TraceOptions.DEFAULT); + private final Span sampledSpan = + new NoopSpan(sampledSpanContext, EnumSet.of(Span.Options.RECORD_EVENTS)); + + @Test + public void alwaysSampleSampler_AlwaysReturnTrue() { + // Sampled parent. + assertThat( + Samplers.alwaysSample() + .shouldSample( + sampledSpanContext, + false, + traceId, + spanId, + "Another name", + Collections.<Span>emptyList())) + .isTrue(); + // Not sampled parent. + assertThat( + Samplers.alwaysSample() + .shouldSample( + notSampledSpanContext, + false, + traceId, + spanId, + "Yet another name", + Collections.<Span>emptyList())) + .isTrue(); + } + + @Test + public void alwaysSampleSampler_ToString() { + assertThat(Samplers.alwaysSample().toString()).isEqualTo("AlwaysSampleSampler"); + } + + @Test + public void neverSampleSampler_AlwaysReturnFalse() { + // Sampled parent. + assertThat( + Samplers.neverSample() + .shouldSample( + sampledSpanContext, + false, + traceId, + spanId, + "bar", + Collections.<Span>emptyList())) + .isFalse(); + // Not sampled parent. + assertThat( + Samplers.neverSample() + .shouldSample( + notSampledSpanContext, + false, + traceId, + spanId, + "quux", + Collections.<Span>emptyList())) + .isFalse(); + } + + @Test + public void neverSampleSampler_ToString() { + assertThat(Samplers.neverSample().toString()).isEqualTo("NeverSampleSampler"); + } + + @Test(expected = IllegalArgumentException.class) + public void probabilitySampler_outOfRangeHighProbability() { + Samplers.probabilitySampler(1.01); + } + + @Test(expected = IllegalArgumentException.class) + public void probabilitySampler_outOfRangeLowProbability() { + Samplers.probabilitySampler(-0.00001); + } + + // Applies the given sampler to NUM_SAMPLE_TRIES random traceId/spanId pairs. + private static void assertSamplerSamplesWithProbability( + Sampler sampler, SpanContext parent, List<Span> parentLinks, double probability) { + Random random = new Random(1234); + int count = 0; // Count of spans with sampling enabled + for (int i = 0; i < NUM_SAMPLE_TRIES; i++) { + if (sampler.shouldSample( + parent, + false, + TraceId.generateRandomId(random), + SpanId.generateRandomId(random), + SPAN_NAME, + parentLinks)) { + count++; + } + } + double proportionSampled = (double) count / NUM_SAMPLE_TRIES; + // Allow for a large amount of slop (+/- 10%) in number of sampled traces, to avoid flakiness. + assertThat(proportionSampled < probability + 0.1 && proportionSampled > probability - 0.1) + .isTrue(); + } + + @Test + public void probabilitySampler_DifferentProbabilities_NotSampledParent() { + final Sampler neverSample = Samplers.probabilitySampler(0.0); + assertSamplerSamplesWithProbability( + neverSample, notSampledSpanContext, Collections.<Span>emptyList(), 0.0); + final Sampler alwaysSample = Samplers.probabilitySampler(1.0); + assertSamplerSamplesWithProbability( + alwaysSample, notSampledSpanContext, Collections.<Span>emptyList(), 1.0); + final Sampler fiftyPercentSample = Samplers.probabilitySampler(0.5); + assertSamplerSamplesWithProbability( + fiftyPercentSample, notSampledSpanContext, Collections.<Span>emptyList(), 0.5); + final Sampler twentyPercentSample = Samplers.probabilitySampler(0.2); + assertSamplerSamplesWithProbability( + twentyPercentSample, notSampledSpanContext, Collections.<Span>emptyList(), 0.2); + final Sampler twoThirdsSample = Samplers.probabilitySampler(2.0 / 3.0); + assertSamplerSamplesWithProbability( + twoThirdsSample, notSampledSpanContext, Collections.<Span>emptyList(), 2.0 / 3.0); + } + + @Test + public void probabilitySampler_DifferentProbabilities_SampledParent() { + final Sampler neverSample = Samplers.probabilitySampler(0.0); + assertSamplerSamplesWithProbability( + neverSample, sampledSpanContext, Collections.<Span>emptyList(), 1.0); + final Sampler alwaysSample = Samplers.probabilitySampler(1.0); + assertSamplerSamplesWithProbability( + alwaysSample, sampledSpanContext, Collections.<Span>emptyList(), 1.0); + final Sampler fiftyPercentSample = Samplers.probabilitySampler(0.5); + assertSamplerSamplesWithProbability( + fiftyPercentSample, sampledSpanContext, Collections.<Span>emptyList(), 1.0); + final Sampler twentyPercentSample = Samplers.probabilitySampler(0.2); + assertSamplerSamplesWithProbability( + twentyPercentSample, sampledSpanContext, Collections.<Span>emptyList(), 1.0); + final Sampler twoThirdsSample = Samplers.probabilitySampler(2.0 / 3.0); + assertSamplerSamplesWithProbability( + twoThirdsSample, sampledSpanContext, Collections.<Span>emptyList(), 1.0); + } + + @Test + public void probabilitySampler_DifferentProbabilities_SampledParentLink() { + final Sampler neverSample = Samplers.probabilitySampler(0.0); + assertSamplerSamplesWithProbability( + neverSample, notSampledSpanContext, Arrays.asList(sampledSpan), 1.0); + final Sampler alwaysSample = Samplers.probabilitySampler(1.0); + assertSamplerSamplesWithProbability( + alwaysSample, notSampledSpanContext, Arrays.asList(sampledSpan), 1.0); + final Sampler fiftyPercentSample = Samplers.probabilitySampler(0.5); + assertSamplerSamplesWithProbability( + fiftyPercentSample, notSampledSpanContext, Arrays.asList(sampledSpan), 1.0); + final Sampler twentyPercentSample = Samplers.probabilitySampler(0.2); + assertSamplerSamplesWithProbability( + twentyPercentSample, notSampledSpanContext, Arrays.asList(sampledSpan), 1.0); + final Sampler twoThirdsSample = Samplers.probabilitySampler(2.0 / 3.0); + assertSamplerSamplesWithProbability( + twoThirdsSample, notSampledSpanContext, Arrays.asList(sampledSpan), 1.0); + } + + @Test + public void probabilitySampler_SampleBasedOnTraceId() { + final Sampler defaultProbability = Samplers.probabilitySampler(0.0001); + // This traceId will not be sampled by the ProbabilitySampler because the first 8 bytes as long + // is not less than probability * Long.MAX_VALUE; + TraceId notSampledtraceId = + TraceId.fromBytes( + new byte[] { + (byte) 0x8F, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }); + assertThat( + defaultProbability.shouldSample( + null, + false, + notSampledtraceId, + SpanId.generateRandomId(random), + SPAN_NAME, + Collections.<Span>emptyList())) + .isFalse(); + // This traceId will be sampled by the ProbabilitySampler because the first 8 bytes as long + // is less than probability * Long.MAX_VALUE; + TraceId sampledtraceId = + TraceId.fromBytes( + new byte[] { + (byte) 0x00, + (byte) 0x00, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + (byte) 0xFF, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }); + assertThat( + defaultProbability.shouldSample( + null, + false, + sampledtraceId, + SpanId.generateRandomId(random), + SPAN_NAME, + Collections.<Span>emptyList())) + .isTrue(); + } + + @Test + public void probabilitySampler_getDescription() { + assertThat((Samplers.probabilitySampler(0.5)).getDescription()) + .isEqualTo(String.format("ProbabilitySampler{%.6f}", 0.5)); + } + + @Test + public void probabilitySampler_ToString() { + assertThat((Samplers.probabilitySampler(0.5)).toString()).contains("0.5"); + } +} |