|
17 | 17 | import org.elasticsearch.common.geo.GeoPoint;
|
18 | 18 | import org.elasticsearch.common.lucene.BytesRefs;
|
19 | 19 | import org.elasticsearch.common.recycler.Recycler;
|
| 20 | +import org.elasticsearch.common.unit.ByteSizeUnit; |
20 | 21 | import org.elasticsearch.common.util.Maps;
|
21 | 22 | import org.elasticsearch.common.util.PageCacheRecycler;
|
22 | 23 | import org.elasticsearch.core.TimeValue;
|
|
38 | 39 | import java.util.Objects;
|
39 | 40 | import java.util.TreeMap;
|
40 | 41 | import java.util.concurrent.TimeUnit;
|
| 42 | +import java.util.concurrent.atomic.AtomicLong; |
41 | 43 | import java.util.function.Supplier;
|
42 | 44 | import java.util.stream.Collectors;
|
43 | 45 | import java.util.stream.IntStream;
|
|
46 | 48 | import static org.hamcrest.Matchers.containsString;
|
47 | 49 | import static org.hamcrest.Matchers.endsWith;
|
48 | 50 | import static org.hamcrest.Matchers.equalTo;
|
| 51 | +import static org.hamcrest.Matchers.greaterThan; |
49 | 52 | import static org.hamcrest.Matchers.hasSize;
|
50 | 53 | import static org.hamcrest.Matchers.instanceOf;
|
51 | 54 | import static org.hamcrest.Matchers.is;
|
@@ -978,4 +981,52 @@ boolean failOnTooManyNestedExceptions(Throwable throwable) {
|
978 | 981 | assertThat(newEx.getMessage(), equalTo("disk broken"));
|
979 | 982 | assertArrayEquals(newEx.getStackTrace(), rootEx.getStackTrace());
|
980 | 983 | }
|
| 984 | + |
| 985 | + public void testOverflow() { |
| 986 | + final var pageSize = randomFrom(ByteSizeUnit.MB.toIntBytes(1L), ByteSizeUnit.KB.toIntBytes(16)) + between(-1024, 1024); |
| 987 | + final var pagesAllocated = new AtomicLong(); |
| 988 | + |
| 989 | + try (RecyclerBytesStreamOutput output = new RecyclerBytesStreamOutput(new Recycler<>() { |
| 990 | + private final V<BytesRef> page = new V<>() { |
| 991 | + private final BytesRef bytesRef = new BytesRef(new byte[pageSize]); |
| 992 | + |
| 993 | + @Override |
| 994 | + public BytesRef v() { |
| 995 | + return bytesRef; |
| 996 | + } |
| 997 | + |
| 998 | + @Override |
| 999 | + public boolean isRecycled() { |
| 1000 | + return false; |
| 1001 | + } |
| 1002 | + |
| 1003 | + @Override |
| 1004 | + public void close() { |
| 1005 | + pagesAllocated.decrementAndGet(); |
| 1006 | + } |
| 1007 | + }; |
| 1008 | + |
| 1009 | + @Override |
| 1010 | + public V<BytesRef> obtain() { |
| 1011 | + pagesAllocated.incrementAndGet(); |
| 1012 | + return page; |
| 1013 | + } |
| 1014 | + })) { |
| 1015 | + var bytesAllocated = 0; |
| 1016 | + while (bytesAllocated < Integer.MAX_VALUE) { |
| 1017 | + var thisAllocation = between(1, Integer.MAX_VALUE - bytesAllocated); |
| 1018 | + bytesAllocated += thisAllocation; |
| 1019 | + final var expectedPages = ((long) bytesAllocated + pageSize - 1) / pageSize; |
| 1020 | + try { |
| 1021 | + output.skip(thisAllocation); |
| 1022 | + assertThat(pagesAllocated.get(), equalTo(expectedPages)); |
| 1023 | + } catch (IllegalArgumentException e) { |
| 1024 | + assertThat(expectedPages * pageSize, greaterThan((long) Integer.MAX_VALUE)); |
| 1025 | + return; |
| 1026 | + } |
| 1027 | + } |
| 1028 | + } finally { |
| 1029 | + assertThat(pagesAllocated.get(), equalTo(0L)); |
| 1030 | + } |
| 1031 | + } |
981 | 1032 | }
|
0 commit comments