diff options
Diffstat (limited to 'jstests/noPassthrough/metadata_size_estimate.js')
| -rw-r--r-- | jstests/noPassthrough/metadata_size_estimate.js | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/jstests/noPassthrough/metadata_size_estimate.js b/jstests/noPassthrough/metadata_size_estimate.js new file mode 100644 index 00000000000..e3b9adcd61b --- /dev/null +++ b/jstests/noPassthrough/metadata_size_estimate.js @@ -0,0 +1,73 @@ +// Test the impact of having too many roles +// @tags: [requires_sharding] + +(function() { +'use strict'; + +// Use a relatively small record size to more reliably hit a tipping point where the write batching +// logic thinks we have more space available for metadata than we really do. Note also that by using +// small records, we are verifying that the batching logic is accounting for the overhead required +// to serialize each document into a BSONArray. +const kDataBlockSize = 4 * 1024; +const kDataBlock = 'x'.repeat(kDataBlockSize); +const kBSONMaxObjSize = 16 * 1024 * 1024; +const kNumRows = (kBSONMaxObjSize / kDataBlockSize) + 5; +const kDBPrefix = 'qwertyuiopasdfghjklzxcvbnm_'; + +function runTest(conn) { + const admin = conn.getDB('admin'); + assert.commandWorked(admin.runCommand({createUser: 'admin', pwd: 'pwd', roles: ['root']})); + assert(admin.auth('admin', 'pwd')); + + // Create more than 16KB of role data. + // These roles are grouped into a meta-role to avoid calls to `usersInfo` unexpectedly + // overflowing from duplication of roles/inheritedRoles plus showPrivileges. + // bigRole has 100 roles: groupRole_[0..99] + // Each groupRole has 100 subordinate builtin roles: read@prefix_XX[0..99] + let firstDB = null; + const userRoles = []; + for (let i = 0; i < 100; ++i) { + const roleRoles = []; + for (let j = 0; j < 100; ++j) { + const db = kDBPrefix + String((i * 100) + j); + if (firstDB === null) { + firstDB = db; + } + roleRoles.push({db: db, role: 'read'}); + } + assert.commandWorked( + admin.runCommand({createRole: 'groupRole_' + i, roles: roleRoles, privileges: []})); + userRoles.push({db: 'admin', role: 'groupRole_' + i}); + } + assert.commandWorked( + admin.runCommand({createRole: 'bigRole', roles: userRoles, privileges: []})); + assert.commandWorked(admin.runCommand({createUser: 'user', pwd: 'pwd', roles: ['bigRole']})); + + const db = conn.getDB(firstDB); + + // Fill a collection with enough rows to necessitate paging. + for (let i = 1; i <= kNumRows; ++i) { + assert.commandWorked(db.myColl.insert({_id: i, data: kDataBlock})); + } + // Verify initial write. + assert.eq(kNumRows, db.myColl.count({})); + + // Switch to user with all the roles. + admin.logout(); + assert(admin.auth('user', 'pwd')); + + // Create an aggregation which will batch up to kMaxWriteBatchSize or 16MB + // (not counting metadata) + assert.eq(0, db.myColl.aggregate([{"$out": 'yourColl'}]).itcount(), 'Aggregation failed'); + + // Verify the $out stage completed. + assert.eq(db.myColl.count({}), db.yourColl.count({})); + assert.eq(kNumRows, db.yourColl.count({})); +} + +{ + const st = new ShardingTest({mongos: 1, config: 1, shards: 1}); + runTest(st.s0); + st.stop(); +} +})(); |
