28
28
import io .grpc .ServerInterceptor ;
29
29
import io .grpc .Status ;
30
30
import java .util .ArrayList ;
31
+ import java .util .Arrays ;
32
+ import java .util .Comparator ;
31
33
import java .util .List ;
32
34
import java .util .Map ;
33
35
import java .util .Objects ;
41
43
42
44
@ RunWith (JUnit4 .class )
43
45
public class XGoogSpannerRequestIdTest {
46
+ public static long NON_DETERMINISTIC = -1 ;
44
47
45
48
@ Test
46
49
public void testEquals () {
@@ -157,40 +160,83 @@ private void assertMonotonicityOfIds(String prefix, List<XGoogSpannerRequestId>
157
160
+ String .join ("\n \t " , violations .toArray (new String [0 ])));
158
161
}
159
162
160
- public static class methodAndRequestId {
161
- String method ;
162
- String requestId ;
163
-
164
- public methodAndRequestId (String method , String requestId ) {
165
- this .method = method ;
166
- this .requestId = requestId ;
167
- }
168
-
169
- public String toString () {
170
- return "{" + this .method + ":" + this .requestId + "}" ;
171
- }
172
- }
173
-
174
- public methodAndRequestId [] accumulatedUnaryValues () {
175
- List <methodAndRequestId > accumulated = new ArrayList ();
163
+ public MethodAndRequestId [] accumulatedUnaryValues () {
164
+ List <MethodAndRequestId > accumulated = new ArrayList ();
176
165
this .unaryResults .forEach (
177
166
(String method , CopyOnWriteArrayList <XGoogSpannerRequestId > values ) -> {
178
167
for (int i = 0 ; i < values .size (); i ++) {
179
- accumulated .add (new methodAndRequestId (method , values .get (i ). toString ( )));
168
+ accumulated .add (new MethodAndRequestId (method , values .get (i )));
180
169
}
181
170
});
182
- return accumulated .toArray (new methodAndRequestId [0 ]);
171
+ return accumulated .toArray (new MethodAndRequestId [0 ]);
183
172
}
184
173
185
- public methodAndRequestId [] accumulatedStreamingValues () {
186
- List <methodAndRequestId > accumulated = new ArrayList ();
174
+ public MethodAndRequestId [] accumulatedStreamingValues () {
175
+ List <MethodAndRequestId > accumulated = new ArrayList ();
187
176
this .streamingResults .forEach (
188
177
(String method , CopyOnWriteArrayList <XGoogSpannerRequestId > values ) -> {
189
178
for (int i = 0 ; i < values .size (); i ++) {
190
- accumulated .add (new methodAndRequestId (method , values .get (i ). toString ( )));
179
+ accumulated .add (new MethodAndRequestId (method , values .get (i )));
191
180
}
192
181
});
193
- return accumulated .toArray (new methodAndRequestId [0 ]);
182
+ return accumulated .toArray (new MethodAndRequestId [0 ]);
183
+ }
184
+
185
+ public void checkExpectedUnaryXGoogRequestIds (MethodAndRequestId ... wantUnaryValues ) {
186
+ MethodAndRequestId [] gotUnaryValues = this .accumulatedUnaryValues ();
187
+ sortValues (gotUnaryValues );
188
+ for (int i = 0 ; i < gotUnaryValues .length && false ; i ++) {
189
+ System .out .println ("\033 [33misUnary: #" + i + ":: " + gotUnaryValues [i ] + "\033 [00m" );
190
+ }
191
+ assertEquals (wantUnaryValues , gotUnaryValues );
192
+ }
193
+
194
+ public void checkAtLeastHasExpectedUnaryXGoogRequestIds (MethodAndRequestId ... wantUnaryValues ) {
195
+ MethodAndRequestId [] gotUnaryValues = this .accumulatedUnaryValues ();
196
+ sortValues (gotUnaryValues );
197
+ for (int i = 0 ; i < gotUnaryValues .length && false ; i ++) {
198
+ System .out .println ("\033 [33misUnary: #" + i + ":: " + gotUnaryValues [i ] + "\033 [00m" );
199
+ }
200
+ if (wantUnaryValues .length < gotUnaryValues .length ) {
201
+ MethodAndRequestId [] gotSliced =
202
+ Arrays .copyOfRange (gotUnaryValues , 0 , wantUnaryValues .length );
203
+ assertEquals (wantUnaryValues , gotSliced );
204
+ } else {
205
+ assertEquals (wantUnaryValues , gotUnaryValues );
206
+ }
207
+ }
208
+
209
+ public void checkExpectedUnaryXGoogRequestIdsAsSuffixes (MethodAndRequestId ... wantUnaryValues ) {
210
+ MethodAndRequestId [] gotUnaryValues = this .accumulatedUnaryValues ();
211
+ sortValues (gotUnaryValues );
212
+ for (int i = 0 ; i < gotUnaryValues .length && false ; i ++) {
213
+ System .out .println ("\033 [33misUnary: #" + i + ":: " + gotUnaryValues [i ] + "\033 [00m" );
214
+ }
215
+ if (wantUnaryValues .length < gotUnaryValues .length ) {
216
+ MethodAndRequestId [] gotSliced =
217
+ Arrays .copyOfRange (
218
+ gotUnaryValues ,
219
+ gotUnaryValues .length - wantUnaryValues .length ,
220
+ gotUnaryValues .length );
221
+ assertEquals (wantUnaryValues , gotSliced );
222
+ } else {
223
+ assertEquals (wantUnaryValues , gotUnaryValues );
224
+ }
225
+ }
226
+
227
+ private void sortValues (MethodAndRequestId [] values ) {
228
+ massageValues (values );
229
+ Arrays .sort (values , new MethodAndRequestIdComparator ());
230
+ }
231
+
232
+ public void checkExpectedStreamingXGoogRequestIds (MethodAndRequestId ... wantStreamingValues ) {
233
+ MethodAndRequestId [] gotStreamingValues = this .accumulatedStreamingValues ();
234
+ for (int i = 0 ; i < gotStreamingValues .length && false ; i ++) {
235
+ System .out .println (
236
+ "\033 [32misStreaming: #" + i + ":: " + gotStreamingValues [i ] + "\033 [00m" );
237
+ }
238
+ sortValues (gotStreamingValues );
239
+ assertEquals (wantStreamingValues , gotStreamingValues );
194
240
}
195
241
196
242
public void reset () {
@@ -199,4 +245,80 @@ public void reset() {
199
245
this .streamingResults .clear ();
200
246
}
201
247
}
248
+
249
+ public static class MethodAndRequestId {
250
+ String method ;
251
+ XGoogSpannerRequestId requestId ;
252
+
253
+ public MethodAndRequestId (String method , XGoogSpannerRequestId requestId ) {
254
+ this .method = method ;
255
+ this .requestId = requestId ;
256
+ }
257
+
258
+ public String toString () {
259
+ return "{" + this .method + ":" + this .requestId .debugToString () + "}" ;
260
+ }
261
+
262
+ @ Override
263
+ public boolean equals (Object o ) {
264
+ if (!(o instanceof MethodAndRequestId )) {
265
+ return false ;
266
+ }
267
+ MethodAndRequestId other = (MethodAndRequestId ) o ;
268
+ return Objects .equals (this .method , other .method )
269
+ && Objects .equals (this .requestId , other .requestId );
270
+ }
271
+ }
272
+
273
+ static class MethodAndRequestIdComparator implements Comparator <MethodAndRequestId > {
274
+ @ Override
275
+ public int compare (MethodAndRequestId mr1 , MethodAndRequestId mr2 ) {
276
+ int cmpMethod = mr1 .method .compareTo (mr2 .method );
277
+ if (cmpMethod != 0 ) {
278
+ return cmpMethod ;
279
+ }
280
+
281
+ if (Objects .equals (mr1 .requestId , mr2 .requestId )) {
282
+ return 0 ;
283
+ }
284
+ if (mr1 .requestId .isGreaterThan (mr2 .requestId )) {
285
+ return +1 ;
286
+ }
287
+ return -1 ;
288
+ }
289
+ }
290
+
291
+ static void massageValues (MethodAndRequestId [] mreqs ) {
292
+ for (int i = 0 ; i < mreqs .length ; i ++) {
293
+ MethodAndRequestId mreq = mreqs [i ];
294
+ // BatchCreateSessions is so hard to control as the round-robin doling out
295
+ // hence we might need to be able to scrub the nth_request that won't match
296
+ // nth_req in consecutive order of nth_client.
297
+ if (mreq .method .compareTo ("google.spanner.v1.Spanner/BatchCreateSessions" ) == 0 ) {
298
+ mreqs [i ] =
299
+ new MethodAndRequestId (
300
+ mreq .method ,
301
+ mreq .requestId
302
+ .withNthRequest (NON_DETERMINISTIC )
303
+ .withChannelId (NON_DETERMINISTIC )
304
+ .withNthClientId (NON_DETERMINISTIC ));
305
+ } else if (mreq .method .compareTo ("google.spanner.v1.Spanner/BeginTransaction" ) == 0
306
+ || mreq .method .compareTo ("google.spanner.v1.Spanner/ExecuteStreamingSql" ) == 0
307
+ || mreq .method .compareTo ("google.spanner.v1.Spanner/ExecuteSql" ) == 0
308
+ || mreq .method .compareTo ("google.spanner.v1.Spanner/CreateSession" ) == 0
309
+ || mreq .method .compareTo ("google.spanner.v1.Spanner/Commit" ) == 0 ) {
310
+ mreqs [i ] =
311
+ new MethodAndRequestId (mreq .method , mreq .requestId .withNthClientId (NON_DETERMINISTIC ));
312
+ }
313
+ }
314
+ }
315
+
316
+ public static MethodAndRequestId ofMethodAndRequestId (String method , String reqId ) {
317
+ return new MethodAndRequestId (method , XGoogSpannerRequestId .of (reqId ));
318
+ }
319
+
320
+ public static MethodAndRequestId ofMethodAndRequestId (
321
+ String method , XGoogSpannerRequestId reqId ) {
322
+ return new MethodAndRequestId (method , reqId );
323
+ }
202
324
}
0 commit comments