Skip to content

Commit 73fca01

Browse files
authored
test: unflake InlineBeginTransactionWithoutExecutorTest (#3699)
Unflake InlineBeginTransactionWithoutExecutorTest by not resetting the 'ignore-inline-begin' flag after the first request. This prevents retried requests from first clearing the flag and then getting the unexpected behavior during the retry.
1 parent 44b3141 commit 73fca01

File tree

2 files changed

+179
-168
lines changed

2 files changed

+179
-168
lines changed

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

Lines changed: 170 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,192 +1668,203 @@ public void testWaitForTransactionTimeoutForCommit() {
16681668
assertEquals(0, countRequests(CommitRequest.class));
16691669
}
16701670

1671+
static void runWithIgnoreInlineBegin(Runnable runnable) {
1672+
// This will cause statements that requests a transaction to not return a transaction id.
1673+
mockSpanner.setIgnoreInlineBeginRequest(true);
1674+
try {
1675+
runnable.run();
1676+
} finally {
1677+
mockSpanner.setIgnoreInlineBeginRequest(false);
1678+
}
1679+
}
1680+
16711681
@Test
16721682
public void testQueryWithInlineBeginDidNotReturnTransaction() {
1673-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1674-
// This will cause the first statement that requests a transaction to not return a transaction
1675-
// id.
1676-
mockSpanner.ignoreNextInlineBeginRequest();
1677-
SpannerException e =
1678-
assertThrows(
1679-
SpannerException.class,
1680-
() ->
1681-
client
1682-
.readWriteTransaction()
1683-
.run(
1684-
transaction -> {
1685-
try (ResultSet rs =
1686-
transaction.executeQuery(SELECT1_UNION_ALL_SELECT2)) {
1687-
while (rs.next()) {}
1688-
}
1689-
return null;
1690-
}));
1691-
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1692-
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1693-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1694-
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1695-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1683+
runWithIgnoreInlineBegin(
1684+
() -> {
1685+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1686+
SpannerException e =
1687+
assertThrows(
1688+
SpannerException.class,
1689+
() ->
1690+
client
1691+
.readWriteTransaction()
1692+
.run(
1693+
transaction -> {
1694+
try (ResultSet rs =
1695+
transaction.executeQuery(SELECT1_UNION_ALL_SELECT2)) {
1696+
while (rs.next()) {}
1697+
}
1698+
return null;
1699+
}));
1700+
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1701+
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1702+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1703+
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1704+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1705+
});
16961706
}
16971707

16981708
@Test
16991709
public void testReadWithInlineBeginDidNotReturnTransaction() {
1700-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1701-
// This will cause the first statement that requests a transaction to not return a transaction
1702-
// id.
1703-
mockSpanner.ignoreNextInlineBeginRequest();
1704-
SpannerException e =
1705-
assertThrows(
1706-
SpannerException.class,
1707-
() ->
1708-
client
1709-
.readWriteTransaction()
1710-
.run(
1711-
transaction ->
1712-
transaction.readRow(
1713-
"FOO", Key.of(1L), Collections.singletonList("BAR"))));
1714-
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1715-
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1716-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1717-
assertThat(countRequests(ReadRequest.class)).isEqualTo(1);
1718-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1710+
runWithIgnoreInlineBegin(
1711+
() -> {
1712+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1713+
SpannerException e =
1714+
assertThrows(
1715+
SpannerException.class,
1716+
() ->
1717+
client
1718+
.readWriteTransaction()
1719+
.run(
1720+
transaction ->
1721+
transaction.readRow(
1722+
"FOO", Key.of(1L), Collections.singletonList("BAR"))));
1723+
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1724+
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1725+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1726+
assertThat(countRequests(ReadRequest.class)).isEqualTo(1);
1727+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1728+
});
17191729
}
17201730

17211731
@Test
17221732
public void testUpdateWithInlineBeginDidNotReturnTransaction() {
1723-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1724-
// This will cause the first statement that requests a transaction to not return a transaction
1725-
// id.
1726-
mockSpanner.ignoreNextInlineBeginRequest();
1727-
SpannerException e =
1728-
assertThrows(
1729-
SpannerException.class,
1730-
() ->
1731-
client
1732-
.readWriteTransaction()
1733-
.run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)));
1734-
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1735-
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1736-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1737-
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1738-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1733+
runWithIgnoreInlineBegin(
1734+
() -> {
1735+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1736+
SpannerException e =
1737+
assertThrows(
1738+
SpannerException.class,
1739+
() ->
1740+
client
1741+
.readWriteTransaction()
1742+
.run(transaction -> transaction.executeUpdate(UPDATE_STATEMENT)));
1743+
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1744+
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1745+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1746+
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1747+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1748+
});
17391749
}
17401750

17411751
@Test
17421752
public void testBatchUpdateWithInlineBeginDidNotReturnTransaction() {
1743-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1744-
// This will cause the first statement that requests a transaction to not return a transaction
1745-
// id.
1746-
mockSpanner.ignoreNextInlineBeginRequest();
1747-
SpannerException e =
1748-
assertThrows(
1749-
SpannerException.class,
1750-
() ->
1751-
client
1752-
.readWriteTransaction()
1753-
.run(
1754-
transaction -> {
1755-
transaction.batchUpdate(Collections.singletonList(UPDATE_STATEMENT));
1756-
return null;
1757-
}));
1758-
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1759-
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1760-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1761-
assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1);
1762-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1753+
runWithIgnoreInlineBegin(
1754+
() -> {
1755+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1756+
SpannerException e =
1757+
assertThrows(
1758+
SpannerException.class,
1759+
() ->
1760+
client
1761+
.readWriteTransaction()
1762+
.run(
1763+
transaction -> {
1764+
transaction.batchUpdate(
1765+
Collections.singletonList(UPDATE_STATEMENT));
1766+
return null;
1767+
}));
1768+
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1769+
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1770+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1771+
assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1);
1772+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1773+
});
17631774
}
17641775

17651776
@Test
17661777
public void testQueryAsyncWithInlineBeginDidNotReturnTransaction() {
1767-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1768-
final ExecutorService executor = Executors.newSingleThreadExecutor();
1769-
// This will cause the first statement that requests a transaction to not return a transaction
1770-
// id.
1771-
mockSpanner.ignoreNextInlineBeginRequest();
1772-
SpannerException outerException =
1773-
assertThrows(
1774-
SpannerException.class,
1775-
() ->
1776-
client
1777-
.readWriteTransaction()
1778-
.run(
1779-
transaction -> {
1780-
try (AsyncResultSet rs =
1781-
transaction.executeQueryAsync(SELECT1_UNION_ALL_SELECT2)) {
1782-
return SpannerApiFutures.get(
1783-
rs.setCallback(
1784-
executor,
1785-
resultSet -> {
1786-
try {
1787-
while (true) {
1788-
switch (resultSet.tryNext()) {
1789-
case OK:
1790-
break;
1791-
case DONE:
1778+
runWithIgnoreInlineBegin(
1779+
() -> {
1780+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1781+
final ExecutorService executor = Executors.newSingleThreadExecutor();
1782+
SpannerException outerException =
1783+
assertThrows(
1784+
SpannerException.class,
1785+
() ->
1786+
client
1787+
.readWriteTransaction()
1788+
.run(
1789+
transaction -> {
1790+
try (AsyncResultSet rs =
1791+
transaction.executeQueryAsync(SELECT1_UNION_ALL_SELECT2)) {
1792+
return SpannerApiFutures.get(
1793+
rs.setCallback(
1794+
executor,
1795+
resultSet -> {
1796+
try {
1797+
while (true) {
1798+
switch (resultSet.tryNext()) {
1799+
case OK:
1800+
break;
1801+
case DONE:
1802+
return CallbackResponse.DONE;
1803+
case NOT_READY:
1804+
return CallbackResponse.CONTINUE;
1805+
}
1806+
}
1807+
} catch (SpannerException e) {
17921808
return CallbackResponse.DONE;
1793-
case NOT_READY:
1794-
return CallbackResponse.CONTINUE;
1795-
}
1796-
}
1797-
} catch (SpannerException e) {
1798-
return CallbackResponse.DONE;
1799-
}
1800-
}));
1801-
}
1802-
}));
1803-
assertEquals(ErrorCode.FAILED_PRECONDITION, outerException.getErrorCode());
1804-
assertThat(outerException.getMessage())
1805-
.contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1806-
1807-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1808-
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1809-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1809+
}
1810+
}));
1811+
}
1812+
}));
1813+
assertEquals(ErrorCode.FAILED_PRECONDITION, outerException.getErrorCode());
1814+
assertThat(outerException.getMessage())
1815+
.contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1816+
1817+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1818+
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1819+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1820+
});
18101821
}
18111822

18121823
@Test
18131824
public void testUpdateAsyncWithInlineBeginDidNotReturnTransaction() {
1814-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1815-
// This will cause the first statement that requests a transaction to not return a transaction
1816-
// id.
1817-
mockSpanner.ignoreNextInlineBeginRequest();
1818-
SpannerException e =
1819-
assertThrows(
1820-
SpannerException.class,
1821-
() ->
1822-
client
1823-
.readWriteTransaction()
1824-
.run(
1825-
transaction ->
1826-
SpannerApiFutures.get(
1827-
transaction.executeUpdateAsync(UPDATE_STATEMENT))));
1828-
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1829-
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1830-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1831-
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1832-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1825+
runWithIgnoreInlineBegin(
1826+
() -> {
1827+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1828+
SpannerException e =
1829+
assertThrows(
1830+
SpannerException.class,
1831+
() ->
1832+
client
1833+
.readWriteTransaction()
1834+
.run(
1835+
transaction ->
1836+
SpannerApiFutures.get(
1837+
transaction.executeUpdateAsync(UPDATE_STATEMENT))));
1838+
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1839+
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1840+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1841+
assertThat(countRequests(ExecuteSqlRequest.class)).isEqualTo(1);
1842+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1843+
});
18331844
}
18341845

18351846
@Test
18361847
public void testBatchUpdateAsyncWithInlineBeginDidNotReturnTransaction() {
1837-
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1838-
// This will cause the first statement that requests a transaction to not return a transaction
1839-
// id.
1840-
mockSpanner.ignoreNextInlineBeginRequest();
1841-
SpannerException e =
1842-
assertThrows(
1843-
SpannerException.class,
1844-
() ->
1845-
client
1846-
.readWriteTransaction()
1847-
.run(
1848-
transaction ->
1849-
SpannerApiFutures.get(
1850-
transaction.batchUpdateAsync(
1851-
Collections.singletonList(UPDATE_STATEMENT)))));
1852-
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1853-
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1854-
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1855-
assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1);
1856-
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1848+
runWithIgnoreInlineBegin(
1849+
() -> {
1850+
DatabaseClient client = spanner.getDatabaseClient(DatabaseId.of("p", "i", "d"));
1851+
SpannerException e =
1852+
assertThrows(
1853+
SpannerException.class,
1854+
() ->
1855+
client
1856+
.readWriteTransaction()
1857+
.run(
1858+
transaction ->
1859+
SpannerApiFutures.get(
1860+
transaction.batchUpdateAsync(
1861+
Collections.singletonList(UPDATE_STATEMENT)))));
1862+
assertEquals(ErrorCode.FAILED_PRECONDITION, e.getErrorCode());
1863+
assertThat(e.getMessage()).contains(AbstractReadContext.NO_TRANSACTION_RETURNED_MSG);
1864+
assertThat(countRequests(BeginTransactionRequest.class)).isEqualTo(0);
1865+
assertThat(countRequests(ExecuteBatchDmlRequest.class)).isEqualTo(1);
1866+
assertThat(countRequests(CommitRequest.class)).isEqualTo(0);
1867+
});
18571868
}
18581869

18591870
@Test

0 commit comments

Comments
 (0)