@@ -112,6 +112,61 @@ async function setup(
112
112
}
113
113
114
114
describe ( 'EndToEnd' , ( ) => {
115
+ const selectSql = 'SELECT 1' ;
116
+ const updateSql = 'UPDATE FOO SET BAR=1 WHERE BAZ=2' ;
117
+
118
+ let server : grpc . Server ;
119
+ let spanner : Spanner ;
120
+ let database : Database ;
121
+ let spannerMock : mock . MockSpanner ;
122
+ let traceExporter : typeof InMemorySpanExporter ;
123
+
124
+ const contextManager = new AsyncHooksContextManager ( ) ;
125
+ setGlobalContextManager ( contextManager ) ;
126
+
127
+ afterEach ( ( ) => {
128
+ disableContextAndManager ( contextManager ) ;
129
+ } ) ;
130
+
131
+ beforeEach ( async ( ) => {
132
+ const setupResult = await setup ( ) ;
133
+ spanner = setupResult . spanner ;
134
+ server = setupResult . server ;
135
+ spannerMock = setupResult . spannerMock ;
136
+
137
+ spannerMock . putStatementResult (
138
+ selectSql ,
139
+ mock . StatementResult . resultSet ( createSelect1ResultSet ( ) )
140
+ ) ;
141
+ spannerMock . putStatementResult (
142
+ updateSql ,
143
+ mock . StatementResult . updateCount ( 1 )
144
+ ) ;
145
+
146
+ traceExporter = new InMemorySpanExporter ( ) ;
147
+ const sampler = new AlwaysOnSampler ( ) ;
148
+
149
+ const provider = new NodeTracerProvider ( {
150
+ sampler : sampler ,
151
+ exporter : traceExporter ,
152
+ } ) ;
153
+ provider . addSpanProcessor ( new SimpleSpanProcessor ( traceExporter ) ) ;
154
+
155
+ const instance = spanner . instance ( 'instance' ) ;
156
+ database = instance . database ( 'database' ) ;
157
+ database . _observabilityOptions = {
158
+ tracerProvider : provider ,
159
+ enableExtendedTracing : false ,
160
+ } ;
161
+ } ) ;
162
+
163
+ afterEach ( ( ) => {
164
+ traceExporter . reset ( ) ;
165
+ spannerMock . resetRequests ( ) ;
166
+ spanner . close ( ) ;
167
+ server . tryShutdown ( ( ) => { } ) ;
168
+ } ) ;
169
+
115
170
describe ( 'Database' , ( ) => {
116
171
let server : grpc . Server ;
117
172
let spanner : Spanner ;
@@ -205,7 +260,7 @@ describe('EndToEnd', () => {
205
260
206
261
traceExporter . forceFlush ( ) ;
207
262
const spans = traceExporter . getFinishedSpans ( ) ;
208
- assert . strictEqual ( spans . length , 1 , 'Exactly 1 span expected' ) ;
263
+ assert . strictEqual ( spans . length , 4 ) ;
209
264
210
265
const actualSpanNames : string [ ] = [ ] ;
211
266
const actualEventNames : string [ ] = [ ] ;
@@ -216,14 +271,19 @@ describe('EndToEnd', () => {
216
271
} ) ;
217
272
} ) ;
218
273
219
- const expectedSpanNames = [ 'CloudSpanner.Database.getSnapshot' ] ;
274
+ const expectedSpanNames = [
275
+ 'CloudSpanner.Snapshot.begin' ,
276
+ 'CloudSpanner.Database.getSnapshot' ,
277
+ 'CloudSpanner.Snapshot.runStream' ,
278
+ 'CloudSpanner.Snapshot.run' ,
279
+ ] ;
220
280
assert . deepStrictEqual (
221
281
actualSpanNames ,
222
282
expectedSpanNames ,
223
283
`span names mismatch:\n\tGot: ${ actualSpanNames } \n\tWant: ${ expectedSpanNames } `
224
284
) ;
225
285
226
- const expectedEventNames = [ ] ;
286
+ const expectedEventNames = [ 'Begin Transaction' ] ;
227
287
assert . deepStrictEqual (
228
288
actualEventNames ,
229
289
expectedEventNames ,
@@ -279,7 +339,7 @@ describe('EndToEnd', () => {
279
339
. on ( 'end' , ( ) => {
280
340
traceExporter . forceFlush ( ) ;
281
341
const spans = traceExporter . getFinishedSpans ( ) ;
282
- assert . strictEqual ( spans . length , 1 , 'Exactly 1 span expected' ) ;
342
+ assert . strictEqual ( spans . length , 2 ) ;
283
343
284
344
const actualSpanNames : string [ ] = [ ] ;
285
345
const actualEventNames : string [ ] = [ ] ;
@@ -290,7 +350,10 @@ describe('EndToEnd', () => {
290
350
} ) ;
291
351
} ) ;
292
352
293
- const expectedSpanNames = [ 'CloudSpanner.Database.runStream' ] ;
353
+ const expectedSpanNames = [
354
+ 'CloudSpanner.Snapshot.runStream' ,
355
+ 'CloudSpanner.Database.runStream' ,
356
+ ] ;
294
357
assert . deepStrictEqual (
295
358
actualSpanNames ,
296
359
expectedSpanNames ,
@@ -313,7 +376,7 @@ describe('EndToEnd', () => {
313
376
314
377
traceExporter . forceFlush ( ) ;
315
378
const spans = traceExporter . getFinishedSpans ( ) ;
316
- assert . strictEqual ( spans . length , 2 , 'Exactly 2 spans expected' ) ;
379
+ assert . strictEqual ( spans . length , 3 , 'Exactly 2 spans expected' ) ;
317
380
318
381
// Sort the spans by duration.
319
382
spans . sort ( ( spanA , spanB ) => {
@@ -330,6 +393,7 @@ describe('EndToEnd', () => {
330
393
} ) ;
331
394
332
395
const expectedSpanNames = [
396
+ 'CloudSpanner.Snapshot.runStream' ,
333
397
'CloudSpanner.Database.runStream' ,
334
398
'CloudSpanner.Database.run' ,
335
399
] ;
@@ -375,7 +439,7 @@ describe('EndToEnd', () => {
375
439
376
440
traceExporter . forceFlush ( ) ;
377
441
const spans = traceExporter . getFinishedSpans ( ) ;
378
- assert . strictEqual ( spans . length , 1 , 'Exactly 1 span expected' ) ;
442
+ assert . strictEqual ( spans . length , 3 ) ;
379
443
380
444
const actualEventNames : string [ ] = [ ] ;
381
445
const actualSpanNames : string [ ] = [ ] ;
@@ -386,7 +450,11 @@ describe('EndToEnd', () => {
386
450
} ) ;
387
451
} ) ;
388
452
389
- const expectedSpanNames = [ 'CloudSpanner.Database.runTransaction' ] ;
453
+ const expectedSpanNames = [
454
+ 'CloudSpanner.Database.runTransaction' ,
455
+ 'CloudSpanner.Snapshot.runStream' ,
456
+ 'CloudSpanner.Snapshot.run' ,
457
+ ] ;
390
458
assert . deepStrictEqual (
391
459
actualSpanNames ,
392
460
expectedSpanNames ,
@@ -413,7 +481,7 @@ describe('EndToEnd', () => {
413
481
414
482
traceExporter . forceFlush ( ) ;
415
483
const spans = traceExporter . getFinishedSpans ( ) ;
416
- assert . strictEqual ( spans . length , 1 , 'Exactly 1 span expected' ) ;
484
+ assert . strictEqual ( spans . length , 2 , 'Exactly 1 span expected' ) ;
417
485
418
486
const actualEventNames : string [ ] = [ ] ;
419
487
const actualSpanNames : string [ ] = [ ] ;
@@ -424,14 +492,21 @@ describe('EndToEnd', () => {
424
492
} ) ;
425
493
} ) ;
426
494
427
- const expectedSpanNames = [ 'CloudSpanner.Database.writeAtLeastOnce' ] ;
495
+ const expectedSpanNames = [
496
+ 'CloudSpanner.Transaction.commit' ,
497
+ 'CloudSpanner.Database.writeAtLeastOnce' ,
498
+ ] ;
428
499
assert . deepStrictEqual (
429
500
actualSpanNames ,
430
501
expectedSpanNames ,
431
502
`span names mismatch:\n\tGot: ${ actualSpanNames } \n\tWant: ${ expectedSpanNames } `
432
503
) ;
433
504
434
- const expectedEventNames = [ 'Using Session' ] ;
505
+ const expectedEventNames = [
506
+ 'Starting Commit' ,
507
+ 'Commit Done' ,
508
+ 'Using Session' ,
509
+ ] ;
435
510
assert . deepStrictEqual (
436
511
actualEventNames ,
437
512
expectedEventNames ,
@@ -442,6 +517,206 @@ describe('EndToEnd', () => {
442
517
} ) ;
443
518
} ) ;
444
519
} ) ;
520
+
521
+ describe ( 'Transaction' , ( ) => {
522
+ it ( 'run' , done => {
523
+ database . getTransaction ( ( err , tx ) => {
524
+ assert . ifError ( err ) ;
525
+
526
+ tx ! . run ( 'SELECT 1' , ( err , rows ) => {
527
+ traceExporter . forceFlush ( ) ;
528
+
529
+ const spans = traceExporter . getFinishedSpans ( ) ;
530
+ assert . strictEqual ( spans . length , 3 ) ;
531
+
532
+ const actualSpanNames : string [ ] = [ ] ;
533
+ const actualEventNames : string [ ] = [ ] ;
534
+ spans . forEach ( span => {
535
+ actualSpanNames . push ( span . name ) ;
536
+ span . events . forEach ( event => {
537
+ actualEventNames . push ( event . name ) ;
538
+ } ) ;
539
+ } ) ;
540
+
541
+ const expectedSpanNames = [
542
+ 'CloudSpanner.Database.getTransaction' ,
543
+ 'CloudSpanner.Snapshot.runStream' ,
544
+ 'CloudSpanner.Snapshot.run' ,
545
+ ] ;
546
+ assert . deepStrictEqual (
547
+ actualSpanNames ,
548
+ expectedSpanNames ,
549
+ `span names mismatch:\n\tGot: ${ actualSpanNames } \n\tWant: ${ expectedSpanNames } `
550
+ ) ;
551
+
552
+ const expectedEventNames = [ 'Using Session' ] ;
553
+ assert . strictEqual (
554
+ actualEventNames . every ( value => expectedEventNames . includes ( value ) ) ,
555
+ true ,
556
+ `Unexpected events:\n\tGot: ${ actualEventNames } \n\tWant: ${ expectedEventNames } `
557
+ ) ;
558
+
559
+ done ( ) ;
560
+ } ) ;
561
+ } ) ;
562
+ } ) ;
563
+
564
+ it ( 'Transaction.begin+Dml.runUpdate' , done => {
565
+ database . getTransaction ( ( err , tx ) => {
566
+ assert . ifError ( err ) ;
567
+
568
+ // Firstly erase the prior spans so that we can have only Transaction spans.
569
+ traceExporter . reset ( ) ;
570
+
571
+ tx ! . begin ( ) ;
572
+ tx ! . runUpdate ( updateSql , ( err , rowCount ) => {
573
+ assert . ifError ( err ) ;
574
+
575
+ traceExporter . forceFlush ( ) ;
576
+
577
+ const spans = traceExporter . getFinishedSpans ( ) ;
578
+ assert . strictEqual ( spans . length , 4 ) ;
579
+
580
+ const actualSpanNames : string [ ] = [ ] ;
581
+ const actualEventNames : string [ ] = [ ] ;
582
+ spans . forEach ( span => {
583
+ actualSpanNames . push ( span . name ) ;
584
+ span . events . forEach ( event => {
585
+ actualEventNames . push ( event . name ) ;
586
+ } ) ;
587
+ } ) ;
588
+
589
+ const expectedSpanNames = [
590
+ 'CloudSpanner.Snapshot.begin' ,
591
+ 'CloudSpanner.Snapshot.runStream' ,
592
+ 'CloudSpanner.Snapshot.run' ,
593
+ 'CloudSpanner.Dml.runUpdate' ,
594
+ ] ;
595
+ assert . deepStrictEqual (
596
+ actualSpanNames ,
597
+ expectedSpanNames ,
598
+ `span names mismatch:\n\tGot: ${ actualSpanNames } \n\tWant: ${ expectedSpanNames } `
599
+ ) ;
600
+
601
+ const expectedEventNames = [
602
+ 'Begin Transaction' ,
603
+ 'Transaction Creation Done' ,
604
+ ] ;
605
+ assert . strictEqual (
606
+ actualEventNames . every ( value => expectedEventNames . includes ( value ) ) ,
607
+ true ,
608
+ `Unexpected events:\n\tGot: ${ actualEventNames } \n\tWant: ${ expectedEventNames } `
609
+ ) ;
610
+
611
+ done ( ) ;
612
+ } ) ;
613
+ } ) ;
614
+ } ) ;
615
+
616
+ it ( 'runStream' , done => {
617
+ let rowCount = 0 ;
618
+ database . getTransaction ( ( err , tx ) => {
619
+ assert . ifError ( err ) ;
620
+ tx !
621
+ . runStream ( selectSql )
622
+ . on ( 'data' , ( ) => rowCount ++ )
623
+ . on ( 'error' , assert . ifError )
624
+ . on ( 'stats' , _stats => { } )
625
+ . on ( 'end' , ( ) => {
626
+ tx ! . end ( ) ;
627
+
628
+ traceExporter . forceFlush ( ) ;
629
+
630
+ const spans = traceExporter . getFinishedSpans ( ) ;
631
+ assert . strictEqual ( spans . length , 2 ) ;
632
+
633
+ const actualSpanNames : string [ ] = [ ] ;
634
+ const actualEventNames : string [ ] = [ ] ;
635
+ spans . forEach ( span => {
636
+ actualSpanNames . push ( span . name ) ;
637
+ span . events . forEach ( event => {
638
+ actualEventNames . push ( event . name ) ;
639
+ } ) ;
640
+ } ) ;
641
+
642
+ const expectedSpanNames = [
643
+ 'CloudSpanner.Database.getTransaction' ,
644
+ 'CloudSpanner.Snapshot.runStream' ,
645
+ ] ;
646
+ assert . deepStrictEqual (
647
+ actualSpanNames ,
648
+ expectedSpanNames ,
649
+ `span names mismatch:\n\tGot: ${ actualSpanNames } \n\tWant: ${ expectedSpanNames } `
650
+ ) ;
651
+
652
+ const expectedEventNames = [ 'Using Session' ] ;
653
+ assert . deepStrictEqual (
654
+ actualEventNames ,
655
+ expectedEventNames ,
656
+ `Unexpected events:\n\tGot: ${ actualEventNames } \n\tWant: ${ expectedEventNames } `
657
+ ) ;
658
+
659
+ done ( ) ;
660
+ } ) ;
661
+ } ) ;
662
+ } ) ;
663
+
664
+ it ( 'rollback' , done => {
665
+ database . getTransaction ( ( err , tx ) => {
666
+ assert . ifError ( err ) ;
667
+
668
+ // Firstly erase the prior spans so that we can have only Transaction spans.
669
+ traceExporter . reset ( ) ;
670
+
671
+ tx ! . begin ( ) ;
672
+
673
+ tx ! . runUpdate ( updateSql , async ( err , rowCount ) => {
674
+ assert . ifError ( err ) ;
675
+ tx ! . rollback ( err => {
676
+ traceExporter . forceFlush ( ) ;
677
+
678
+ const spans = traceExporter . getFinishedSpans ( ) ;
679
+
680
+ const actualSpanNames : string [ ] = [ ] ;
681
+ const actualEventNames : string [ ] = [ ] ;
682
+ spans . forEach ( span => {
683
+ actualSpanNames . push ( span . name ) ;
684
+ span . events . forEach ( event => {
685
+ actualEventNames . push ( event . name ) ;
686
+ } ) ;
687
+ } ) ;
688
+
689
+ const expectedSpanNames = [
690
+ 'CloudSpanner.Snapshot.begin' ,
691
+ 'CloudSpanner.Snapshot.runStream' ,
692
+ 'CloudSpanner.Snapshot.run' ,
693
+ 'CloudSpanner.Dml.runUpdate' ,
694
+ 'CloudSpanner.Transaction.rollback' ,
695
+ ] ;
696
+ assert . deepStrictEqual (
697
+ actualSpanNames ,
698
+ expectedSpanNames ,
699
+ `span names mismatch:\n\tGot: ${ actualSpanNames } \n\tWant: ${ expectedSpanNames } `
700
+ ) ;
701
+
702
+ const expectedEventNames = [
703
+ 'Begin Transaction' ,
704
+ 'Transaction Creation Done' ,
705
+ ] ;
706
+ assert . strictEqual (
707
+ actualEventNames . every ( value =>
708
+ expectedEventNames . includes ( value )
709
+ ) ,
710
+ true ,
711
+ `Unexpected events:\n\tGot: ${ actualEventNames } \n\tWant: ${ expectedEventNames } `
712
+ ) ;
713
+
714
+ done ( ) ;
715
+ } ) ;
716
+ } ) ;
717
+ } ) ;
718
+ } ) ;
719
+ } ) ;
445
720
} ) ;
446
721
447
722
describe ( 'ObservabilityOptions injection and propagation' , async ( ) => {
0 commit comments