autotest: remove unneccesary indirection in tko db handle creation
We only support a mysql based tko db, yet we have indirection to fork
between different db backends that adds confusion and complexity.
- delete db_mysql.py and move its connect method back to tko/db.py
- delete _get_error_class frok tko/db.py
BUG=chromium:852083, chromium:860166
TEST=grep for db_mysql and get_error_class reveals no other callers;
examination of calls to |driver| at import time to ensure that they are
satisfied by the fake if necessary
Change-Id: I1c2d0e0daae6fc6b23c4e6c084c37c6602e777ed
Reviewed-on: https://chromium-review.googlesource.com/1135814
Commit-Ready: Aviv Keshet <akeshet@chromium.org>
Tested-by: Aviv Keshet <akeshet@chromium.org>
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
diff --git a/tko/db.py b/tko/db.py
index 0dda40d..1e8af23 100644
--- a/tko/db.py
+++ b/tko/db.py
@@ -2,6 +2,20 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+try:
+ import MySQLdb as driver
+except ImportError:
+ # This module (tko) is unconditionally imported by autoserv,
+ # even in environments where MyQSLdb is unavailable. Thus, we
+ # need to cope with import failure here.
+ # See https://bugs.chromium.org/p/chromium/issues/detail?id=860166#c17 for
+ # context.
+ class UtterlyFakeDb(object):
+ """Lame fake of MySQLdb for import time needs of this file."""
+ OperationalError = object()
+
+ driver = UtterlyFakeDb
+
import math
import os
import random
@@ -11,9 +25,8 @@
import common
from autotest_lib.client.common_lib import global_config
+from autotest_lib.client.common_lib.cros import retry
from autotest_lib.frontend import database_settings_helper
-from autotest_lib.tko import utils
-
def _log_error(msg):
"""Log an error message.
@@ -141,6 +154,22 @@
time.sleep(delay)
+ @retry.retry(driver.OperationalError, timeout_min=10,
+ delay_sec=5)
+ def connect(self, host, database, user, password, port):
+ """Open and return a connection to mysql database."""
+ connection_args = {
+ 'host': host,
+ 'user': user,
+ 'db': database,
+ 'passwd': password,
+ 'connect_timeout': 20,
+ }
+ if port:
+ connection_args['port'] = int(port)
+ return driver.connect(**connection_args)
+
+
def run_with_retry(self, function, *args, **dargs):
"""Call function(*args, **dargs) until either it passes
without an operational error, or a timeout is reached.
@@ -155,14 +184,12 @@
@param args: The arguments
@param dargs: The named arguments.
"""
- OperationalError = _get_error_class("OperationalError")
-
success = False
start_time = time.time()
while not success:
try:
result = function(*args, **dargs)
- except OperationalError, e:
+ except driver.OperationalError, e:
_log_error("%s; retrying, don't panic yet"
% _format_operational_error(e))
stop_time = time.time()
@@ -173,7 +200,7 @@
try:
self._random_delay()
self._init_db()
- except OperationalError, e:
+ except driver.OperationalError, e:
_log_error('%s; panic now'
% _format_operational_error(e))
else:
@@ -790,21 +817,6 @@
return None
-def _get_db_type():
- """Get the database type name to use from the global config."""
- get_value = global_config.global_config.get_config_value_with_fallback
- return "db_" + get_value("AUTOTEST_WEB", "global_db_type", "db_type",
- default="mysql")
-
-
-def _get_error_class(class_name):
- """Retrieves the appropriate error class by name from the database
- module."""
- db_module = __import__("autotest_lib.tko." + _get_db_type(),
- globals(), locals(), ["driver"])
- return getattr(db_module.driver, class_name)
-
-
def db(*args, **dargs):
"""Creates an instance of the database class with the arguments
provided in args and dargs, using the database type specified by
@@ -815,8 +827,4 @@
@return: An db object.
"""
- db_type = _get_db_type()
- db_module = __import__("autotest_lib.tko." + db_type, globals(),
- locals(), [db_type])
- db = getattr(db_module, db_type)(*args, **dargs)
- return db
+ return db_sql(*args, **dargs)