|
17 | 17 | import org.elasticsearch.common.blobstore.fs.FsBlobStore;
|
18 | 18 | import org.elasticsearch.common.bytes.BytesArray;
|
19 | 19 | import org.elasticsearch.common.io.Streams;
|
20 |
| -import org.elasticsearch.common.io.stream.BytesStreamOutput; |
21 | 20 | import org.elasticsearch.common.util.MockBigArrays;
|
22 | 21 | import org.elasticsearch.common.xcontent.ToXContent;
|
23 | 22 | import org.elasticsearch.common.xcontent.ToXContentFragment;
|
24 | 23 | import org.elasticsearch.common.xcontent.XContentBuilder;
|
25 | 24 | import org.elasticsearch.common.xcontent.XContentParser;
|
26 |
| -import org.elasticsearch.index.translog.BufferedChecksumStreamOutput; |
27 | 25 | import org.elasticsearch.repositories.blobstore.ChecksumBlobStoreFormat;
|
28 | 26 | import org.elasticsearch.test.ESTestCase;
|
29 | 27 |
|
30 | 28 | import java.io.EOFException;
|
31 | 29 | import java.io.IOException;
|
32 | 30 | import java.io.InputStream;
|
33 | 31 | import java.util.Map;
|
| 32 | + |
34 | 33 | import static org.hamcrest.Matchers.containsString;
|
35 | 34 | import static org.hamcrest.Matchers.greaterThan;
|
36 | 35 |
|
@@ -145,24 +144,24 @@ protected BlobStore createTestBlobStore() throws IOException {
|
145 | 144 | }
|
146 | 145 |
|
147 | 146 | protected void randomCorruption(BlobContainer blobContainer, String blobName) throws IOException {
|
148 |
| - byte[] buffer = new byte[(int) blobContainer.listBlobsByPrefix(blobName).get(blobName).length()]; |
149 |
| - long originalChecksum = checksum(buffer); |
| 147 | + final byte[] buffer = new byte[(int) blobContainer.listBlobsByPrefix(blobName).get(blobName).length()]; |
150 | 148 | try (InputStream inputStream = blobContainer.readBlob(blobName)) {
|
151 | 149 | Streams.readFully(inputStream, buffer);
|
152 | 150 | }
|
153 |
| - do { |
154 |
| - int location = randomIntBetween(0, buffer.length - 1); |
155 |
| - buffer[location] = (byte) (buffer[location] ^ 42); |
156 |
| - } while (originalChecksum == checksum(buffer)); |
157 |
| - blobContainer.writeBlob(blobName, new BytesArray(buffer), false); |
158 |
| - } |
159 |
| - |
160 |
| - private long checksum(byte[] buffer) throws IOException { |
161 |
| - try (BytesStreamOutput streamOutput = new BytesStreamOutput()) { |
162 |
| - try (BufferedChecksumStreamOutput checksumOutput = new BufferedChecksumStreamOutput(streamOutput)) { |
163 |
| - checksumOutput.write(buffer); |
164 |
| - return checksumOutput.getChecksum(); |
165 |
| - } |
| 151 | + final BytesArray corruptedBytes; |
| 152 | + final int location = randomIntBetween(0, buffer.length - 1); |
| 153 | + if (randomBoolean()) { |
| 154 | + // flipping bits in a single byte will always invalidate the file: CRC-32 certainly detects all eight-bit-burst errors; we don't |
| 155 | + // checksum the last 8 bytes but we do verify that they contain the checksum preceded by 4 zero bytes so in any case this will |
| 156 | + // be a detectable error: |
| 157 | + buffer[location] = (byte) (buffer[location] ^ between(1, 255)); |
| 158 | + corruptedBytes = new BytesArray(buffer); |
| 159 | + } else { |
| 160 | + // truncation will invalidate the file: the last 12 bytes should start with 8 zero bytes but by construction we won't have |
| 161 | + // another sequence of 8 zero bytes anywhere in the file, let alone such a sequence followed by a correct checksum. |
| 162 | + corruptedBytes = new BytesArray(buffer, 0, location); |
166 | 163 | }
|
| 164 | + blobContainer.writeBlob(blobName, corruptedBytes, false); |
167 | 165 | }
|
| 166 | + |
168 | 167 | }
|
0 commit comments