Skip to content

Commit 1864f77

Browse files
committed
chore(spanner): add SessionNotFound test case
1 parent efe4366 commit 1864f77

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

google-cloud-spanner/src/test/java/com/google/cloud/spanner/MultiplexedSessionDatabaseClientMockServerTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,6 +2010,62 @@ public void testBatchWriteAtLeastOnce() {
20102010
mockSpanner.getSession(beginTransactionRequests.get(1).getSession()).getMultiplexed());
20112011
}
20122012

2013+
@Test
2014+
public void
2015+
testReadWriteUnimplementedError_RetriedWithRegularSessionForInFlightTransaction_FailsWithSessionNotFound() {
2016+
// Test scenario:
2017+
// 1. The initial attempt performs an inline begin using a multiplexed session, but with the
2018+
// backend flag assumed to be OFF, resulting in an UNIMPLEMENTED error.
2019+
// 2. Upon encountering the UNIMPLEMENTED error, the entire transaction callable is retried
2020+
// using regular sessions. However, the Commit request fails due to a SessionNotFound error.
2021+
// 3. A final retry is triggered to handle the SessionNotFound error by selecting a new session
2022+
// from the pool, leading to a successful transaction.
2023+
Spanner spanner = setupSpannerForAbortedBeginTransactionTests();
2024+
2025+
// The first ExecuteSql request that does an inline begin with multiplexed sessions fail with
2026+
// UNIMPLEMENTED error.
2027+
mockSpanner.setExecuteSqlExecutionTime(
2028+
SimulatedExecutionTime.ofException(
2029+
Status.UNIMPLEMENTED
2030+
.withDescription(
2031+
"Transaction type read_write not supported with multiplexed sessions")
2032+
.asRuntimeException()));
2033+
2034+
// The first Commit request fails with SessionNotFound exception. The first time this commit is
2035+
// called with be using regular sessions.
2036+
// This is done to verify if SessionNotFound errors on regular sessions are handled.
2037+
mockSpanner.setCommitExecutionTime(
2038+
SimulatedExecutionTime.ofException(
2039+
mockSpanner.createSessionNotFoundException("TEST_SESSION_NAME")));
2040+
2041+
DatabaseClientImpl client =
2042+
(DatabaseClientImpl) spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
2043+
TransactionRunner runner = client.readWriteTransaction();
2044+
Long updateCount =
2045+
runner.run(
2046+
transaction -> {
2047+
return transaction.executeUpdate(UPDATE_STATEMENT);
2048+
});
2049+
2050+
assertThat(updateCount).isEqualTo(1L);
2051+
List<ExecuteSqlRequest> executeSqlRequests =
2052+
mockSpanner.getRequestsOfType(ExecuteSqlRequest.class);
2053+
assertEquals(3, executeSqlRequests.size());
2054+
2055+
// Verify the first BeginTransaction request is executed using multiplexed sessions.
2056+
assertTrue(mockSpanner.getSession(executeSqlRequests.get(0).getSession()).getMultiplexed());
2057+
2058+
// Verify the second BeginTransaction request is executed using regular sessions.
2059+
assertFalse(mockSpanner.getSession(executeSqlRequests.get(1).getSession()).getMultiplexed());
2060+
2061+
// Verify the second BeginTransaction request is executed using regular sessions.
2062+
assertFalse(mockSpanner.getSession(executeSqlRequests.get(2).getSession()).getMultiplexed());
2063+
2064+
// Verify that after the first regular session failed with SessionNotFoundException, a new
2065+
// regular session is picked up to re-run the transaction.
2066+
assertNotEquals(executeSqlRequests.get(1).getSession(), executeSqlRequests.get(2).getSession());
2067+
}
2068+
20132069
private void waitForSessionToBeReplaced(DatabaseClientImpl client) {
20142070
assertNotNull(client.multiplexedSessionDatabaseClient);
20152071
SessionReference sessionReference =

0 commit comments

Comments
 (0)