diff options
Diffstat (limited to 'jstests/slowWeekly')
-rw-r--r-- | jstests/slowWeekly/geo_full.js | 487 | ||||
-rw-r--r-- | jstests/slowWeekly/geo_mnypts_plus_fields.js | 98 | ||||
-rw-r--r-- | jstests/slowWeekly/query_yield2.js | 2 | ||||
-rw-r--r-- | jstests/slowWeekly/repair2.js | 29 | ||||
-rw-r--r-- | jstests/slowWeekly/update_yield1.js | 2 |
5 files changed, 616 insertions, 2 deletions
diff --git a/jstests/slowWeekly/geo_full.js b/jstests/slowWeekly/geo_full.js new file mode 100644 index 0000000..9eb1b7a --- /dev/null +++ b/jstests/slowWeekly/geo_full.js @@ -0,0 +1,487 @@ +// +// Integration test of the geo code +// +// Basically, this tests adds a random number of docs with a random number of points, +// given a 2d environment of random precision which is either randomly earth-like or of +// random bounds, and indexes these points after a random amount of points have been added +// with a random number of additional fields which correspond to whether the documents are +// in randomly generated circular, spherical, box, and box-polygon shapes (and exact), +// queried randomly from a set of query types. Each point is randomly either and object +// or array, and all points and document data fields are nested randomly in arrays (or not). +// +// We approximate the user here as a random function :-) +// +// These random point fields can then be tested against all types of geo queries using these random shapes. +// +// Tests can be easily reproduced by getting the test number from the output directly before a +// test fails, and hard-wiring that as the test number. +// + + +var randEnvironment = function(){ + + // Normal earth environment + if( Random.rand() < 0.5 ){ + return { max : 180, + min : -180, + bits : Math.floor( Random.rand() * 32 ) + 1, + earth : true, + bucketSize : 360 / ( 4 * 1024 * 1024 * 1024 ) } + } + + var scales = [ 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000, 100000 ] + var scale = scales[ Math.floor( Random.rand() * scales.length ) ] + var offset = Random.rand() * scale + + var max = Random.rand() * scale + offset + var min = - Random.rand() * scale + offset + var bits = Math.floor( Random.rand() * 32 ) + 1 + var range = max - min + var bucketSize = range / ( 4 * 1024 * 1024 * 1024 ) + + return { max : max, + min : min, + bits : bits, + earth : false, + bucketSize : bucketSize } + +} + +var randPoint = function( env, query ) { + + if( query && Random.rand() > 0.5 ) + return query.exact + + if( env.earth ) + return [ Random.rand() * 360 - 180, Random.rand() * 180 - 90 ] + + var range = env.max - env.min + return [ Random.rand() * range + env.min, Random.rand() * range + env.min ]; +} + +var randLocType = function( loc, wrapIn ){ + return randLocTypes( [ loc ], wrapIn )[0] +} + +var randLocTypes = function( locs, wrapIn ) { + + var rLocs = [] + + for( var i = 0; i < locs.length; i++ ){ + if( Random.rand() < 0.5 ) + rLocs.push( { x : locs[i][0], y : locs[i][1] } ) + else + rLocs.push( locs[i] ) + } + + if( wrapIn ){ + var wrappedLocs = [] + for( var i = 0; i < rLocs.length; i++ ){ + var wrapper = {} + wrapper[wrapIn] = rLocs[i] + wrappedLocs.push( wrapper ) + } + + return wrappedLocs + } + + return rLocs + +} + +var randDataType = function() { + + var scales = [ 1, 10, 100, 1000, 10000 ] + var docScale = scales[ Math.floor( Random.rand() * scales.length ) ] + var locScale = scales[ Math.floor( Random.rand() * scales.length ) ] + + var numDocs = 40000 + var maxLocs = 40000 + // Make sure we don't blow past our test resources + while( numDocs * maxLocs > 40000 ){ + numDocs = Math.floor( Random.rand() * docScale ) + 1 + maxLocs = Math.floor( Random.rand() * locScale ) + 1 + } + + return { numDocs : numDocs, + maxLocs : maxLocs } + +} + +var randQuery = function( env ) { + + var center = randPoint( env ) + + var sphereRadius = -1 + var sphereCenter = null + if( env.earth ){ + // Get a start point that doesn't require wrapping + // TODO: Are we a bit too aggressive with wrapping issues? + sphereRadius = Random.rand() * 45 * Math.PI / 180 + sphereCenter = randPoint( env ) + var i + for( i = 0; i < 5; i++ ){ + var t = db.testSphere; t.drop(); t.ensureIndex({ loc : "2d" }, env ) + try{ t.find({ loc : { $within : { $centerSphere : [ sphereCenter, sphereRadius ] } } } ).count(); var err; if( err = db.getLastError() ) throw err; } + catch(e) { print( e ); continue } + print( " Radius " + sphereRadius + " and center " + sphereCenter + " ok ! ") + break; + } + if( i == 5 ) sphereRadius = -1; + + } + + var box = [ randPoint( env ), randPoint( env ) ] + + var boxPoly = [[ box[0][0], box[0][1] ], + [ box[0][0], box[1][1] ], + [ box[1][0], box[1][1] ], + [ box[1][0], box[0][1] ] ] + + if( box[0][0] > box[1][0] ){ + var swap = box[0][0] + box[0][0] = box[1][0] + box[1][0] = swap + } + + if( box[0][1] > box[1][1] ){ + var swap = box[0][1] + box[0][1] = box[1][1] + box[1][1] = swap + } + + return { center : center, + radius : box[1][0] - box[0][0], + exact : randPoint( env ), + sphereCenter : sphereCenter, + sphereRadius : sphereRadius, + box : box, + boxPoly : boxPoly } + +} + + +var resultTypes = { +"exact" : function( loc ){ + return query.exact[0] == loc[0] && query.exact[1] == loc[1] +}, +"center" : function( loc ){ + return Geo.distance( query.center, loc ) <= query.radius +}, +"box" : function( loc ){ + return loc[0] >= query.box[0][0] && loc[0] <= query.box[1][0] && + loc[1] >= query.box[0][1] && loc[1] <= query.box[1][1] + +}, +"sphere" : function( loc ){ + return ( query.sphereRadius >= 0 ? ( Geo.sphereDistance( query.sphereCenter, loc ) <= query.sphereRadius ) : false ) +}, +"poly" : function( loc ){ + return loc[0] >= query.box[0][0] && loc[0] <= query.box[1][0] && + loc[1] >= query.box[0][1] && loc[1] <= query.box[1][1] +}} + +var queryResults = function( locs, query, results ){ + + if( ! results["center"] ){ + for( var type in resultTypes ){ + results[type] = { + docsIn : 0, + docsOut : 0, + locsIn : 0, + locsOut : 0 + } + } + } + + var indResults = {} + for( var type in resultTypes ){ + indResults[type] = { + docIn : false, + locsIn : 0, + locsOut : 0 + } + } + + for( var type in resultTypes ){ + + var docIn = false + for( var i = 0; i < locs.length; i++ ){ + if( resultTypes[type]( locs[i] ) ){ + results[type].locsIn++ + indResults[type].locsIn++ + indResults[type].docIn = true + } + else{ + results[type].locsOut++ + indResults[type].locsOut++ + } + } + if( indResults[type].docIn ) results[type].docsIn++ + else results[type].docsOut++ + + } + + return indResults + +} + +var randQueryAdditions = function( doc, indResults ){ + + for( var type in resultTypes ){ + var choice = Random.rand() + if( Random.rand() < 0.25 ) + doc[type] = ( indResults[type].docIn ? { docIn : "yes" } : { docIn : "no" } ) + else if( Random.rand() < 0.5 ) + doc[type] = ( indResults[type].docIn ? { docIn : [ "yes" ] } : { docIn : [ "no" ] } ) + else if( Random.rand() < 0.75 ) + doc[type] = ( indResults[type].docIn ? [ { docIn : "yes" } ] : [ { docIn : "no" } ] ) + else + doc[type] = ( indResults[type].docIn ? [ { docIn : [ "yes" ] } ] : [ { docIn : [ "no" ] } ] ) + } + +} + +var randIndexAdditions = function( indexDoc ){ + + for( var type in resultTypes ){ + + if( Random.rand() < 0.5 ) continue; + + var choice = Random.rand() + if( Random.rand() < 0.5 ) + indexDoc[type] = 1 + else + indexDoc[type + ".docIn"] = 1 + + } + +} + +var randYesQuery = function(){ + + var choice = Math.floor( Random.rand() * 7 ) + if( choice == 0 ) + return { $ne : "no" } + else if( choice == 1 ) + return "yes" + else if( choice == 2 ) + return /^yes/ + else if( choice == 3 ) + return { $in : [ "good", "yes", "ok" ] } + else if( choice == 4 ) + return { $exists : true } + else if( choice == 5 ) + return { $nin : [ "bad", "no", "not ok" ] } + else if( choice == 6 ) + return { $not : /^no/ } +} + +var locArray = function( loc ){ + if( loc.x ) return [ loc.x, loc.y ] + if( ! loc.length ) return [ loc[0], loc[1] ] + return loc +} + +var locsArray = function( locs ){ + if( locs.loc ){ + arr = [] + for( var i = 0; i < locs.loc.length; i++ ) arr.push( locArray( locs.loc[i] ) ) + return arr + } + else{ + arr = [] + for( var i = 0; i < locs.length; i++ ) arr.push( locArray( locs[i].loc ) ) + return arr + } +} + +var minBoxSize = function( env, box ){ + return env.bucketSize * Math.pow( 2, minBucketScale( env, box ) ) +} + +var minBucketScale = function( env, box ){ + + if( box.length && box[0].length ) + box = [ box[0][0] - box[1][0], box[0][1] - box[1][1] ] + + if( box.length ) + box = Math.max( box[0], box[1] ) + + print( box ) + print( env.bucketSize ) + + return Math.ceil( Math.log( box / env.bucketSize ) / Math.log( 2 ) ) + +} + +// TODO: Add spherical $uniqueDocs tests +var numTests = 100 + +// Our seed will change every time this is run, but +// each individual test will be reproducible given +// that seed and test number +var seed = new Date().getTime() + +for ( var test = 0; test < numTests; test++ ) { + + Random.srand( seed + test ); + //Random.srand( 42240 ) + //Random.srand( 7344 ) + var t = db.testAllGeo + t.drop() + + print( "Generating test environment #" + test ) + var env = randEnvironment() + //env.bits = 11 + var query = randQuery( env ) + var data = randDataType() + //data.numDocs = 100; data.maxLocs = 3; + var results = {} + var totalPoints = 0 + print( "Calculating target results for " + data.numDocs + " docs with max " + data.maxLocs + " locs " ) + + // Index after a random number of docs added + var indexIt = Math.floor( Random.rand() * data.numDocs ) + + for ( var i = 0; i < data.numDocs; i++ ) { + + if( indexIt == i ){ + var indexDoc = { "locs.loc" : "2d" } + randIndexAdditions( indexDoc ) + + // printjson( indexDoc ) + + t.ensureIndex( indexDoc, env ) + assert.isnull( db.getLastError() ) + } + + var numLocs = Math.floor( Random.rand() * data.maxLocs + 1 ) + totalPoints += numLocs + + var multiPoint = [] + for ( var p = 0; p < numLocs; p++ ) { + var point = randPoint( env, query ) + multiPoint.push( point ) + } + + var indResults = queryResults( multiPoint, query, results ) + + var doc + // Nest the keys differently + if( Random.rand() < 0.5 ) + doc = { locs : { loc : randLocTypes( multiPoint ) } } + else + doc = { locs : randLocTypes( multiPoint, "loc" ) } + + randQueryAdditions( doc, indResults ) + + //printjson( doc ) + doc._id = i + t.insert( doc ) + + } + + printjson( { seed : seed, + test: test, + env : env, + query : query, + data : data, + results : results } ) + + + // exact + print( "Exact query..." ) + assert.eq( results.exact.docsIn, t.find( { "locs.loc" : randLocType( query.exact ), "exact.docIn" : randYesQuery() } ).count() ) + + // $center + print( "Center query..." ) + print( "Min box : " + minBoxSize( env, query.radius ) ) + assert.eq( results.center.docsIn, t.find( { "locs.loc" : { $within : { $center : [ query.center, query.radius ], $uniqueDocs : 1 } }, "center.docIn" : randYesQuery() } ).count() ) + assert.eq( results.center.locsIn, t.find( { "locs.loc" : { $within : { $center : [ query.center, query.radius ], $uniqueDocs : false } }, "center.docIn" : randYesQuery() } ).count() ) + if( query.sphereRadius >= 0 ){ + print( "Center sphere query...") + // $centerSphere + assert.eq( results.sphere.docsIn, t.find( { "locs.loc" : { $within : { $centerSphere : [ query.sphereCenter, query.sphereRadius ] } }, "sphere.docIn" : randYesQuery() } ).count() ) + assert.eq( results.sphere.locsIn, t.find( { "locs.loc" : { $within : { $centerSphere : [ query.sphereCenter, query.sphereRadius ], $uniqueDocs : 0.0 } }, "sphere.docIn" : randYesQuery() } ).count() ) + } + + // $box + print( "Box query..." ) + assert.eq( results.box.docsIn, t.find( { "locs.loc" : { $within : { $box : query.box, $uniqueDocs : true } }, "box.docIn" : randYesQuery() } ).count() ) + assert.eq( results.box.locsIn, t.find( { "locs.loc" : { $within : { $box : query.box, $uniqueDocs : false } }, "box.docIn" : randYesQuery() } ).count() ) + + // $polygon + print( "Polygon query..." ) + assert.eq( results.poly.docsIn, t.find( { "locs.loc" : { $within : { $polygon : query.boxPoly } }, "poly.docIn" : randYesQuery() } ).count() ) + assert.eq( results.poly.locsIn, t.find( { "locs.loc" : { $within : { $polygon : query.boxPoly, $uniqueDocs : 0 } }, "poly.docIn" : randYesQuery() } ).count() ) + + // $near + print( "Near query..." ) + assert.eq( results.center.locsIn > 100 ? 100 : results.center.locsIn, t.find( { "locs.loc" : { $near : query.center, $maxDistance : query.radius } } ).count( true ) ) + + if( query.sphereRadius >= 0 ){ + print( "Near sphere query...") + // $centerSphere + assert.eq( results.sphere.locsIn > 100 ? 100 : results.sphere.locsIn, t.find( { "locs.loc" : { $nearSphere : query.sphereCenter, $maxDistance : query.sphereRadius } } ).count( true ) ) + } + + + // geoNear + // results limited by size of objects + if( data.maxLocs < 100 ){ + + // GeoNear query + print( "GeoNear query..." ) + assert.eq( results.center.locsIn > 100 ? 100 : results.center.locsIn, t.getDB().runCommand({ geoNear : "testAllGeo", near : query.center, maxDistance : query.radius }).results.length ) + // GeoNear query + assert.eq( results.center.docsIn > 100 ? 100 : results.center.docsIn, t.getDB().runCommand({ geoNear : "testAllGeo", near : query.center, maxDistance : query.radius, uniqueDocs : true }).results.length ) + + + var num = 2 * results.center.locsIn; + if( num > 200 ) num = 200; + + var output = db.runCommand( { + geoNear : "testAllGeo", + near : query.center, + maxDistance : query.radius , + includeLocs : true, + num : num } ).results + + assert.eq( Math.min( 200, results.center.locsIn ), output.length ) + + var distance = 0; + for ( var i = 0; i < output.length; i++ ) { + var retDistance = output[i].dis + var retLoc = locArray( output[i].loc ) + + // print( "Dist from : " + results[i].loc + " to " + startPoint + " is " + // + retDistance + " vs " + radius ) + + var arrLocs = locsArray( output[i].obj.locs ) + + assert.contains( retLoc, arrLocs ) + + // printjson( arrLocs ) + + var distInObj = false + for ( var j = 0; j < arrLocs.length && distInObj == false; j++ ) { + var newDistance = Geo.distance( locArray( query.center ) , arrLocs[j] ) + distInObj = ( newDistance >= retDistance - 0.0001 && newDistance <= retDistance + 0.0001 ) + } + + assert( distInObj ) + assert.between( retDistance - 0.0001 , Geo.distance( locArray( query.center ), retLoc ), retDistance + 0.0001 ) + assert.lte( retDistance, query.radius ) + assert.gte( retDistance, distance ) + distance = retDistance + } + + } + + //break; + + +} + + diff --git a/jstests/slowWeekly/geo_mnypts_plus_fields.js b/jstests/slowWeekly/geo_mnypts_plus_fields.js new file mode 100644 index 0000000..f67e49b --- /dev/null +++ b/jstests/slowWeekly/geo_mnypts_plus_fields.js @@ -0,0 +1,98 @@ +// Test sanity of geo queries with a lot of points + +var maxFields = 2; + +for( var fields = 1; fields < maxFields; fields++ ){ + + var coll = db.testMnyPts + coll.drop() + + var totalPts = 500 * 1000 + + // Add points in a 100x100 grid + for( var i = 0; i < totalPts; i++ ){ + var ii = i % 10000 + + var doc = { loc : [ ii % 100, Math.floor( ii / 100 ) ] } + + // Add fields with different kinds of data + for( var j = 0; j < fields; j++ ){ + + var field = null + + if( j % 3 == 0 ){ + // Make half the points not searchable + field = "abcdefg" + ( i % 2 == 0 ? "h" : "" ) + } + else if( j % 3 == 1 ){ + field = new Date() + } + else{ + field = true + } + + doc[ "field" + j ] = field + } + + coll.insert( doc ) + } + + // Create the query for the additional fields + queryFields = {} + for( var j = 0; j < fields; j++ ){ + + var field = null + + if( j % 3 == 0 ){ + field = "abcdefg" + } + else if( j % 3 == 1 ){ + field = { $lte : new Date() } + } + else{ + field = true + } + + queryFields[ "field" + j ] = field + } + + coll.ensureIndex({ loc : "2d" }) + + // Check that quarter of points in each quadrant + for( var i = 0; i < 4; i++ ){ + var x = i % 2 + var y = Math.floor( i / 2 ) + + var box = [[0, 0], [49, 49]] + box[0][0] += ( x == 1 ? 50 : 0 ) + box[1][0] += ( x == 1 ? 50 : 0 ) + box[0][1] += ( y == 1 ? 50 : 0 ) + box[1][1] += ( y == 1 ? 50 : 0 ) + + // Now only half of each result comes back + assert.eq( totalPts / ( 4 * 2 ), coll.find(Object.extend( { loc : { $within : { $box : box } } }, queryFields ) ).count() ) + assert.eq( totalPts / ( 4 * 2 ), coll.find(Object.extend( { loc : { $within : { $box : box } } }, queryFields ) ).itcount() ) + + } + + // Check that half of points in each half + for( var i = 0; i < 2; i++ ){ + + var box = [[0, 0], [49, 99]] + box[0][0] += ( i == 1 ? 50 : 0 ) + box[1][0] += ( i == 1 ? 50 : 0 ) + + assert.eq( totalPts / ( 2 * 2 ), coll.find(Object.extend( { loc : { $within : { $box : box } } }, queryFields ) ).count() ) + assert.eq( totalPts / ( 2 * 2 ), coll.find(Object.extend( { loc : { $within : { $box : box } } }, queryFields ) ).itcount() ) + + } + + // Check that all but corner set of points in radius + var circle = [[0, 0], (100 - 1) * Math.sqrt( 2 ) - 0.25 ] + + // All [99,x] pts are field0 : "abcdefg" + assert.eq( totalPts / 2 - totalPts / ( 100 * 100 ), coll.find(Object.extend( { loc : { $within : { $center : circle } } }, queryFields ) ).count() ) + assert.eq( totalPts / 2 - totalPts / ( 100 * 100 ), coll.find(Object.extend( { loc : { $within : { $center : circle } } }, queryFields ) ).itcount() ) + +} + diff --git a/jstests/slowWeekly/query_yield2.js b/jstests/slowWeekly/query_yield2.js index dd7e5d9..6d06357 100644 --- a/jstests/slowWeekly/query_yield2.js +++ b/jstests/slowWeekly/query_yield2.js @@ -59,7 +59,7 @@ while ( ( (new Date()).getTime() - start ) < ( time * 2 ) ){ assert.eq( 1 , x.inprog.length , "nothing in prog" ); } - assert.gt( 100 , me ); + assert.gt( 200 , me ); if ( x.inprog.length == 0 ) break; diff --git a/jstests/slowWeekly/repair2.js b/jstests/slowWeekly/repair2.js new file mode 100644 index 0000000..3097d81 --- /dev/null +++ b/jstests/slowWeekly/repair2.js @@ -0,0 +1,29 @@ +// SERVER-2843 The repair command should not yield. + +baseName = "jstests_repair2"; + +t = db.getSisterDB( baseName )[ baseName ]; +t.drop(); + +function protect( f ) { + try { + f(); + } catch( e ) { + printjson( e ); + } +} + +s = startParallelShell( "db = db.getSisterDB( '" + baseName + "'); for( i = 0; i < 10; ++i ) { db.repairDatabase(); sleep( 5000 ); }" ); + +for( i = 0; i < 30; ++i ) { + + for( j = 0; j < 5000; ++j ) { + protect( function() { t.insert( {_id:j} ); } ); + } + + for( j = 0; j < 5000; ++j ) { + protect( function() { t.remove( {_id:j} ); } ); + } + + assert.eq( 0, t.count() ); +}
\ No newline at end of file diff --git a/jstests/slowWeekly/update_yield1.js b/jstests/slowWeekly/update_yield1.js index 7e95855..5f71830 100644 --- a/jstests/slowWeekly/update_yield1.js +++ b/jstests/slowWeekly/update_yield1.js @@ -54,7 +54,7 @@ while ( ( (new Date()).getTime() - start ) < ( time * 2 ) ){ assert.eq( 1 , x.inprog.length , "nothing in prog" ); } - assert.gt( 2000 , me ); + assert.gt( time / 3 , me ); } join(); |