From 65fc5d09d7e1e3eeb08073594b47545c8da04d0a Mon Sep 17 00:00:00 2001 From: kedder Date: Sat, 15 Feb 2003 14:26:38 +0000 Subject: [PATCH] mysql tests will not be run if there is no chance of passing. Notes about mysql backend added git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1511 57a73879-2fb5-44c3-a270-3262357dd7e2 --- doc/mysql.txt | 44 ++++++++++++++++++++ roundup/backends/back_mysql.py | 13 +++++- test/test_db.py | 73 ++++++++++++++++++++-------------- 3 files changed, 99 insertions(+), 31 deletions(-) create mode 100644 doc/mysql.txt diff --git a/doc/mysql.txt b/doc/mysql.txt new file mode 100644 index 0000000..f64cb52 --- /dev/null +++ b/doc/mysql.txt @@ -0,0 +1,44 @@ +============= +MySQL Backend +============= + +This is notes about mysql backend for roundup issue tracker. + + +Prerequisites +============= + +To use MySQL as backend for storing roundup data, you should additionally +install: + + 1. MySQL RDBMS 3.23.34 or higher - http://www.mysql.com. Your MySQL + installation should support Berkeley DB (BDB) tabes for transaction + support. + 2. Python interface to mysql - http://sourceforge.net/projects/mysql-python + + +How to run mysql tests? +======================= + +Roundup tests expect empty database available for use. There are two ways how to +provide it: + + 1. If you have root permissions on mysql server, you can create necessary + database using this SQL sequence: + + CREATE DATABASE rounduptest + GRANT ALL PRIVILEGES ON rounduptest TO rounduptest@localhost IDENTIFIED BY 'rounduptest' + FLUSH PRIVILEGES + + 2. If your administrator has provided you with database connection info, you + can modify MYSQL_* constants in test/test_db.py with corresponding + values. + +Note, that mysql database should not contain any tables. Tests will not dare to +drop database with data. + + + Andrey Lebedev + + + vim: et tw=80 diff --git a/roundup/backends/back_mysql.py b/roundup/backends/back_mysql.py index 4c9c8af..7ff747f 100644 --- a/roundup/backends/back_mysql.py +++ b/roundup/backends/back_mysql.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2003 Martynas Sklyzmantas, Andrey Lebedev +# Copyright (c) 2003 Martynas Sklyzmantas, Andrey Lebedev # # This module is free software, and you may redistribute it and/or modify # under the same terms as Python, so long as this copyright message and @@ -29,6 +29,9 @@ class Database(Database): self.sql("BEGIN") try: self.database_schema = self.load_dbschema() + except MySQLdb.OperationalError, message: + if message[0] != ER.NO_DB_ERROR: + raise except MySQLdb.ProgrammingError, message: if message[0] != ER.NO_SUCH_TABLE: raise DatabaseError, message @@ -171,7 +174,7 @@ class MysqlClass: self.db.sql(query, vals) l += [x[0] for x in self.db.sql_fetchall()] if __debug__: - print >>hyperdb.DEBUG, 'find ... ', l + print >>hyperdb.DEBUG, 'find ... ', l #db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME) # Remove duplicated ids d = {} @@ -188,3 +191,9 @@ class IssueClass(MysqlClass, rdbms_common.IssueClass): class FileClass(MysqlClass, rdbms_common.FileClass): pass +def nuke(config): + """ Clear all database contents and drop database itself""" + # Connect to db + db = Database(config, 'admin') + db.sql("DROP DATABASE %s" % config.MYSQL_DBNAME) + db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME) diff --git a/test/test_db.py b/test/test_db.py index 5c078bb..a582e65 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: test_db.py,v 1.69 2003-02-08 15:31:28 kedder Exp $ +# $Id: test_db.py,v 1.70 2003-02-15 14:26:38 kedder Exp $ import unittest, os, shutil, time @@ -65,6 +65,15 @@ class config: ANONYMOUS_REGISTER = 'deny' # either 'deny' or 'allow' MESSAGES_TO_AUTHOR = 'no' # either 'yes' or 'no' EMAIL_SIGNATURE_POSITION = 'bottom' + # Mysql connection data + MYSQL_DBHOST = 'localhost' + MYSQL_DBUSER = 'rounduptest' + MYSQL_DBPASSWORD = 'rounduptest' + MYSQL_DBNAME = 'rounduptest' + MYSQL_DATABASE = (MYSQL_DBHOST, MYSQL_DBUSER, MYSQL_DBPASSWORD, MYSQL_DBNAME) + +class nodbconfig(config): + MYSQL_DATABASE = (config.MYSQL_DBHOST, config.MYSQL_DBUSER, config.MYSQL_DBPASSWORD) class anydbmDBTestCase(MyTestCase): def setUp(self): @@ -715,32 +724,22 @@ class gadflyReadOnlyDBTestCase(anydbmReadOnlyDBTestCase): self.db = gadfly.Database(config) setupSchema(self.db, 0, gadfly) - -# XXX to fix the mysql tests... -# From: Andrey Lebedev -# I believe we can DROP DATABASE and then CREATE DATABASE -# .. it's an easiest way. This will work if db user has all -# privileges on database. -# Another way - to perform "SHOW TABLES" SQL and then perform DROP TABLE -# on each table... class mysqlDBTestCase(anydbmDBTestCase): def setUp(self): from roundup.backends import mysql # remove previous test, ignore errors if os.path.exists(config.DATABASE): shutil.rmtree(config.DATABASE) - config.MYSQL_DATABASE = ('localhost', 'rounduptest', 'rounduptest', - 'rounduptest') os.makedirs(config.DATABASE + '/files') - # open database for cleaning - self.db = mysql.Database(config, 'admin') - self.db.sql("DROP DATABASE %s" % config.MYSQL_DATABASE[1]) - self.db.sql("CREATE DATABASE %s" % config.MYSQL_DATABASE[1]) - self.db.close() # open database for testing - self.db = mysql.Database(config, 'admin') - + self.db = mysql.Database(config, 'admin') setupSchema(self.db, 1, mysql) + + def tearDown(self): + from roundup.backends import mysql + self.db.close() + mysql.nuke(config) + anydbmDBTestCase.tearDown(self) class mysqlReadOnlyDBTestCase(anydbmReadOnlyDBTestCase): def setUp(self): @@ -748,18 +747,16 @@ class mysqlReadOnlyDBTestCase(anydbmReadOnlyDBTestCase): # remove previous test, ignore errors if os.path.exists(config.DATABASE): shutil.rmtree(config.DATABASE) - config.MYSQL_DATABASE = ('localhost', 'rounduptest', 'rounduptest', - 'rounduptest') os.makedirs(config.DATABASE + '/files') - # open database for cleaning - self.db = mysql.Database(config, 'admin') - self.db.sql("DROP DATABASE %s" % config.MYSQL_DATABASE[1]) - self.db.sql("CREATE DATABASE %s" % config.MYSQL_DATABASE[1]) - self.db.close() - # open database for testing self.db = mysql.Database(config) setupSchema(self.db, 0, mysql) + def tearDown(self): + from roundup.backends import mysql + self.db.close() + mysql.nuke(config) + anydbmReadOnlyDBTestCase.tearDown(self) + class sqliteDBTestCase(anydbmDBTestCase): def setUp(self): from roundup.backends import sqlite @@ -865,9 +862,27 @@ def suite(): from roundup import backends p = [] if hasattr(backends, 'mysql'): - p.append('mysql') - l.append(unittest.makeSuite(mysqlDBTestCase, 'test')) - l.append(unittest.makeSuite(mysqlReadOnlyDBTestCase, 'test')) + from roundup.backends import mysql + try: + # Check if we can run mysql tests + import MySQLdb + db = mysql.Database(nodbconfig, 'admin') + db.conn.select_db(config.MYSQL_DBNAME) + db.sql("SHOW TABLES"); + tables = db.sql_fetchall() + if tables: + # Database should be empty. We don't dare to delete any data + raise DatabaseError, "(Database %s contains tables)" % config.MYSQL_DBNAME + db.sql("DROP DATABASE IF EXISTS %s" % config.MYSQL_DBNAME) + db.sql("CREATE DATABASE %s" % config.MYSQL_DBNAME) + db.close() + except (MySQLdb.ProgrammingError, DatabaseError), msg: + print "Warning! Mysql tests will not be performed", msg + print "See doc/mysql.txt for more details." + else: + p.append('mysql') + l.append(unittest.makeSuite(mysqlDBTestCase, 'test')) + l.append(unittest.makeSuite(mysqlReadOnlyDBTestCase, 'test')) #return unittest.TestSuite(l) if hasattr(backends, 'gadfly'): -- 2.30.2