[SERVER-5308] Random seed based tests are not deterministic on windows Created: 14/Mar/12  Updated: 11/Jul/16  Resolved: 26/Mar/12

Status: Closed
Project: Core Server
Component/s: Testing Infrastructure
Affects Version/s: None
Fix Version/s: 2.1.1

Type: Bug Priority: Major - P3
Reporter: Aaron Staple Assignee: Tad Marshall
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
is depended on by SERVER-5305 "point not in interval" error in geo_... Closed
Operating System: Windows
Participants:

 Description   

On windows the random seed is not used

        BSONObj JSRand( const BSONObj &a, void* data ) {
            uassert( 12519, "rand accepts no arguments", a.nFields() == 0 );
            unsigned r;
#if !defined(_WIN32)
            r = rand_r( &_randomSeed );
#else
            r = rand(); // seed not used in this case
#endif
            return BSON( "" << double( r ) / ( double( RAND_MAX ) + 1 ) );
        }



 Comments   
Comment by Tad Marshall [ 26/Mar/12 ]

Fixed as part of work on SERVER-5305.

Comment by Tad Marshall [ 26/Mar/12 ]

@Aaron, the reason that Windows was acting truly "random" is because the code calls "srand(curTimeMicros());" in db/db.cpp's main() (and then again in _initAndListen() with "srand((unsigned) (curTimeMicros() ^ startupSrandTimer.micros()));"). This combined with the absence of a call to srand() in the Windows version of JSSrand() in shell/shell_utils.cpp made the random numbers on Windows both uncontrollable and unpredictable. The "uncontrollable" part is now fixed by adding a call to srand() in the Windows version of JSSrand(). https://github.com/mongodb/mongo/commit/c59fd7cbc1623d6bf60e8ff24ff08aa589b1ef87

Comment by Tad Marshall [ 14/Mar/12 ]

My impression is that you would get the first part of your suggestion by just making the code use the provided seed in a call to srand() before the call to rand() in Windows ... it would make it possible to get the same sequence of pseudo-random numbers on demand by providing the same seed each time.

The second part sounds very desirable ... get the same sequence on all platforms by using common code.

Comment by Aaron Staple [ 14/Mar/12 ]

For some background: The observed issue is that we have some js tests running in buildbot that call Random.srand() (our javascript function) with hardcoded values so the tests run the same way every time. But on windows each run behaves differently. I don't know if this is because there is some nondeterminism in the number of times rand() gets called by the mongo shell before the test in question starts or some other reason. But it would be helpful to be able to create a repeatable test by putting the random number generator in a known state at the beginning of the test.

Not positive, but it looks like one advantage of rand_r is that it doesn't rely on global state and has a seed passed as a pointer that gets updated so the next random number can be generated. I don't know off the top of my head if this behavior is required in the shell though.

Incidentally at some point it might be desirable to use a different random number generator that works across different platforms. (So if I have a random seed from a run on one platform I can reproduce the same behavior on another platform.)

Comment by Tad Marshall [ 14/Mar/12 ]

It sounds from the Windows docs as if when you don't call srand() first, it always uses the same sequence of pseudo-random numbers (http://msdn.microsoft.com/en-us/library/398ax69y(v=vs.80).aspx and http://msdn.microsoft.com/en-us/library/f0d4wb4t(v=vs.80).aspx). So maybe calling srand(seed) followed by rand() on Windows is like calling rand_r(seed) on Linux ...?

Generated at Thu Feb 08 03:08:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.