diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/XGoogSpannerRequestId.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/XGoogSpannerRequestId.java index 274592f9b4..1a81679c5e 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/XGoogSpannerRequestId.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/XGoogSpannerRequestId.java @@ -199,4 +199,10 @@ XGoogSpannerRequestId withNthClientId(long replacementClientId) { return XGoogSpannerRequestId.of( replacementClientId, this.nthChannelId, this.nthRequest, this.attempt); } + + @VisibleForTesting + XGoogSpannerRequestId withAttempt(long replacementAttempt) { + return XGoogSpannerRequestId.of( + this.nthClientId, this.nthChannelId, this.nthRequest, replacementAttempt); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java index fa8b5c982f..f4b70e86b4 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java @@ -1417,8 +1417,7 @@ public void testWriteAtLeastOnceAborted() { List commitRequests = mockSpanner.getRequestsOfType(CommitRequest.class); assertEquals(2, commitRequests.size()); - // TODO(@odeke-em): Enable in later PR. - // xGoogReqIdInterceptor.assertIntegrity(); + xGoogReqIdInterceptor.assertIntegrity(); } @Test @@ -2910,34 +2909,34 @@ public void testPartitionedDmlDoesNotTimeout() { DatabaseClientImpl dbImpl = ((DatabaseClientImpl) client); int channelId = 0; - try (Session session = dbImpl.getSession()) { - channelId = ((PooledSessionFuture) session).getChannel(); + try (PooledSessionFuture session = dbImpl.getSession()) { + channelId = session.getChannel(); } int dbId = dbImpl.dbId; long NON_DETERMINISTIC = XGoogSpannerRequestIdTest.NON_DETERMINISTIC; XGoogSpannerRequestIdTest.MethodAndRequestId[] wantStreamingValues = { XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/ExecuteStreamingSql", - new XGoogSpannerRequestId(NON_DETERMINISTIC, channelId, 6, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), }; - if (false) { // TODO(@odeke-em): enable in next PRs. - xGoogReqIdInterceptor.checkExpectedStreamingXGoogRequestIds(wantStreamingValues); - } + xGoogReqIdInterceptor.checkExpectedStreamingXGoogRequestIds(wantStreamingValues); XGoogSpannerRequestIdTest.MethodAndRequestId[] wantUnaryValues = { XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/BeginTransaction", - new XGoogSpannerRequestId(NON_DETERMINISTIC, channelId, 7, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/CreateSession", - new XGoogSpannerRequestId(NON_DETERMINISTIC, 0, 1, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/ExecuteSql", - new XGoogSpannerRequestId(NON_DETERMINISTIC, channelId, 8, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), }; - if (false) { // TODO(@odeke-em): enable in next PRs. - xGoogReqIdInterceptor.checkExpectedUnaryXGoogRequestIdsAsSuffixes(wantUnaryValues); - } + xGoogReqIdInterceptor.checkExpectedUnaryXGoogRequestIdsAsSuffixes(wantUnaryValues); } } @@ -3023,35 +3022,35 @@ public void testPartitionedDmlWithHigherTimeout() { DatabaseClientImpl dbImpl = ((DatabaseClientImpl) client); int channelId = 0; - try (Session session = dbImpl.getSession()) { - channelId = ((PooledSessionFuture) session).getChannel(); + try (PooledSessionFuture session = dbImpl.getSession()) { + channelId = session.getChannel(); } int dbId = dbImpl.dbId; long NON_DETERMINISTIC = XGoogSpannerRequestIdTest.NON_DETERMINISTIC; XGoogSpannerRequestIdTest.MethodAndRequestId[] wantStreamingValues = { XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/ExecuteStreamingSql", - new XGoogSpannerRequestId(NON_DETERMINISTIC, channelId, 6, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), }; - if (false) { // TODO(@odeke-em): enable in next PRs. - xGoogReqIdInterceptor.checkExpectedStreamingXGoogRequestIds(wantStreamingValues); - } + xGoogReqIdInterceptor.checkExpectedStreamingXGoogRequestIds(wantStreamingValues); XGoogSpannerRequestIdTest.MethodAndRequestId[] wantUnaryValues = { XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/BeginTransaction", - new XGoogSpannerRequestId(NON_DETERMINISTIC, channelId, 7, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/CreateSession", - new XGoogSpannerRequestId(NON_DETERMINISTIC, 0, 1, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), XGoogSpannerRequestIdTest.ofMethodAndRequestId( "google.spanner.v1.Spanner/ExecuteSql", - new XGoogSpannerRequestId(NON_DETERMINISTIC, channelId, 8, 1)), + new XGoogSpannerRequestId( + NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC, NON_DETERMINISTIC)), }; - if (false) { // TODO(@odeke-em): enable in next PRs. - xGoogReqIdInterceptor.checkExpectedUnaryXGoogRequestIdsAsSuffixes(wantUnaryValues); - } + xGoogReqIdInterceptor.checkExpectedUnaryXGoogRequestIdsAsSuffixes(wantUnaryValues); } } @@ -5304,8 +5303,7 @@ public void testSelectHasXGoogRequestIdHeader() { assertEquals(1L, resultSet.getLong(0)); assertFalse(resultSet.next()); } finally { - // TODO(@odeke-em): Enable in later PR. - // xGoogReqIdInterceptor.assertIntegrity(); + xGoogReqIdInterceptor.assertIntegrity(); } } @@ -5394,9 +5392,7 @@ public void testSessionPoolExhaustedError_containsStackTraces() { "google.spanner.v1.Spanner/CreateSession", new XGoogSpannerRequestId(NON_DETERMINISTIC, 0, 1, 1)), }; - if (false) { // TODO(@odeke-em): enable in next PRs. - xGoogReqIdInterceptor.checkExpectedUnaryXGoogRequestIdsAsSuffixes(wantUnaryValues); - } + xGoogReqIdInterceptor.checkExpectedUnaryXGoogRequestIdsAsSuffixes(wantUnaryValues); } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/XGoogSpannerRequestIdTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/XGoogSpannerRequestIdTest.java index 719b94593b..fb43d8b82a 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/XGoogSpannerRequestIdTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/XGoogSpannerRequestIdTest.java @@ -73,11 +73,9 @@ public static class ServerHeaderEnforcer implements ServerInterceptor { private Set checkMethods; ServerHeaderEnforcer(Set checkMethods) { - this.gotValues = new CopyOnWriteArrayList(); - this.unaryResults = - new ConcurrentHashMap>(); - this.streamingResults = - new ConcurrentHashMap>(); + this.gotValues = new CopyOnWriteArrayList<>(); + this.unaryResults = new ConcurrentHashMap<>(); + this.streamingResults = new ConcurrentHashMap<>(); this.checkMethods = checkMethods; } @@ -139,6 +137,11 @@ public void assertIntegrity() { } private void assertMonotonicityOfIds(String prefix, List reqIds) { + reqIds.sort( + (id1, id2) -> { + if (id1.equals(id2)) return 0; + return id1.isGreaterThan(id2) ? 1 : -1; + }); int size = reqIds.size(); List violations = new ArrayList<>(); @@ -161,7 +164,7 @@ private void assertMonotonicityOfIds(String prefix, List } public MethodAndRequestId[] accumulatedUnaryValues() { - List accumulated = new ArrayList(); + List accumulated = new ArrayList<>(); this.unaryResults.forEach( (String method, CopyOnWriteArrayList values) -> { for (int i = 0; i < values.size(); i++) { @@ -172,7 +175,7 @@ public MethodAndRequestId[] accumulatedUnaryValues() { } public MethodAndRequestId[] accumulatedStreamingValues() { - List accumulated = new ArrayList(); + List accumulated = new ArrayList<>(); this.streamingResults.forEach( (String method, CopyOnWriteArrayList values) -> { for (int i = 0; i < values.size(); i++) { @@ -308,7 +311,13 @@ static void massageValues(MethodAndRequestId[] mreqs) { || mreq.method.compareTo("google.spanner.v1.Spanner/CreateSession") == 0 || mreq.method.compareTo("google.spanner.v1.Spanner/Commit") == 0) { mreqs[i] = - new MethodAndRequestId(mreq.method, mreq.requestId.withNthClientId(NON_DETERMINISTIC)); + new MethodAndRequestId( + mreq.method, + mreq.requestId + .withNthClientId(NON_DETERMINISTIC) + .withChannelId(NON_DETERMINISTIC) + .withNthRequest(NON_DETERMINISTIC) + .withAttempt(NON_DETERMINISTIC)); } } }