Skip to content

Commit 575fa1f

Browse files
committed
Add test for blob channels, remove duplicated call in BlobWriterChannelImpl
1 parent abb421e commit 575fa1f

3 files changed

Lines changed: 361 additions & 1 deletion

File tree

gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriterChannelImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class BlobWriterChannelImpl implements BlobWriteChannel {
5555
this.options = options;
5656
this.blobInfo = blobInfo;
5757
initTransients();
58-
uploadId = options.storageRpc().open(storageObject, optionsMap);
58+
uploadId = storageRpc.open(storageObject, optionsMap);
5959
}
6060

6161
private void writeObject(ObjectOutputStream out) throws IOException {
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
* Copyright 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.gcloud.storage;
18+
19+
import static org.junit.Assert.assertArrayEquals;
20+
import static org.junit.Assert.assertTrue;
21+
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.fail;
23+
24+
import com.google.common.collect.ImmutableMap;
25+
import com.google.gcloud.RetryParams;
26+
import com.google.gcloud.spi.StorageRpc;
27+
28+
import org.easymock.EasyMock;
29+
import org.junit.Test;
30+
import org.junit.Before;
31+
32+
import java.io.IOException;
33+
import java.nio.ByteBuffer;
34+
import java.util.Arrays;
35+
import java.util.Map;
36+
import java.util.Random;
37+
38+
public class BlobReadChannelTest {
39+
40+
private static final String BUCKET_NAME = "b";
41+
private static final String BLOB_NAME = "n";
42+
private static final BlobInfo BLOB_INFO = BlobInfo.of(BUCKET_NAME, BLOB_NAME);
43+
private static final Map<StorageRpc.Option, ?> EMPTY_RPC_OPTIONS = ImmutableMap.of();
44+
private static final int DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024;
45+
private static final int CUSTOM_CHUNK_SIZE = 2 * 1024 * 1024;
46+
private static final Random RANDOM = new Random();
47+
48+
private StorageOptions optionsMock;
49+
private StorageRpc storageRpcMock;
50+
private BlobReadChannelImpl reader;
51+
52+
@Before
53+
public void setUp() throws IOException, InterruptedException {
54+
optionsMock = EasyMock.createMock(StorageOptions.class);
55+
storageRpcMock = EasyMock.createMock(StorageRpc.class);
56+
}
57+
58+
@Test
59+
public void testCreate() {
60+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
61+
EasyMock.replay(optionsMock);
62+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
63+
assertTrue(reader.isOpen());
64+
}
65+
66+
@Test
67+
public void testReadSmall() throws IOException {
68+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
69+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
70+
EasyMock.replay(optionsMock);
71+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
72+
byte[] result = randomByteArray(DEFAULT_CHUNK_SIZE);
73+
ByteBuffer readBuffer = ByteBuffer.allocate(42);
74+
EasyMock
75+
.expect(storageRpcMock.read(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS, 0, DEFAULT_CHUNK_SIZE))
76+
.andReturn(result);
77+
EasyMock.replay(storageRpcMock);
78+
reader.read(readBuffer);
79+
assertArrayEquals(Arrays.copyOf(result, readBuffer.capacity()), readBuffer.array());
80+
}
81+
82+
@Test
83+
public void testReadBuffered() throws IOException {
84+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
85+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
86+
EasyMock.replay(optionsMock);
87+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
88+
byte[] result = randomByteArray(DEFAULT_CHUNK_SIZE);
89+
ByteBuffer firstReadBuffer = ByteBuffer.allocate(42);
90+
ByteBuffer secondReadBuffer = ByteBuffer.allocate(42);
91+
EasyMock
92+
.expect(storageRpcMock.read(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS, 0, DEFAULT_CHUNK_SIZE))
93+
.andReturn(result);
94+
EasyMock.replay(storageRpcMock);
95+
reader.read(firstReadBuffer);
96+
reader.read(secondReadBuffer);
97+
assertArrayEquals(Arrays.copyOf(result, firstReadBuffer.capacity()), firstReadBuffer.array());
98+
assertArrayEquals(
99+
Arrays.copyOfRange(result, firstReadBuffer.capacity(), firstReadBuffer.capacity()
100+
+ secondReadBuffer.capacity()),
101+
secondReadBuffer.array());
102+
}
103+
104+
@Test
105+
public void testReadBig() throws IOException {
106+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
107+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries()).times(2);
108+
EasyMock.replay(optionsMock);
109+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
110+
reader.chunkSize(CUSTOM_CHUNK_SIZE);
111+
byte[] firstResult = randomByteArray(DEFAULT_CHUNK_SIZE);
112+
byte[] secondResult = randomByteArray(DEFAULT_CHUNK_SIZE);
113+
ByteBuffer firstReadBuffer = ByteBuffer.allocate(DEFAULT_CHUNK_SIZE);
114+
ByteBuffer secondReadBuffer = ByteBuffer.allocate(42);
115+
EasyMock
116+
.expect(storageRpcMock.read(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS, 0, DEFAULT_CHUNK_SIZE))
117+
.andReturn(firstResult);
118+
EasyMock
119+
.expect(
120+
storageRpcMock.read(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS, DEFAULT_CHUNK_SIZE,
121+
CUSTOM_CHUNK_SIZE))
122+
.andReturn(secondResult);
123+
EasyMock.expectLastCall();
124+
EasyMock.replay(storageRpcMock);
125+
reader.read(firstReadBuffer);
126+
reader.read(secondReadBuffer);
127+
assertArrayEquals(firstResult, firstReadBuffer.array());
128+
assertArrayEquals(Arrays.copyOf(secondResult, secondReadBuffer.capacity()),
129+
secondReadBuffer.array());
130+
}
131+
132+
@Test
133+
public void testReadFinish() throws IOException {
134+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
135+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
136+
EasyMock.replay(optionsMock);
137+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
138+
byte[] result = {};
139+
ByteBuffer readBuffer = ByteBuffer.allocate(DEFAULT_CHUNK_SIZE);
140+
EasyMock
141+
.expect(storageRpcMock.read(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS, 0, DEFAULT_CHUNK_SIZE))
142+
.andReturn(result);
143+
EasyMock.replay(storageRpcMock);
144+
assertEquals(-1, reader.read(readBuffer));
145+
}
146+
147+
@Test
148+
public void testSeek() throws IOException {
149+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
150+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
151+
EasyMock.replay(optionsMock);
152+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
153+
reader.seek(42);
154+
byte[] result = randomByteArray(DEFAULT_CHUNK_SIZE);
155+
ByteBuffer readBuffer = ByteBuffer.allocate(DEFAULT_CHUNK_SIZE);
156+
EasyMock
157+
.expect(storageRpcMock.read(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS, 42, DEFAULT_CHUNK_SIZE))
158+
.andReturn(result);
159+
EasyMock.replay(storageRpcMock);
160+
reader.read(readBuffer);
161+
assertArrayEquals(result, readBuffer.array());
162+
}
163+
164+
@Test
165+
public void testClose() throws IOException {
166+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
167+
EasyMock.replay(optionsMock);
168+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
169+
assertTrue(reader.isOpen());
170+
reader.close();
171+
assertTrue(!reader.isOpen());
172+
}
173+
174+
@Test
175+
public void testReadClosed() {
176+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
177+
EasyMock.replay(optionsMock);
178+
reader = new BlobReadChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
179+
reader.close();
180+
try {
181+
ByteBuffer readBuffer = ByteBuffer.allocate(DEFAULT_CHUNK_SIZE);
182+
reader.read(readBuffer);
183+
fail("Expected BlobReadChannel read to throw IOException");
184+
} catch (IOException ex) {
185+
// expected
186+
}
187+
}
188+
189+
private static byte[] randomByteArray(int size) {
190+
byte[] byteArray = new byte[size];
191+
RANDOM.nextBytes(byteArray);
192+
return byteArray;
193+
}
194+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.gcloud.storage;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertArrayEquals;
21+
import static org.junit.Assert.assertTrue;
22+
import static org.junit.Assert.fail;
23+
24+
import com.google.common.collect.ImmutableMap;
25+
import com.google.gcloud.RetryParams;
26+
import com.google.gcloud.spi.StorageRpc;
27+
28+
import org.easymock.Capture;
29+
import org.easymock.EasyMock;
30+
import org.junit.Test;
31+
import org.junit.Before;
32+
33+
import java.io.IOException;
34+
import java.nio.ByteBuffer;
35+
import java.util.Arrays;
36+
import java.util.Map;
37+
import java.util.Random;
38+
39+
public class BlobWriterChannelTest {
40+
41+
private static final String BUCKET_NAME = "b";
42+
private static final String BLOB_NAME = "n";
43+
private static final String UPLOAD_ID = "uploadid";
44+
private static final BlobInfo BLOB_INFO = BlobInfo.of(BUCKET_NAME, BLOB_NAME);
45+
private static final Map<StorageRpc.Option, ?> EMPTY_RPC_OPTIONS = ImmutableMap.of();
46+
private static final int MIN_CHUNK_SIZE = 256 * 1024;
47+
private static final int DEFAULT_CHUNK_SIZE = 8 * MIN_CHUNK_SIZE;
48+
private static final int CUSTOM_CHUNK_SIZE = 4 * MIN_CHUNK_SIZE;
49+
private static final Random RANDOM = new Random();
50+
51+
private StorageOptions optionsMock;
52+
private StorageRpc storageRpcMock;
53+
private BlobWriterChannelImpl writer;
54+
55+
@Before
56+
public void setUp() throws IOException, InterruptedException {
57+
optionsMock = EasyMock.createMock(StorageOptions.class);
58+
storageRpcMock = EasyMock.createMock(StorageRpc.class);
59+
}
60+
61+
@Test
62+
public void testCreate() {
63+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
64+
EasyMock.replay(optionsMock);
65+
EasyMock.expect(storageRpcMock.open(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS)).andReturn(UPLOAD_ID);
66+
EasyMock.replay(storageRpcMock);
67+
writer = new BlobWriterChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
68+
assertTrue(writer.isOpen());
69+
}
70+
71+
@Test
72+
public void testWriteWithoutFlush() throws IOException {
73+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
74+
EasyMock.replay(optionsMock);
75+
EasyMock.expect(storageRpcMock.open(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS)).andReturn(UPLOAD_ID);
76+
EasyMock.replay(storageRpcMock);
77+
writer = new BlobWriterChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
78+
assertEquals(MIN_CHUNK_SIZE, writer.write(ByteBuffer.allocate(MIN_CHUNK_SIZE)));
79+
}
80+
81+
@Test
82+
public void testWriteWithFlush() throws IOException {
83+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
84+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
85+
EasyMock.replay(optionsMock);
86+
EasyMock.expect(storageRpcMock.open(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS)).andReturn(UPLOAD_ID);
87+
Capture<byte[]> capturedBuffer = Capture.newInstance();
88+
storageRpcMock.write(EasyMock.eq(UPLOAD_ID), EasyMock.capture(capturedBuffer), EasyMock.eq(0),
89+
EasyMock.eq(BLOB_INFO.toPb()), EasyMock.eq(0L), EasyMock.eq(CUSTOM_CHUNK_SIZE),
90+
EasyMock.eq(false));
91+
EasyMock.expectLastCall();
92+
EasyMock.replay(storageRpcMock);
93+
writer = new BlobWriterChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
94+
writer.chunkSize(CUSTOM_CHUNK_SIZE);
95+
ByteBuffer buffer = randomBuffer(CUSTOM_CHUNK_SIZE);
96+
assertEquals(CUSTOM_CHUNK_SIZE, writer.write(buffer));
97+
assertArrayEquals(buffer.array(), capturedBuffer.getValue());
98+
}
99+
100+
@Test
101+
public void testCloseWithoutFlush() throws IOException {
102+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
103+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
104+
EasyMock.replay(optionsMock);
105+
EasyMock.expect(storageRpcMock.open(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS)).andReturn(UPLOAD_ID);
106+
Capture<byte[]> capturedBuffer = Capture.newInstance();
107+
storageRpcMock.write(EasyMock.eq(UPLOAD_ID), EasyMock.capture(capturedBuffer), EasyMock.eq(0),
108+
EasyMock.eq(BLOB_INFO.toPb()), EasyMock.eq(0L), EasyMock.eq(0), EasyMock.eq(true));
109+
EasyMock.expectLastCall();
110+
EasyMock.replay(storageRpcMock);
111+
writer = new BlobWriterChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
112+
assertTrue(writer.isOpen());
113+
writer.close();
114+
assertArrayEquals(new byte[0], capturedBuffer.getValue());
115+
assertTrue(!writer.isOpen());
116+
}
117+
118+
@Test
119+
public void testCloseWithFlush() throws IOException {
120+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
121+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
122+
EasyMock.replay(optionsMock);
123+
EasyMock.expect(storageRpcMock.open(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS)).andReturn(UPLOAD_ID);
124+
Capture<byte[]> capturedBuffer = Capture.newInstance();
125+
ByteBuffer buffer = randomBuffer(MIN_CHUNK_SIZE);
126+
storageRpcMock.write(EasyMock.eq(UPLOAD_ID), EasyMock.capture(capturedBuffer), EasyMock.eq(0),
127+
EasyMock.eq(BLOB_INFO.toPb()), EasyMock.eq(0L), EasyMock.eq(MIN_CHUNK_SIZE),
128+
EasyMock.eq(true));
129+
EasyMock.expectLastCall();
130+
EasyMock.replay(storageRpcMock);
131+
writer = new BlobWriterChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
132+
assertTrue(writer.isOpen());
133+
writer.write(buffer);
134+
writer.close();
135+
assertEquals(DEFAULT_CHUNK_SIZE, capturedBuffer.getValue().length);
136+
assertArrayEquals(buffer.array(), Arrays.copyOf(capturedBuffer.getValue(), MIN_CHUNK_SIZE));
137+
assertTrue(!writer.isOpen());
138+
}
139+
140+
@Test
141+
public void testWriteClosed() throws IOException {
142+
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
143+
EasyMock.expect(optionsMock.retryParams()).andReturn(RetryParams.noRetries());
144+
EasyMock.replay(optionsMock);
145+
EasyMock.expect(storageRpcMock.open(BLOB_INFO.toPb(), EMPTY_RPC_OPTIONS)).andReturn(UPLOAD_ID);
146+
Capture<byte[]> capturedBuffer = Capture.newInstance();
147+
storageRpcMock.write(EasyMock.eq(UPLOAD_ID), EasyMock.capture(capturedBuffer), EasyMock.eq(0),
148+
EasyMock.eq(BLOB_INFO.toPb()), EasyMock.eq(0L), EasyMock.eq(0), EasyMock.eq(true));
149+
EasyMock.expectLastCall();
150+
EasyMock.replay(storageRpcMock);
151+
writer = new BlobWriterChannelImpl(optionsMock, BLOB_INFO, EMPTY_RPC_OPTIONS);
152+
writer.close();
153+
try {
154+
writer.write(ByteBuffer.allocate(MIN_CHUNK_SIZE));
155+
fail("Expected BlobWriteChannel write to throw IOException");
156+
} catch (IOException ex) {
157+
// expected
158+
}
159+
}
160+
161+
private static ByteBuffer randomBuffer(int size) {
162+
byte[] byteArray = new byte[size];
163+
RANDOM.nextBytes(byteArray);
164+
return ByteBuffer.wrap(byteArray);
165+
}
166+
}

0 commit comments

Comments
 (0)