aboutsummaryrefslogtreecommitdiff
path: root/impl_core/src
diff options
context:
space:
mode:
Diffstat (limited to 'impl_core/src')
-rw-r--r--impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java25
-rw-r--r--impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextDeserializationTest.java25
-rw-r--r--impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextRoundtripTest.java31
-rw-r--r--impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextSerializationTest.java30
4 files changed, 71 insertions, 40 deletions
diff --git a/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java
index 3de44fa3..756aeb5d 100644
--- a/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java
+++ b/impl_core/src/main/java/io/opencensus/implcore/tags/propagation/SerializationUtils.java
@@ -68,6 +68,7 @@ final class SerializationUtils {
@VisibleForTesting static final int VERSION_ID = 0;
@VisibleForTesting static final int TAG_FIELD_ID = 0;
+ // This size limit only applies to the bytes representing tag keys and values.
@VisibleForTesting static final int TAGCONTEXT_SERIALIZED_SIZE_LIMIT = 8192;
// Serializes a TagContext to the on-the-wire format.
@@ -76,17 +77,19 @@ final class SerializationUtils {
// Use a ByteArrayDataOutput to avoid needing to handle IOExceptions.
final ByteArrayDataOutput byteArrayDataOutput = ByteStreams.newDataOutput();
byteArrayDataOutput.write(VERSION_ID);
+ int totalChars = 0; // Here chars are equivalent to bytes, since we're using ascii chars.
for (Iterator<Tag> i = InternalUtils.getTags(tags); i.hasNext(); ) {
Tag tag = i.next();
+ totalChars += tag.getKey().getName().length();
+ totalChars += tag.getValue().asString().length();
encodeTag(tag, byteArrayDataOutput);
}
- byte[] bytes = byteArrayDataOutput.toByteArray();
- if (bytes.length > TAGCONTEXT_SERIALIZED_SIZE_LIMIT) {
+ if (totalChars > TAGCONTEXT_SERIALIZED_SIZE_LIMIT) {
throw new TagContextSerializationException(
- "Size of serialized TagContext exceeds the maximum serialized size "
+ "Size of TagContext exceeds the maximum serialized size "
+ TAGCONTEXT_SERIALIZED_SIZE_LIMIT);
}
- return bytes;
+ return byteArrayDataOutput.toByteArray();
}
// Deserializes input to TagContext based on the binary format standard.
@@ -96,10 +99,6 @@ final class SerializationUtils {
if (bytes.length == 0) {
// Does not allow empty byte array.
throw new TagContextDeserializationException("Input byte[] can not be empty.");
- } else if (bytes.length > TAGCONTEXT_SERIALIZED_SIZE_LIMIT) {
- throw new TagContextDeserializationException(
- "Size of input byte[] exceeds the maximum serialized size "
- + TAGCONTEXT_SERIALIZED_SIZE_LIMIT);
}
ByteBuffer buffer = ByteBuffer.wrap(bytes).asReadOnlyBuffer();
@@ -118,18 +117,26 @@ final class SerializationUtils {
throws TagContextDeserializationException {
Map<TagKey, TagValue> tags = new HashMap<TagKey, TagValue>();
int limit = buffer.limit();
+ int totalChars = 0; // Here chars are equivalent to bytes, since we're using ascii chars.
while (buffer.position() < limit) {
int type = buffer.get();
if (type == TAG_FIELD_ID) {
TagKey key = createTagKey(decodeString(buffer));
TagValue val = createTagValue(key, decodeString(buffer));
+ totalChars += key.getName().length();
+ totalChars += val.asString().length();
tags.put(key, val);
} else {
// Stop parsing at the first unknown field ID, since there is no way to know its length.
// TODO(sebright): Consider storing the rest of the byte array in the TagContext.
- return tags;
+ break;
}
}
+ if (totalChars > TAGCONTEXT_SERIALIZED_SIZE_LIMIT) {
+ throw new TagContextDeserializationException(
+ "Size of TagContext exceeds the maximum serialized size "
+ + TAGCONTEXT_SERIALIZED_SIZE_LIMIT);
+ }
return tags;
}
diff --git a/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextDeserializationTest.java b/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextDeserializationTest.java
index 09f6878d..a2245255 100644
--- a/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextDeserializationTest.java
+++ b/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextDeserializationTest.java
@@ -78,9 +78,30 @@ public class TagContextDeserializationTest {
@Test
public void testDeserializeTooLargeByteArrayThrowException()
throws TagContextDeserializationException {
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.write(SerializationUtils.VERSION_ID);
+ for (int i = 0; i < SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT / 8 - 1; i++) {
+ // Each tag will be with format {key : "0123", value : "0123"}, so the length of it is 8.
+ String str;
+ if (i < 10) {
+ str = "000" + i;
+ } else if (i < 100) {
+ str = "00" + i;
+ } else if (i < 1000) {
+ str = "0" + i;
+ } else {
+ str = String.valueOf(i);
+ }
+ encodeTagToOutput(str, str, output);
+ }
+ // The last tag will be of size 9, so the total size of the TagContext (8193) will be one byte
+ // more than limit.
+ encodeTagToOutput("last", "last1", output);
+
+ byte[] bytes = output.toByteArray();
thrown.expect(TagContextDeserializationException.class);
- thrown.expectMessage("Size of input byte[] exceeds the maximum serialized size ");
- serializer.fromByteArray(new byte[SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT + 1]);
+ thrown.expectMessage("Size of TagContext exceeds the maximum serialized size ");
+ serializer.fromByteArray(bytes);
}
@Test
diff --git a/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextRoundtripTest.java b/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextRoundtripTest.java
index c49e53a4..1b1aa042 100644
--- a/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextRoundtripTest.java
+++ b/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextRoundtripTest.java
@@ -59,23 +59,22 @@ public class TagContextRoundtripTest {
@Test
public void testRoundtrip_TagContextWithMaximumSize() throws Exception {
TagContextBuilder builder = tagger.emptyBuilder();
- int i = 0;
-
- // This loop should fill in tags that have a total size of 8185
- while (serializer.toByteArray(builder.build()).length
- < SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT - 8) {
- TagKey key = TagKey.create("k" + i);
- TagValue value = TagValue.create("v" + i);
- builder.put(key, value);
- i++;
+ for (int i = 0; i < SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT / 8; i++) {
+ // Each tag will be with format {key : "0123", value : "0123"}, so the length of it is 8.
+ // Add 1024 tags, the total size should just be 8192.
+ String str;
+ if (i < 10) {
+ str = "000" + i;
+ } else if (i < 100) {
+ str = "00" + i;
+ } else if (i < 1000) {
+ str = "0" + i;
+ } else {
+ str = "" + i;
+ }
+ builder.put(TagKey.create(str), TagValue.create(str));
}
- // The last tag has size 7, after putting it, the size of TagContext should just meet the limit
- builder.put(TagKey.create("last"), TagValue.create(""));
-
- TagContext expected = builder.build();
- assertThat(serializer.toByteArray(expected).length)
- .isEqualTo(SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT);
- testRoundtripSerialization(expected);
+ testRoundtripSerialization(builder.build());
}
private void testRoundtripSerialization(TagContext expected) throws Exception {
diff --git a/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextSerializationTest.java b/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextSerializationTest.java
index 551b7ff8..771b2899 100644
--- a/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextSerializationTest.java
+++ b/impl_core/src/test/java/io/opencensus/implcore/tags/propagation/TagContextSerializationTest.java
@@ -91,23 +91,27 @@ public class TagContextSerializationTest {
@Test
public void testSerializeTooLargeTagContext() throws TagContextSerializationException {
TagContextBuilder builder = tagger.emptyBuilder();
- int i = 0;
-
- // This loop should fill in tags that have a total size of 8185
- while (serializer.toByteArray(builder.build()).length
- < SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT - 8) {
- TagKey key = TagKey.create("k" + i);
- TagValue value = TagValue.create("v" + i);
- builder.put(key, value);
- i++;
+ for (int i = 0; i < SerializationUtils.TAGCONTEXT_SERIALIZED_SIZE_LIMIT / 8 - 1; i++) {
+ // Each tag will be with format {key : "0123", value : "0123"}, so the length of it is 8.
+ String str;
+ if (i < 10) {
+ str = "000" + i;
+ } else if (i < 100) {
+ str = "00" + i;
+ } else if (i < 1000) {
+ str = "0" + i;
+ } else {
+ str = String.valueOf(i);
+ }
+ builder.put(TagKey.create(str), TagValue.create(str));
}
- // The last tag has size 8, after putting it, the size of TagContext (8193) should just exceed
- // the limit
- builder.put(TagKey.create("last"), TagValue.create("1"));
+ // The last tag will be of size 9, so the total size of the TagContext (8193) will be one byte
+ // more than limit.
+ builder.put(TagKey.create("last"), TagValue.create("last1"));
TagContext tagContext = builder.build();
thrown.expect(TagContextSerializationException.class);
- thrown.expectMessage("Size of serialized TagContext exceeds the maximum serialized size ");
+ thrown.expectMessage("Size of TagContext exceeds the maximum serialized size ");
serializer.toByteArray(tagContext);
}