[autotest] suite-scheduler sanity check should not rely on django
Resubmit of CL:288396
This reverts commit babd70ccd5866fe5eb875e9c725a129d3c881c2c.
It also contains a fix for importing django.
TEST=Test on a ganeti
/usr/local/autotest/site_utils/suite_scheduler/suite_scheduler.py -b -d
/usr/local/autotest/logs -f /usr/local/autotest/suite_scheduler.ini
TEST=Test on a geneti
/usr/local/autotest/site_utils/suite_scheduler/suite_scheduler.py --sanity
(remove site-packages)
BUG=chromium:474671
Change-Id: I155750de1d05b6e3f2625a4ae210622f748975f7
Reviewed-on: https://chromium-review.googlesource.com/290251
Tested-by: Fang Deng <fdeng@chromium.org>
Reviewed-by: Dan Shi <dshi@chromium.org>
Commit-Queue: Fang Deng <fdeng@chromium.org>
diff --git a/scheduler/scheduler_lib.py b/scheduler/scheduler_lib.py
index cdd6c18..304572c 100644
--- a/scheduler/scheduler_lib.py
+++ b/scheduler/scheduler_lib.py
@@ -18,6 +18,7 @@
from autotest_lib.database import database_connection
from autotest_lib.frontend import setup_django_environment
from autotest_lib.frontend.afe import readonly_connection
+from autotest_lib.server import utils as server_utils
DB_CONFIG_SECTION = 'AUTOTEST_WEB'
@@ -42,24 +43,12 @@
"""Raised by the scheduler when an inconsistent state occurs."""
-class Singleton(type):
- """Enforce that only one client class is instantiated per process."""
- _instances = {}
-
- def __call__(cls, *args, **kwargs):
- """Fetch the instance of a class to use for subsequent calls."""
- if cls not in cls._instances:
- cls._instances[cls] = super(Singleton, cls).__call__(
- *args, **kwargs)
- return cls._instances[cls]
-
-
class ConnectionManager(object):
"""Manager for the django database connections.
The connection is used through scheduler_models and monitor_db.
"""
- __metaclass__ = Singleton
+ __metaclass__ = server_utils.Singleton
def __init__(self, readonly=True, autocommit=True):
"""Set global django database options for correct connection handling.
diff --git a/scheduler/scheduler_lib_unittest.py b/scheduler/scheduler_lib_unittest.py
index 0ef7f28..b7bda22 100755
--- a/scheduler/scheduler_lib_unittest.py
+++ b/scheduler/scheduler_lib_unittest.py
@@ -12,6 +12,7 @@
from autotest_lib.database import database_connection
from autotest_lib.frontend import setup_django_environment
from autotest_lib.frontend.afe import readonly_connection
+from autotest_lib.server import utils as server_utils
from autotest_lib.scheduler import scheduler_lib
from django.db import utils as django_utils
@@ -23,7 +24,7 @@
self.connection_manager = None
readonly_connection.set_globally_disabled = mock.MagicMock()
setup_django_environment.enable_autocommit = mock.MagicMock()
- scheduler_lib.Singleton._instances = {}
+ server_utils.Singleton._instances = {}
def tearDown(self):
diff --git a/server/site_utils.py b/server/site_utils.py
index 0f6e303..a0df249 100644
--- a/server/site_utils.py
+++ b/server/site_utils.py
@@ -49,6 +49,18 @@
pass
+class Singleton(type):
+ """Enforce that only one client class is instantiated per process."""
+ _instances = {}
+
+ def __call__(cls, *args, **kwargs):
+ """Fetch the instance of a class to use for subsequent calls."""
+ if cls not in cls._instances:
+ cls._instances[cls] = super(Singleton, cls).__call__(
+ *args, **kwargs)
+ return cls._instances[cls]
+
+
def ParseBuildName(name):
"""Format a build name, given board, type, milestone, and manifest num.
diff --git a/site_utils/suite_scheduler/suite_scheduler.py b/site_utils/suite_scheduler/suite_scheduler.py
index d4b07d8..c43afdc 100755
--- a/site_utils/suite_scheduler/suite_scheduler.py
+++ b/site_utils/suite_scheduler/suite_scheduler.py
@@ -42,7 +42,15 @@
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import logging_config, logging_manager
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
-from autotest_lib.site_utils import server_manager_utils
+try:
+ from autotest_lib.frontend import setup_django_environment
+ # server_manager_utils depend on django which
+ # may not be available when people run checks with --sanity
+ from autotest_lib.site_utils import server_manager_utils
+except ImportError:
+ server_manager_utils = None
+ logging.debug('Could not load server_manager_utils module, expected '
+ 'if you are running sanity check or pre-submit hook')
CONFIG_SECTION = 'SCHEDULER'
@@ -227,6 +235,9 @@
# If server database is enabled, check if the server has role
# `suite_scheduler`. If the server does not have suite_scheduler role,
# exception will be raised and suite scheduler will not continue to run.
+ if not server_manager_utils:
+ raise ImportError(
+ 'Could not import autotest_lib.site_utils.server_manager_utils')
if server_manager_utils.use_server_db():
server_manager_utils.confirm_server_has_role(hostname='localhost',
role='suite_scheduler')
diff --git a/site_utils/suite_scheduler/task.py b/site_utils/suite_scheduler/task.py
index 109bf18..0ef61d8 100644
--- a/site_utils/suite_scheduler/task.py
+++ b/site_utils/suite_scheduler/task.py
@@ -16,8 +16,8 @@
from constants import Builds
import common
+from autotest_lib.server import utils as server_utils
from autotest_lib.server.cros.dynamic_suite import constants
-from autotest_lib.scheduler import scheduler_lib
class MalformedConfigEntry(Exception):
@@ -48,7 +48,7 @@
scheduler's ini file.
"""
- __metaclass__ = scheduler_lib.Singleton
+ __metaclass__ = server_utils.Singleton
# True if suite_scheduler is running for sanity check. When it's set to
# True, the code won't make gsutil call to get the actual tot milestone to