You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by zm...@apache.org on 2015/04/10 01:06:41 UTC

aurora git commit: Remove factory.py

Repository: aurora
Updated Branches:
  refs/heads/master f48d0e11a -> 02717ec6a


Remove factory.py

This patch removes `src/main/python/apache/aurora/client/factory.py` which was a
pile of technical debt. By removing the indirection of creating client object
the code is much easier to understand. As a result of removing this file many
tests had to be touched because they were patching CLUSTERS via factory.py. The
need to patch CLUSTERS at each test site was removed and replaced by modifying
`AuroraClientCommandTest` to patch CLUSTERS before running any test. This
approach is required because `FakeAuroraCommandContext` inherits from
`AuroraCommandContext` which causes the execute on import code in clusters.py to
execute for each test.

Testing Done:
./pants test.pytest src/test/python/apache/aurora/client/cli::

Reviewed at https://reviews.apache.org/r/32905/


Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/02717ec6
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/02717ec6
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/02717ec6

Branch: refs/heads/master
Commit: 02717ec6a6ea0d167fee87aabe56e92d6e66cdcc
Parents: f48d0e1
Author: Zameer Manji <zm...@apache.org>
Authored: Thu Apr 9 16:06:33 2015 -0700
Committer: zmanji@apache.org <zm...@twitter.com>
Committed: Thu Apr 9 16:06:33 2015 -0700

----------------------------------------------------------------------
 src/main/python/apache/aurora/admin/BUILD       |  1 -
 src/main/python/apache/aurora/admin/admin.py    |  8 +++-
 src/main/python/apache/aurora/client/BUILD      | 12 -----
 src/main/python/apache/aurora/client/cli/BUILD  |  1 -
 .../python/apache/aurora/client/cli/context.py  |  9 +++-
 src/main/python/apache/aurora/client/factory.py | 45 -------------------
 .../apache/aurora/admin/test_admin_sla.py       | 36 +++++++--------
 src/test/python/apache/aurora/client/BUILD      | 22 ----------
 src/test/python/apache/aurora/client/cli/BUILD  |  2 -
 .../aurora/client/cli/test_api_from_cli.py      | 15 ++-----
 .../aurora/client/cli/test_cancel_update.py     |  6 +--
 .../apache/aurora/client/cli/test_context.py    | 46 ++++++++------------
 .../apache/aurora/client/cli/test_diff.py       |  3 --
 .../apache/aurora/client/cli/test_kill.py       | 33 +++++---------
 .../apache/aurora/client/cli/test_quota.py      |  5 +--
 .../apache/aurora/client/cli/test_restart.py    |  8 ----
 .../python/apache/aurora/client/cli/test_sla.py | 18 ++------
 .../apache/aurora/client/cli/test_status.py     | 28 +++---------
 .../apache/aurora/client/cli/test_task.py       |  4 --
 .../apache/aurora/client/cli/test_update.py     | 14 +-----
 .../python/apache/aurora/client/cli/util.py     | 17 ++++++--
 .../python/apache/aurora/client/test_factory.py | 32 --------------
 src/test/python/apache/aurora/client/util.py    | 25 -----------
 23 files changed, 94 insertions(+), 296 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/main/python/apache/aurora/admin/BUILD
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/admin/BUILD b/src/main/python/apache/aurora/admin/BUILD
index 84305f9..c51a90b 100644
--- a/src/main/python/apache/aurora/admin/BUILD
+++ b/src/main/python/apache/aurora/admin/BUILD
@@ -26,7 +26,6 @@ python_library(
     'src/main/python/apache/aurora/client:base',
     'src/main/python/apache/aurora/common:clusters',
     'src/main/python/apache/aurora/client:config',
-    'src/main/python/apache/aurora/client:factory',
     'api/src/main/thrift/org/apache/aurora/gen:py-thrift',
   ]
 )

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/main/python/apache/aurora/admin/admin.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/admin/admin.py b/src/main/python/apache/aurora/admin/admin.py
index d9ed66c..d2f7bd1 100644
--- a/src/main/python/apache/aurora/admin/admin.py
+++ b/src/main/python/apache/aurora/admin/admin.py
@@ -23,6 +23,7 @@ from twitter.common import app, log
 from twitter.common.quantity import Amount, Data, Time
 from twitter.common.quantity.parse_simple import parse_data, parse_time
 
+from apache.aurora.client.api import AuroraClientAPI
 from apache.aurora.client.api.sla import JobUpTimeLimit
 from apache.aurora.client.base import (
     AURORA_ADMIN_USER_AGENT_NAME,
@@ -33,7 +34,6 @@ from apache.aurora.client.base import (
     GROUPING_OPTION,
     requires
 )
-from apache.aurora.client.factory import make_client
 from apache.aurora.common.aurora_job_key import AuroraJobKey
 from apache.aurora.common.clusters import CLUSTERS
 from apache.aurora.common.shellify import shellify
@@ -64,7 +64,11 @@ MIN_SLA_INSTANCE_COUNT = optparse.Option(
 
 
 def make_admin_client(cluster):
-  return make_client(cluster, AURORA_ADMIN_USER_AGENT_NAME)
+  if cluster not in CLUSTERS:
+    die('Unknown cluster: %s. Known clusters: %s' % (cluster, ", ".join(CLUSTERS.keys())))
+
+  verbose = getattr(app.get_options(), 'verbosity', 'normal') == 'verbose'
+  return AuroraClientAPI(CLUSTERS[cluster], AURORA_ADMIN_USER_AGENT_NAME, verbose=verbose)
 
 
 @app.command

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/main/python/apache/aurora/client/BUILD
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/BUILD b/src/main/python/apache/aurora/client/BUILD
index 351fc55..e73cd52 100644
--- a/src/main/python/apache/aurora/client/BUILD
+++ b/src/main/python/apache/aurora/client/BUILD
@@ -56,18 +56,6 @@ python_library(
 )
 
 python_library(
-  name = 'factory',
-  sources = ['factory.py'],
-  dependencies = [
-    ':base',
-    '3rdparty/python:twitter.common.app',
-    'src/main/python/apache/aurora/client/hooks',
-    'src/main/python/apache/aurora/common:cluster',
-    'src/main/python/apache/aurora/common:clusters',
-  ]
-)
-
-python_library(
   name = 'client-packaged',
   dependencies = [
     'src/main/python/apache/aurora/common',

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/main/python/apache/aurora/client/cli/BUILD
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/BUILD b/src/main/python/apache/aurora/client/cli/BUILD
index c6b4e8a..3ab41cc 100644
--- a/src/main/python/apache/aurora/client/cli/BUILD
+++ b/src/main/python/apache/aurora/client/cli/BUILD
@@ -56,7 +56,6 @@ python_library(
     'src/main/python/apache/aurora/client/hooks',
     'src/main/python/apache/aurora/client:base',
     'src/main/python/apache/aurora/client:config',
-    'src/main/python/apache/aurora/client:factory',
     'src/main/python/apache/aurora/common',
     'src/main/resources/apache/aurora/client/cli:auroraversion',
     'api/src/main/thrift/org/apache/aurora/gen:py-thrift',

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/main/python/apache/aurora/client/cli/context.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/context.py b/src/main/python/apache/aurora/client/cli/context.py
index 3d4a428..adbffc4 100644
--- a/src/main/python/apache/aurora/client/cli/context.py
+++ b/src/main/python/apache/aurora/client/cli/context.py
@@ -17,6 +17,7 @@ from __future__ import print_function
 import logging
 from fnmatch import fnmatch
 
+from apache.aurora.client.api import AuroraClientAPI
 from apache.aurora.client.base import AURORA_V2_USER_AGENT_NAME, combine_messages
 from apache.aurora.client.cli import (
     Context,
@@ -26,7 +27,7 @@ from apache.aurora.client.cli import (
     EXIT_INVALID_PARAMETER
 )
 from apache.aurora.client.config import get_config
-from apache.aurora.client.factory import make_client
+from apache.aurora.client.hooks.hooked_api import HookedAuroraClientAPI
 from apache.aurora.common.aurora_job_key import AuroraJobKey
 from apache.aurora.common.clusters import CLUSTERS
 
@@ -54,10 +55,14 @@ class AuroraCommandContext(Context):
     Keeps the API handle cached, so that only one handle for each cluster will be created in a
     session.
     """
+    if cluster not in CLUSTERS:
+      raise self.CommandError(EXIT_INVALID_CONFIGURATION, "Unknown cluster: %s" % cluster)
+
     apis = self.apis if enable_hooks else self.unhooked_apis
+    base_class = HookedAuroraClientAPI if enable_hooks else AuroraClientAPI
 
     if cluster not in apis:
-      api = make_client(cluster, AURORA_V2_USER_AGENT_NAME, enable_hooks)
+      api = base_class(CLUSTERS[cluster], AURORA_V2_USER_AGENT_NAME, verbose=True)
       apis[cluster] = api
     return apis[cluster]
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/main/python/apache/aurora/client/factory.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/factory.py b/src/main/python/apache/aurora/client/factory.py
deleted file mode 100644
index f3ae66b..0000000
--- a/src/main/python/apache/aurora/client/factory.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import functools
-
-from twitter.common import app
-
-from apache.aurora.client.api import AuroraClientAPI
-from apache.aurora.client.hooks.hooked_api import HookedAuroraClientAPI
-from apache.aurora.common.cluster import Cluster
-from apache.aurora.common.clusters import CLUSTERS
-
-from .base import die
-
-
-# TODO(wickman) Kill make_client and make_client_factory as part of MESOS-3801.
-# These are currently necessary indirections for the LiveJobDisambiguator among
-# other things but can go away once those are scrubbed.
-def make_client_factory(user_agent, enable_hooks=True):
-  verbose = getattr(app.get_options(), 'verbosity', 'normal') == 'verbose'
-
-  base_class = HookedAuroraClientAPI if enable_hooks else AuroraClientAPI
-
-  class TwitterAuroraClientAPI(base_class):
-    def __init__(self, cluster, *args, **kw):
-      if cluster not in CLUSTERS:
-        die('Unknown cluster: %s' % cluster)
-      super(TwitterAuroraClientAPI, self).__init__(CLUSTERS[cluster], *args, **kw)
-  return functools.partial(TwitterAuroraClientAPI, user_agent=user_agent, verbose=verbose)
-
-
-def make_client(cluster, user_agent, enable_hooks=True):
-  factory = make_client_factory(user_agent, enable_hooks)
-  return factory(cluster.name if isinstance(cluster, Cluster) else cluster)

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/admin/test_admin_sla.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/admin/test_admin_sla.py b/src/test/python/apache/aurora/admin/test_admin_sla.py
index 225251b..54b5a82 100644
--- a/src/test/python/apache/aurora/admin/test_admin_sla.py
+++ b/src/test/python/apache/aurora/admin/test_admin_sla.py
@@ -70,8 +70,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_options = self.setup_mock_options()
     mock_vector = self.create_mock_vector(self.create_hosts(3, 80, 100))
     with contextlib.nested(
-        patch('apache.aurora.admin.admin.make_client',
-            new=create_autospec(spec=AuroraClientAPI)),
+        patch('apache.aurora.admin.admin.make_admin_client',
+              return_value=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.admin.admin.print_results'),
         patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -95,8 +95,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
       fp.flush()
       mock_options = self.setup_mock_options(exclude=fp.name)
       with contextlib.nested(
-          patch('apache.aurora.admin.admin.make_client',
-              new=create_autospec(spec=AuroraClientAPI)),
+          patch('apache.aurora.admin.admin.make_admin_client',
+              return_value=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.admin.admin.print_results'),
           patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)
@@ -118,8 +118,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_vector = self.create_mock_vector(self.create_hosts(3, 80, 100))
     mock_options = self.setup_mock_options(exclude_list=','.join(['h0', 'h1']))
     with contextlib.nested(
-        patch('apache.aurora.admin.admin.make_client',
-            new=create_autospec(spec=AuroraClientAPI)),
+        patch('apache.aurora.admin.admin.make_admin_client',
+            return_value=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.admin.admin.print_results'),
         patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -145,8 +145,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
       fp.flush()
       mock_options = self.setup_mock_options(include=fp.name)
       with contextlib.nested(
-          patch('apache.aurora.admin.admin.make_client',
-              new=create_autospec(spec=AuroraClientAPI)),
+          patch('apache.aurora.admin.admin.make_admin_client',
+              return_value=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.admin.admin.print_results'),
           patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)
@@ -171,8 +171,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     hosts = ['h0', 'h1']
     mock_options = self.setup_mock_options(include_list=','.join(hosts))
     with contextlib.nested(
-        patch('apache.aurora.admin.admin.make_client',
-            new=create_autospec(spec=AuroraClientAPI)),
+        patch('apache.aurora.admin.admin.make_admin_client',
+            return_value=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.admin.admin.print_results'),
         patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -199,8 +199,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
       fp.flush()
       mock_options = self.setup_mock_options(override=fp.name)
       with contextlib.nested(
-          patch('apache.aurora.admin.admin.make_client',
-              new=create_autospec(spec=AuroraClientAPI)),
+          patch('apache.aurora.admin.admin.make_admin_client',
+              return_value=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.admin.admin.print_results'),
           patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)
@@ -224,8 +224,8 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_options = self.setup_mock_options(list_jobs=True)
     mock_vector = self.create_mock_vector(self.create_hosts(3, 50, 100))
     with contextlib.nested(
-        patch('apache.aurora.admin.admin.make_client',
-            new=create_autospec(spec=AuroraClientAPI)),
+        patch('apache.aurora.admin.admin.make_admin_client',
+            return_value=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.admin.admin.print_results'),
         patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -331,8 +331,8 @@ class TestAdminSlaProbeHostsCommand(AuroraClientCommandTest):
     mock_options = self.setup_mock_options(hosts=','.join(hosts))
     mock_vector = self.create_mock_probe_hosts_vector([self.create_probe_hosts(2, 80, True, 0)])
     with contextlib.nested(
-        patch('apache.aurora.admin.admin.make_client',
-            new=create_autospec(spec=AuroraClientAPI)),
+        patch('apache.aurora.admin.admin.make_admin_client',
+            return_value=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.admin.admin.print_results'),
         patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -361,8 +361,8 @@ class TestAdminSlaProbeHostsCommand(AuroraClientCommandTest):
       fp.flush()
       mock_options = self.setup_mock_options(filename=fp.name)
       with contextlib.nested(
-          patch('apache.aurora.admin.admin.make_client',
-              new=create_autospec(spec=AuroraClientAPI)),
+          patch('apache.aurora.admin.admin.make_admin_client',
+              return_value=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.admin.admin.print_results'),
           patch('apache.aurora.admin.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/BUILD
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/BUILD b/src/test/python/apache/aurora/client/BUILD
index fb706bd..c55adfe 100644
--- a/src/test/python/apache/aurora/client/BUILD
+++ b/src/test/python/apache/aurora/client/BUILD
@@ -17,7 +17,6 @@ python_test_suite(name = 'all',
     ':base',
     ':binding_helper',
     ':config',
-    ':factory',
     'src/test/python/apache/aurora/client/api:all',
     'src/test/python/apache/aurora/client/cli:all',
     'src/test/python/apache/aurora/client/hooks:all',
@@ -50,18 +49,6 @@ python_tests(name = 'config',
   ],
 )
 
-python_tests(name = 'factory',
-  sources = ['test_factory.py'],
-  dependencies = [
-    '3rdparty/python:mock',
-    ':util',
-    'src/main/python/apache/aurora/client/api',
-    'src/main/python/apache/aurora/client:factory',
-    'src/main/python/apache/aurora/client/hooks',
-    'src/test/python/apache/aurora/client/cli:util',
-  ],
-)
-
 python_library(
   name = 'fake_scheduler_proxy',
   sources = ['fake_scheduler_proxy.py'],
@@ -69,12 +56,3 @@ python_library(
     'src/main/python/apache/aurora/client/api:scheduler_client',
   ]
 )
-
-python_library(
-  name = 'util',
-  sources = ['util.py'],
-  dependencies = [
-    'src/main/python/apache/aurora/common:cluster',
-    'src/main/python/apache/aurora/common:clusters',
-  ]
-)

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/BUILD
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/BUILD b/src/test/python/apache/aurora/client/cli/BUILD
index c755689..5d92296 100644
--- a/src/test/python/apache/aurora/client/cli/BUILD
+++ b/src/test/python/apache/aurora/client/cli/BUILD
@@ -39,7 +39,6 @@ python_library(
   dependencies = [
     '3rdparty/python:mock',
     'src/main/python/apache/aurora/client/cli',
-    'src/test/python/apache/aurora/client:util',
   ]
 )
 
@@ -222,6 +221,5 @@ python_tests(
   dependencies = [
     '3rdparty/python:mock',
     'src/main/python/apache/aurora/client/cli',
-    'src/main/python/apache/aurora/client:factory',
   ]
 )

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_api_from_cli.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_api_from_cli.py b/src/test/python/apache/aurora/client/cli/test_api_from_cli.py
index ba59957..550c5b6 100644
--- a/src/test/python/apache/aurora/client/cli/test_api_from_cli.py
+++ b/src/test/python/apache/aurora/client/cli/test_api_from_cli.py
@@ -12,8 +12,6 @@
 # limitations under the License.
 #
 
-import contextlib
-
 from mock import call, create_autospec, patch
 
 from apache.aurora.client.api.scheduler_client import SchedulerClient
@@ -70,10 +68,8 @@ class TestApiFromCLI(AuroraClientCommandTest):
     mock_thrift_client = create_autospec(spec=AuroraAdmin.Client, instance=True)
     mock_scheduler_client.get_thrift_client.return_value = mock_thrift_client
     mock_thrift_client.getTasksWithoutConfigs.return_value = self.create_status_response()
-    with contextlib.nested(
-        patch('apache.aurora.client.api.scheduler_client.SchedulerClient.get',
-            return_value=mock_scheduler_client),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.api.scheduler_client.SchedulerClient.get',
+               return_value=mock_scheduler_client):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
       assert mock_thrift_client.getTasksWithoutConfigs.mock_calls == [
@@ -85,11 +81,8 @@ class TestApiFromCLI(AuroraClientCommandTest):
     mock_scheduler_client.get_thrift_client.return_value = mock_thrift_client
 
     mock_thrift_client.getTasksWithoutConfigs.side_effect = IOError("Uh-Oh")
-    with contextlib.nested(
-        patch('apache.aurora.client.api.scheduler_client.SchedulerClient.get',
-            return_value=mock_scheduler_client),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
-
+    with patch('apache.aurora.client.api.scheduler_client.SchedulerClient.get',
+            return_value=mock_scheduler_client):
       cmd = AuroraCommandLine()
       # This should create a scheduler client, set everything up, and then issue a
       # getTasksWithoutConfigs call against the mock_scheduler_client. That should raise an

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_cancel_update.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_cancel_update.py b/src/test/python/apache/aurora/client/cli/test_cancel_update.py
index b0eef0e..f9facb6 100644
--- a/src/test/python/apache/aurora/client/cli/test_cancel_update.py
+++ b/src/test/python/apache/aurora/client/cli/test_cancel_update.py
@@ -12,8 +12,6 @@
 # limitations under the License.
 #
 
-import contextlib
-
 from mock import patch
 from twitter.common.contextutil import temporary_file
 
@@ -66,9 +64,7 @@ class TestClientCancelUpdateCommand(AuroraClientCommandTest):
     """Test kill client-side API logic."""
     (mock_api, mock_scheduler_proxy) = self.create_mock_api()
     mock_scheduler_proxy.releaseLock.return_value = self.get_release_lock_response()
-    with contextlib.nested(
-        patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy):
       with temporary_file() as fp:
         fp.write(self.get_valid_config())
         fp.flush()

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_context.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_context.py b/src/test/python/apache/aurora/client/cli/test_context.py
index da3c003..d63f060 100644
--- a/src/test/python/apache/aurora/client/cli/test_context.py
+++ b/src/test/python/apache/aurora/client/cli/test_context.py
@@ -12,34 +12,34 @@
 # limitations under the License.
 #
 
-from mock import call, Mock, patch
-
-from apache.aurora.client.base import AURORA_V2_USER_AGENT_NAME
+from apache.aurora.client.api import AuroraClientAPI
 from apache.aurora.client.cli.context import AuroraCommandContext
+from apache.aurora.client.hooks.hooked_api import HookedAuroraClientAPI
+from apache.aurora.common.cluster import Cluster
+from apache.aurora.common.clusters import CLUSTERS
 
+TEST_CLUSTER = Cluster(name='some-cluster')
 
-def test_get_api_defaults_to_hooks_enabled():
-  with patch('apache.aurora.client.cli.context.make_client') as mock_make_client:
-    cluster = 'some-cluster'
 
-    AuroraCommandContext().get_api(cluster)
-    assert mock_make_client.mock_calls == [call(cluster, AURORA_V2_USER_AGENT_NAME, True)]
+def test_get_api_defaults_to_hooks_enabled():
+  with CLUSTERS.patch([TEST_CLUSTER]):
+    api = AuroraCommandContext().get_api(TEST_CLUSTER.name)
+    assert isinstance(api, HookedAuroraClientAPI)
+    assert api._cluster == TEST_CLUSTER
 
 
-def test_get_api_caches_hook_enabled_apis_separately():
-  with patch('apache.aurora.client.cli.context.make_client') as mock_make_client:
-    # return a new Mock instance for each call of the two calls we're expecting.
-    mock_make_client.side_effect = [Mock(), Mock()]
+def test_get_api_forwards_hooks_disabled():
+  with CLUSTERS.patch([TEST_CLUSTER]):
+    api = AuroraCommandContext().get_api(TEST_CLUSTER.name, enable_hooks=False)
+    assert isinstance(api, AuroraClientAPI)
+    assert api._cluster == TEST_CLUSTER
 
-    cluster = 'some-cluster'
 
+def test_get_api_caches_hook_enabled_apis_separately():
+  with CLUSTERS.patch([TEST_CLUSTER]):
     context = AuroraCommandContext()
-    hooked_api = context.get_api(cluster)
-    unhooked_api = context.get_api(cluster, False)
-
-    assert mock_make_client.mock_calls == [
-      call(cluster, AURORA_V2_USER_AGENT_NAME, True),
-      call(cluster, AURORA_V2_USER_AGENT_NAME, False)]
+    hooked_api = context.get_api(TEST_CLUSTER.name)
+    unhooked_api = context.get_api(TEST_CLUSTER.name, enable_hooks=False)
 
     assert hooked_api != unhooked_api
 
@@ -48,11 +48,3 @@ def test_get_api_caches_hook_enabled_apis_separately():
 
     assert unhooked_api in context.unhooked_apis.values()
     assert unhooked_api not in context.apis.values()
-
-
-def test_get_api_forwards_hooks_disabled():
-  with patch('apache.aurora.client.cli.context.make_client') as mock_make_client:
-    cluster = 'some-cluster'
-
-    AuroraCommandContext().get_api(cluster, enable_hooks=False)
-    assert mock_make_client.mock_calls == [call(cluster, AURORA_V2_USER_AGENT_NAME, False)]

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_diff.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_diff.py b/src/test/python/apache/aurora/client/cli/test_diff.py
index c8b27a4..f6ce00e 100644
--- a/src/test/python/apache/aurora/client/cli/test_diff.py
+++ b/src/test/python/apache/aurora/client/cli/test_diff.py
@@ -72,7 +72,6 @@ class TestDiffCommand(AuroraClientCommandTest):
     (mock_api, mock_scheduler_proxy) = self.create_mock_api()
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('subprocess.call', return_value=0),
         patch('json.loads', return_value=Mock())) as (_, _, subprocess_patch, _):
 
@@ -105,7 +104,6 @@ class TestDiffCommand(AuroraClientCommandTest):
     self.setup_populate_job_config(mock_scheduler_proxy)
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options),
         patch('subprocess.call', return_value=0),
         patch('json.loads', return_value=Mock())) as (
@@ -132,7 +130,6 @@ class TestDiffCommand(AuroraClientCommandTest):
     self.setup_populate_job_config(mock_scheduler_proxy)
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options),
         patch('subprocess.call', return_value=0),
         patch('json.loads', return_value=Mock())) as (

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_kill.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_kill.py b/src/test/python/apache/aurora/client/cli/test_kill.py
index 7d25860..09734a7 100644
--- a/src/test/python/apache/aurora/client/cli/test_kill.py
+++ b/src/test/python/apache/aurora/client/cli/test_kill.py
@@ -209,8 +209,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)) as (_, m, _):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m):
 
       api = mock_context.get_api('west')
       api.kill_job.return_value = self.create_simple_success_response()
@@ -231,8 +230,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)) as (_, m, _):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m):
 
       api = mock_context.get_api('west')
       api.kill_job.return_value = self.create_simple_success_response()
@@ -255,8 +253,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)) as (_, m, _):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m):
       api = mock_context.get_api('west')
       api.kill_job.return_value = self.create_simple_success_response()
 
@@ -275,8 +272,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     """Test kill client-side API logic."""
     mock_context = FakeAuroraCommandContext()
     with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context)):
       api = mock_context.get_api('west')
       api.kill_job.return_value = self.create_simple_success_response()
 
@@ -295,8 +291,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)) as (_, m, _):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m):
       api = mock_context.get_api('west')
       api.kill_job.return_value = self.create_simple_success_response()
 
@@ -317,8 +312,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)) as (_, m, _):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)) as (_, m):
       api = mock_context.get_api('west')
       mock_context.add_expected_query_result(
           self.create_query_call_result(), job_key=self.TEST_JOBKEY)
@@ -341,8 +335,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock(result=False)
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)):
       api = mock_context.get_api('west')
       mock_context.add_expected_query_result(
           self.create_query_call_result(), job_key=self.TEST_JOBKEY)
@@ -364,8 +357,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     """Test kill client-side API logic."""
     mock_context = FakeAuroraCommandContext()
     with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context)):
       api = mock_context.get_api('west')
       # set up an empty instance list in the getTasksWithoutConfigs response
       status_response = self.create_simple_success_response()
@@ -386,8 +378,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_context = FakeAuroraCommandContext()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=self.get_monitor_mock()),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=self.get_monitor_mock())):
       api = mock_context.get_api('west')
       api.kill_job.return_value = self.create_simple_success_response()
 
@@ -405,8 +396,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_context = FakeAuroraCommandContext()
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=self.get_monitor_mock()),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=self.get_monitor_mock())):
       api = mock_context.get_api('west')
       mock_context.add_expected_query_result(self.create_query_call_result())
       api.kill_job.return_value = self.create_simple_success_response()
@@ -428,8 +418,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
     mock_monitor = self.get_monitor_mock(result=False)
     with contextlib.nested(
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+        patch('apache.aurora.client.cli.jobs.JobMonitor', return_value=mock_monitor)):
       api = mock_context.get_api('west')
       mock_context.add_expected_query_result(self.create_query_call_result())
       api.kill_job.return_value = self.create_simple_success_response()

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_quota.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_quota.py b/src/test/python/apache/aurora/client/cli/test_quota.py
index b97e5c4..3573e4c 100644
--- a/src/test/python/apache/aurora/client/cli/test_quota.py
+++ b/src/test/python/apache/aurora/client/cli/test_quota.py
@@ -12,7 +12,6 @@
 # limitations under the License.
 #
 
-import contextlib
 import json
 
 from mock import patch
@@ -89,9 +88,7 @@ class TestGetQuotaCommand(AuroraClientCommandTest):
     return self._call_get_quota(mock_context, command_args)
 
   def _call_get_quota(self, mock_context, command_args):
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.quota.Quota.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.quota.Quota.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(command_args)
       out = '\n'.join(mock_context.get_out())

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_restart.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_restart.py b/src/test/python/apache/aurora/client/cli/test_restart.py
index 488c6c9..dc67cfe 100644
--- a/src/test/python/apache/aurora/client/cli/test_restart.py
+++ b/src/test/python/apache/aurora/client/cli/test_restart.py
@@ -130,7 +130,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     self.setup_mock_scheduler_for_simple_restart(mock_api)
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -160,7 +159,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     self.setup_mock_scheduler_for_simple_restart(mock_api)
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -182,7 +180,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     self.setup_mock_scheduler_for_simple_restart(mock_api)
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -205,7 +202,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     mock_scheduler_proxy.getTasksWithoutConfigs.return_value = self.create_error_response()
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -231,7 +227,6 @@ class TestRestartCommand(AuroraClientCommandTest):
         patch('apache.aurora.client.cli.context.AuroraCommandContext.print_err',
               side_effect=mock_io.put),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -260,7 +255,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     mock_scheduler_proxy.restartShards.return_value = self.create_error_response()
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -303,7 +297,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     self.setup_mock_scheduler_for_simple_restart(mock_api)
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),
@@ -330,7 +323,6 @@ class TestRestartCommand(AuroraClientCommandTest):
     mock_scheduler_proxy.restartShards.return_value = self.create_error_response()
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
         patch('time.time', side_effect=functools.partial(self.fake_time, self)),

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_sla.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_sla.py b/src/test/python/apache/aurora/client/cli/test_sla.py
index 3d6d99c..0d9ae32 100644
--- a/src/test/python/apache/aurora/client/cli/test_sla.py
+++ b/src/test/python/apache/aurora/client/cli/test_sla.py
@@ -12,8 +12,6 @@
 # limitations under the License.
 #
 
-import contextlib
-
 from mock import create_autospec, patch
 
 from apache.aurora.client.api.sla import JobUpTimeSlaVector
@@ -33,9 +31,7 @@ class TestGetTaskUpCountCommand(AuroraClientCommandTest):
   def test_get_task_up_count_no_duration(self):
     mock_context = FakeAuroraCommandContext()
     self.setup_mock_sla_uptime_vector(mock_context, 10.6533333333)
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['sla', 'get-task-up-count', 'west/role/env/test'])
       out = '\n'.join(mock_context.get_out())
@@ -48,9 +44,7 @@ class TestGetTaskUpCountCommand(AuroraClientCommandTest):
   def test_get_task_up_count_with_durations(self):
     mock_context = FakeAuroraCommandContext()
     self.setup_mock_sla_uptime_vector(mock_context, 95.3577434734)
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['sla', 'get-task-up-count', 'west/role/env/test', '--durations=3m,2d6h,3h'])
       out = '\n'.join(mock_context.get_out())
@@ -70,9 +64,7 @@ class TestGetJobUptimeCommand(AuroraClientCommandTest):
   def test_get_job_uptime_no_percentile(self):
     mock_context = FakeAuroraCommandContext()
     self.setup_mock_sla_uptime_vector(mock_context, 915)
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['sla', 'get-job-uptime', 'west/role/env/test'])
       out = '\n'.join(mock_context.get_out())
@@ -89,9 +81,7 @@ class TestGetJobUptimeCommand(AuroraClientCommandTest):
   def test_get_job_uptime_with_percentiles(self):
     mock_context = FakeAuroraCommandContext()
     self.setup_mock_sla_uptime_vector(mock_context, 915)
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.sla.Sla.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['sla', 'get-job-uptime', 'west/role/env/test', '--percentiles=99.9,85.5'])
       out = '\n'.join(mock_context.get_out())

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_status.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_status.py b/src/test/python/apache/aurora/client/cli/test_status.py
index cf69de8..a75f15e 100644
--- a/src/test/python/apache/aurora/client/cli/test_status.py
+++ b/src/test/python/apache/aurora/client/cli/test_status.py
@@ -223,9 +223,7 @@ class TestJobStatus(AuroraClientCommandTest):
     job, it should end up doing a query using getTasksWithoutConfigs."""
     _, mock_scheduler_proxy = self.create_mock_api()
     mock_scheduler_proxy.getTasksWithoutConfigs.return_value = self.create_status_null_metadata()
-    with contextlib.nested(
-        patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
       mock_scheduler_proxy.getTasksWithoutConfigs.assert_called_with(
@@ -236,9 +234,7 @@ class TestJobStatus(AuroraClientCommandTest):
     job, it should end up doing a query using getTasksWithoutConfigs."""
     mock_context = FakeAuroraCommandContext()
     mock_context.add_expected_status_query_result(self.create_status_null_metadata())
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
       actual = re.sub("\\d\\d:\\d\\d:\\d\\d", "##:##:##", '\n'.join(mock_context.get_out()))
@@ -265,9 +261,7 @@ class TestJobStatus(AuroraClientCommandTest):
     job, it should end up doing a query using getTasksWithoutConfigs."""
     mock_context = FakeAuroraCommandContext()
     mock_context.add_expected_status_query_result(self.create_status_with_inactives())
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
       actual = re.sub("\\d\\d:\\d\\d:\\d\\d", "##:##:##", '\n'.join(mock_context.get_out()))
@@ -314,9 +308,7 @@ class TestJobStatus(AuroraClientCommandTest):
     job, it should end up doing a query using getTasksWithoutConfigs."""
     mock_context = FakeAuroraCommandContext()
     mock_context.add_expected_status_query_result(self.create_status_with_metadata())
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
       actual = re.sub("\\d\\d:\\d\\d:\\d\\d", "##:##:##", '\n'.join(mock_context.get_out()))
@@ -352,9 +344,7 @@ class TestJobStatus(AuroraClientCommandTest):
   def test_successful_status_deep_null_metadata(self):
     (mock_api, mock_scheduler_proxy) = self.create_mock_api()
     mock_scheduler_proxy.getTasksWithoutConfigs.return_value = self.create_status_null_metadata()
-    with contextlib.nested(
-        patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
       mock_scheduler_proxy.getTasksWithoutConfigs.assert_called_with(
@@ -367,9 +357,7 @@ class TestJobStatus(AuroraClientCommandTest):
     mock_api = mock_context.get_api('west')
     mock_api.check_status.return_value = self.create_status_response()
     mock_api.get_jobs.return_value = self.create_getjobs_response()
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.cli.context.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', '*'])
 
@@ -437,9 +425,7 @@ class TestJobStatus(AuroraClientCommandTest):
     job, it should end up doing a query using getTasksWithoutConfigs."""
     mock_context = FakeAuroraCommandContext()
     mock_context.add_expected_status_query_result(self.get_task_status_json())
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', '--write-json', 'west/bozo/test/hello'])
       actual = re.sub("\\d\\d:\\d\\d:\\d\\d", "##:##:##", '\n'.join(mock_context.get_out()))

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_task.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_task.py b/src/test/python/apache/aurora/client/cli/test_task.py
index 2580664..abf6252 100644
--- a/src/test/python/apache/aurora/client/cli/test_task.py
+++ b/src/test/python/apache/aurora/client/cli/test_task.py
@@ -72,8 +72,6 @@ class TestRunCommand(AuroraClientCommandTest):
     sandbox_args = {'slave_root': '/slaveroot', 'slave_run_directory': 'slaverun'}
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
-        patch('apache.aurora.client.cli.task.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.command_runner.'
               'InstanceDistributedCommandRunner.sandbox_args',
             return_value=sandbox_args),
@@ -128,7 +126,6 @@ class TestSshCommand(AuroraClientCommandTest):
     sandbox_args = {'slave_root': '/slaveroot', 'slave_run_directory': 'slaverun'}
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.command_runner.DistributedCommandRunner.sandbox_args',
             return_value=sandbox_args),
         patch('subprocess.call', return_value=0)) as (
@@ -157,7 +154,6 @@ class TestSshCommand(AuroraClientCommandTest):
     mock_scheduler_proxy.getTasksStatus.return_value = self.create_nojob_status_response()
     with contextlib.nested(
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('subprocess.call', return_value=0)) as (
             mock_scheduler_proxy_class,
             mock_clusters,

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/test_update.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_update.py b/src/test/python/apache/aurora/client/cli/test_update.py
index 03c286f..22b2ca7 100644
--- a/src/test/python/apache/aurora/client/cli/test_update.py
+++ b/src/test/python/apache/aurora/client/cli/test_update.py
@@ -163,9 +163,7 @@ class TestUpdateCommand(AuroraClientCommandTest):
   # that the client makes the right API call to the updated.
   def test_update_command_line_succeeds(self):
     mock_context = FakeAuroraCommandContext()
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       mock_api = mock_context.get_api('west')
       mock_api.update_job.return_value = self.create_simple_success_response()
       with temporary_file() as fp:
@@ -182,9 +180,7 @@ class TestUpdateCommand(AuroraClientCommandTest):
 
   def test_update_invalid_config(self):
     mock_context = FakeAuroraCommandContext()
-    with contextlib.nested(
-        patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
+    with patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context):
       mock_api = mock_context.get_api('west')
       with temporary_file() as fp:
         fp.write(self.get_invalid_config('invalid_field=False,'))
@@ -317,7 +313,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
     # - The mock_context stubs out the API.
     # - the test relies on using live code in the API.
     with contextlib.nested(
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
@@ -356,7 +351,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
     fake_mux = self.FakeSchedulerMux()
     self.setup_mock_scheduler_for_simple_update(mock_api)
     with contextlib.nested(
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
@@ -393,7 +387,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
             side_effect=mock_out.put),
         patch('apache.aurora.client.cli.jobs.AuroraCommandContext.print_err',
             side_effect=mock_err.put),
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
@@ -421,7 +414,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
     config = self.get_service_config()
     config = config.replace("instances = 20", "instances = 2")
     with contextlib.nested(
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
@@ -450,7 +442,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
     config = self.get_service_config()
     config = config.replace("instances = 20", "instances = 200")
     with contextlib.nested(
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),
@@ -477,7 +468,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
     config = self.get_valid_config()
     config = config.replace("instances = 20", "instances = 200")
     with contextlib.nested(
-        patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
         patch('apache.aurora.client.api.instance_watcher.StatusHealthCheck',
             return_value=mock_health_check),

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/cli/util.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/util.py b/src/test/python/apache/aurora/client/cli/util.py
index f856fcc..5903101 100644
--- a/src/test/python/apache/aurora/client/cli/util.py
+++ b/src/test/python/apache/aurora/client/cli/util.py
@@ -20,9 +20,10 @@ from mock import create_autospec, Mock, patch
 from apache.aurora.client.cli.context import AuroraCommandContext
 from apache.aurora.client.hooks.hooked_api import HookedAuroraClientAPI
 from apache.aurora.common.aurora_job_key import AuroraJobKey
+from apache.aurora.common.cluster import Cluster
+from apache.aurora.common.clusters import CLUSTERS, Clusters
 
 from ...api_util import SchedulerProxyApiSpec, SchedulerThriftApiSpec
-from ..util import TEST_CLUSTER, TEST_CLUSTERS
 
 from gen.apache.aurora.api.constants import ACTIVE_STATES, CURRENT_API_VERSION
 from gen.apache.aurora.api.ttypes import (
@@ -122,6 +123,12 @@ class AuroraClientCommandTest(unittest.TestCase):
     self.mock_webbrowser = patcher.start()
     self.addCleanup(patcher.stop)
 
+  def run(self, result=None):
+    # Since CLUSTERS is a global value that evaluates code on import this is the best way to
+    # ensure it does not pollute any tests.
+    with CLUSTERS.patch(self.TEST_CLUSTERS._clusters.values()):
+      super(AuroraClientCommandTest, self).run()
+
   @classmethod
   def create_blank_response(cls, code, msg):
     return Response(
@@ -292,13 +299,17 @@ jobs = [HELLO_WORLD]
 
   TEST_JOB = 'hello'
 
-  TEST_CLUSTER = TEST_CLUSTER
+  TEST_CLUSTER = 'west'
 
   TEST_JOBSPEC = 'west/bozo/test/hello'
 
   TEST_JOBKEY = AuroraJobKey('west', 'bozo', 'test', 'hello')
 
-  TEST_CLUSTERS = TEST_CLUSTERS
+  TEST_CLUSTERS = Clusters([Cluster(
+    name=TEST_CLUSTER,
+    zk='zookeeper.example.com',
+    scheduler_zk_path='/foo/bar',
+    auth_mechanism='UNAUTHENTICATED')])
 
   @classmethod
   def get_instance_spec(cls, instances_spec):

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/test_factory.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/test_factory.py b/src/test/python/apache/aurora/client/test_factory.py
deleted file mode 100644
index 5598567..0000000
--- a/src/test/python/apache/aurora/client/test_factory.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from mock import patch
-
-from apache.aurora.client.api import AuroraClientAPI
-from apache.aurora.client.factory import make_client
-from apache.aurora.client.hooks.hooked_api import HookedAuroraClientAPI
-from apache.aurora.client.util import TEST_CLUSTER, TEST_CLUSTERS
-
-
-def test_make_client_defaults_to_hooks_enabled():
-  with patch('apache.aurora.client.factory.CLUSTERS', new=TEST_CLUSTERS):
-    assert isinstance(make_client(TEST_CLUSTER, 'some-user-agent'), HookedAuroraClientAPI)
-
-
-def test_make_client_hooks_disabled():
-  with patch('apache.aurora.client.factory.CLUSTERS', new=TEST_CLUSTERS):
-    client = make_client(TEST_CLUSTER, 'some-user-agent', enable_hooks=False)
-    assert not isinstance(client, HookedAuroraClientAPI)
-    assert isinstance(client, AuroraClientAPI)

http://git-wip-us.apache.org/repos/asf/aurora/blob/02717ec6/src/test/python/apache/aurora/client/util.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/util.py b/src/test/python/apache/aurora/client/util.py
deleted file mode 100644
index 0598697..0000000
--- a/src/test/python/apache/aurora/client/util.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from apache.aurora.common.cluster import Cluster
-from apache.aurora.common.clusters import Clusters
-
-TEST_CLUSTER = 'west'
-
-
-TEST_CLUSTERS = Clusters([Cluster(
-  name=TEST_CLUSTER,
-  zk='zookeeper.example.com',
-  scheduler_zk_path='/foo/bar',
-  auth_mechanism='UNAUTHENTICATED')])