@@ -621,6 +621,90 @@ func (s *S) TestTxnQueueStashStressTest(c *C) {
621621 }
622622}
623623
624+ func (s * S ) checkTxnQueueLength (c * C , expectedQueueLength int ) {
625+ txn .SetDebug (false )
626+ txn .SetChaos (txn.Chaos {
627+ KillChance : 1 ,
628+ Breakpoint : "set-applying" ,
629+ })
630+ defer txn .SetChaos (txn.Chaos {})
631+ err := s .accounts .Insert (M {"_id" : 0 , "balance" : 100 })
632+ c .Assert (err , IsNil )
633+ ops := []txn.Op {{
634+ C : "accounts" ,
635+ Id : 0 ,
636+ Update : M {"$inc" : M {"balance" : 100 }},
637+ }}
638+ for i := 0 ; i < expectedQueueLength ; i ++ {
639+ err := s .runner .Run (ops , "" , nil )
640+ c .Assert (err , Equals , txn .ErrChaos )
641+ }
642+ txn .SetDebug (true )
643+ // Now that we've filled up the queue, we should see that there are 1000
644+ // items in the queue, and the error applying a new one will change.
645+ var doc bson.M
646+ err = s .accounts .FindId (0 ).One (& doc )
647+ c .Assert (err , IsNil )
648+ c .Check (len (doc ["txn-queue" ].([]interface {})), Equals , expectedQueueLength )
649+ err = s .runner .Run (ops , "" , nil )
650+ c .Check (err , ErrorMatches , `txn-queue for 0 in "accounts" has too many transactions \(\d+\)` )
651+ // The txn-queue should not have grown
652+ err = s .accounts .FindId (0 ).One (& doc )
653+ c .Assert (err , IsNil )
654+ c .Check (len (doc ["txn-queue" ].([]interface {})), Equals , expectedQueueLength )
655+ }
656+
657+ func (s * S ) TestTxnQueueDefaultMaxSize (c * C ) {
658+ s .runner .SetOptions (txn .DefaultRunnerOptions ())
659+ s .checkTxnQueueLength (c , 1000 )
660+ }
661+
662+ func (s * S ) TestTxnQueueCustomMaxSize (c * C ) {
663+ opts := txn .DefaultRunnerOptions ()
664+ opts .MaxTxnQueueLength = 100
665+ s .runner .SetOptions (opts )
666+ s .checkTxnQueueLength (c , 100 )
667+ }
668+
669+ func (s * S ) TestTxnQueueUnlimited (c * C ) {
670+ opts := txn .DefaultRunnerOptions ()
671+ // A value of 0 should mean 'unlimited'
672+ opts .MaxTxnQueueLength = 0
673+ s .runner .SetOptions (opts )
674+ // it isn't possible to actually prove 'unlimited' but we can prove that
675+ // we at least can insert more than the default number of transactions
676+ // without getting a 'too many transactions' failure.
677+ txn .SetDebug (false )
678+ txn .SetChaos (txn.Chaos {
679+ KillChance : 1 ,
680+ // Use set-prepared because we are adding more transactions than
681+ // other tests, and this speeds up setup time a bit
682+ Breakpoint : "set-prepared" ,
683+ })
684+ defer txn .SetChaos (txn.Chaos {})
685+ err := s .accounts .Insert (M {"_id" : 0 , "balance" : 100 })
686+ c .Assert (err , IsNil )
687+ ops := []txn.Op {{
688+ C : "accounts" ,
689+ Id : 0 ,
690+ Update : M {"$inc" : M {"balance" : 100 }},
691+ }}
692+ for i := 0 ; i < 1100 ; i ++ {
693+ err := s .runner .Run (ops , "" , nil )
694+ c .Assert (err , Equals , txn .ErrChaos )
695+ }
696+ txn .SetDebug (true )
697+ var doc bson.M
698+ err = s .accounts .FindId (0 ).One (& doc )
699+ c .Assert (err , IsNil )
700+ c .Check (len (doc ["txn-queue" ].([]interface {})), Equals , 1100 )
701+ err = s .runner .Run (ops , "" , nil )
702+ c .Check (err , Equals , txn .ErrChaos )
703+ err = s .accounts .FindId (0 ).One (& doc )
704+ c .Assert (err , IsNil )
705+ c .Check (len (doc ["txn-queue" ].([]interface {})), Equals , 1101 )
706+ }
707+
624708func (s * S ) TestPurgeMissingPipelineSizeLimit (c * C ) {
625709 // This test ensures that PurgeMissing can handle very large
626710 // txn-queue fields. Previous iterations of PurgeMissing would
0 commit comments