diff options
Diffstat (limited to 'jstests/noPassthrough/transaction_reaper.js')
-rw-r--r-- | jstests/noPassthrough/transaction_reaper.js | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/jstests/noPassthrough/transaction_reaper.js b/jstests/noPassthrough/transaction_reaper.js new file mode 100644 index 00000000000..c9a9e992cb2 --- /dev/null +++ b/jstests/noPassthrough/transaction_reaper.js @@ -0,0 +1,149 @@ +(function() { + 'use strict'; + + function Repl(lifetime) { + this.rst = new ReplSetTest({ + nodes: 1, + nodeOptions: {setParameter: {TransactionRecordMinimumLifetimeMinutes: lifetime}}, + }); + this.rst.startSet(); + this.rst.initiate(); + } + + Repl.prototype.stop = function() { + this.rst.stopSet(); + }; + + Repl.prototype.getConn = function() { + return this.rst.getPrimary(); + }; + + Repl.prototype.getTransactionConn = function() { + return this.rst.getPrimary(); + }; + + function Sharding(lifetime) { + this.st = new ShardingTest({ + shards: 1, + mongos: 1, + config: 1, + other: { + rs: true, + rsOptions: {setParameter: {TransactionRecordMinimumLifetimeMinutes: lifetime}}, + rs0: {nodes: 1}, + }, + }); + + this.st.s0.getDB("admin").runCommand({enableSharding: "test"}); + this.st.s0.getDB("admin").runCommand({shardCollection: "test.test", key: {_id: 1}}); + } + + Sharding.prototype.stop = function() { + this.st.stop(); + }; + + Sharding.prototype.getConn = function() { + return this.st.s0; + }; + + Sharding.prototype.getTransactionConn = function() { + return this.st.rs0.getPrimary(); + }; + + const nSessions = 1500; + + function Fixture(impl) { + this.impl = impl; + this.conn = impl.getConn(); + this.transactionConn = impl.getTransactionConn(); + + this.sessions = []; + + for (var i = 0; i < nSessions; i++) { + // make a session and get it to the collection + var session = this.conn.startSession({retryWrites: 1}); + session.getDatabase("test").test.count({}); + this.sessions.push(session); + } + + this.refresh(); + this.assertOutstandingTransactions(0); + this.assertOutstandingSessions(nSessions); + + for (var i = 0; i < nSessions; i++) { + // make a session and get it to the collection + var session = this.sessions[i]; + session.getDatabase("test").test.save({a: 1}); + } + + // Ensure a write flushes a transaction + this.assertOutstandingTransactions(nSessions); + this.assertOutstandingSessions(nSessions); + + // Ensure a refresh/reap doesn't remove the transaction + this.refresh(); + this.reap(); + this.assertOutstandingTransactions(nSessions); + this.assertOutstandingSessions(nSessions); + } + + Fixture.prototype.assertOutstandingTransactions = function(count) { + assert.eq(count, this.transactionConn.getDB("config").transactions.count()); + }; + + Fixture.prototype.assertOutstandingSessions = function(count) { + assert.eq(count, this.getDB("admin").system.sessions.count()); + }; + + Fixture.prototype.refresh = function() { + assert.commandWorked(this.getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1})); + }; + + Fixture.prototype.reap = function() { + assert.commandWorked( + this.transactionConn.getDB("admin").runCommand({reapLogicalSessionCacheNow: 1})); + }; + + Fixture.prototype.getDB = function(db) { + return this.conn.getDB(db); + }; + + Fixture.prototype.stop = function() { + this.sessions.forEach(function(session) { + session.endSession(); + }); + return this.impl.stop(); + }; + + [Repl, Sharding].forEach(function(Impl) { + { + var fixture = new Fixture(new Impl(-1)); + // Remove a session + fixture.getDB("admin").system.sessions.remove({}); + fixture.assertOutstandingTransactions(nSessions); + fixture.assertOutstandingSessions(0); + + // See the transaction get reaped as a result + fixture.reap(); + fixture.assertOutstandingTransactions(0); + fixture.assertOutstandingSessions(0); + + fixture.stop(); + } + + { + var fixture = new Fixture(new Impl(30)); + // Remove a session + fixture.getDB("admin").system.sessions.remove({}); + fixture.assertOutstandingTransactions(nSessions); + fixture.assertOutstandingSessions(0); + + // See the transaction was not reaped as a result + fixture.reap(); + fixture.assertOutstandingTransactions(nSessions); + fixture.assertOutstandingSessions(0); + + fixture.stop(); + } + }); +})(); |