Skip to content

Commit 5455f83

Browse files
committed
---
yaml --- r: 959 b: refs/heads/master c: b455911 h: refs/heads/master i: 957: 406cc3b 955: b896887 951: f31bde7 943: 3d7bb3e 927: a5f39c0 895: b92f5a2 v: v3
1 parent 26aea92 commit 5455f83

9 files changed

Lines changed: 168 additions & 31 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: b52ded39f922ffbab63be18944d50a108185bbc5
2+
refs/heads/master: b455911f706290c689e7461359dcfa70f9c94a04
33
refs/heads/travis: 0fa997e2fc9c6b61b2d91e6d163655aae67d44b6
44
refs/heads/gh-pages: 5a10432ecc75f29812e33a8236c900379509fe99

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.gcloud.datastore;
17+
package com.google.gcloud.datastore.testing;
1818

1919
import static java.nio.charset.StandardCharsets.UTF_8;
2020

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
/**
18+
* A testing helper for Google Cloud Datastore.
19+
*
20+
* <p>A simple usage example:
21+
* <p>Before the test:
22+
* <pre> {@code
23+
* LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT_NUMBER);
24+
* DatastoreOptions options = DatastoreOptions.builder()
25+
* .projectId(PROJECT_ID)
26+
* .host("localhost:8080")
27+
* .build();
28+
* Datastore localDatastore = DatastoreFactory.instance().get(options);
29+
* } </pre>
30+
*
31+
* <p>After the test:
32+
* <pre> {@code
33+
* gcdHelper.stop();
34+
* } </pre>
35+
*
36+
* @see <a href="https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-datastore">
37+
* gcloud-java tools for testing</a>
38+
*/
39+
package com.google.gcloud.datastore.testing;

trunk/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.api.services.datastore.client.DatastoreException;
3333
import com.google.api.services.datastore.client.DatastoreFactory;
3434
import com.google.api.services.datastore.client.DatastoreOptions.Builder;
35+
import com.google.common.base.Preconditions;
3536
import com.google.common.collect.ImmutableMap;
3637
import com.google.gcloud.datastore.DatastoreOptions;
3738
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason;
@@ -40,6 +41,10 @@
4041
import org.json.JSONObject;
4142
import org.json.JSONTokener;
4243

44+
import java.net.InetAddress;
45+
import java.net.MalformedURLException;
46+
import java.net.URL;
47+
import java.net.UnknownHostException;
4348
import java.util.HashMap;
4449
import java.util.Map;
4550

@@ -62,14 +67,45 @@ public class DefaultDatastoreRpc implements DatastoreRpc {
6267
}
6368

6469
public DefaultDatastoreRpc(DatastoreOptions options) {
70+
String normalizedHost = normalizeHost(options.host());
6571
client = DatastoreFactory.get().create(
6672
new Builder()
6773
.dataset(options.projectId())
68-
.host(options.host())
74+
.host(normalizedHost)
6975
.initializer(options.httpRequestInitializer())
7076
.build());
7177
}
7278

79+
private static String normalizeHost(String host) {
80+
host = host.toLowerCase();
81+
if (includesScheme(host)) {
82+
Preconditions.checkArgument(!(host.startsWith("https://") && isLocalHost(host)),
83+
"\"https\" is not supported for localhost. Use \"http\" instead.");
84+
return host;
85+
}
86+
return "http://" + host;
87+
}
88+
89+
private static boolean isLocalHost(String host) {
90+
if (host != null) {
91+
try {
92+
String normalizedHost = host;
93+
if (!includesScheme(normalizedHost)) {
94+
normalizedHost = "http://" + normalizedHost;
95+
}
96+
InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost());
97+
return hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress();
98+
} catch (UnknownHostException | MalformedURLException e) {
99+
// ignore
100+
}
101+
}
102+
return false;
103+
}
104+
105+
private static boolean includesScheme(String url) {
106+
return url.startsWith("http://") || url.startsWith("https://");
107+
}
108+
73109
private static DatastoreRpcException translate(DatastoreException exception) {
74110
String message = exception.getMessage();
75111
String reasonStr = "";

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.junit.Assert.assertSame;
2323
import static org.junit.Assert.assertTrue;
2424

25+
import com.google.gcloud.datastore.testing.LocalGcdHelper;
2526
import com.google.gcloud.spi.DatastoreRpc;
2627
import com.google.gcloud.spi.DatastoreRpcFactory;
2728

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.google.gcloud.datastore.StructuredQuery.OrderBy;
3434
import com.google.gcloud.datastore.StructuredQuery.Projection;
3535
import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
36+
import com.google.gcloud.datastore.testing.LocalGcdHelper;
3637
import com.google.gcloud.spi.DatastoreRpc;
3738
import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason;
3839
import com.google.gcloud.spi.DatastoreRpcFactory;

trunk/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelper.java renamed to trunk/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.gcloud.storage;
17+
package com.google.gcloud.storage.testing;
1818

1919
import com.google.common.collect.ImmutableMap;
2020
import com.google.gcloud.AuthCredentials;
21-
import com.google.gcloud.storage.RemoteGcsHelper.Option.KeyFromClasspath;
21+
import com.google.gcloud.storage.BlobInfo;
22+
import com.google.gcloud.RetryParams;
23+
import com.google.gcloud.storage.Storage;
24+
import com.google.gcloud.storage.StorageException;
25+
import com.google.gcloud.storage.StorageOptions;
26+
import com.google.gcloud.storage.testing.RemoteGcsHelper.Option.KeyFromClasspath;
2227

2328
import java.io.FileInputStream;
2429
import java.io.FileNotFoundException;
@@ -53,7 +58,7 @@ private RemoteGcsHelper(StorageOptions options) {
5358
}
5459

5560
/**
56-
* Returns a {@StorageOptions} object to be used for testing.
61+
* Returns a {@link StorageOptions} object to be used for testing.
5762
*/
5863
public StorageOptions options() {
5964
return options;
@@ -92,50 +97,37 @@ public static String generateBucketName() {
9297
}
9398

9499
/**
95-
* Creates a {@code RemoteGcsHelper} object.
100+
* Creates a {@code RemoteGcsHelper} object for the given project id and JSON key path.
96101
*
102+
* @param projectId id of the project to be used for running the tests
103+
* @param keyPath path to the JSON key to be used for running the tests
97104
* @param options creation options
98105
* @return A {@code RemoteGcsHelper} object for the provided options.
99-
* @throws com.google.gcloud.storage.RemoteGcsHelper.GcsHelperException if environment variables
100-
* {@code GCLOUD_TESTS_PROJECT_ID} and {@code GCLOUD_TESTS_KEY} are not set or if the file
101-
* pointed by {@code GCLOUD_TESTS_KEY} does not exist
106+
* @throws com.google.gcloud.storage.testing.RemoteGcsHelper.GcsHelperException if the file pointed by
107+
* {@code keyPath} does not exist
102108
*/
103-
public static RemoteGcsHelper create(Option... options) throws GcsHelperException {
109+
public static RemoteGcsHelper create(String projectId, String keyPath, Option... options)
110+
throws GcsHelperException {
104111
boolean keyFromClassPath = false;
105112
Map<Class<? extends Option>, Option> optionsMap = Option.asImmutableMap(options);
106113
if (optionsMap.containsKey(KeyFromClasspath.class)) {
107114
keyFromClassPath =
108115
((KeyFromClasspath) optionsMap.get(KeyFromClasspath.class)).keyFromClasspath();
109116
}
110-
String projectId = System.getenv(PROJECT_ID_ENV_VAR);
111-
String stringKeyPath = System.getenv(PRIVATE_KEY_ENV_VAR);
112-
if (projectId == null) {
113-
String message = "Environment variable " + PROJECT_ID_ENV_VAR + " not set";
114-
if (log.isLoggable(Level.WARNING)) {
115-
log.log(Level.WARNING, message);
116-
}
117-
throw new GcsHelperException(message);
118-
}
119-
if (stringKeyPath == null) {
120-
String message = "Environment variable " + PRIVATE_KEY_ENV_VAR + " not set";
121-
if (log.isLoggable(Level.WARNING)) {
122-
log.log(Level.WARNING, message);
123-
}
124-
throw new GcsHelperException(message);
125-
}
126117
try {
127118
InputStream keyFileStream;
128119
if (keyFromClassPath) {
129-
keyFileStream = RemoteGcsHelper.class.getResourceAsStream(stringKeyPath);
120+
keyFileStream = RemoteGcsHelper.class.getResourceAsStream(keyPath);
130121
if (keyFileStream == null) {
131-
throw new FileNotFoundException(stringKeyPath + " not found in classpath");
122+
throw new FileNotFoundException(keyPath + " not found in classpath");
132123
}
133124
} else {
134-
keyFileStream = new FileInputStream(stringKeyPath);
125+
keyFileStream = new FileInputStream(keyPath);
135126
}
136127
StorageOptions storageOptions = StorageOptions.builder()
137128
.authCredentials(AuthCredentials.createForJson(keyFileStream))
138129
.projectId(projectId)
130+
.retryParams(RetryParams.getDefaultInstance())
139131
.build();
140132
return new RemoteGcsHelper(storageOptions);
141133
} catch (FileNotFoundException ex) {
@@ -151,6 +143,36 @@ public static RemoteGcsHelper create(Option... options) throws GcsHelperExceptio
151143
}
152144
}
153145

146+
/**
147+
* Creates a {@code RemoteGcsHelper} object. Project id and path to JSON key are read from two
148+
* environment variables: {@code GCLOUD_TESTS_PROJECT_ID} and {@code GCLOUD_TESTS_KEY}.
149+
*
150+
* @param options creation options
151+
* @return A {@code RemoteGcsHelper} object for the provided options.
152+
* @throws com.google.gcloud.storage.testing.RemoteGcsHelper.GcsHelperException if environment variables
153+
* {@code GCLOUD_TESTS_PROJECT_ID} and {@code GCLOUD_TESTS_KEY} are not set or if the file
154+
* pointed by {@code GCLOUD_TESTS_KEY} does not exist
155+
*/
156+
public static RemoteGcsHelper create(Option... options) throws GcsHelperException {
157+
String projectId = System.getenv(PROJECT_ID_ENV_VAR);
158+
String keyPath = System.getenv(PRIVATE_KEY_ENV_VAR);
159+
if (projectId == null) {
160+
String message = "Environment variable " + PROJECT_ID_ENV_VAR + " not set";
161+
if (log.isLoggable(Level.WARNING)) {
162+
log.log(Level.WARNING, message);
163+
}
164+
throw new GcsHelperException(message);
165+
}
166+
if (keyPath == null) {
167+
String message = "Environment variable " + PRIVATE_KEY_ENV_VAR + " not set";
168+
if (log.isLoggable(Level.WARNING)) {
169+
log.log(Level.WARNING, message);
170+
}
171+
throw new GcsHelperException(message);
172+
}
173+
return create(projectId, keyPath, options);
174+
}
175+
154176
private static class DeleteBucketTask implements Callable<Boolean> {
155177

156178
private Storage storage;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
/**
18+
* A testing helper for Google Cloud Storage.
19+
*
20+
* <p>A simple usage example:
21+
* <p>Before the test:
22+
* <pre> {@code
23+
* RemoteGcsHelper gcsHelper = RemoteGcsHelper.create(PROJECT_ID, "/path/to/JSON/key.json");
24+
* Storage storage = StorageFactory.instance().get(gcsHelper.options());
25+
* String bucket = RemoteGcsHelper.generateBucketName();
26+
* storage.create(BucketInfo.of(bucket));
27+
* } </pre>
28+
*
29+
* <p>After the test:
30+
* <pre> {@code
31+
* RemoteGcsHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS);
32+
* } </pre>
33+
*
34+
* @see <a href="https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-storage">
35+
* gcloud-java tools for testing</a>
36+
*/
37+
package com.google.gcloud.storage.testing;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.junit.Assert.fail;
2525

2626
import com.google.common.collect.ImmutableList;
27+
import com.google.gcloud.storage.testing.RemoteGcsHelper;
2728

2829
import java.io.ByteArrayInputStream;
2930
import java.io.IOException;
@@ -66,7 +67,7 @@ public static void beforeClass() {
6667
@AfterClass
6768
public static void afterClass()
6869
throws ExecutionException, TimeoutException, InterruptedException {
69-
if (!RemoteGcsHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS)) {
70+
if (storage != null && !RemoteGcsHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS)) {
7071
if (log.isLoggable(Level.WARNING)) {
7172
log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", bucket);
7273
}

0 commit comments

Comments
 (0)