Skip to content

Commit 594f3ae

Browse files
authored
Add tests for servlet-rw BufferedReader and PrintWriter instrumentations (hypertrace#245)
adding tests for servlet-rw BufferedReader and PrintWriter instrumentations
1 parent a799207 commit 594f3ae

File tree

6 files changed

+455
-0
lines changed

6 files changed

+455
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.rw.reader;
18+
19+
import static net.bytebuddy.matcher.ElementMatchers.*;
20+
21+
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
22+
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
23+
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
24+
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
25+
import java.io.BufferedReader;
26+
import java.util.Collections;
27+
import java.util.HashMap;
28+
import java.util.List;
29+
import java.util.Map;
30+
import net.bytebuddy.asm.Advice;
31+
import net.bytebuddy.description.method.MethodDescription;
32+
import net.bytebuddy.description.type.TypeDescription;
33+
import net.bytebuddy.matcher.ElementMatcher;
34+
import org.hypertrace.agent.core.instrumentation.buffer.CharBufferSpanPair;
35+
36+
// SPI explicitly added in META-INF/services/...
37+
public class BufferedReaderContextAccessInstrumentationModule extends InstrumentationModule {
38+
39+
public BufferedReaderContextAccessInstrumentationModule() {
40+
super("test-buffered-reader");
41+
}
42+
43+
@Override
44+
protected Map<String, String> contextStore() {
45+
return Collections.singletonMap("java.io.BufferedReader", CharBufferSpanPair.class.getName());
46+
}
47+
48+
@Override
49+
public List<TypeInstrumentation> typeInstrumentations() {
50+
return Collections.singletonList(new BufferedReaderTriggerInstrumentation());
51+
}
52+
53+
class BufferedReaderTriggerInstrumentation implements TypeInstrumentation {
54+
55+
@Override
56+
public ElementMatcher<? super TypeDescription> typeMatcher() {
57+
return named("org.BufferedReaderPrintWriterContextAccess");
58+
}
59+
60+
@Override
61+
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
62+
Map<ElementMatcher.Junction<MethodDescription>, String> matchers = new HashMap<>();
63+
matchers.put(
64+
named("addToBufferedReaderContext").and(takesArguments(2)).and(isPublic()),
65+
BufferedReaderContextAccessInstrumentationModule.class.getName() + "$TestAdvice");
66+
return matchers;
67+
}
68+
}
69+
70+
static class TestAdvice {
71+
@Advice.OnMethodEnter(suppress = Throwable.class)
72+
public static void enter(
73+
@Advice.Argument(0) BufferedReader bufferedReader,
74+
@Advice.Argument(1) CharBufferSpanPair metadata) {
75+
ContextStore<BufferedReader, CharBufferSpanPair> contextStore =
76+
InstrumentationContext.get(BufferedReader.class, CharBufferSpanPair.class);
77+
contextStore.put(bufferedReader, metadata);
78+
}
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.rw.reader;
18+
19+
import io.opentelemetry.api.trace.Span;
20+
import java.io.BufferedReader;
21+
import java.io.CharArrayReader;
22+
import java.io.IOException;
23+
import org.BufferedReaderPrintWriterContextAccess;
24+
import org.hypertrace.agent.core.instrumentation.buffer.*;
25+
import org.hypertrace.agent.testing.AbstractInstrumenterTest;
26+
import org.junit.jupiter.api.Assertions;
27+
import org.junit.jupiter.api.Test;
28+
29+
public class BufferedReaderInstrumentationTest extends AbstractInstrumenterTest {
30+
31+
private static final String TEST_SPAN_NAME = "foo";
32+
private static final String BODY = "boobar";
33+
34+
@Test
35+
public void read() throws IOException {
36+
Span span = TEST_TRACER.spanBuilder(TEST_SPAN_NAME).startSpan();
37+
38+
BufferedReader bufferedReader = new BufferedReader(new CharArrayReader(BODY.toCharArray()));
39+
40+
BoundedCharArrayWriter buffer = BoundedBuffersFactory.createWriter();
41+
CharBufferSpanPair bufferSpanPair = new CharBufferSpanPair(span, buffer);
42+
43+
BufferedReaderPrintWriterContextAccess.addToBufferedReaderContext(
44+
bufferedReader, bufferSpanPair);
45+
46+
while (bufferedReader.read() != -1) {}
47+
Assertions.assertEquals(BODY, buffer.toString());
48+
}
49+
50+
@Test
51+
public void read_callDepth_isCleared() throws IOException {
52+
Span span = TEST_TRACER.spanBuilder(TEST_SPAN_NAME).startSpan();
53+
54+
BufferedReader bufferedReader = new BufferedReader(new CharArrayReader(BODY.toCharArray()));
55+
bufferedReader.read();
56+
57+
BoundedCharArrayWriter buffer = BoundedBuffersFactory.createWriter();
58+
CharBufferSpanPair bufferSpanPair = new CharBufferSpanPair(span, buffer);
59+
60+
BufferedReaderPrintWriterContextAccess.addToBufferedReaderContext(
61+
bufferedReader, bufferSpanPair);
62+
63+
while (bufferedReader.read() != -1) {}
64+
Assertions.assertEquals(BODY.substring(1), buffer.toString());
65+
}
66+
67+
@Test
68+
public void read_char_arr() throws IOException {
69+
Span span = TEST_TRACER.spanBuilder(TEST_SPAN_NAME).startSpan();
70+
71+
BufferedReader bufferedReader = new BufferedReader(new CharArrayReader(BODY.toCharArray()));
72+
73+
BoundedCharArrayWriter buffer = BoundedBuffersFactory.createWriter();
74+
CharBufferSpanPair bufferSpanPair = new CharBufferSpanPair(span, buffer);
75+
76+
BufferedReaderPrintWriterContextAccess.addToBufferedReaderContext(
77+
bufferedReader, bufferSpanPair);
78+
79+
while (bufferedReader.read(new char[BODY.length()]) != -1) {}
80+
Assertions.assertEquals(BODY, buffer.toString());
81+
}
82+
83+
@Test
84+
public void read_callDepth_char_arr() throws IOException {
85+
Span span = TEST_TRACER.spanBuilder(TEST_SPAN_NAME).startSpan();
86+
87+
BufferedReader bufferedReader = new BufferedReader(new CharArrayReader(BODY.toCharArray()));
88+
bufferedReader.read(new char[2]);
89+
90+
BoundedCharArrayWriter buffer = BoundedBuffersFactory.createWriter();
91+
CharBufferSpanPair bufferSpanPair = new CharBufferSpanPair(span, buffer);
92+
93+
BufferedReaderPrintWriterContextAccess.addToBufferedReaderContext(
94+
bufferedReader, bufferSpanPair);
95+
96+
while (bufferedReader.read(new char[BODY.length()]) != -1) {}
97+
Assertions.assertEquals(BODY.substring(2), buffer.toString());
98+
}
99+
100+
@Test
101+
public void read_char_arr_offset() throws IOException {
102+
Span span = TEST_TRACER.spanBuilder(TEST_SPAN_NAME).startSpan();
103+
104+
BufferedReader bufferedReader = new BufferedReader(new CharArrayReader(BODY.toCharArray()));
105+
106+
BoundedCharArrayWriter buffer = BoundedBuffersFactory.createWriter();
107+
CharBufferSpanPair bufferSpanPair = new CharBufferSpanPair(span, buffer);
108+
109+
BufferedReaderPrintWriterContextAccess.addToBufferedReaderContext(
110+
bufferedReader, bufferSpanPair);
111+
112+
bufferedReader.read(new char[BODY.length()], 0, 2);
113+
bufferedReader.read(new char[BODY.length()], 2, BODY.length() - 2);
114+
Assertions.assertEquals(BODY, buffer.toString());
115+
}
116+
117+
@Test
118+
public void readLine() throws IOException {
119+
Span span = TEST_TRACER.spanBuilder(TEST_SPAN_NAME).startSpan();
120+
121+
BufferedReader bufferedReader =
122+
new BufferedReader(new CharArrayReader((BODY + "\n").toCharArray()));
123+
124+
BoundedCharArrayWriter buffer = BoundedBuffersFactory.createWriter();
125+
CharBufferSpanPair bufferSpanPair = new CharBufferSpanPair(span, buffer);
126+
127+
BufferedReaderPrintWriterContextAccess.addToBufferedReaderContext(
128+
bufferedReader, bufferSpanPair);
129+
130+
bufferedReader.readLine();
131+
Assertions.assertEquals(BODY, buffer.toString());
132+
}
133+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.opentelemetry.javaagent.instrumentation.hypertrace.servlet.rw.writer;
18+
19+
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
20+
import static net.bytebuddy.matcher.ElementMatchers.named;
21+
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
22+
23+
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
24+
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
25+
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
26+
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
27+
import java.io.PrintWriter;
28+
import java.util.Collections;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Map;
32+
import net.bytebuddy.asm.Advice;
33+
import net.bytebuddy.description.method.MethodDescription;
34+
import net.bytebuddy.description.type.TypeDescription;
35+
import net.bytebuddy.matcher.ElementMatcher;
36+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedCharArrayWriter;
37+
38+
// SPI explicitly added in META-INF/services/...
39+
public class PrintWriterContextAccessInstrumentationModule extends InstrumentationModule {
40+
41+
public PrintWriterContextAccessInstrumentationModule() {
42+
super("test-print-writer");
43+
}
44+
45+
@Override
46+
protected Map<String, String> contextStore() {
47+
return Collections.singletonMap("java.io.PrintWriter", BoundedCharArrayWriter.class.getName());
48+
}
49+
50+
@Override
51+
public List<TypeInstrumentation> typeInstrumentations() {
52+
return Collections.singletonList(new PrintWriterTriggerInstrumentation());
53+
}
54+
55+
class PrintWriterTriggerInstrumentation implements TypeInstrumentation {
56+
57+
@Override
58+
public ElementMatcher<? super TypeDescription> typeMatcher() {
59+
return named("org.BufferedReaderPrintWriterContextAccess");
60+
}
61+
62+
@Override
63+
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
64+
Map<ElementMatcher.Junction<MethodDescription>, String> matchers = new HashMap<>();
65+
matchers.put(
66+
named("addToPrintWriterContext").and(takesArguments(2)).and(isPublic()),
67+
PrintWriterContextAccessInstrumentationModule.class.getName() + "$TestAdvice");
68+
return matchers;
69+
}
70+
}
71+
72+
static class TestAdvice {
73+
@Advice.OnMethodEnter(suppress = Throwable.class)
74+
public static void enter(
75+
@Advice.Argument(0) PrintWriter printWriter,
76+
@Advice.Argument(1) BoundedCharArrayWriter metadata) {
77+
ContextStore<PrintWriter, BoundedCharArrayWriter> contextStore =
78+
InstrumentationContext.get(PrintWriter.class, BoundedCharArrayWriter.class);
79+
contextStore.put(printWriter, metadata);
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)