Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import com.google.api.core.ApiFunction;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.testing.LocalChannelProvider;
import com.google.api.gax.retrying.RetrySettings;
import com.google.api.gax.rpc.UnaryCallSettings;
Expand All @@ -30,8 +30,6 @@
import com.google.cloud.spanner.MockSpannerServiceImpl.SimulatedExecutionTime;
import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult;
import com.google.cloud.spanner.TransactionRunner.TransactionCallable;
import com.google.cloud.spanner.v1.SpannerClient;
import com.google.cloud.spanner.v1.SpannerSettings;
import com.google.protobuf.ListValue;
import com.google.spanner.v1.ResultSetMetadata;
import com.google.spanner.v1.StructType;
Expand All @@ -41,7 +39,6 @@
import io.grpc.StatusRuntimeException;
import io.grpc.inprocess.InProcessServerBuilder;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.After;
Expand All @@ -57,40 +54,6 @@

@RunWith(JUnit4.class)
public class SpannerGaxRetryTest {
private static final ResultSetMetadata READ_METADATA =
ResultSetMetadata.newBuilder()
.setRowType(
StructType.newBuilder()
.addFields(
Field.newBuilder()
.setName("BAR")
.setType(
com.google.spanner.v1.Type.newBuilder()
.setCode(TypeCode.INT64)
.build())
.build())
.build())
.build();
private static final com.google.spanner.v1.ResultSet READ_RESULTSET =
com.google.spanner.v1.ResultSet.newBuilder()
.addRows(
ListValue.newBuilder()
.addValues(com.google.protobuf.Value.newBuilder().setStringValue("1").build())
.build())
.addRows(
ListValue.newBuilder()
.addValues(com.google.protobuf.Value.newBuilder().setStringValue("2").build())
.build())
.setMetadata(READ_METADATA)
.build();
private static final com.google.spanner.v1.ResultSet READ_ROW_RESULTSET =
com.google.spanner.v1.ResultSet.newBuilder()
.addRows(
ListValue.newBuilder()
.addValues(com.google.protobuf.Value.newBuilder().setStringValue("1").build())
.build())
.setMetadata(READ_METADATA)
.build();
private static final Statement SELECT1AND2 =
Statement.of("SELECT 1 AS COL1 UNION ALL SELECT 2 AS COL1");
private static final ResultSetMetadata SELECT1AND2_METADATA =
Expand Down Expand Up @@ -122,8 +85,8 @@ public class SpannerGaxRetryTest {
private static final Statement UPDATE_STATEMENT =
Statement.of("UPDATE FOO SET BAR=1 WHERE BAZ=2");
private static final long UPDATE_COUNT = 1L;
private static final SimulatedExecutionTime ONE_SECOND =
SimulatedExecutionTime.ofMinimumAndRandomTime(1000, 0);
private static final SimulatedExecutionTime HUNDRED_MS =
SimulatedExecutionTime.ofMinimumAndRandomTime(100, 0);
private static final StatusRuntimeException UNAVAILABLE =
io.grpc.Status.UNAVAILABLE.withDescription("Retryable test exception.").asRuntimeException();
private static final StatusRuntimeException FAILED_PRECONDITION =
Expand All @@ -133,21 +96,17 @@ public class SpannerGaxRetryTest {
private static MockSpannerServiceImpl mockSpanner;
private static Server server;
private static LocalChannelProvider channelProvider;
private static SpannerClient spannerClient;
private static Spanner spanner;
private static DatabaseClient client;
private Spanner spanner;
private DatabaseClient client;
private Spanner spannerWithTimeout;
private DatabaseClient clientWithTimeout;

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

@BeforeClass
public static void startStaticServer() throws IOException {
mockSpanner = new MockSpannerServiceImpl();
mockSpanner.setAbortProbability(0.0D); // We don't want any unpredictable aborted transactions.
mockSpanner.putStatementResult(
StatementResult.read("FOO", KeySet.all(), Arrays.asList("BAR"), READ_RESULTSET));
mockSpanner.putStatementResult(
StatementResult.read(
"FOO", KeySet.singleKey(Key.of()), Arrays.asList("BAR"), READ_ROW_RESULTSET));
mockSpanner.putStatementResult(StatementResult.query(SELECT1AND2, SELECT1_RESULTSET));
mockSpanner.putStatementResult(StatementResult.update(UPDATE_STATEMENT, UPDATE_COUNT));

Expand All @@ -160,31 +119,38 @@ public static void startStaticServer() throws IOException {
.build()
.start();
channelProvider = LocalChannelProvider.create(uniqueName);

SpannerSettings settings =
SpannerSettings.newBuilder()
.setTransportChannelProvider(channelProvider)
.setCredentialsProvider(NoCredentialsProvider.create())
.build();
spannerClient = SpannerClient.create(settings);
}

@AfterClass
public static void stopServer() {
spannerClient.close();
server.shutdown();
}

@Before
public void setUp() throws Exception {
mockSpanner.reset();
mockSpanner.removeAllExecutionTimes();
SpannerOptions.Builder builder =
SpannerOptions.newBuilder()
.setProjectId("[PROJECT]")
.setChannelProvider(channelProvider)
.setCredentials(NoCredentials.getInstance());
// Make sure the session pool is empty by default.
builder.setSessionPoolOption(
SessionPoolOptions.newBuilder().setMinSessions(0).setWriteSessionsFraction(0.0f).build());
// Create one client with default timeout values and one with short timeout values specifically
// for the test cases that expect a DEADLINE_EXCEEDED.
spanner = builder.build().getService();
client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"));

final RetrySettings retrySettings =
RetrySettings.newBuilder()
.setInitialRpcTimeout(Duration.ofMillis(500L))
.setMaxRpcTimeout(Duration.ofMillis(500L))
.setInitialRetryDelay(Duration.ofMillis(10L))
.setMaxRetryDelay(Duration.ofMillis(10L))
.setInitialRpcTimeout(Duration.ofMillis(75L))
.setMaxRpcTimeout(Duration.ofMillis(75L))
.setMaxAttempts(3)
.setTotalTimeout(Duration.ofMillis(1500L))
.setTotalTimeout(Duration.ofMillis(200L))
.build();
RetrySettings commitRetrySettings =
RetrySettings.newBuilder()
Expand All @@ -193,11 +159,6 @@ public void setUp() throws Exception {
.setMaxAttempts(1)
.setTotalTimeout(Duration.ofMillis(20000L))
.build();
SpannerOptions.Builder builder =
SpannerOptions.newBuilder()
.setProjectId("[PROJECT]")
.setChannelProvider(channelProvider)
.setCredentials(NoCredentials.getInstance());
builder
.getSpannerStubSettingsBuilder()
.applyToAllUnaryMethods(
Expand All @@ -214,16 +175,19 @@ public Void apply(Builder<?, ?> input) {
.executeStreamingSqlSettings()
.setRetrySettings(retrySettings);
builder.getSpannerStubSettingsBuilder().streamingReadSettings().setRetrySettings(retrySettings);
spanner = builder.build().getService();
client = spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"));
spannerWithTimeout = builder.build().getService();
clientWithTimeout =
spannerWithTimeout.getDatabaseClient(
DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"));
}

@After
public void tearDown() throws Exception {
spannerWithTimeout.close();
spanner.close();
}

private void warmUpSessionPool() {
private void warmUpSessionPool(DatabaseClient client) {
for (int i = 0; i < 10; i++) {
int retryCount = 0;
while (true) {
Expand All @@ -249,18 +213,13 @@ public Long run(TransactionContext transaction) throws Exception {
}
}
}
// Wait a little to allow the session pool to prepare read/write sessions.
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
}
}

@Test
public void singleUseTimeout() {
expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.DEADLINE_EXCEEDED));
mockSpanner.setCreateSessionExecutionTime(ONE_SECOND);
try (ResultSet rs = client.singleUse().executeQuery(SELECT1AND2)) {
mockSpanner.setCreateSessionExecutionTime(HUNDRED_MS);
try (ResultSet rs = clientWithTimeout.singleUse().executeQuery(SELECT1AND2)) {
while (rs.next()) {}
}
}
Expand Down Expand Up @@ -303,8 +262,9 @@ public void singleUseInternal() {
@Test
public void singleUseReadOnlyTransactionTimeout() {
expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.DEADLINE_EXCEEDED));
mockSpanner.setCreateSessionExecutionTime(ONE_SECOND);
try (ResultSet rs = client.singleUseReadOnlyTransaction().executeQuery(SELECT1AND2)) {
mockSpanner.setCreateSessionExecutionTime(HUNDRED_MS);
try (ResultSet rs =
clientWithTimeout.singleUseReadOnlyTransaction().executeQuery(SELECT1AND2)) {
while (rs.next()) {}
}
}
Expand All @@ -320,8 +280,8 @@ public void singleUseReadOnlyTransactionUnavailable() {
@Test
public void singleUseExecuteStreamingSqlTimeout() {
expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.DEADLINE_EXCEEDED));
try (ResultSet rs = client.singleUse().executeQuery(SELECT1AND2)) {
mockSpanner.setExecuteStreamingSqlExecutionTime(ONE_SECOND);
try (ResultSet rs = clientWithTimeout.singleUse().executeQuery(SELECT1AND2)) {
mockSpanner.setExecuteStreamingSqlExecutionTime(HUNDRED_MS);
while (rs.next()) {}
}
}
Expand All @@ -336,10 +296,9 @@ public void singleUseExecuteStreamingSqlUnavailable() {

@Test
public void readWriteTransactionTimeout() {
warmUpSessionPool();
expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.DEADLINE_EXCEEDED));
mockSpanner.setBeginTransactionExecutionTime(ONE_SECOND);
TransactionRunner runner = client.readWriteTransaction();
mockSpanner.setBeginTransactionExecutionTime(HUNDRED_MS);
TransactionRunner runner = clientWithTimeout.readWriteTransaction();
long updateCount =
runner.run(
new TransactionCallable<Long>() {
Expand All @@ -353,7 +312,7 @@ public Long run(TransactionContext transaction) throws Exception {

@Test
public void readWriteTransactionUnavailable() {
warmUpSessionPool();
warmUpSessionPool(client);
mockSpanner.addException(UNAVAILABLE);
TransactionRunner runner = client.readWriteTransaction();
long updateCount =
Expand Down Expand Up @@ -435,10 +394,8 @@ public Long run(TransactionContext transaction) throws Exception {
@SuppressWarnings("resource")
@Test
public void transactionManagerTimeout() {
warmUpSessionPool();
expectedException.expect(SpannerMatchers.isSpannerException(ErrorCode.DEADLINE_EXCEEDED));
mockSpanner.setBeginTransactionExecutionTime(ONE_SECOND);
try (TransactionManager txManager = client.transactionManager()) {
mockSpanner.setBeginTransactionExecutionTime(HUNDRED_MS);
try (TransactionManager txManager = clientWithTimeout.transactionManager()) {
TransactionContext tx = txManager.begin();
while (true) {
try {
Expand All @@ -449,13 +406,16 @@ public void transactionManagerTimeout() {
tx = txManager.resetForRetry();
}
}
fail("missing DEADLINE_EXCEEDED exception");
} catch (SpannerException e) {
assertThat(e.getErrorCode(), is(equalTo(ErrorCode.DEADLINE_EXCEEDED)));
}
}

@SuppressWarnings("resource")
@Test
public void transactionManagerUnavailable() {
warmUpSessionPool();
warmUpSessionPool(client);
mockSpanner.addException(UNAVAILABLE);
try (TransactionManager txManager = client.transactionManager()) {
TransactionContext tx = txManager.begin();
Expand Down