The default ShardingTest verbosity is currently zero, but we have many tests, which bump it to 1 and even higher. Since verbosity level of 0 is sometimes insufficient for investigating transient failures, this change makes the default to be 1 and removes all places, which explicitly make it 1 or higher.
200 lines
7.9 KiB
JavaScript
200 lines
7.9 KiB
JavaScript
(function () {
|
|
|
|
var s = new ShardingTest({ name: "stats",
|
|
shards: 2,
|
|
mongos: 1,
|
|
other: { enableBalancer: true } });
|
|
|
|
s.adminCommand( { enablesharding : "test" } );
|
|
|
|
a = s._connections[0].getDB( "test" );
|
|
b = s._connections[1].getDB( "test" );
|
|
|
|
db = s.getDB( "test" );
|
|
s.ensurePrimaryShard('test', 'shard0001');
|
|
|
|
function numKeys(o){
|
|
var num = 0;
|
|
for (var x in o)
|
|
num++;
|
|
return num;
|
|
}
|
|
|
|
db.foo.drop();
|
|
assert.commandFailed(db.foo.stats(),
|
|
'db.collection.stats() should fail on non-existent collection');
|
|
|
|
// ---------- load some data -----
|
|
|
|
// need collections sharded before and after main collection for proper test
|
|
s.adminCommand( { shardcollection : "test.aaa" , key : { _id : 1 } } );
|
|
s.adminCommand( { shardcollection : "test.foo" , key : { _id : 1 } } ); // this collection is actually used
|
|
s.adminCommand( { shardcollection : "test.zzz" , key : { _id : 1 } } );
|
|
|
|
|
|
N = 10000;
|
|
s.adminCommand( { split : "test.foo" , middle : { _id : N/2 } } )
|
|
s.adminCommand({ moveChunk: "test.foo", find: { _id: 3 },
|
|
to: s.getNonPrimaries("test")[0], _waitForDelete: true });
|
|
|
|
var bulk = db.foo.initializeUnorderedBulkOp();
|
|
for ( i=0; i<N; i++ )
|
|
bulk.insert( { _id : i } );
|
|
assert.writeOK(bulk.execute());
|
|
|
|
x = db.foo.stats();
|
|
assert.eq( N , x.count , "coll total count expected" )
|
|
assert.eq( db.foo.count() , x.count , "coll total count match" )
|
|
assert.eq( 2 , x.nchunks , "coll chunk num" )
|
|
assert.eq( 2 , numKeys(x.shards) , "coll shard num" )
|
|
assert.eq( N / 2 , x.shards.shard0000.count , "coll count on shard0000 expected" )
|
|
assert.eq( N / 2 , x.shards.shard0001.count , "coll count on shard0001 expected" )
|
|
assert.eq( a.foo.count() , x.shards.shard0000.count , "coll count on shard0000 match" )
|
|
assert.eq( b.foo.count() , x.shards.shard0001.count , "coll count on shard0001 match" )
|
|
assert(!x.shards.shard0000.indexDetails,
|
|
'indexDetails should not be present in shard0000: ' + tojson(x.shards.shard0000));
|
|
assert(!x.shards.shard0001.indexDetails,
|
|
'indexDetails should not be present in shard0001: ' + tojson(x.shards.shard0001));
|
|
|
|
|
|
a_extras = a.stats().objects - a.foo.count(); // things like system.namespaces and system.indexes
|
|
b_extras = b.stats().objects - b.foo.count(); // things like system.namespaces and system.indexes
|
|
print("a_extras: " + a_extras);
|
|
print("b_extras: " + b_extras);
|
|
|
|
x = db.stats();
|
|
|
|
//dbstats uses Future::CommandResult so raw output uses connection strings not shard names
|
|
shards = Object.keySet(x.raw);
|
|
|
|
assert.eq( N + (a_extras + b_extras) , x.objects , "db total count expected" )
|
|
assert.eq( 2 , numKeys(x.raw) , "db shard num" )
|
|
assert.eq( (N / 2) + a_extras, x.raw[shards[0]].objects , "db count on shard0000 expected" )
|
|
assert.eq( (N / 2) + b_extras, x.raw[shards[1]].objects , "db count on shard0001 expected" )
|
|
assert.eq( a.stats().objects , x.raw[shards[0]].objects , "db count on shard0000 match" )
|
|
assert.eq( b.stats().objects , x.raw[shards[1]].objects , "db count on shard0001 match" )
|
|
|
|
/* Test db.stat() and db.collection.stat() scaling */
|
|
|
|
/* Helper functions */
|
|
function statComp(stat, stat_scaled, scale) {
|
|
/* Because of loss of floating point precision, do not check exact equality */
|
|
if ( stat == stat_scaled )
|
|
return true;
|
|
assert(((stat_scaled - 2) <= (stat / scale)) &&
|
|
((stat / scale) <= (stat_scaled + 2)));
|
|
}
|
|
|
|
function dbStatComp(stat_obj, stat_obj_scaled, scale) {
|
|
statComp(stat_obj.dataSize, stat_obj_scaled.dataSize, scale);
|
|
statComp(stat_obj.storageSize, stat_obj_scaled.storageSize, scale);
|
|
statComp(stat_obj.indexSize, stat_obj_scaled.indexSize, scale);
|
|
statComp(stat_obj.fileSize, stat_obj_scaled.fileSize, scale);
|
|
/* avgObjSize not scaled. See SERVER-7347 */
|
|
statComp(stat_obj.avgObjSize, stat_obj_scaled.avgObjSize, 1);
|
|
}
|
|
|
|
function collStatComp(stat_obj, stat_obj_scaled, scale, mongos) {
|
|
statComp(stat_obj.size, stat_obj_scaled.size, scale);
|
|
statComp(stat_obj.storageSize, stat_obj_scaled.storageSize, scale);
|
|
statComp(stat_obj.totalIndexSize, stat_obj_scaled.totalIndexSize, scale);
|
|
statComp(stat_obj.avgObjSize, stat_obj_scaled.avgObjSize, scale);
|
|
/* lastExtentSize doesn't exist in mongos level collection stats */
|
|
if (!mongos) {
|
|
statComp(stat_obj.lastExtentSize, stat_obj_scaled.lastExtentSize, scale);
|
|
}
|
|
}
|
|
|
|
/* db.stats() tests */
|
|
db_not_scaled = db.stats();
|
|
db_scaled_512 = db.stats(512);
|
|
db_scaled_1024 = db.stats(1024);
|
|
|
|
for (var shard in db_not_scaled.raw) {
|
|
dbStatComp(db_not_scaled.raw[shard], db_scaled_512.raw[shard], 512);
|
|
dbStatComp(db_not_scaled.raw[shard], db_scaled_1024.raw[shard], 1024);
|
|
}
|
|
|
|
dbStatComp(db_not_scaled, db_scaled_512, 512);
|
|
dbStatComp(db_not_scaled, db_scaled_1024, 1024);
|
|
|
|
/* db.collection.stats() tests */
|
|
coll_not_scaled = db.foo.stats();
|
|
coll_scaled_512 = db.foo.stats(512);
|
|
coll_scaled_1024 = db.foo.stats(1024);
|
|
|
|
for (var shard in coll_not_scaled.shards) {
|
|
collStatComp(coll_not_scaled.shards[shard], coll_scaled_512.shards[shard], 512, false);
|
|
collStatComp(coll_not_scaled.shards[shard], coll_scaled_1024.shards[shard], 1024, false);
|
|
}
|
|
|
|
collStatComp(coll_not_scaled, coll_scaled_512, 512, true);
|
|
collStatComp(coll_not_scaled, coll_scaled_1024, 1024, true);
|
|
|
|
/* db.collection.stats() - indexDetails tests */
|
|
(function() {
|
|
var t = db.foo;
|
|
|
|
assert.commandWorked(t.ensureIndex({a: 1}));
|
|
assert.eq(2, t.getIndexes().length);
|
|
|
|
var isWiredTiger = (!jsTest.options().storageEngine
|
|
|| jsTest.options().storageEngine === "wiredTiger");
|
|
|
|
var stats = assert.commandWorked(t.stats({indexDetails: true}));
|
|
var shardName;
|
|
var shardStats;
|
|
for (shardName in stats.shards) {
|
|
shardStats = stats.shards[shardName];
|
|
assert(shardStats.indexDetails,
|
|
'indexDetails missing for ' + shardName + ': ' + tojson(shardStats));
|
|
if (isWiredTiger) {
|
|
assert.eq(t.getIndexes().length, Object.keys(shardStats.indexDetails).length,
|
|
'incorrect number of entries in WiredTiger indexDetails: ' +
|
|
tojson(shardStats));
|
|
}
|
|
}
|
|
|
|
function getIndexName(indexKey) {
|
|
var indexes = t.getIndexes().filter(function(doc) {
|
|
return friendlyEqual(doc.key, indexKey);
|
|
});
|
|
assert.eq(1, indexes.length, tojson(indexKey) + ' not found in getIndexes() result: ' +
|
|
tojson(t.getIndexes()));
|
|
return indexes[0].name;
|
|
}
|
|
|
|
function checkIndexDetails(options, indexName) {
|
|
var stats = assert.commandWorked(t.stats(options));
|
|
for (shardName in stats.shards) {
|
|
shardStats = stats.shards[shardName];
|
|
assert(shardStats.indexDetails,
|
|
'indexDetails missing from db.collection.stats(' + tojson(options) +
|
|
').shards[' + shardName + '] result: ' + tojson(shardStats));
|
|
// Currently, indexDetails is only supported with WiredTiger.
|
|
if (isWiredTiger) {
|
|
assert.eq(1, Object.keys(shardStats.indexDetails).length,
|
|
'WiredTiger indexDetails must have exactly one entry');
|
|
assert(shardStats.indexDetails[indexName],
|
|
indexName + ' missing from WiredTiger indexDetails: ' +
|
|
tojson(shardStats.indexDetails));
|
|
assert.neq(0, Object.keys(shardStats.indexDetails[indexName]).length,
|
|
indexName + ' exists in indexDetails but contains no information: ' +
|
|
tojson(shardStats.indexDetails));
|
|
}
|
|
}
|
|
}
|
|
|
|
// indexDetailsKey - show indexDetails results for this index key only.
|
|
var indexKey = {a: 1};
|
|
var indexName = getIndexName(indexKey);
|
|
checkIndexDetails({indexDetails: true, indexDetailsKey: indexKey}, indexName);
|
|
|
|
// indexDetailsName - show indexDetails results for this index name only.
|
|
checkIndexDetails({indexDetails: true, indexDetailsName: indexName}, indexName);
|
|
}());
|
|
|
|
s.stop();
|
|
|
|
})();
|