Skip to content

Commit bbc4aef

Browse files
authored
Adds test cases for readVectored() (#284)
1 parent b89d41e commit bbc4aef

File tree

24 files changed

+649
-125
lines changed

24 files changed

+649
-125
lines changed

common/src/main/java/software/amazon/s3/analyticsaccelerator/request/ReadMode.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,35 @@
1515
*/
1616
package software.amazon.s3.analyticsaccelerator.request;
1717

18+
import lombok.AllArgsConstructor;
19+
1820
/**
1921
* Enum to help with the annotation of reads. We mark reads SYNC when they were triggered by a
2022
* synchronous read or ASYNC when they were to do logical or physical prefetching.
2123
*/
24+
@AllArgsConstructor
2225
public enum ReadMode {
23-
SYNC,
24-
ASYNC,
25-
SMALL_OBJECT_PREFETCH;
26+
SYNC(true),
27+
ASYNC(true),
28+
SMALL_OBJECT_PREFETCH(true),
29+
SEQUENTIAL_FILE_PREFETCH(true),
30+
DICTIONARY_PREFETCH(false),
31+
COLUMN_PREFETCH(false),
32+
REMAINING_COLUMN_PREFETCH(false),
33+
PREFETCH_TAIL(false),
34+
READ_VECTORED(false);
35+
36+
private final boolean allowRequestExtension;
37+
38+
/**
39+
* Should requests be extended for this read mode?
40+
*
41+
* <p>When the read is from the parquet prefetcher or readVectored(), we know the exact ranges we
42+
* want to read, so in this case don't extend the ranges.
43+
*
44+
* @return true if requests should be extended
45+
*/
46+
public boolean allowRequestExtension() {
47+
return allowRequestExtension;
48+
}
2649
}

common/src/main/java/software/amazon/s3/analyticsaccelerator/util/MetricKey.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ public enum MetricKey {
3535
/**
3636
* Tracks the number of cache misses. Incremented when requested block is not found in the cache
3737
*/
38-
CACHE_MISS("CacheMiss");
38+
CACHE_MISS("CacheMiss"),
39+
40+
/** Counts number of GET requests made. */
41+
GET_REQUEST_COUNT("GetRequestCount"),
42+
43+
/** Counts number of HEAD requests made. */
44+
HEAD_REQUEST_COUNT("HeadRequestCount");
3945

4046
/** The string name representation of the metric. */
4147
private final String name;

common/src/test/java/software/amazon/s3/analyticsaccelerator/common/MetricKeyTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ public void testMetricKeyNames() {
2727
assertEquals("MemoryUsage", MetricKey.MEMORY_USAGE.getName());
2828
assertEquals("CacheHit", MetricKey.CACHE_HIT.getName());
2929
assertEquals("CacheMiss", MetricKey.CACHE_MISS.getName());
30+
assertEquals("GetRequestCount", MetricKey.GET_REQUEST_COUNT.getName());
31+
assertEquals("HeadRequestCount", MetricKey.HEAD_REQUEST_COUNT.getName());
3032
}
3133

3234
@Test
3335
public void testEnumValues() {
3436
MetricKey[] values = MetricKey.values();
35-
assertEquals(3, values.length);
37+
assertEquals(5, values.length);
3638
assertEquals(MetricKey.MEMORY_USAGE, values[0]);
3739
assertEquals(MetricKey.CACHE_HIT, values[1]);
3840
assertEquals(MetricKey.CACHE_MISS, values[2]);
41+
assertEquals(MetricKey.GET_REQUEST_COUNT, values[3]);
42+
assertEquals(MetricKey.HEAD_REQUEST_COUNT, values[4]);
3943
}
4044
}

input-stream/src/integrationTest/java/software/amazon/s3/analyticsaccelerator/access/IntegrationTestBase.java

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@
2727

2828
import java.io.IOException;
2929
import java.io.InputStream;
30-
import java.nio.ByteBuffer;
3130
import java.security.SecureRandom;
3231
import java.util.*;
3332
import java.util.concurrent.*;
3433
import java.util.concurrent.atomic.AtomicReference;
35-
import java.util.function.IntFunction;
3634
import java.util.stream.Stream;
3735
import lombok.NonNull;
3836
import org.junit.jupiter.api.AfterEach;
@@ -45,7 +43,6 @@
4543
import software.amazon.awssdk.services.s3.S3AsyncClient;
4644
import software.amazon.awssdk.services.s3.model.S3Exception;
4745
import software.amazon.s3.analyticsaccelerator.S3SeekableInputStream;
48-
import software.amazon.s3.analyticsaccelerator.common.ObjectRange;
4946
import software.amazon.s3.analyticsaccelerator.util.OpenStreamInformation;
5047
import software.amazon.s3.analyticsaccelerator.util.S3URI;
5148

@@ -187,58 +184,6 @@ protected void testChangingEtagMidStream(
187184
}
188185
}
189186

190-
/**
191-
* This test verifies that the data in the buffers is the same when a file is read through
192-
* readVectored() vs stream.read(buf[], off, len).
193-
*
194-
* @param s3ClientKind S3 client kind to use
195-
* @param s3Object S3 object to read
196-
* @param streamReadPatternKind stream read pattern to apply
197-
* @param AALInputStreamConfigurationKind configuration kind
198-
* @param allocate method to allocate the buffer, can be direct or non-direct
199-
* @throws IOException on any IOException
200-
*/
201-
protected void testReadVectored(
202-
@NonNull S3ClientKind s3ClientKind,
203-
@NonNull S3Object s3Object,
204-
@NonNull StreamReadPatternKind streamReadPatternKind,
205-
@NonNull AALInputStreamConfigurationKind AALInputStreamConfigurationKind,
206-
@NonNull IntFunction<ByteBuffer> allocate)
207-
throws IOException {
208-
209-
try (S3AALClientStreamReader s3AALClientStreamReader =
210-
this.createS3AALClientStreamReader(s3ClientKind, AALInputStreamConfigurationKind)) {
211-
212-
S3SeekableInputStream s3SeekableInputStream =
213-
s3AALClientStreamReader.createReadStream(s3Object, OpenStreamInformation.DEFAULT);
214-
215-
List<ObjectRange> objectRanges = new ArrayList<>();
216-
objectRanges.add(new ObjectRange(new CompletableFuture<>(), 50, 500));
217-
objectRanges.add(new ObjectRange(new CompletableFuture<>(), 1000, 800));
218-
objectRanges.add(new ObjectRange(new CompletableFuture<>(), 4000, 5000));
219-
220-
s3SeekableInputStream.readVectored(
221-
objectRanges,
222-
allocate,
223-
(buffer) -> {
224-
LOG.debug("Release buffer of length {}: {}", buffer.limit(), buffer);
225-
});
226-
227-
for (ObjectRange objectRange : objectRanges) {
228-
ByteBuffer byteBuffer = objectRange.getByteBuffer().join();
229-
230-
S3SeekableInputStream verificationStream =
231-
s3AALClientStreamReader.createReadStream(s3Object, OpenStreamInformation.DEFAULT);
232-
verificationStream.seek(objectRange.getOffset());
233-
byte[] buffer = new byte[objectRange.getLength()];
234-
int readBytes = verificationStream.read(buffer, 0, buffer.length);
235-
236-
assertEquals(readBytes, buffer.length);
237-
verifyBufferContentsEqual(byteBuffer, buffer);
238-
}
239-
}
240-
}
241-
242187
/**
243188
* Used to read and assert helps when we want to run it in a lambda.
244189
*
@@ -254,18 +199,6 @@ private void readAndAssert(S3SeekableInputStream stream, byte[] buffer, int offs
254199
assertEquals(readBytes, len);
255200
}
256201

257-
/**
258-
* Verify the contents of two buffers are equal
259-
*
260-
* @param buffer ByteBuffer to verify contents for
261-
* @param expected expected contents in byte buffer
262-
*/
263-
private void verifyBufferContentsEqual(ByteBuffer buffer, byte[] expected) {
264-
for (int i = 0; i < expected.length; i++) {
265-
assertEquals(buffer.get(i), expected[i]);
266-
}
267-
}
268-
269202
/**
270203
* Tests to make sure if we have read our whole object we pass and return our cached data even if
271204
* the etag has changed after the read is complete

0 commit comments

Comments
 (0)