forked from open-telemetry/opentelemetry-java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
W3CBaggagePropagatorFuzzTest.java
153 lines (131 loc) · 4.99 KB
/
W3CBaggagePropagatorFuzzTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.api.baggage.propagation;
import static org.assertj.core.api.Assertions.assertThat;
import com.pholser.junit.quickcheck.From;
import com.pholser.junit.quickcheck.generator.java.lang.AbstractStringGenerator;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
import edu.berkeley.cs.jqf.fuzz.Fuzz;
import edu.berkeley.cs.jqf.fuzz.JQF;
import edu.berkeley.cs.jqf.fuzz.junit.GuidedFuzzing;
import edu.berkeley.cs.jqf.fuzz.random.NoGuidance;
import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageEntryMetadata;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
@SuppressWarnings("SystemOut")
class W3CBaggagePropagatorFuzzTest {
@RunWith(JQF.class)
public static class TestCases {
private final W3CBaggagePropagator baggagePropagator = W3CBaggagePropagator.getInstance();
@Fuzz
public void roundTripRandomValues(String baggageValue, String metadataBlob) {
Baggage baggage =
Baggage.builder()
.put("b", baggageValue, BaggageEntryMetadata.create(metadataBlob))
.build();
Map<String, String> carrier = new HashMap<>();
baggagePropagator.inject(Context.root().with(baggage), carrier, Map::put);
Context extractedContext =
baggagePropagator.extract(Context.root(), carrier, new MapTextMapGetter());
Baggage extractedBaggage = Baggage.fromContext(extractedContext);
assertThat(extractedBaggage).isEqualTo(baggage);
}
/** Test ascii values, to favor values with baggage delimiters in them. */
@Fuzz
public void roundTripAsciiValues(
@From(AsciiGenerator.class) String baggageValue,
@From(AsciiGenerator.class) String metadataBlob) {
Baggage baggage =
Baggage.builder()
.put("b", baggageValue, BaggageEntryMetadata.create(metadataBlob))
.build();
Map<String, String> carrier = new HashMap<>();
baggagePropagator.inject(Context.root().with(baggage), carrier, Map::put);
Context extractedContext =
baggagePropagator.extract(Context.root(), carrier, new MapTextMapGetter());
Baggage extractedBaggage = Baggage.fromContext(extractedContext);
assertThat(extractedBaggage).isEqualTo(baggage);
}
@Fuzz
public void baggageOctet(@From(BaggageOctetGenerator.class) String baggageValue) {
Map<String, String> carrier = new HashMap<>();
carrier.put("baggage", "key=" + baggageValue);
Context context =
baggagePropagator.extract(Context.current(), carrier, new MapTextMapGetter());
Baggage baggage = Baggage.fromContext(context);
String value = baggage.getEntryValue("key");
assertThat(value).isEqualTo(baggageValue);
}
}
// driver methods to avoid having to use the vintage junit engine, and to enable increasing the
// number of iterations:
@Test
void roundTripAsciiFuzzing() {
Result result = runTestCase("roundTripAsciiValues");
assertThat(result.wasSuccessful()).isTrue();
}
@Test
void roundTripFuzzing() {
Result result = runTestCase("roundTripRandomValues");
assertThat(result.wasSuccessful()).isTrue();
}
@Test
void baggageOctetFuzzing() {
Result result = runTestCase("baggageOctet");
assertThat(result.wasSuccessful()).isTrue();
}
private static Result runTestCase(String testCaseName) {
return GuidedFuzzing.run(
TestCases.class, testCaseName, new NoGuidance(10000, System.out), System.out);
}
public static class AsciiGenerator extends AbstractStringGenerator {
@Override
protected int nextCodePoint(SourceOfRandomness random) {
return random.nextChar(' ', '~');
}
@Override
protected boolean codePointInRange(int codePoint) {
return codePoint >= ' ' && codePoint <= '~';
}
}
private static class MapTextMapGetter implements TextMapGetter<Map<String, String>> {
@Override
public Iterable<String> keys(Map<String, String> carrier) {
return carrier.keySet();
}
@Nullable
@Override
public String get(Map<String, String> carrier, String key) {
return carrier.get(key);
}
}
public static class BaggageOctetGenerator extends AbstractStringGenerator {
private static final Set<Character> excluded =
new HashSet<>(Arrays.asList(' ', '"', ',', ';', '\\', '%'));
@Override
protected int nextCodePoint(SourceOfRandomness random) {
while (true) {
char c = random.nextChar(' ', '~');
if (!excluded.contains(c)) {
return c;
}
}
}
@Override
protected boolean codePointInRange(int codePoint) {
return !excluded.contains((char) codePoint);
}
}
}