@@ -142,6 +142,11 @@ describe('EndToEnd', async () => {
142142 tracerProvider : tracerProvider ,
143143 enableExtendedTracing : false ,
144144 } ) ;
145+ let dbCounter = 1 ;
146+
147+ function newTestDatabase ( ) : Database {
148+ return instance . database ( `database-${ dbCounter ++ } ` , ) ;
149+ }
145150
146151 const server = setupResult . server ;
147152 const spannerMock = setupResult . spannerMock ;
@@ -305,6 +310,7 @@ describe('EndToEnd', async () => {
305310 } ) ;
306311
307312 it ( 'runTransactionAsync' , async ( ) => {
313+
308314 await database . runTransactionAsync ( async transaction => {
309315 await transaction ! . run ( 'SELECT 1' ) ;
310316 } ) ;
@@ -327,6 +333,108 @@ describe('EndToEnd', async () => {
327333 ) ;
328334 } ) ;
329335
336+ it ( 'runTransaction with abort' , done => {
337+ let attempts = 0 ;
338+ let rowCount = 0 ;
339+ const database = newTestDatabase ( ) ;
340+ database . runTransaction ( async ( err , transaction ) => {
341+ assert . ifError ( err ) ;
342+ if ( ! attempts ) {
343+ spannerMock . abortTransaction ( transaction ! ) ;
344+ }
345+ attempts ++ ;
346+ transaction ! . run ( selectSql , ( err , rows ) => {
347+ assert . ifError ( err ) ;
348+ rows . forEach ( ( ) => rowCount ++ ) ;
349+ transaction !
350+ . commit ( )
351+ . catch ( done )
352+ . then ( async ( ) => {
353+ const expectedSpanNames = [
354+ 'CloudSpanner.Database.batchCreateSessions' ,
355+ 'CloudSpanner.SessionPool.createSessions' ,
356+ 'CloudSpanner.Snapshot.runStream' ,
357+ 'CloudSpanner.Snapshot.run' ,
358+ 'CloudSpanner.Snapshot.runStream' ,
359+ 'CloudSpanner.Snapshot.run' ,
360+ 'CloudSpanner.Transaction.commit' ,
361+ 'CloudSpanner.Snapshot.begin' ,
362+ 'CloudSpanner.Database.runTransaction' ,
363+ ] ;
364+ const expectedEventNames = [
365+ ...cacheSessionEvents ,
366+ 'Using Session' ,
367+ 'Retrying Transaction' ,
368+ 'Starting stream' ,
369+ 'exception' ,
370+ 'Stream broken. Not safe to retry' ,
371+ 'Begin Transaction' ,
372+ 'Transaction Creation Done' ,
373+ 'Starting stream' ,
374+ 'Starting Commit' ,
375+ 'Commit Done' ,
376+ ] ;
377+ await verifySpansAndEvents ( traceExporter , expectedSpanNames , expectedEventNames )
378+ database
379+ . close ( )
380+ . catch ( done )
381+ . then ( ( ) => done ( ) ) ;
382+ } ) ;
383+ } ) ;
384+ } ) ;
385+ } ) ;
386+
387+ it . only ( 'runTransactionAsync with abort' , async ( ) => {
388+ let attempts = 0 ;
389+ const database = newTestDatabase ( ) ;
390+ await database . runTransactionAsync ( ( transaction ) : Promise < number > => {
391+ if ( ! attempts ) {
392+ spannerMock . abortTransaction ( transaction ) ;
393+ }
394+ attempts ++ ;
395+ return transaction . run ( selectSql ) . then ( ( [ rows ] ) => {
396+ let count = 0 ;
397+ rows . forEach ( ( ) => count ++ ) ;
398+ return transaction . commit ( ) . then ( ( ) => count ) ;
399+ } ) ;
400+ } ) ;
401+ assert . strictEqual ( attempts , 2 ) ;
402+ const expectedSpanNames = [
403+ 'CloudSpanner.Database.batchCreateSessions' ,
404+ 'CloudSpanner.SessionPool.createSessions' ,
405+ 'CloudSpanner.Snapshot.runStream' ,
406+ 'CloudSpanner.Snapshot.run' ,
407+ 'CloudSpanner.Snapshot.begin' ,
408+ 'CloudSpanner.Snapshot.runStream' ,
409+ 'CloudSpanner.Snapshot.run' ,
410+ 'CloudSpanner.Transaction.commit' ,
411+ 'CloudSpanner.Database.runTransactionAsync' ,
412+ ] ;
413+ const expectedEventNames = [
414+ 'Requesting 25 sessions' ,
415+ 'Creating 25 sessions' ,
416+ 'Requested for 25 sessions returned 25' ,
417+ 'Starting stream' ,
418+ 'exception' ,
419+ 'Stream broken. Not safe to retry' ,
420+ 'Begin Transaction' ,
421+ 'Transaction Creation Done' ,
422+ 'Starting stream' ,
423+ 'Starting Commit' ,
424+ 'Commit Done' ,
425+ ...cacheSessionEvents ,
426+ 'Using Session' ,
427+ 'Retrying transaction' ,
428+ ] ;
429+ await verifySpansAndEvents (
430+ traceExporter ,
431+ expectedSpanNames ,
432+ expectedEventNames
433+ ) ;
434+ await database . close ( ) ;
435+ } ) ;
436+
437+
330438 it ( 'writeAtLeastOnce' , done => {
331439 const blankMutations = new MutationSet ( ) ;
332440 database . writeAtLeastOnce ( blankMutations , async ( err , response ) => {
0 commit comments