|
16 | 16 |
|
17 | 17 | package com.google.cloud.storage;
|
18 | 18 |
|
| 19 | +import static com.google.cloud.storage.TestUtils.assertAll; |
| 20 | +import static com.google.cloud.storage.TestUtils.xxd; |
19 | 21 | import static com.google.common.truth.Truth.assertThat;
|
| 22 | +import static com.google.common.truth.Truth.assertWithMessage; |
20 | 23 | import static org.junit.Assert.assertThrows;
|
21 | 24 |
|
22 | 25 | import com.google.common.collect.ImmutableList;
|
|
33 | 36 | import java.time.Duration;
|
34 | 37 | import java.time.Instant;
|
35 | 38 | import java.util.Objects;
|
| 39 | +import java.util.Random; |
36 | 40 | import java.util.stream.Stream;
|
37 | 41 | import org.junit.Rule;
|
38 | 42 | import org.junit.Test;
|
@@ -143,4 +147,40 @@ public void fileAssignmentIsRoundRobin() throws IOException {
|
143 | 147 | assertThat(parentDirs).isEqualTo(ImmutableSet.of(tempDir1, tempDir2, tempDir3));
|
144 | 148 | }
|
145 | 149 | }
|
| 150 | + |
| 151 | + @Test |
| 152 | + public void multipleRecoveryFilesForEqualBlobInfoAreAbleToExistConcurrently() throws Exception { |
| 153 | + Path tempDir = temporaryFolder.newFolder(testName.getMethodName()).toPath(); |
| 154 | + RecoveryFileManager rfm = |
| 155 | + RecoveryFileManager.of( |
| 156 | + ImmutableList.of(tempDir), |
| 157 | + path -> ThroughputSink.logged(path.toAbsolutePath().toString(), clock)); |
| 158 | + |
| 159 | + BlobInfo info = BlobInfo.newBuilder("bucket", "object").build(); |
| 160 | + try (RecoveryFile rf1 = rfm.newRecoveryFile(info); |
| 161 | + RecoveryFile rf2 = rfm.newRecoveryFile(info); ) { |
| 162 | + |
| 163 | + Random rand = new Random(467123); |
| 164 | + byte[] bytes1 = DataGenerator.rand(rand).genBytes(7); |
| 165 | + byte[] bytes2 = DataGenerator.rand(rand).genBytes(41); |
| 166 | + try (WritableByteChannel writer = rf1.writer()) { |
| 167 | + writer.write(ByteBuffer.wrap(bytes1)); |
| 168 | + } |
| 169 | + try (WritableByteChannel writer = rf2.writer()) { |
| 170 | + writer.write(ByteBuffer.wrap(bytes2)); |
| 171 | + } |
| 172 | + |
| 173 | + byte[] actual1 = ByteStreams.toByteArray(Files.newInputStream(rf1.getPath())); |
| 174 | + byte[] actual2 = ByteStreams.toByteArray(Files.newInputStream(rf2.getPath())); |
| 175 | + |
| 176 | + String expected1 = xxd(bytes1); |
| 177 | + String expected2 = xxd(bytes2); |
| 178 | + |
| 179 | + String xxd1 = xxd(actual1); |
| 180 | + String xxd2 = xxd(actual2); |
| 181 | + assertAll( |
| 182 | + () -> assertWithMessage("rf1 should contain bytes1").that(xxd1).isEqualTo(expected1), |
| 183 | + () -> assertWithMessage("rf2 should contain bytes2").that(xxd2).isEqualTo(expected2)); |
| 184 | + } |
| 185 | + } |
146 | 186 | }
|
0 commit comments