[Maas-devel] MongoDB in the test suite
John Arbash Meinel
john at arbash-meinel.com
Tue Sep 11 11:47:39 UTC 2012
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Just some notes about how we would likely integrate Mongo into a test
suite.
1) 'mongod --dbpath=/path/to/somewhere --port=9999 --smallfiles
- --noprealloc --nojournal'
a) --dbpath lets us put the files wherever we want in the filesystem
b) --port is pretty obvious if we are going to be starting a server,
we need to know where to talk to it. We can use the
'socket.socket()' bind-but-don't-listen trick to get a new-random
port that we know is not already in use.
c) 'use admin; db.shutdownServer()' can be used to stop a server you
are connected to (if you have rights to the admin db). Though if
we start the server, we can just kill it with SIGINT as well.
d) --noprealloc
Mongo defaults to pre-allocating nulled-content on disk (to avoid
fragmentation.) It pre-allocates by doubling the current size. So
dbname.0 is 16MB, dbname.1 is 32MB, etc.
There is also a .ns file that defaults to 16MB. Prealloc seems to
be 'when the current file is close to full, allocate another one
to work from in the future'.
Without this, every db is 64MB (16MB .0, 32MB .1, 16MB .ns), with
it, we are at least down to 32MB and we might set --nssize to make
it smaller.
e) --smallfiles, in my testing this no longer does anything, but it
probably did in other versions of mongo. From what I can tell in
the docs, the default size was .0=64MB, whereas on Precise
dbname.0 is 16MB. We may want to set this just so we can expect it
to be 16MB.
f) Passing an invalid path to 'mongod --path' will startup and die in
30ms. So if we had a clear separation of what are integration
tests (touch mongo) and what are not, then we could start a mongod
for each test.
However, it probably makes more sense to start a mongod for the
whole test suite, and just use temp-named databases for each test.
Still not perfect, as each test case then uses at least 32MB. So
we might use 'collections' as the namespace.
In console terms the alternatives are:
> use testabcd
> db.hardware.save({"content": 1})
Vs
> use tests
> db.testabcd.hardware.save({"content": 1})
The former is a bit more obvious, the later will save a lot of
space during the test suite run.
Note that you can do both:
> use tests
> db.testabcd.drop()
To drop a single collection from a database. Or
> use testabcd
> db.dropDatabase()
To drop the whole database (and free up the space on disk).
Also, 'time mongo DB donothing.js' takes 20ms. That may be client
startup time, or connection time, or something. So we might also
want to maintain a persistent db connection just because of that
overhead.
Changing that to 'time mongo DB create_and_drop.js' changes it to
32ms. So on my hardware, I can create and drop a database in about
12ms. Note that without '--noprealloc' allocating the extra 32MB
increases this overhead to 55ms total or 35ms per db.
Creating namespaces and data is cheap. Dropping them is a bit more
expensive. Creating 100 collections with 1 item in each and then
dropping the db costs 67ms. Creating 100 collections then dropping
them individually and then the db is 147ms.
So it would be good to use a separate collection per test case,
dropping the test suite overhead to around 1.5ms, it may not be
feasible to pass around the collection prefix. In which case,
we're talking about 12ms overhead if we do a per-test-case db, or
30-40ms if we were talking about a per-test-case mongod server.
g) --nojournal is the default on 32-bit, but not on 64-bit. If you
have journaling, mongo preallocates 256MB*3 files (0.75GB). They
apparently will never grow beyond 1GB, but that is still
ridiculous for testing.
I'll post more as I uncover more details. It does look like
integrating mongod in a test infrastructure is doable. Still something
that you probably don't want to have at a 'unittest' level of detail,
but reasonable at a 'integration' test level.
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/
iEYEARECAAYFAlBPJNsACgkQJdeBCYSNAANzCQCbBp4TM0szhBtxSLe/cA20/0zO
AO8AoJ4FYrZFspQcHqxZkg1ZJRjeA3b9
=GJes
-----END PGP SIGNATURE-----
More information about the Maas-devel
mailing list