Skip to content

Commit ba8714b

Browse files
committed
---
yaml --- r: 1095 b: refs/heads/master c: 33e932e h: refs/heads/master i: 1093: 9d7a325 1091: ba1d95e 1087: 286899b v: v3
1 parent 56388e5 commit ba8714b

10 files changed

Lines changed: 319 additions & 15 deletions

File tree

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
---
2-
refs/heads/master: 682848a60389769e66c7a0e4e6f3ec4ac7dad572
2+
refs/heads/master: 33e932e533bc9e8c1ecbe2587d662cc728447162
33
refs/heads/travis: 0fa997e2fc9c6b61b2d91e6d163655aae67d44b6
44
refs/heads/gh-pages: 5a10432ecc75f29812e33a8236c900379509fe99

trunk/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,8 @@ private static void extractFile(ZipInputStream zipIn, File filePath) throws IOEx
524524
}
525525
}
526526

527-
public static void sendQuitRequest(int port) {
527+
public static boolean sendQuitRequest(int port) {
528+
StringBuilder result = new StringBuilder();
528529
try {
529530
URL url = new URL("http", "localhost", port, "/_ah/admin/quit");
530531
HttpURLConnection con = (HttpURLConnection) url.openConnection();
@@ -535,12 +536,14 @@ public static void sendQuitRequest(int port) {
535536
out.write("".getBytes());
536537
out.flush();
537538
InputStream in = con.getInputStream();
538-
while (in.read() != -1) {
539-
// consume input
539+
int currByte = 0;
540+
while ((currByte = in.read()) != -1) {
541+
result.append(((char) currByte));
540542
}
541543
} catch (IOException ignore) {
542544
// ignore
543545
}
546+
return result.toString().startsWith("Shutting down local server");
544547
}
545548

546549
public void stop() throws IOException, InterruptedException {

trunk/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
3636
import com.google.gcloud.datastore.testing.LocalGcdHelper;
3737
import com.google.gcloud.spi.DatastoreRpc;
38+
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException;
3839
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason;
3940
import com.google.gcloud.spi.DatastoreRpcFactory;
4041

@@ -49,9 +50,12 @@
4950
import org.junit.runners.JUnit4;
5051

5152
import java.io.IOException;
53+
import java.util.ArrayList;
5254
import java.util.Collections;
55+
import java.util.HashSet;
5356
import java.util.Iterator;
5457
import java.util.List;
58+
import java.util.Set;
5559

5660
@RunWith(JUnit4.class)
5761
public class DatastoreTest {
@@ -520,7 +524,7 @@ public void testGet() {
520524
}
521525

522526
@Test
523-
public void testGetArray() {
527+
public void testGetArrayNoDeferredResults() {
524528
datastore.put(ENTITY3);
525529
Iterator<Entity> result =
526530
datastore.fetch(KEY1, Key.builder(KEY1).name("bla").build(), KEY2, KEY3).iterator();
@@ -546,7 +550,85 @@ public void testGetArray() {
546550
// expected - no such property
547551
}
548552
assertFalse(result.hasNext());
549-
// TODO(ozarov): construct a test to verify more results
553+
}
554+
555+
public void testGetArrayDeferredResults() throws DatastoreRpcException {
556+
Set<Key> requestedKeys = new HashSet<>();
557+
requestedKeys.add(KEY1);
558+
requestedKeys.add(KEY2);
559+
requestedKeys.add(KEY3);
560+
requestedKeys.add(KEY4);
561+
requestedKeys.add(KEY5);
562+
Iterator<Entity> iter = createDatastoreForDeferredLookup().get(KEY1, KEY2, KEY3, KEY4, KEY5);
563+
Set<Key> keysOfFoundEntities = new HashSet<>();
564+
while (iter.hasNext()) {
565+
keysOfFoundEntities.add(iter.next().key());
566+
}
567+
assertEquals(requestedKeys, keysOfFoundEntities);
568+
}
569+
570+
public void testFetchArrayDeferredResults() throws DatastoreRpcException {
571+
List<Entity> foundEntities =
572+
createDatastoreForDeferredLookup().fetch(KEY1, KEY2, KEY3, KEY4, KEY5);
573+
assertEquals(foundEntities.get(0).key(), KEY1);
574+
assertEquals(foundEntities.get(1).key(), KEY2);
575+
assertEquals(foundEntities.get(2).key(), KEY3);
576+
assertEquals(foundEntities.get(3).key(), KEY4);
577+
assertEquals(foundEntities.get(4).key(), KEY5);
578+
assertEquals(foundEntities.size(), 5);
579+
}
580+
581+
private Datastore createDatastoreForDeferredLookup() throws DatastoreRpcException {
582+
List<DatastoreV1.Key> keysPb = new ArrayList<>();
583+
keysPb.add(KEY1.toPb());
584+
keysPb.add(KEY2.toPb());
585+
keysPb.add(KEY3.toPb());
586+
keysPb.add(KEY4.toPb());
587+
keysPb.add(KEY5.toPb());
588+
List<DatastoreV1.LookupRequest> lookupRequests = new ArrayList<>();
589+
lookupRequests.add(DatastoreV1.LookupRequest.newBuilder().addAllKey(keysPb).build());
590+
lookupRequests.add(
591+
DatastoreV1.LookupRequest.newBuilder()
592+
.addKey(keysPb.get(2))
593+
.addKey(keysPb.get(3))
594+
.addKey(keysPb.get(5))
595+
.build());
596+
lookupRequests.add(DatastoreV1.LookupRequest.newBuilder().addKey(keysPb.get(5)).build());
597+
Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build();
598+
Entity entity5 = Entity.builder(KEY5).set("value", "value").build();
599+
List<DatastoreV1.LookupResponse> lookupResponses = new ArrayList<>();
600+
lookupResponses.add(
601+
DatastoreV1.LookupResponse.newBuilder()
602+
.addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb()))
603+
.addFound(EntityResult.newBuilder().setEntity(entity4.toPb()))
604+
.addDeferred(keysPb.get(2))
605+
.addDeferred(keysPb.get(3))
606+
.addDeferred(keysPb.get(5))
607+
.build());
608+
lookupResponses.add(
609+
DatastoreV1.LookupResponse.newBuilder()
610+
.addFound(EntityResult.newBuilder().setEntity(ENTITY3.toPb()))
611+
.addFound(EntityResult.newBuilder().setEntity(entity4.toPb()))
612+
.addDeferred(keysPb.get(5))
613+
.build());
614+
lookupResponses.add(
615+
DatastoreV1.LookupResponse.newBuilder()
616+
.addFound(EntityResult.newBuilder().setEntity(entity5.toPb()))
617+
.build());
618+
DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class);
619+
DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class);
620+
EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class)))
621+
.andReturn(rpcMock);
622+
for (int i = 0; i < lookupRequests.size(); i++) {
623+
EasyMock.expect(rpcMock.lookup(lookupRequests.get(i))).andReturn(lookupResponses.get(i));
624+
}
625+
EasyMock.replay(rpcFactoryMock, rpcMock);
626+
DatastoreOptions options =
627+
this.options.toBuilder()
628+
.retryParams(RetryParams.getDefaultInstance())
629+
.serviceRpcFactory(rpcFactoryMock)
630+
.build();
631+
return DatastoreFactory.instance().get(options);
550632
}
551633

552634
@Test
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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.datastore;
18+
19+
import static org.junit.Assert.assertFalse;
20+
import static org.junit.Assert.assertTrue;
21+
import static org.junit.Assert.fail;
22+
23+
import com.google.gcloud.datastore.testing.LocalGcdHelper;
24+
25+
import org.junit.Test;
26+
import org.junit.runner.RunWith;
27+
import org.junit.runners.JUnit4;
28+
29+
import java.io.IOException;
30+
import java.net.ServerSocket;
31+
32+
@RunWith(JUnit4.class)
33+
public class LocalGcdHelperTest {
34+
35+
private static final String PROJECT_ID = LocalGcdHelper.DEFAULT_PROJECT_ID;
36+
private static final int PORT = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT);
37+
38+
@Test
39+
public void testFindAvailablePort() {
40+
int chosenPort = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT);
41+
try (ServerSocket tempSocket = new ServerSocket(chosenPort)) {
42+
// success
43+
} catch (IOException e) {
44+
if (chosenPort != LocalGcdHelper.DEFAULT_PORT) {
45+
fail("Chosen port not free, even though LocalGcdHelper claimed it was.");
46+
}
47+
}
48+
}
49+
50+
@Test
51+
public void testSendQuitRequest() throws IOException, InterruptedException {
52+
LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT);
53+
assertTrue(LocalGcdHelper.sendQuitRequest(PORT));
54+
long timeoutMillis = 30000;
55+
long startTime = System.currentTimeMillis();
56+
boolean datastoreActive = LocalGcdHelper.isActive(PROJECT_ID, PORT);
57+
while (datastoreActive && System.currentTimeMillis() - startTime < timeoutMillis) {
58+
datastoreActive = LocalGcdHelper.isActive(PROJECT_ID, PORT);
59+
}
60+
assertFalse(datastoreActive);
61+
assertFalse(LocalGcdHelper.sendQuitRequest(PORT));
62+
gcdHelper.stop();
63+
}
64+
65+
@Test
66+
public void testStartStop() throws IOException, InterruptedException {
67+
LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT);
68+
assertFalse(LocalGcdHelper.isActive("wrong-project-id", PORT));
69+
assertTrue(LocalGcdHelper.isActive(PROJECT_ID, PORT));
70+
gcdHelper.stop();
71+
assertFalse(LocalGcdHelper.isActive(PROJECT_ID, PORT));
72+
}
73+
}

trunk/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public boolean equals(Object obj) {
133133
BatchResponse other = (BatchResponse) obj;
134134
return Objects.equals(deleteResult, other.deleteResult)
135135
&& Objects.equals(updateResult, other.updateResult)
136-
&& Objects.equals(updateResult, other.updateResult);
136+
&& Objects.equals(getResult, other.getResult);
137137
}
138138

139139
/**

trunk/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@
1919
import static com.google.common.base.Preconditions.checkArgument;
2020
import static com.google.common.base.Preconditions.checkNotNull;
2121

22+
import com.google.common.base.MoreObjects;
2223
import com.google.gcloud.storage.Storage.BlobSourceOption;
2324
import com.google.gcloud.storage.Storage.BlobTargetOption;
25+
import com.google.gcloud.storage.Storage.BlobWriteOption;
2426
import com.google.gcloud.storage.Storage.BucketSourceOption;
2527
import com.google.gcloud.storage.Storage.BucketTargetOption;
28+
import java.io.InputStream;
2629

2730
import java.util.ArrayList;
2831
import java.util.Collections;
@@ -172,17 +175,43 @@ public List<Blob> get(String blobName1, String blobName2, String... blobNames) {
172175
}
173176

174177
/**
175-
* Creates a new blob in this bucket.
178+
* Creates a new blob in this bucket. Direct upload is used to upload {@code content}.
179+
* For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)}
180+
* is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are
181+
* computed and used for validating transferred data.
176182
*
177183
* @param blob a blob name
178184
* @param content the blob content
185+
* @param contentType the blob content type. If {@code null} then
186+
* {@value com.google.gcloud.storage.Storage#DEFAULT_CONTENT_TYPE} is used.
179187
* @param options options for blob creation
180188
* @return a complete blob information.
181189
* @throws StorageException upon failure
182190
*/
183-
Blob create(String blob, byte[] content, BlobTargetOption... options) {
184-
BlobId blobId = BlobId.of(info.name(), blob);
185-
return new Blob(storage, storage.create(BlobInfo.builder(blobId).build(), content, options));
191+
public Blob create(String blob, byte[] content, String contentType, BlobTargetOption... options) {
192+
BlobInfo blobInfo = BlobInfo.builder(BlobId.of(info.name(), blob))
193+
.contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build();
194+
return new Blob(storage, storage.create(blobInfo, content, options));
195+
}
196+
197+
/**
198+
* Creates a new blob in this bucket. Direct upload is used to upload {@code content}.
199+
* For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)}
200+
* is recommended as it uses resumable upload.
201+
*
202+
* @param blob a blob name
203+
* @param content the blob content as a stream
204+
* @param contentType the blob content type. If {@code null} then
205+
* {@value com.google.gcloud.storage.Storage#DEFAULT_CONTENT_TYPE} is used.
206+
* @param options options for blob creation
207+
* @return a complete blob information.
208+
* @throws StorageException upon failure
209+
*/
210+
public Blob create(String blob, InputStream content, String contentType,
211+
BlobWriteOption... options) {
212+
BlobInfo blobInfo = BlobInfo.builder(BlobId.of(info.name(), blob))
213+
.contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build();
214+
return new Blob(storage, storage.create(blobInfo, content, options));
186215
}
187216

188217
/**

trunk/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
*/
4747
public interface Storage extends Service<StorageOptions> {
4848

49+
public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
50+
4951
enum PredefinedAcl {
5052
AUTHENTICATED_READ("authenticatedRead"),
5153
ALL_AUTHENTICATED_USERS("allAuthenticatedUsers"),

trunk/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchRequestTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.gcloud.storage.Storage.PredefinedAcl.PUBLIC_READ;
2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertFalse;
22+
import static org.junit.Assert.assertNotEquals;
2223
import static org.junit.Assert.assertTrue;
2324

2425
import com.google.common.collect.Iterables;
@@ -82,4 +83,56 @@ public void testBatchRequest() {
8283
assertTrue(Iterables.isEmpty(get.getValue()));
8384
assertFalse(gets.hasNext());
8485
}
86+
87+
@Test
88+
public void testEquals() {
89+
BatchRequest request = BatchRequest.builder()
90+
.delete("b1", "o1")
91+
.delete("b1", "o2")
92+
.update(BlobInfo.builder("b2", "o1").build())
93+
.update(BlobInfo.builder("b2", "o2").build())
94+
.get("b3", "o1")
95+
.get("b3", "o2")
96+
.build();
97+
BatchRequest requestEquals = BatchRequest.builder()
98+
.delete("b1", "o1")
99+
.delete("b1", "o2")
100+
.update(BlobInfo.builder("b2", "o1").build())
101+
.update(BlobInfo.builder("b2", "o2").build())
102+
.get("b3", "o1")
103+
.get("b3", "o2")
104+
.build();
105+
BatchRequest requestNotEquals1 = BatchRequest.builder()
106+
.delete("b1", "o1")
107+
.delete("b1", "o3")
108+
.update(BlobInfo.builder("b2", "o1").build())
109+
.update(BlobInfo.builder("b2", "o2").build())
110+
.get("b3", "o1")
111+
.get("b3", "o2")
112+
.build();
113+
BatchRequest requestNotEquals2 = BatchRequest.builder()
114+
.delete("b1", "o1")
115+
.delete("b1", "o2")
116+
.update(BlobInfo.builder("b2", "o1").build())
117+
.update(BlobInfo.builder("b2", "o3").build())
118+
.get("b3", "o1")
119+
.get("b3", "o2")
120+
.build();
121+
BatchRequest requestNotEquals3 = BatchRequest.builder()
122+
.delete("b1", "o1")
123+
.delete("b1", "o2")
124+
.update(BlobInfo.builder("b2", "o1").build())
125+
.update(BlobInfo.builder("b2", "o2").build())
126+
.get("b3", "o1")
127+
.get("b3", "o3")
128+
.build();
129+
assertEquals(request, requestEquals);
130+
assertEquals(request.hashCode(), requestEquals.hashCode());
131+
assertNotEquals(request, requestNotEquals1);
132+
assertNotEquals(request.hashCode(), requestNotEquals1.hashCode());
133+
assertNotEquals(request, requestNotEquals2);
134+
assertNotEquals(request.hashCode(), requestNotEquals2.hashCode());
135+
assertNotEquals(request, requestNotEquals3);
136+
assertNotEquals(request.hashCode(), requestNotEquals3.hashCode());
137+
}
85138
}

0 commit comments

Comments
 (0)