Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions datastore-v1-proto-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,24 +109,11 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<!-- Excludes integration tests and smoke tests when unit tests are run -->
<excludes>
<exclude>**/*SmokeTest.java</exclude>
<exclude>**/IT*.java</exclude>
</excludes>
<reportNameSuffix>sponge_log</reportNameSuffix>
<argLine>-Xmx2048m</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.0.0-M5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Args = --enable-url-protocols=https,http
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this library use HTTP (not HTTPS) somewhere in users' environment? (What's the error without this argument?)

If the request is only for testing, then this file should be under test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the stacktrace, this is coming from com.google.datastore.v1.client.RemoteRpc:

 Caused by: java.lang.IllegalArgumentException: java.net.MalformedURLException: Accessing an URL protocol that was not enabled. The URL protocol https is supported but not enabled by default. It must be enabled by adding the --enable-url-protocols=https option to the native-image command. com.google.api.client.http.GenericUrl.parseURL(GenericUrl.java:679) com.google.api.client.http.GenericUrl.<init>(GenericUrl.java:125) com.google.api.client.http.GenericUrl.<init>(GenericUrl.java:108) com.google.datastore.v1.client.RemoteRpc.resolveURL(RemoteRpc.java:161) com.google.datastore.v1.client.RemoteRpc.<init>(RemoteRpc.java:62) 

Normally this configuration would come from gax, but this module doesn't import it so we had to add this setting in.

Copy link
Member

@suztomo suztomo Apr 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe RemoteRpc constructor takes an HTTP URL. Where is the value defined? (My guess is it's only for tests)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error is coming from RemoteRpc.resolveURL but it's used in RemoteRpc#call which is later referenced in Datastore. For this reason, I think we would still need it in the main configuration?

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"name":"com.google.datastore.v1.client.Datastore",
"methods":[
{"name":"allocateIds","parameterTypes":["com.google.datastore.v1.AllocateIdsRequest"] },
{"name":"beginTransaction","parameterTypes":["com.google.datastore.v1.BeginTransactionRequest"] },
{"name":"commit","parameterTypes":["com.google.datastore.v1.CommitRequest"] },
{"name":"lookup","parameterTypes":["com.google.datastore.v1.LookupRequest"] },
{"name":"reserveIds","parameterTypes":["com.google.datastore.v1.ReserveIdsRequest"] },
{"name":"rollback","parameterTypes":["com.google.datastore.v1.RollbackRequest"] },
{"name":"runQuery","parameterTypes":["com.google.datastore.v1.RunQueryRequest"] }
]
},
{
"name":"com.google.api.client.http.HttpRequest",
"allDeclaredFields":true,
"allPublicFields":true,
"allDeclaredMethods":true,
"allPublicMethods":true,
"allDeclaredConstructors" : true,
"allPublicConstructors" : true
},
{
"name":"com.google.api.client.http.HttpHeaders",
"allDeclaredFields":true,
"allPublicFields":true,
"allDeclaredMethods":true,
"allPublicMethods":true,
"allDeclaredConstructors" : true,
"allPublicConstructors" : true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import com.google.api.client.auth.oauth2.Credential;
Expand Down Expand Up @@ -62,108 +63,144 @@
import java.lang.reflect.Method;
import java.net.SocketTimeoutException;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link DatastoreFactory} and {@link Datastore}. */
@RunWith(JUnit4.class)
public class DatastoreTest {
public class DatastoreClientTest {
private static final String PROJECT_ID = "project-id";

@Rule public ExpectedException thrown = ExpectedException.none();

private DatastoreFactory factory = new MockDatastoreFactory();
private DatastoreOptions.Builder options =
new DatastoreOptions.Builder().projectId(PROJECT_ID).credential(new MockCredential());

@Test
public void options_NoProjectIdOrProjectEndpoint() throws Exception {
options = new DatastoreOptions.Builder();
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Either project ID or project endpoint must be provided");
public void options_NoProjectIdOrProjectEndpoint() {
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() -> factory.create(new DatastoreOptions.Builder().build()));
assertThat(exception)
.hasMessageThat()
.contains("Either project ID or project endpoint must be provided");
factory.create(options.build());
}

@Test
public void options_ProjectIdAndProjectEndpoint() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Cannot set both project endpoint and project ID");
options =
new DatastoreOptions.Builder()
.projectId(PROJECT_ID)
.projectEndpoint("http://localhost:1234/datastore/v1beta42/projects/project-id");
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
new DatastoreOptions.Builder()
.projectId(PROJECT_ID)
.projectEndpoint(
"http://localhost:1234/datastore/v1beta42/projects/project-id"));
assertThat(exception)
.hasMessageThat()
.contains("Cannot set both project endpoint and project ID");
}

@Test
public void options_LocalHostAndProjectEndpoint() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Can set at most one of project endpoint, host, and local host");
options =
new DatastoreOptions.Builder()
.localHost("localhost:8080")
.projectEndpoint("http://localhost:1234/datastore/v1beta42/projects/project-id");
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
new DatastoreOptions.Builder()
.localHost("localhost:8080")
.projectEndpoint(
"http://localhost:1234/datastore/v1beta42/projects/project-id"));
assertThat(exception)
.hasMessageThat()
.contains("Can set at most one of project endpoint, host, and local host");
}

@Test
public void options_HostAndProjectEndpoint() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Can set at most one of project endpoint, host, and local host");
options =
new DatastoreOptions.Builder()
.host("foo-datastore.googleapis.com")
.projectEndpoint("http://localhost:1234/datastore/v1beta42/projects/project-id");
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
new DatastoreOptions.Builder()
.host("foo-datastore.googleapis.com")
.projectEndpoint(
"http://localhost:1234/datastore/v1beta42/projects/project-id"));
assertThat(exception)
.hasMessageThat()
.contains("Can set at most one of project endpoint, host, and local host");
}

@Test
public void options_HostAndLocalHost() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Can set at most one of project endpoint, host, and local host");
options =
new DatastoreOptions.Builder()
.host("foo-datastore.googleapis.com")
.localHost("localhost:8080");
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
new DatastoreOptions.Builder()
.host("foo-datastore.googleapis.com")
.localHost("localhost:8080"));
assertThat(exception)
.hasMessageThat()
.contains("Can set at most one of project endpoint, host, and local host");
}

@Test
public void options_InvalidLocalHost() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Illegal character");
factory.create(
new DatastoreOptions.Builder()
.projectId(PROJECT_ID)
.localHost("!not a valid url!")
.build());
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
factory.create(
new DatastoreOptions.Builder()
.projectId(PROJECT_ID)
.localHost("!not a valid url!")
.build()));
assertThat(exception).hasMessageThat().contains("Illegal character");
}

@Test
public void options_SchemeInLocalHost() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Local host \"http://localhost:8080\" must not include scheme");
new DatastoreOptions.Builder().localHost("http://localhost:8080");
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() -> new DatastoreOptions.Builder().localHost("http://localhost:8080"));
assertThat(exception)
.hasMessageThat()
.contains("Local host \"http://localhost:8080\" must not include scheme");
}

@Test
public void options_InvalidHost() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Illegal character");
factory.create(
new DatastoreOptions.Builder().projectId(PROJECT_ID).host("!not a valid url!").build());
public void options_InvalidHost() {
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
factory.create(
new DatastoreOptions.Builder()
.projectId(PROJECT_ID)
.host("!not a valid url!")
.build()));
assertThat(exception).hasMessageThat().contains("Illegal character");
}

@Test
public void options_SchemeInHost() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Host \"http://foo-datastore.googleapis.com\" must not include scheme");
new DatastoreOptions.Builder().host("http://foo-datastore.googleapis.com");
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() -> new DatastoreOptions.Builder().host("http://foo-datastore.googleapis.com"));

assertThat(exception)
.hasMessageThat()
.contains("Host \"http://foo-datastore.googleapis.com\" must not include scheme.");
}

@Test
public void create_NullOptions() throws Exception {
thrown.expect(NullPointerException.class);
factory.create(null);
assertThrows(NullPointerException.class, () -> factory.create(null));
}

@Test
Expand Down Expand Up @@ -223,14 +260,19 @@ public void create_ProjectEndpoint() {

@Test
public void create_ProjectEndpointNoScheme() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage(
"Project endpoint \"localhost:1234/datastore/v1beta42/projects/project-id\" must"
+ " include scheme.");
factory.create(
new DatastoreOptions.Builder()
.projectEndpoint("localhost:1234/datastore/v1beta42/projects/project-id")
.build());
IllegalArgumentException exception =
assertThrows(
IllegalArgumentException.class,
() ->
factory.create(
new DatastoreOptions.Builder()
.projectEndpoint("localhost:1234/datastore/v1beta42/projects/project-id")
.build()));
assertThat(exception)
.hasMessageThat()
.contains(
"Project endpoint \"localhost:1234/datastore/v1beta42/projects/project-id\" must"
+ " include scheme.");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
import org.threeten.bp.Duration;

@RunWith(JUnit4.class)
public class ITDatastoreTest {
public class DatastoreTest {

private static LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0);
private static final DatastoreOptions options = helper.getOptions();
Expand Down