14
14
import org .apache .lucene .util .RamUsageEstimator ;
15
15
import org .elasticsearch .common .breaker .CircuitBreaker ;
16
16
import org .elasticsearch .common .breaker .CircuitBreakingException ;
17
+ import org .elasticsearch .common .io .stream .BytesRefStreamOutput ;
18
+ import org .elasticsearch .common .io .stream .StreamOutput ;
17
19
import org .elasticsearch .common .unit .ByteSizeValue ;
18
20
import org .elasticsearch .common .util .MockBigArrays ;
19
21
import org .elasticsearch .test .ESTestCase ;
22
+ import org .elasticsearch .xcontent .XContentBuilder ;
23
+ import org .elasticsearch .xcontent .json .JsonXContent ;
20
24
25
+ import java .io .IOException ;
26
+ import java .io .UncheckedIOException ;
21
27
import java .util .function .Supplier ;
22
28
23
29
import static org .hamcrest .Matchers .equalTo ;
@@ -34,11 +40,6 @@ public void testAddByte() {
34
40
testAgainstOracle (() -> new TestIteration () {
35
41
final byte b = randomByte ();
36
42
37
- @ Override
38
- public int size () {
39
- return 1 ;
40
- }
41
-
42
43
@ Override
43
44
public void applyToBuilder (BreakingBytesRefBuilder builder ) {
44
45
builder .append (b );
@@ -55,11 +56,6 @@ public void testAddBytesRef() {
55
56
testAgainstOracle (() -> new TestIteration () {
56
57
final BytesRef ref = new BytesRef (randomAlphaOfLengthBetween (1 , 100 ));
57
58
58
- @ Override
59
- public int size () {
60
- return ref .length ;
61
- }
62
-
63
59
@ Override
64
60
public void applyToBuilder (BreakingBytesRefBuilder builder ) {
65
61
builder .append (ref );
@@ -90,11 +86,6 @@ public void testGrow() {
90
86
final int length = between (1 , 100 );
91
87
final byte b = randomByte ();
92
88
93
- @ Override
94
- public int size () {
95
- return length ;
96
- }
97
-
98
89
@ Override
99
90
public void applyToBuilder (BreakingBytesRefBuilder builder ) {
100
91
builder .grow (builder .length () + length );
@@ -111,9 +102,90 @@ public void applyToOracle(BytesRefBuilder oracle) {
111
102
});
112
103
}
113
104
114
- interface TestIteration {
115
- int size ();
105
+ public void testStream () {
106
+ testAgainstOracle (() -> switch (between (0 , 3 )) {
107
+ case 0 -> new XContentTestIteration () {
108
+ @ Override
109
+ protected void apply (XContentBuilder builder ) throws IOException {
110
+ // Noop
111
+ }
112
+
113
+ @ Override
114
+ public String toString () {
115
+ return "noop" ;
116
+ }
117
+ };
118
+ case 1 -> new XContentTestIteration () {
119
+ private final String value = randomAlphanumericOfLength (10 );
120
+
121
+ @ Override
122
+ protected void apply (XContentBuilder builder ) throws IOException {
123
+ builder .value (value );
124
+ }
125
+
126
+ @ Override
127
+ public String toString () {
128
+ return '"' + value + '"' ;
129
+ }
130
+ };
131
+ case 2 -> new XContentTestIteration () {
132
+ private final long value = randomLong ();
133
+
134
+ @ Override
135
+ protected void apply (XContentBuilder builder ) throws IOException {
136
+ builder .value (value );
137
+ }
138
+
139
+ @ Override
140
+ public String toString () {
141
+ return Long .toString (value );
142
+ }
143
+ };
144
+ case 3 -> new XContentTestIteration () {
145
+ private final String name = randomAlphanumericOfLength (5 );
146
+ private final String value = randomAlphanumericOfLength (5 );
147
+
148
+ @ Override
149
+ protected void apply (XContentBuilder builder ) throws IOException {
150
+ builder .startObject ().field (name , value ).endObject ();
151
+ }
152
+
153
+ @ Override
154
+ public String toString () {
155
+ return name + ": " + value ;
156
+ }
157
+ };
158
+ default -> throw new UnsupportedOperationException ();
159
+ });
160
+ }
161
+
162
+ private abstract static class XContentTestIteration implements TestIteration {
163
+ protected abstract void apply (XContentBuilder builder ) throws IOException ;
164
+
165
+ @ Override
166
+ public void applyToBuilder (BreakingBytesRefBuilder builder ) {
167
+ applyToStream (builder .stream ());
168
+ }
169
+
170
+ @ Override
171
+ public void applyToOracle (BytesRefBuilder oracle ) {
172
+ BytesRefStreamOutput out = new BytesRefStreamOutput ();
173
+ applyToStream (out );
174
+ oracle .append (out .get ());
175
+ }
176
+
177
+ private void applyToStream (StreamOutput out ) {
178
+ try {
179
+ try (XContentBuilder builder = new XContentBuilder (JsonXContent .jsonXContent , out )) {
180
+ apply (builder );
181
+ }
182
+ } catch (IOException e ) {
183
+ throw new UncheckedIOException (e );
184
+ }
185
+ }
186
+ }
116
187
188
+ interface TestIteration {
117
189
void applyToBuilder (BreakingBytesRefBuilder builder );
118
190
119
191
void applyToOracle (BytesRefBuilder oracle );
@@ -131,7 +203,11 @@ private void testAgainstOracle(Supplier<TestIteration> iterations) {
131
203
assertThat (builder .bytesRefView (), equalTo (oracle .get ()));
132
204
while (true ) {
133
205
TestIteration iteration = iterations .get ();
134
- int targetSize = builder .length () + iteration .size ();
206
+
207
+ int prevOracle = oracle .length ();
208
+ iteration .applyToOracle (oracle );
209
+ int size = oracle .length () - prevOracle ;
210
+ int targetSize = builder .length () + size ;
135
211
boolean willResize = targetSize >= builder .bytes ().length ;
136
212
if (willResize ) {
137
213
long resizeMemoryUsage = BreakingBytesRefBuilder .SHALLOW_SIZE + ramForArray (builder .bytes ().length );
@@ -143,7 +219,6 @@ private void testAgainstOracle(Supplier<TestIteration> iterations) {
143
219
}
144
220
}
145
221
iteration .applyToBuilder (builder );
146
- iteration .applyToOracle (oracle );
147
222
assertThat (builder .bytesRefView (), equalTo (oracle .get ()));
148
223
assertThat (
149
224
builder .ramBytesUsed (),
0 commit comments