1616package software .amazon .awssdk .services .s3 .checksums ;
1717
1818import static org .junit .Assert .assertArrayEquals ;
19- import static org .junit .Assert .assertEquals ;
2019import static org .junit .Assert .assertFalse ;
2120import static org .junit .Assert .assertTrue ;
2221import static org .junit .Assert .fail ;
2322
23+ import java .io .ByteArrayOutputStream ;
24+ import java .io .IOException ;
25+ import java .io .UncheckedIOException ;
2426import java .nio .ByteBuffer ;
2527import java .util .ArrayList ;
2628import java .util .Arrays ;
3133import org .reactivestreams .Subscriber ;
3234import org .reactivestreams .Subscription ;
3335import software .amazon .awssdk .core .checksums .Md5Checksum ;
36+ import software .amazon .awssdk .utils .BinaryUtils ;
3437
3538/**
3639 * Unit test for ChecksumValidatingPublisher
@@ -39,6 +42,7 @@ public class ChecksumValidatingPublisherTest {
3942 private static int TEST_DATA_SIZE = 32 ; // size of the test data, in bytes
4043 private static final int CHECKSUM_SIZE = 16 ;
4144 private static byte [] testData ;
45+ private static byte [] testDataWithoutChecksum ;
4246
4347 @ BeforeClass
4448 public static void populateData () {
@@ -52,34 +56,55 @@ public static void populateData() {
5256 for (int i = 0 ; i < CHECKSUM_SIZE ; i ++) {
5357 testData [TEST_DATA_SIZE + i ] = checksumBytes [i ];
5458 }
59+
60+ testDataWithoutChecksum = Arrays .copyOfRange (testData , 0 , TEST_DATA_SIZE );
5561 }
5662
5763 @ Test
5864 public void testSinglePacket () {
5965 final TestPublisher driver = new TestPublisher ();
60- final TestSubscriber s = new TestSubscriber (Arrays . copyOfRange ( testData , 0 , TEST_DATA_SIZE ) );
66+ final TestSubscriber s = new TestSubscriber ();
6167 final ChecksumValidatingPublisher p = new ChecksumValidatingPublisher (driver , new Md5Checksum (), TEST_DATA_SIZE + CHECKSUM_SIZE );
6268 p .subscribe (s );
6369
6470 driver .doOnNext (ByteBuffer .wrap (testData ));
6571 driver .doOnComplete ();
6672
73+ assertArrayEquals (testDataWithoutChecksum , s .receivedData ());
6774 assertTrue (s .hasCompleted ());
6875 assertFalse (s .isOnErrorCalled ());
6976 }
7077
78+ @ Test
79+ public void testLastChecksumByteCorrupted () {
80+ TestPublisher driver = new TestPublisher ();
81+
82+ TestSubscriber s = new TestSubscriber ();
83+ ChecksumValidatingPublisher p = new ChecksumValidatingPublisher (driver , new Md5Checksum (), TEST_DATA_SIZE + CHECKSUM_SIZE );
84+ p .subscribe (s );
85+
86+ byte [] incorrectChecksumData = Arrays .copyOfRange (testData , 0 , TEST_DATA_SIZE );
87+ incorrectChecksumData [TEST_DATA_SIZE - 1 ] = (byte ) ~incorrectChecksumData [TEST_DATA_SIZE - 1 ];
88+ driver .doOnNext (ByteBuffer .wrap (incorrectChecksumData ));
89+ driver .doOnComplete ();
90+
91+ assertFalse (s .hasCompleted ());
92+ assertTrue (s .isOnErrorCalled ());
93+ }
94+
7195 @ Test
7296 public void testTwoPackets () {
7397 for (int i = 1 ; i < TEST_DATA_SIZE + CHECKSUM_SIZE - 1 ; i ++) {
7498 final TestPublisher driver = new TestPublisher ();
75- final TestSubscriber s = new TestSubscriber (Arrays . copyOfRange ( testData , 0 , TEST_DATA_SIZE ) );
99+ final TestSubscriber s = new TestSubscriber ();
76100 final ChecksumValidatingPublisher p = new ChecksumValidatingPublisher (driver , new Md5Checksum (), TEST_DATA_SIZE + CHECKSUM_SIZE );
77101 p .subscribe (s );
78102
79103 driver .doOnNext (ByteBuffer .wrap (testData , 0 , i ));
80104 driver .doOnNext (ByteBuffer .wrap (testData , i , TEST_DATA_SIZE + CHECKSUM_SIZE - i ));
81105 driver .doOnComplete ();
82106
107+ assertArrayEquals (testDataWithoutChecksum , s .receivedData ());
83108 assertTrue (s .hasCompleted ());
84109 assertFalse (s .isOnErrorCalled ());
85110 }
@@ -89,7 +114,7 @@ public void testTwoPackets() {
89114 public void testTinyPackets () {
90115 for (int packetSize = 1 ; packetSize < CHECKSUM_SIZE ; packetSize ++) {
91116 final TestPublisher driver = new TestPublisher ();
92- final TestSubscriber s = new TestSubscriber (Arrays . copyOfRange ( testData , 0 , TEST_DATA_SIZE ) );
117+ final TestSubscriber s = new TestSubscriber ();
93118 final ChecksumValidatingPublisher p = new ChecksumValidatingPublisher (driver , new Md5Checksum (), TEST_DATA_SIZE + CHECKSUM_SIZE );
94119 p .subscribe (s );
95120 int currOffset = 0 ;
@@ -100,6 +125,7 @@ public void testTinyPackets() {
100125 }
101126 driver .doOnComplete ();
102127
128+ assertArrayEquals (testDataWithoutChecksum , s .receivedData ());
103129 assertTrue (s .hasCompleted ());
104130 assertFalse (s .isOnErrorCalled ());
105131 }
@@ -109,7 +135,7 @@ public void testTinyPackets() {
109135 public void testUnknownLength () {
110136 // When the length is unknown, the last 16 bytes are treated as a checksum, but are later ignored when completing
111137 final TestPublisher driver = new TestPublisher ();
112- final TestSubscriber s = new TestSubscriber (Arrays . copyOfRange ( testData , 0 , TEST_DATA_SIZE ) );
138+ final TestSubscriber s = new TestSubscriber ();
113139 final ChecksumValidatingPublisher p = new ChecksumValidatingPublisher (driver , new Md5Checksum (), 0 );
114140 p .subscribe (s );
115141
@@ -122,6 +148,7 @@ public void testUnknownLength() {
122148 driver .doOnNext (ByteBuffer .wrap (randomChecksumData ));
123149 driver .doOnComplete ();
124150
151+ assertArrayEquals (testDataWithoutChecksum , s .receivedData ());
125152 assertTrue (s .hasCompleted ());
126153 assertFalse (s .isOnErrorCalled ());
127154 }
@@ -130,7 +157,7 @@ public void testUnknownLength() {
130157 public void checksumValidationFailure_throwsSdkClientException_NotNPE () {
131158 final byte [] incorrectData = new byte [0 ];
132159 final TestPublisher driver = new TestPublisher ();
133- final TestSubscriber s = new TestSubscriber (Arrays . copyOfRange ( incorrectData , 0 , TEST_DATA_SIZE ) );
160+ final TestSubscriber s = new TestSubscriber ();
134161 final ChecksumValidatingPublisher p = new ChecksumValidatingPublisher (driver , new Md5Checksum (), TEST_DATA_SIZE + CHECKSUM_SIZE );
135162 p .subscribe (s );
136163
@@ -142,13 +169,11 @@ public void checksumValidationFailure_throwsSdkClientException_NotNPE() {
142169 }
143170
144171 private class TestSubscriber implements Subscriber <ByteBuffer > {
145- final byte [] expected ;
146172 final List <ByteBuffer > received ;
147173 boolean completed ;
148174 boolean onErrorCalled ;
149175
150- TestSubscriber (byte [] expected ) {
151- this .expected = expected ;
176+ TestSubscriber () {
152177 this .received = new ArrayList <>();
153178 this .completed = false ;
154179 }
@@ -172,17 +197,21 @@ public void onError(Throwable t) {
172197
173198 @ Override
174199 public void onComplete () {
175- int matchPos = 0 ;
176- for (ByteBuffer buffer : received ) {
177- byte [] bufferData = new byte [buffer .limit () - buffer .position ()];
178- buffer .get (bufferData );
179- assertArrayEquals (Arrays .copyOfRange (expected , matchPos , matchPos + bufferData .length ), bufferData );
180- matchPos += bufferData .length ;
181- }
182- assertEquals (expected .length , matchPos );
183200 completed = true ;
184201 }
185202
203+ public byte [] receivedData () {
204+ try {
205+ ByteArrayOutputStream os = new ByteArrayOutputStream ();
206+ for (ByteBuffer buffer : received ) {
207+ os .write (BinaryUtils .copyBytesFrom (buffer ));
208+ }
209+ return os .toByteArray ();
210+ } catch (IOException e ) {
211+ throw new UncheckedIOException (e );
212+ }
213+ }
214+
186215 public boolean hasCompleted () {
187216 return completed ;
188217 }
0 commit comments