diff options
author | Jason Carey <jcarey@argv.me> | 2017-09-12 17:54:48 -0400 |
---|---|---|
committer | Jason Carey <jcarey@argv.me> | 2017-09-20 12:09:23 -0400 |
commit | 79df037ceb43882726e9484b9ab8b1c23c538034 (patch) | |
tree | f885c270b723f35520bd357b626a43bb44a5c16f /jstests/noPassthrough/transaction_reaper.js | |
parent | 976371fdd34ade74f59ee9f3863bf9047421666e (diff) | |
download | mongo-79df037ceb43882726e9484b9ab8b1c23c538034.tar.gz |
SERVER-31011 Provide transaction record deletion hook
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(); + } + }); +})(); |