>>> from lovely.testlayers import mysql
>>> import tempfile, os
>>> tmp = tempfile.mkdtemp()
>>> dbDir = os.path.join(tmp, 'db')
>>> dbDirFake = os.path.join(tmp, 'dbfake')
>>> dbName = 'testing'
Let us create a mysql server.
>>> srv = mysql.Server(dbDir, port=17777)
And init the db.
>>> srv.initDB()
>>> srv.start()
>>> import time
>>> time.sleep(3)
>>> srv.createDB(dbName)
Now we can get a list of databases.
>>> sorted(srv.listDatabases())
['mysql', 'test', 'testing']
If no mysql server is installed on the system we will get an exception:
>>> srv.orig_method = srv.mysqld_path
>>> srv.mysqld_path = lambda: None
>>> srv.start()
Traceback (most recent call last):
IOError: mysqld was not found. Is a MySQL server installed?
>>> srv.mysqld_path = srv.orig_method
We can run scripts from the filesystem.
>>> script = os.path.join(tmp, 'ascript.sql')
>>> f = file(script, 'w')
>>> f.write("""drop table if exists a; create table a (title varchar(64));""")
>>> f.close()
>>> srv.runScripts(dbName, [script])
Let us make a dump of our database
>>> dumpA = os.path.join(tmp, 'a.sql')
>>> srv.dump(dbName, dumpA)
And now some changes
>>> import _mysql
>>> conn = _mysql.connect(host='127.0.0.1', port=17777, user='root', db=dbName)
>>> for i in range(5):
... conn.query('insert into a values(%i)' % i)
>>> conn.commit()
>>> conn.close()
Another dump.
>>> dumpB = os.path.join(tmp, 'b.sql')
>>> srv.dump(dbName, dumpB)
We restore dumpA and the table is emtpy.
>>> srv.restore(dbName, dumpA)
>>> conn = _mysql.connect(host='127.0.0.1', port=17777, user='root', db=dbName)
>>> conn.query('select count(*) from a')
>>> conn.store_result().fetch_row()
(('0',),)
>>> conn.close()
Now restore dumpB and we have our 5 rows back.
>>> srv.restore(dbName, dumpB)
>>> conn = _mysql.connect(host='127.0.0.1', port=17777, user='root', db=dbName)
>>> conn.query('select count(*) from a')
>>> conn.store_result().fetch_row()
(('5',),)
>>> conn.close()
If we try to restore a none existing file we gat a ValueError.
>>> srv.restore(dbName, 'asdf')
Traceback (most recent call last):
...
ValueError: No such file '.../asdf'
>>> srv.stop()
We can generate a control script for use as commandline script.
The simplest script is just to define a server.
>>> dbDir2 = os.path.join(tmp, 'db2')
>>> main = mysql.MySQLDBScript(dbDir2, port=17777)
>>> main.start()
>>> sorted(main.srv.listDatabases())
['mysql', 'test']
>>> main.stop()
We can also define a database to be created upon startup.
>>> main = mysql.MySQLDBScript(dbDir2, dbName='hoschi', port=17777)
>>> main.start()
>>> sorted(main.srv.listDatabases())
['hoschi', 'mysql', 'test']
>>> main.stop()
The database is created only one time.
>>> main.start()
>>> main.stop()
And also scripts to be executed.
>>> main = mysql.MySQLDBScript(dbDir2, dbName='hoschi2',
... scripts=[script], port=17777)
>>> main.start()
Note that we used the same directory here so the other db is still there.
>>> sorted(main.srv.listDatabases())
['hoschi', 'hoschi2', 'mysql', 'test']
We can run the scripts again. Note that scripts should always be none-destructive. So if a schema update is due one just needs to run all scripts again.
>>> main.runscripts()
>>> main.stop()
Let’s create a layer:
>>> layer = mysql.MySQLDatabaseLayer('testing')
We can get the store uri.
>>> layer.storeURI()
'mysql://localhost:16543/testing'
>>> layer.setUp()
>>> layer.tearDown()
The second time the server ist started it takes the snapshot.
>>> layer.setUp()
>>> layer.tearDown()
If we try to run setup twice or the port is occupied, we get an error.
>>> layer.setUp()
>>> layer.setUp()
Traceback (most recent call last):
RuntimeError: Port already listening: 16543
>>> layer.tearDown()
We can have appsetup definitions and sql scripts. There is also a convinience class that let’s us execute sql statements as setup.
>>> setup = mysql.ExecuteSQL('create table testing (title varchar(32))')
>>> layer = mysql.MySQLDatabaseLayer('testing', setup=setup)
>>> layer.setUp()
>>> layer.tearDown()
>>> layer = mysql.MySQLDatabaseLayer('testing', setup=setup)
>>> layer.setUp()
>>> layer.tearDown()
Also if the database name is different, the same snapshots can be used.
>>> layer2 = mysql.MySQLDatabaseLayer('testing2', setup=setup)
>>> layer2.setUp()
>>> layer2.tearDown()
If we do not provide the snapsotIdent the ident is built by using the dotted name of the setup callable and the hash of the arguments.
>>> layer.snapshotIdent
u'lovely.testlayers.mysql.ExecuteSQLe449d7734c67c100e0662d3319fe3f410e78ebcf'
Let us provide an ident and scripts.
>>> layer = mysql.MySQLDatabaseLayer('testing3', setup=setup,
... snapshotIdent='blah',
... scripts=[script])
>>> layer.snapshotIdent
'blah'
>>> layer.scripts
['/.../ascript.sql']
On setup the snapshot with the setup is created, therefore setup is called with the server as argument.
>>> layer.setUp()
Upon testSetUp this snapshot is now restored.
>>> layer.testSetUp()
So now we should have the table there.
>>> conn = _mysql.connect(host='127.0.0.1', port=16543, user='root', db=dbName)
>>> conn.query('select * from testing')
>>> conn.store_result().fetch_row()
()
>>> conn.close()
Let us add some data (we are now in a test):
>>> conn = _mysql.connect(host='127.0.0.1', port=16543, user='root', db=dbName)
>>> conn.query("insert into testing values('hoschi')")
>>> conn.commit()
>>> conn.query('select * from testing')
>>> conn.store_result().fetch_row()
(('hoschi',),)
>>> conn.close()
>>> layer.testTearDown()
>>> layer.tearDown()
Finally do some cleanup:
>>> import shutil
>>> shutil.rmtree(tmp)