aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wfar...@apache.org
Subject [2/2] git commit: Convert most uses of Mock to create_autospec, remove some uses of mocking altogether.
Date Thu, 06 Nov 2014 06:00:11 GMT
Convert most uses of Mock to create_autospec, remove some uses of mocking altogether.

Bugs closed: AURORA-889

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


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

Branch: refs/heads/master
Commit: d01f0c382e18b065c5823e909cb07a573a6a551b
Parents: 0ad2fca
Author: Bill Farner <wfarner@apache.org>
Authored: Wed Nov 5 21:06:40 2014 -0800
Committer: Bill Farner <wfarner@apache.org>
Committed: Wed Nov 5 21:06:40 2014 -0800

----------------------------------------------------------------------
 .../python/apache/aurora/client/cli/update.py   |   5 +-
 .../python/apache/aurora/client/api/api_util.py | 111 ++++++++++++
 .../python/apache/aurora/client/api/test_api.py |  26 +--
 .../aurora/client/api/test_job_monitor.py       |   6 +-
 .../aurora/client/api/test_quota_check.py       |   6 +-
 .../aurora/client/api/test_scheduler_client.py  |  13 +-
 .../apache/aurora/client/api/test_task_util.py  |   8 +-
 .../aurora/client/cli/test_api_from_cli.py      |  49 ++---
 .../aurora/client/cli/test_cancel_update.py     |  29 +--
 .../aurora/client/cli/test_command_hooks.py     |  38 ++--
 .../apache/aurora/client/cli/test_create.py     |  18 +-
 .../apache/aurora/client/cli/test_cron.py       |  47 ++---
 .../apache/aurora/client/cli/test_diff.py       |  10 +-
 .../apache/aurora/client/cli/test_inspect.py    |   8 +-
 .../apache/aurora/client/cli/test_kill.py       |  23 ++-
 .../apache/aurora/client/cli/test_logging.py    |  15 +-
 .../apache/aurora/client/cli/test_plugins.py    |  15 +-
 .../apache/aurora/client/cli/test_quota.py      |  16 +-
 .../apache/aurora/client/cli/test_restart.py    |  12 +-
 .../python/apache/aurora/client/cli/test_sla.py |   7 +-
 .../apache/aurora/client/cli/test_status.py     |  23 ++-
 .../apache/aurora/client/cli/test_supdate.py    |   4 +-
 .../apache/aurora/client/cli/test_task_run.py   |  12 +-
 .../apache/aurora/client/cli/test_update.py     |  35 ++--
 .../python/apache/aurora/client/cli/util.py     |  55 +++---
 .../apache/aurora/client/commands/test_admin.py |  19 +-
 .../aurora/client/commands/test_admin_sla.py    |  34 ++--
 .../client/commands/test_cancel_update.py       |  24 +--
 .../aurora/client/commands/test_create.py       |  16 +-
 .../apache/aurora/client/commands/test_diff.py  |  24 +--
 .../apache/aurora/client/commands/test_hooks.py |  18 +-
 .../apache/aurora/client/commands/test_kill.py  |  82 ++++-----
 .../aurora/client/commands/test_listjobs.py     |   4 +-
 .../aurora/client/commands/test_restart.py      | 177 ++++++++++---------
 .../apache/aurora/client/commands/test_run.py   |  63 +++----
 .../apache/aurora/client/commands/test_ssh.py   |   8 +-
 .../aurora/client/commands/test_status.py       |  77 ++++----
 .../aurora/client/commands/test_update.py       |  58 +++---
 .../apache/aurora/client/commands/util.py       |  33 ++--
 .../aurora/client/hooks/test_hooked_api.py      |   4 +-
 .../apache/aurora/common/test_transport.py      |  14 +-
 .../aurora/executor/common/test_announcer.py    |  36 ++--
 .../executor/common/test_executor_timeout.py    |   4 +-
 .../aurora/executor/test_status_manager.py      |   2 +-
 .../python/apache/thermos/core/test_helper.py   |   2 +-
 45 files changed, 686 insertions(+), 604 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/main/python/apache/aurora/client/cli/update.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/update.py b/src/main/python/apache/aurora/client/cli/update.py
index 1d3fd66..0797e30 100644
--- a/src/main/python/apache/aurora/client/cli/update.py
+++ b/src/main/python/apache/aurora/client/cli/update.py
@@ -177,7 +177,7 @@ class ListUpdates(Verb):
     api = context.get_api(context.options.cluster)
     response = api.query_job_updates(
         role=context.options.role,
-        jobKey=context.options.jobspec,
+        job_key=context.options.jobspec,
         user=context.options.user,
         update_statuses=context.options.status)
     context.check_and_log_response(response)
@@ -221,8 +221,7 @@ class UpdateStatus(Verb):
 
   def _get_update_id(self, context, jobkey):
     api = context.get_api(context.options.jobspec.cluster)
-    response = api.query_job_updates(
-        jobKey=context.options.jobspec)
+    response = api.query_job_updates(job_key=context.options.jobspec)
     context.check_and_log_response(response, "")
     for summary in response.result.getJobUpdateSummariesResult.updateSummaries:
       if summary.jobKey == jobkey:

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/api/api_util.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/api/api_util.py b/src/test/python/apache/aurora/client/api/api_util.py
new file mode 100644
index 0000000..6e12154
--- /dev/null
+++ b/src/test/python/apache/aurora/client/api/api_util.py
@@ -0,0 +1,111 @@
+from apache.aurora.client.api.scheduler_client import SchedulerProxy
+
+from gen.apache.aurora.api import ReadOnlyScheduler
+
+
+class SchedulerThriftApiSpec(ReadOnlyScheduler.Iface):
+  """
+  A concrete definition of the thrift API used by the client. Intended primarily to be used as a
+  spec definition for unit testing, since the client effectively augments function signatures by
+  allowing callers to omit the session argument (in SchedulerProxy). These signatures should be
+  identical to those in AuroraAdmin.Iface, with the session removed.
+  """
+
+  def setQuota(self, ownerRole, quota):
+    pass
+
+  def forceTaskState(self, taskId, status):
+    pass
+
+  def performBackup(self):
+    pass
+
+  def listBackups(self):
+    pass
+
+  def stageRecovery(self, backupId):
+    pass
+
+  def queryRecovery(self, query):
+    pass
+
+  def deleteRecoveryTasks(self, query):
+    pass
+
+  def commitRecovery(self):
+    pass
+
+  def unloadRecovery(self):
+    pass
+
+  def startMaintenance(self, hosts):
+    pass
+
+  def drainHosts(self, hosts):
+    pass
+
+  def maintenanceStatus(self, hosts):
+    pass
+
+  def endMaintenance(self, hosts):
+    pass
+
+  def snapshot(self):
+    pass
+
+  def rewriteConfigs(self, request):
+    pass
+
+  def createJob(self, description, lock):
+    pass
+
+  def scheduleCronJob(self, description, lock):
+    pass
+
+  def descheduleCronJob(self, job, lock):
+    pass
+
+  def startCronJob(self, job):
+    pass
+
+  def restartShards(self, job, shardIds, lock):
+    pass
+
+  def killTasks(self, query, lock):
+    pass
+
+  def addInstances(self, config, lock):
+    pass
+
+  def acquireLock(self, lockKey):
+    pass
+
+  def releaseLock(self, lock, validation):
+    pass
+
+  def replaceCronTemplate(self, config, lock):
+    pass
+
+  def startJobUpdate(self, request):
+    pass
+
+  def pauseJobUpdate(self, jobKey):
+    pass
+
+  def resumeJobUpdate(self, jobKey):
+    pass
+
+  def abortJobUpdate(self, jobKey):
+    pass
+
+  def pulseJobUpdate(self, updateId):
+    pass
+
+
+class SchedulerProxyApiSpec(SchedulerThriftApiSpec, SchedulerProxy):
+  """
+  A concrete definition of the API provided by SchedulerProxy.
+  """
+
+  def url(self):
+    pass

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/api/test_api.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/api/test_api.py b/src/test/python/apache/aurora/client/api/test_api.py
index 47b5236..1f4e9fe 100644
--- a/src/test/python/apache/aurora/client/api/test_api.py
+++ b/src/test/python/apache/aurora/client/api/test_api.py
@@ -13,14 +13,18 @@
 #
 import unittest
 
-from mock import Mock
+from mock import create_autospec
 
 from apache.aurora.client.api import AuroraClientAPI
 from apache.aurora.common.aurora_job_key import AuroraJobKey
 from apache.aurora.common.cluster import Cluster
 from apache.aurora.config import AuroraConfig
+from apache.aurora.config.schema.base import UpdateConfig
+
+from .api_util import SchedulerThriftApiSpec
 
 from gen.apache.aurora.api.ttypes import (
+    JobConfiguration,
     JobUpdateQuery,
     JobUpdateRequest,
     JobUpdateSettings,
@@ -49,11 +53,11 @@ class TestJobUpdateApis(unittest.TestCase):
 
   @classmethod
   def create_blank_response(cls, code, msg):
-    response = Mock(spec=Response)
-    response.responseCode = code
-    response.messageDEPRECATED = msg
-    response.result = Mock(spec=Result)
-    return response
+    return Response(
+      responseCode=code,
+      messageDEPRECATED=msg,
+      result=create_autospec(spec=Result, spec_set=True, instance=True)
+    )
 
   @classmethod
   def create_simple_success_response(cls):
@@ -66,7 +70,7 @@ class TestJobUpdateApis(unittest.TestCase):
   @classmethod
   def mock_api(cls):
     api = AuroraClientAPI(Cluster(name="foo"))
-    mock_proxy = Mock()
+    mock_proxy = create_autospec(spec=SchedulerThriftApiSpec, spec_set=True, instance=True)
     api._scheduler_proxy = mock_proxy
     return api, mock_proxy
 
@@ -90,14 +94,14 @@ class TestJobUpdateApis(unittest.TestCase):
 
   @classmethod
   def mock_job_config(cls, error=None):
-    config = Mock(spec=AuroraConfig)
-    mock_get = Mock()
+    config = create_autospec(spec=AuroraConfig, instance=True)
+    mock_get = create_autospec(spec=UpdateConfig, instance=True)
     mock_get.get.return_value = cls.UPDATE_CONFIG
     if error:
       config.update_config.side_effect = error
     else:
       config.update_config.return_value = mock_get
-    mock_task_config = Mock()
+    mock_task_config = create_autospec(spec=JobConfiguration, instance=True)
     mock_task_config.taskConfig = TaskConfig()
     config.job.return_value = mock_task_config
     config.role.return_value = "role"
@@ -169,7 +173,7 @@ class TestJobUpdateApis(unittest.TestCase):
     job_key = AuroraJobKey("foo", "role", "env", "name")
     query = JobUpdateQuery(
         jobKey=job_key.to_thrift(),
-        updateStatuses=set([JobUpdateStatus.ROLLING_FORWARD]))
+        updateStatuses={JobUpdateStatus.ROLLING_FORWARD})
     api.query_job_updates(job_key=job_key, update_statuses=query.updateStatuses)
     mock_proxy.getJobUpdateSummaries.assert_called_once_with(query)
 

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/api/test_job_monitor.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/api/test_job_monitor.py b/src/test/python/apache/aurora/client/api/test_job_monitor.py
index cb2503e..27d8025 100644
--- a/src/test/python/apache/aurora/client/api/test_job_monitor.py
+++ b/src/test/python/apache/aurora/client/api/test_job_monitor.py
@@ -13,11 +13,13 @@
 #
 import unittest
 
-from mock import Mock
+from mock import create_autospec
 
 from apache.aurora.client.api.job_monitor import JobMonitor
 from apache.aurora.common.aurora_job_key import AuroraJobKey
 
+from .api_util import SchedulerThriftApiSpec
+
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
     JobKey,
@@ -49,7 +51,7 @@ class FakeEvent(object):
 class JobMonitorTest(unittest.TestCase):
 
   def setUp(self):
-    self._scheduler = Mock()
+    self._scheduler = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     self._job_key = AuroraJobKey('cl', 'johndoe', 'test', 'test_job')
     self._event = FakeEvent()
 

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/api/test_quota_check.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/api/test_quota_check.py b/src/test/python/apache/aurora/client/api/test_quota_check.py
index d75bd1b..cb443c2 100644
--- a/src/test/python/apache/aurora/client/api/test_quota_check.py
+++ b/src/test/python/apache/aurora/client/api/test_quota_check.py
@@ -15,10 +15,12 @@
 import unittest
 from copy import deepcopy
 
-from mock import Mock
+from mock import create_autospec
 
 from apache.aurora.client.api.quota_check import CapacityRequest, QuotaCheck
 
+from .api_util import SchedulerThriftApiSpec
+
 from gen.apache.aurora.api.ttypes import (
     GetQuotaResult,
     JobKey,
@@ -31,7 +33,7 @@ from gen.apache.aurora.api.ttypes import (
 
 class QuotaCheckTest(unittest.TestCase):
   def setUp(self):
-    self._scheduler = Mock()
+    self._scheduler = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     self._quota_checker = QuotaCheck(self._scheduler)
     self._role = 'mesos'
     self._name = 'quotajob'

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/api/test_scheduler_client.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/api/test_scheduler_client.py b/src/test/python/apache/aurora/client/api/test_scheduler_client.py
index af8353e..1f1c6e0 100644
--- a/src/test/python/apache/aurora/client/api/test_scheduler_client.py
+++ b/src/test/python/apache/aurora/client/api/test_scheduler_client.py
@@ -334,7 +334,7 @@ def test_url_when_not_connected_and_cluster_has_no_proxy_url(scheme):
   host = 'some-host.example.com'
   port = 31181
 
-  mock_zk = mock.MagicMock(spec=TwitterKazooClient)
+  mock_zk = mock.create_autospec(spec=TwitterKazooClient, instance=True)
 
   service_json = '''{
     "additionalEndpoints": {
@@ -382,7 +382,7 @@ def test_url_when_not_connected_and_cluster_has_no_proxy_url(scheme):
 @mock.patch('apache.aurora.client.api.scheduler_client.TRequestsTransport', spec=TRequestsTransport)
 def test_connect_scheduler(mock_client):
   mock_client.return_value.open.side_effect = [TTransport.TTransportException, True]
-  mock_time = mock.Mock(spec=time)
+  mock_time = mock.create_autospec(spec=time, instance=True)
   scheduler_client.SchedulerClient._connect_scheduler(
       'https://scheduler.example.com:1337',
       mock_time)
@@ -395,8 +395,11 @@ def test_connect_scheduler(mock_client):
             spec=scheduler_client.SchedulerClient)
 @mock.patch('threading._Event.wait')
 def test_transient_error(_, client):
-  mock_scheduler_client = mock.Mock(spec=scheduler_client.SchedulerClient)
-  mock_thrift_client = mock.Mock(spec=AuroraAdmin.Client)
+  mock_scheduler_client = mock.create_autospec(
+      spec=scheduler_client.SchedulerClient,
+      spec_set=False,
+      instance=True)
+  mock_thrift_client = mock.create_autospec(spec=AuroraAdmin.Client, instance=True)
   mock_thrift_client.killTasks.side_effect = [
       Response(responseCode=ResponseCode.ERROR_TRANSIENT,
                details=[ResponseDetail(message="message1"), ResponseDetail(message="message2")],
@@ -410,6 +413,6 @@ def test_transient_error(_, client):
   client.get.return_value = mock_scheduler_client
 
   proxy = TestSchedulerProxy(Cluster(name='local'))
-  proxy.killTasks(TaskQuery())
+  proxy.killTasks(TaskQuery(), None)
 
   assert mock_thrift_client.killTasks.call_count == 3

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/api/test_task_util.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/api/test_task_util.py b/src/test/python/apache/aurora/client/api/test_task_util.py
index 582c708..3e772b9 100644
--- a/src/test/python/apache/aurora/client/api/test_task_util.py
+++ b/src/test/python/apache/aurora/client/api/test_task_util.py
@@ -14,11 +14,13 @@
 
 import unittest
 
-from mock import Mock
+from mock import create_autospec
 
 from apache.aurora.client.api.scheduler_mux import SchedulerMux
 from apache.aurora.client.api.task_util import StatusMuxHelper
 
+from ..api.api_util import SchedulerThriftApiSpec
+
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
     Response,
@@ -49,13 +51,13 @@ class TaskUtilTest(unittest.TestCase):
 
   @classmethod
   def mock_mux(cls, tasks):
-    mux = Mock(spec=SchedulerMux)
+    mux = create_autospec(spec=SchedulerMux, instance=True)
     mux.enqueue_and_wait.return_value = tasks
     return mux
 
   @classmethod
   def mock_scheduler(cls, response_code=None):
-    scheduler = Mock()
+    scheduler = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     response_code = ResponseCode.OK if response_code is None else response_code
     resp = Response(responseCode=response_code, messageDEPRECATED='test')
     resp.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=cls.create_tasks()))

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 3e7006e..b855c3c 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
@@ -14,7 +14,7 @@
 
 import contextlib
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 
 from apache.aurora.client.api.scheduler_client import SchedulerClient
 from apache.aurora.client.cli import EXIT_UNKNOWN_ERROR
@@ -24,10 +24,7 @@ from .util import AuroraClientCommandTest
 
 from gen.apache.aurora.api import AuroraAdmin
 from gen.apache.aurora.api.ttypes import (
-    GetJobsResult,
-    JobConfiguration,
     JobKey,
-    Response,
     ResponseCode,
     Result,
     ScheduleStatusResult,
@@ -48,36 +45,18 @@ class TestApiFromCLI(AuroraClientCommandTest):
     return result
 
   @classmethod
-  def create_getjobs_response(cls):
-    result = Mock(spec=Response)
-    result.responseCode = ResponseCode.OK
-    result.result = Mock(spec=Result)
-    result.result.getJobsResult = Mock(spec=GetJobsResult)
-    mock_job_one = Mock(spec=JobConfiguration)
-    mock_job_one.key = Mock(spec=JobKey)
-    mock_job_one.key.role = 'RoleA'
-    mock_job_one.key.environment = 'test'
-    mock_job_one.key.name = 'hithere'
-    mock_job_two = Mock(spec=JobConfiguration)
-    mock_job_two.key = Mock(spec=JobKey)
-    mock_job_two.key.role = 'bozo'
-    mock_job_two.key.environment = 'test'
-    mock_job_two.key.name = 'hello'
-    result.result.getJobsResult.configs = [mock_job_one, mock_job_two]
-    return result
-
-  @classmethod
   def create_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    resp.result.scheduleStatusResult.tasks = set(cls.create_scheduled_tasks())
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(tasks=set(cls.create_scheduled_tasks())))
     return resp
 
   @classmethod
   def create_status_response_null_metadata(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    resp.result.scheduleStatusResult.tasks = set(cls.create_mock_scheduled_task_no_metadata())
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(
+            tasks=set(cls.create_mock_scheduled_task_no_metadata())))
     return resp
 
   @classmethod
@@ -87,20 +66,22 @@ class TestApiFromCLI(AuroraClientCommandTest):
   def test_successful_status_deep(self):
     """Test the status command more deeply: in a request with a fully specified
     job, it should end up doing a query using getTasksWithoutConfigs."""
-    _, mock_scheduler_proxy = self.create_mock_api()
-    mock_scheduler_proxy.query.return_value = self.create_status_response()
+    mock_scheduler_client = create_autospec(spec=SchedulerClient, instance=True)
+    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.SchedulerProxy', return_value=mock_scheduler_proxy),
+        patch('apache.aurora.client.api.scheduler_client.SchedulerClient.get',
+            return_value=mock_scheduler_client),
         patch('apache.aurora.client.factory.CLUSTERS', new=self.TEST_CLUSTERS)):
       cmd = AuroraCommandLine()
       cmd.execute(['job', 'status', 'west/bozo/test/hello'])
-      mock_scheduler_proxy.getTasksWithoutConfigs.assert_called_with(
+      mock_thrift_client.getTasksWithoutConfigs.assert_called_with(
           TaskQuery(jobKeys=[JobKey(role='bozo', environment='test', name='hello')]))
 
   def test_status_api_failure(self):
-    # TODO(wfarner): Consider spec_set instead of spec.
-    mock_scheduler_client = Mock(spec=SchedulerClient)
-    mock_thrift_client = Mock(spec=AuroraAdmin.Client)
+    mock_scheduler_client = create_autospec(spec=SchedulerClient, instance=True)
+    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.side_effect = IOError("Uh-Oh")

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 fb5a527..b0eef0e 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
@@ -14,7 +14,7 @@
 
 import contextlib
 
-from mock import Mock, patch
+from mock import patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli.client import AuroraCommandLine
@@ -22,40 +22,17 @@ from apache.aurora.common.aurora_job_key import AuroraJobKey
 
 from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 
-from gen.apache.aurora.api.ttypes import JobKey, ScheduleStatus, ScheduleStatusResult, TaskQuery
+from gen.apache.aurora.api.ttypes import JobKey, TaskQuery
 
 
 class TestClientCancelUpdateCommand(AuroraClientCommandTest):
 
   @classmethod
-  def setup_mock_api_factory(cls):
-    mock_api_factory, mock_api = cls.create_mock_api_factory()
-    mock_api_factory.return_value.cancel_update.return_value = cls.get_cancel_update_response()
-    return mock_api_factory
-
-  @classmethod
-  def create_mock_status_query_result(cls, scheduleStatus):
-    mock_query_result = cls.create_simple_success_response()
-    mock_query_result.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    if scheduleStatus == ScheduleStatus.INIT:
-      # status query result for before job is launched.
-      mock_query_result.result.scheduleStatusResult.tasks = []
-    else:
-      mock_task_one = cls.create_mock_task('hello', 0, 1000, scheduleStatus)
-      mock_task_two = cls.create_mock_task('hello', 1, 1004, scheduleStatus)
-      mock_query_result.result.scheduleStatusResult.tasks = [mock_task_one, mock_task_two]
-    return mock_query_result
-
-  @classmethod
-  def get_cancel_update_response(cls):
-    return cls.create_simple_success_response()
-
-  @classmethod
   def assert_cancel_update_called(cls, mock_api):
     # Running cancel update should result in calling the API cancel_update
     # method once, with an AuroraJobKey parameter.
     assert mock_api.cancel_update.call_count == 1
-    assert mock_api.cancel_update.called_with(
+    mock_api.cancel_update.assert_called_with(
         AuroraJobKey(cls.TEST_CLUSTER, cls.TEST_ROLE, cls.TEST_ENV, cls.TEST_JOB),
         config=None)
 

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_command_hooks.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_command_hooks.py b/src/test/python/apache/aurora/client/cli/test_command_hooks.py
index eb4d413..d3b3b9d 100644
--- a/src/test/python/apache/aurora/client/cli/test_command_hooks.py
+++ b/src/test/python/apache/aurora/client/cli/test_command_hooks.py
@@ -14,7 +14,8 @@
 
 import contextlib
 
-from mock import Mock, patch
+import requests
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli import EXIT_PERMISSION_VIOLATION
@@ -27,6 +28,7 @@ from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
     JobKey,
+    Result,
     ScheduledTask,
     ScheduleStatus,
     ScheduleStatusResult,
@@ -99,27 +101,25 @@ class TestClientCreateCommand(AuroraClientCommandTest):
 
   @classmethod
   def create_mock_task(cls, task_id, instance_id, initial_time, status):
-    mock_task = Mock(spec=ScheduledTask)
-    mock_task.assignedTask = Mock(spec=AssignedTask)
-    mock_task.assignedTask.taskId = task_id
-    mock_task.assignedTask.instanceId = instance_id
-    mock_task.status = status
-    mock_task_event = Mock(spec=TaskEvent)
-    mock_task_event.timestamp = initial_time
-    mock_task.taskEvents = [mock_task_event]
-    return mock_task
+    return ScheduledTask(
+        status=status,
+        assignedTask=AssignedTask(
+          taskId=task_id,
+          instanceId=instance_id),
+        taskEvents=[TaskEvent(timestamp=initial_time)]
+    )
 
   @classmethod
   def create_mock_status_query_result(cls, scheduleStatus):
     mock_query_result = cls.create_simple_success_response()
-    mock_query_result.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
     if scheduleStatus == ScheduleStatus.INIT:
       # status query result for before job is launched.
-      mock_query_result.result.scheduleStatusResult.tasks = []
+      tasks = []
     else:
       mock_task_one = cls.create_mock_task("hello", 0, 1000, scheduleStatus)
       mock_task_two = cls.create_mock_task("hello", 1, 1004, scheduleStatus)
-      mock_query_result.result.scheduleStatusResult.tasks = [mock_task_one, mock_task_two]
+      tasks = [mock_task_one, mock_task_two]
+    mock_query_result.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=tasks))
     return mock_query_result
 
   @classmethod
@@ -158,11 +158,11 @@ class TestClientCreateCommand(AuroraClientCommandTest):
     with patch("apache.aurora.client.cli.jobs.Job.create_context", return_value=mock_context):
       mock_query = self.create_mock_query()
       mock_context.add_expected_status_query_result(
-        self.create_mock_status_query_result(ScheduleStatus.INIT))
+          self.create_mock_status_query_result(ScheduleStatus.INIT))
       mock_context.add_expected_status_query_result(
-        self.create_mock_status_query_result(ScheduleStatus.RUNNING))
+          self.create_mock_status_query_result(ScheduleStatus.RUNNING))
       mock_context.add_expected_status_query_result(
-        self.create_mock_status_query_result(ScheduleStatus.RUNNING))
+          self.create_mock_status_query_result(ScheduleStatus.RUNNING))
       mock_context.get_api("west").check_status.side_effect = (
         lambda x: self.create_mock_status_query_result(ScheduleStatus.RUNNING))
       api = mock_context.get_api("west")
@@ -253,7 +253,7 @@ class TestClientCreateCommand(AuroraClientCommandTest):
     """Load up a set of skips, specified in JSON, and then check a bunch of different
     cases to see that the skip rules work correctly.
     """
-    mock_response = Mock()
+    mock_response = create_autospec(spec=requests.Response, instance=True)
     mock_context = FakeAuroraCommandContext()
     with patch("requests.get", return_value=mock_response):
       mock_response.json.return_value = {
@@ -300,7 +300,7 @@ class TestClientCreateCommand(AuroraClientCommandTest):
     GlobalCommandHookRegistry.register_command_hook(command_hook)
     command_hook_two = SecondHookForTesting(False)
     GlobalCommandHookRegistry.register_command_hook(command_hook_two)
-    mock_response = Mock()
+    mock_response = create_autospec(spec=requests.Response, instance=True)
     mock_context = FakeAuroraCommandContext()
 
     with contextlib.nested(
@@ -350,7 +350,7 @@ class TestClientCreateCommand(AuroraClientCommandTest):
     GlobalCommandHookRegistry.register_command_hook(command_hook)
     command_hook_two = SecondHookForTesting(False)
     GlobalCommandHookRegistry.register_command_hook(command_hook_two)
-    mock_response = Mock()
+    mock_response = create_autospec(spec=requests.Response, instance=True)
     mock_context = FakeAuroraCommandContext()
 
     with contextlib.nested(

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_create.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_create.py b/src/test/python/apache/aurora/client/cli/test_create.py
index 6013fa1..1dec54c 100644
--- a/src/test/python/apache/aurora/client/cli/test_create.py
+++ b/src/test/python/apache/aurora/client/cli/test_create.py
@@ -16,7 +16,7 @@ import contextlib
 import os
 import shutil
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli import (
@@ -34,6 +34,7 @@ from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
     JobKey,
+    Result,
     ScheduledTask,
     ScheduleStatus,
     ScheduleStatusResult,
@@ -50,12 +51,12 @@ class TestClientCreateCommand(AuroraClientCommandTest):
 
   @classmethod
   def create_mock_task(cls, task_id, instance_id, initial_time, status):
-    mock_task = Mock(spec=ScheduledTask)
-    mock_task.assignedTask = Mock(spec=AssignedTask)
+    mock_task = create_autospec(spec=ScheduledTask, instance=True)
+    mock_task.assignedTask = create_autospec(spec=AssignedTask, instance=True)
     mock_task.assignedTask.taskId = task_id
     mock_task.assignedTask.instanceId = instance_id
     mock_task.status = status
-    mock_task_event = Mock(spec=TaskEvent)
+    mock_task_event = create_autospec(spec=TaskEvent, instance=True)
     mock_task_event.timestamp = initial_time
     mock_task.taskEvents = [mock_task_event]
     return mock_task
@@ -63,10 +64,10 @@ class TestClientCreateCommand(AuroraClientCommandTest):
   @classmethod
   def create_mock_status_query_result(cls, scheduleStatus):
     mock_query_result = cls.create_simple_success_response()
-    mock_query_result.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    mock_task_one = cls.create_mock_task('hello', 0, 1000, scheduleStatus)
-    mock_task_two = cls.create_mock_task('hello', 1, 1004, scheduleStatus)
-    mock_query_result.result.scheduleStatusResult.tasks = [mock_task_one, mock_task_two]
+    mock_query_result.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=[
+        cls.create_mock_task('hello', 0, 1000, scheduleStatus),
+        cls.create_mock_task('hello', 1, 1004, scheduleStatus)
+    ]))
     return mock_query_result
 
   @classmethod
@@ -249,7 +250,6 @@ class TestClientCreateCommand(AuroraClientCommandTest):
       # Check that create_job was not called.
       api = mock_context.get_api('west')
       assert api.create_job.call_count == 0
-      assert api.scheduler_proxy.test_simple_successful_create_job.call_count == 0
 
   def test_interrupt(self):
     mock_context = FakeAuroraCommandContext()

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_cron.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_cron.py b/src/test/python/apache/aurora/client/cli/test_cron.py
index b84bbfc..029a0c5 100644
--- a/src/test/python/apache/aurora/client/cli/test_cron.py
+++ b/src/test/python/apache/aurora/client/cli/test_cron.py
@@ -16,16 +16,17 @@
 
 import contextlib
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli import EXIT_API_ERROR, EXIT_INVALID_CONFIGURATION, EXIT_OK
 from apache.aurora.client.cli.client import AuroraCommandLine
 from apache.aurora.config import AuroraConfig
 
+from ..api.api_util import SchedulerProxyApiSpec
 from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 
-from gen.apache.aurora.api.ttypes import JobKey
+from gen.apache.aurora.api.ttypes import GetJobsResult, JobConfiguration, JobKey, Result
 
 
 class TestCronNoun(AuroraClientCommandTest):
@@ -126,19 +127,16 @@ class TestCronNoun(AuroraClientCommandTest):
   @classmethod
   def _create_getjobs_response(cls):
     response = cls.create_simple_success_response()
-    response.result = Mock()
-    response.result.getJobsResult = Mock()
-    mockjob = Mock()
-    mockjob.cronSchedule = "* * * * *"
-    mockjob.key = Mock()
-    mockjob.key.environment = "test"
-    mockjob.key.name = "hello"
-    mockjob.key.role = "bozo"
-    response.result.getJobsResult.configs = [mockjob]
+    response.result = Result(getJobsResult=GetJobsResult(configs=[
+        JobConfiguration(
+            cronSchedule='* * * * *',
+            key=JobKey(role='bozo', environment='test', name='hello'))
+    ]))
     return response
 
   def test_cron_status(self):
-    (mock_api, mock_scheduler_proxy) = self.create_mock_api()
+    (_, mock_scheduler_proxy) = self.create_mock_api()
+    mock_scheduler_proxy = create_autospec(spec=SchedulerProxyApiSpec)
     with contextlib.nested(
         patch('time.sleep'),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
@@ -154,7 +152,7 @@ class TestCronNoun(AuroraClientCommandTest):
       mock_print.assert_called_with("west/bozo/test/hello\t * * * * *")
 
   def test_cron_status_multiple_jobs(self):
-    (mock_api, mock_scheduler_proxy) = self.create_mock_api()
+    _, mock_scheduler_proxy = self.create_mock_api()
     with contextlib.nested(
         patch('time.sleep'),
         patch('apache.aurora.client.api.SchedulerProxy', return_value=mock_scheduler_proxy),
@@ -162,21 +160,14 @@ class TestCronNoun(AuroraClientCommandTest):
         patch('apache.aurora.client.cli.context.AuroraCommandContext.print_out')) as (
             _, _, _, mock_print):
       response = self.create_simple_success_response()
-      response.result = Mock()
-      response.result.getJobsResult = Mock()
-      mockjob1 = Mock()
-      mockjob1.cronSchedule = "* * * * *"
-      mockjob1.key = Mock()
-      mockjob1.key.environment = "test"
-      mockjob1.key.name = "hello2"
-      mockjob1.key.role = "bozo"
-      mockjob2 = Mock()
-      mockjob2.cronSchedule = "* * * * *"
-      mockjob2.key = Mock()
-      mockjob2.key.environment = "test"
-      mockjob2.key.name = "hello"
-      mockjob2.key.role = "bozo"
-      response.result.getJobsResult.configs = [mockjob1, mockjob2]
+      response.result = Result(getJobsResult=GetJobsResult(configs=[
+          JobConfiguration(
+              key=JobKey(role='bozo', environment='test', name='hello'),
+              cronSchedule='* * * * *'),
+          JobConfiguration(
+              key=JobKey(role='bozo', environment='test', name='hello2'),
+              cronSchedule='* * * * *')
+      ]))
       mock_scheduler_proxy.getJobs.return_value = response
 
       cmd = AuroraCommandLine()

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 f7c07f2..95c7c92 100644
--- a/src/test/python/apache/aurora/client/cli/test_diff.py
+++ b/src/test/python/apache/aurora/client/cli/test_diff.py
@@ -29,6 +29,7 @@ from gen.apache.aurora.api.ttypes import (
     JobKey,
     PopulateJobResult,
     ResponseCode,
+    Result,
     ScheduleStatusResult,
     TaskQuery
 )
@@ -50,8 +51,8 @@ class TestDiffCommand(AuroraClientCommandTest):
   @classmethod
   def create_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    resp.result.scheduleStatusResult.tasks = set(cls.create_scheduled_tasks())
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(tasks=set(cls.create_scheduled_tasks())))
     return resp
 
   @classmethod
@@ -61,10 +62,11 @@ class TestDiffCommand(AuroraClientCommandTest):
   @classmethod
   def setup_populate_job_config(cls, api):
     populate = cls.create_simple_success_response()
-    populate.result.populateJobResult = Mock(spec=PopulateJobResult)
     api.populateJobConfig.return_value = populate
     tasks = set(task.assignedTask.task for task in cls.create_scheduled_tasks())
-    populate.result.populateJobResult.populatedDEPRECATED = tasks
+    populate.result = Result(populateJobResult=PopulateJobResult(
+        populatedDEPRECATED=tasks
+    ))
     return populate
 
   def test_successful_diff(self):

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_inspect.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_inspect.py b/src/test/python/apache/aurora/client/cli/test_inspect.py
index b5b949b..1c07d91 100644
--- a/src/test/python/apache/aurora/client/cli/test_inspect.py
+++ b/src/test/python/apache/aurora/client/cli/test_inspect.py
@@ -14,7 +14,7 @@
 
 import contextlib
 
-from mock import Mock, patch
+from mock import create_autospec, Mock, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli.client import AuroraCommandLine
@@ -27,9 +27,9 @@ from gen.apache.aurora.api.ttypes import CronCollisionPolicy
 
 class TestInspectCommand(AuroraClientCommandTest):
   def get_mock_config(self):
-    config = Mock(spec=AuroraConfig)
-    # TODO(mchucarroll): figure out how to spec this. The raw_config is a Pystachio spec,
-    # and that seems to blow up mock.
+    config = create_autospec(spec=AuroraConfig, instance=True)
+    # TODO(wfarner): figure out how to spec this. The raw_config is a Pystachio spec, and that seems
+    # to blow up mock.
     raw_config = Mock()
     config.raw.return_value = raw_config
     raw_config.contact.return_value = "bozo@the.clown"

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 6f5b1bb..78f5f04 100644
--- a/src/test/python/apache/aurora/client/cli/test_kill.py
+++ b/src/test/python/apache/aurora/client/cli/test_kill.py
@@ -15,7 +15,7 @@
 import contextlib
 import unittest
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli import EXIT_TIMEOUT
@@ -23,9 +23,16 @@ from apache.aurora.client.cli.client import AuroraCommandLine
 from apache.aurora.client.cli.options import parse_instances
 from apache.aurora.common.aurora_job_key import AuroraJobKey
 
+from ..api.api_util import SchedulerThriftApiSpec
 from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 
-from gen.apache.aurora.api.ttypes import JobKey, ScheduleStatus, ScheduleStatusResult, TaskQuery
+from gen.apache.aurora.api.ttypes import (
+    JobKey,
+    Result,
+    ScheduleStatus,
+    ScheduleStatusResult,
+    TaskQuery
+)
 
 
 class TestInstancesParser(unittest.TestCase):
@@ -65,7 +72,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
   def test_killall_job(self):
     """Test kill client-side API logic."""
     mock_context = FakeAuroraCommandContext()
-    mock_scheduler_proxy = Mock()
+    mock_scheduler_proxy = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     with contextlib.nested(
         patch('threading._Event.wait'),
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
@@ -92,7 +99,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
   def test_killall_job_wait_until_timeout(self):
     """Test kill client-side API logic."""
     mock_context = FakeAuroraCommandContext()
-    mock_scheduler_proxy = Mock()
+    mock_scheduler_proxy = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     with contextlib.nested(
         patch('threading._Event.wait'),
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
@@ -121,7 +128,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
   def test_killall_job_something_else(self):
     """Test kill client-side API logic."""
     mock_context = FakeAuroraCommandContext()
-    mock_scheduler_proxy = Mock()
+    mock_scheduler_proxy = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     with contextlib.nested(
         patch('threading._Event.wait'),
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),
@@ -303,9 +310,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
       api = mock_context.get_api('west')
       # set up an empty instance list in the getTasksWithoutConfigs response
       status_response = self.create_simple_success_response()
-      schedule_status = Mock(spec=ScheduleStatusResult)
-      status_response.result.scheduleStatusResult = schedule_status
-      schedule_status.tasks = []
+      status_response.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=[[]]))
       mock_context.add_expected_status_query_result(status_response)
       api.kill_job.return_value = self.get_kill_job_response()
       with temporary_file() as fp:
@@ -340,7 +345,7 @@ class TestClientKillCommand(AuroraClientCommandTest):
   def test_killall_job_output(self):
     """Test kill output."""
     mock_context = FakeAuroraCommandContext()
-    mock_scheduler_proxy = Mock()
+    mock_scheduler_proxy = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     with contextlib.nested(
         patch('threading._Event.wait'),
         patch('apache.aurora.client.cli.jobs.Job.create_context', return_value=mock_context),

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_logging.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_logging.py b/src/test/python/apache/aurora/client/cli/test_logging.py
index 10fa015..401d091 100644
--- a/src/test/python/apache/aurora/client/cli/test_logging.py
+++ b/src/test/python/apache/aurora/client/cli/test_logging.py
@@ -15,7 +15,7 @@
 import logging
 from logging import Handler
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli.client import AuroraCommandLine
@@ -25,6 +25,7 @@ from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
+    Result,
     ScheduledTask,
     ScheduleStatus,
     ScheduleStatusResult,
@@ -45,12 +46,12 @@ class TestLogging(AuroraClientCommandTest):
 
   @classmethod
   def create_mock_task(cls, task_id, instance_id, initial_time, status):
-    mock_task = Mock(spec=ScheduledTask)
-    mock_task.assignedTask = Mock(spec=AssignedTask)
+    mock_task = create_autospec(spec=ScheduledTask, instance=True)
+    mock_task.assignedTask = create_autospec(spec=AssignedTask, instance=True)
     mock_task.assignedTask.taskId = task_id
     mock_task.assignedTask.instanceId = instance_id
     mock_task.status = status
-    mock_task_event = Mock(spec=TaskEvent)
+    mock_task_event = create_autospec(spec=TaskEvent, instance=True)
     mock_task_event.timestamp = initial_time
     mock_task.taskEvents = [mock_task_event]
     return mock_task
@@ -58,14 +59,14 @@ class TestLogging(AuroraClientCommandTest):
   @classmethod
   def create_mock_status_query_result(cls, scheduleStatus):
     mock_query_result = cls.create_simple_success_response()
-    mock_query_result.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
     if scheduleStatus == ScheduleStatus.INIT:
       # status query result for before job is launched.
-      mock_query_result.result.scheduleStatusResult.tasks = []
+      tasks = []
     else:
       mock_task_one = cls.create_mock_task('hello', 0, 1000, scheduleStatus)
       mock_task_two = cls.create_mock_task('hello', 1, 1004, scheduleStatus)
-      mock_query_result.result.scheduleStatusResult.tasks = [mock_task_one, mock_task_two]
+      tasks = [mock_task_one, mock_task_two]
+    mock_query_result.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=tasks))
     return mock_query_result
 
   @classmethod

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_plugins.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_plugins.py b/src/test/python/apache/aurora/client/cli/test_plugins.py
index 0b29346..43765f2 100644
--- a/src/test/python/apache/aurora/client/cli/test_plugins.py
+++ b/src/test/python/apache/aurora/client/cli/test_plugins.py
@@ -14,7 +14,7 @@
 
 import logging
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.cli import ConfigurationPlugin, EXIT_OK
@@ -27,6 +27,7 @@ from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
     JobKey,
+    Result,
     ScheduledTask,
     ScheduleStatus,
     ScheduleStatusResult,
@@ -67,12 +68,12 @@ class TestPlugins(AuroraClientCommandTest):
 
   @classmethod
   def create_mock_task(cls, task_id, instance_id, initial_time, status):
-    mock_task = Mock(spec=ScheduledTask)
-    mock_task.assignedTask = Mock(spec=AssignedTask)
+    mock_task = create_autospec(spec=ScheduledTask, instance=True)
+    mock_task.assignedTask = create_autospec(spec=AssignedTask, instance=True)
     mock_task.assignedTask.taskId = task_id
     mock_task.assignedTask.instanceId = instance_id
     mock_task.status = status
-    mock_task_event = Mock(spec=TaskEvent)
+    mock_task_event = create_autospec(spec=TaskEvent, instance=True)
     mock_task_event.timestamp = initial_time
     mock_task.taskEvents = [mock_task_event]
     return mock_task
@@ -80,14 +81,14 @@ class TestPlugins(AuroraClientCommandTest):
   @classmethod
   def create_mock_status_query_result(cls, scheduleStatus):
     mock_query_result = cls.create_simple_success_response()
-    mock_query_result.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
     if scheduleStatus == ScheduleStatus.INIT:
       # status query result for before job is launched.
-      mock_query_result.result.scheduleStatusResult.tasks = []
+      tasks = []
     else:
       mock_task_one = cls.create_mock_task('hello', 0, 1000, scheduleStatus)
       mock_task_two = cls.create_mock_task('hello', 1, 1004, scheduleStatus)
-      mock_query_result.result.scheduleStatusResult.tasks = [mock_task_one, mock_task_two]
+      tasks = [mock_task_one, mock_task_two]
+    mock_query_result.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=tasks))
     return mock_query_result
 
   @classmethod

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 6e38227..202cc45 100644
--- a/src/test/python/apache/aurora/client/cli/test_quota.py
+++ b/src/test/python/apache/aurora/client/cli/test_quota.py
@@ -21,7 +21,7 @@ from apache.aurora.client.cli.client import AuroraCommandLine
 
 from .util import AuroraClientCommandTest, FakeAuroraCommandContext
 
-from gen.apache.aurora.api.ttypes import GetQuotaResult, ResourceAggregate
+from gen.apache.aurora.api.ttypes import GetQuotaResult, ResourceAggregate, Result
 
 
 class TestGetQuotaCommand(AuroraClientCommandTest):
@@ -29,22 +29,22 @@ class TestGetQuotaCommand(AuroraClientCommandTest):
   def setup_mock_quota_call_no_consumption(cls, mock_context):
     api = mock_context.get_api('west')
     response = cls.create_simple_success_response()
-    response.result.getQuotaResult = GetQuotaResult(
-      quota=ResourceAggregate(numCpus=5, ramMb=20480, diskMb=40960),
-      prodConsumption=None,
-      nonProdConsumption=None
-    )
+    response.result = Result(getQuotaResult=GetQuotaResult(
+        quota=ResourceAggregate(numCpus=5, ramMb=20480, diskMb=40960),
+        prodConsumption=None,
+        nonProdConsumption=None
+    ))
     api.get_quota.return_value = response
 
   @classmethod
   def setup_mock_quota_call_with_consumption(cls, mock_context):
     api = mock_context.get_api('west')
     response = cls.create_simple_success_response()
-    response.result.getQuotaResult = GetQuotaResult(
+    response.result = Result(getQuotaResult=GetQuotaResult(
       quota=ResourceAggregate(numCpus=5, ramMb=20480, diskMb=40960),
       prodConsumption=ResourceAggregate(numCpus=1, ramMb=1024, diskMb=2048),
       nonProdConsumption=ResourceAggregate(numCpus=1, ramMb=1024, diskMb=2048),
-    )
+    ))
     api.get_quota.return_value = response
 
   def test_get_quota_no_consumption(self):

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 ff70264..a8180a3 100644
--- a/src/test/python/apache/aurora/client/cli/test_restart.py
+++ b/src/test/python/apache/aurora/client/cli/test_restart.py
@@ -14,7 +14,7 @@
 import contextlib
 import functools
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.api.health_check import Retriable, StatusHealthCheck
@@ -23,7 +23,7 @@ from apache.aurora.client.cli.client import AuroraCommandLine
 
 from .util import AuroraClientCommandTest, IOMock
 
-from gen.apache.aurora.api.ttypes import JobKey, PopulateJobResult, TaskConfig
+from gen.apache.aurora.api.ttypes import JobKey, PopulateJobResult, Result, TaskConfig
 
 
 class TestRestartCommand(AuroraClientCommandTest):
@@ -39,15 +39,15 @@ class TestRestartCommand(AuroraClientCommandTest):
   @classmethod
   def setup_populate_job_config(cls, api):
     populate = cls.create_simple_success_response()
-    populate.result.populateJobResult = Mock(spec=PopulateJobResult)
+    populate.result = Result(populateJobResult=PopulateJobResult(
+        populatedDEPRECATED={TaskConfig()}
+    ))
     api.populateJobConfig.return_value = populate
-    configs = [Mock(spec=TaskConfig) for i in range(20)]
-    populate.result.populateJobResult.populatedDEPRECATED = set(configs)
     return populate
 
   @classmethod
   def setup_health_checks(cls, mock_api):
-    mock_health_check = Mock(spec=StatusHealthCheck)
+    mock_health_check = create_autospec(spec=StatusHealthCheck, instance=True)
     mock_health_check.health.return_value = Retriable.alive()
     return mock_health_check
 

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 a7bfd35..3d6d99c 100644
--- a/src/test/python/apache/aurora/client/cli/test_sla.py
+++ b/src/test/python/apache/aurora/client/cli/test_sla.py
@@ -14,8 +14,9 @@
 
 import contextlib
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 
+from apache.aurora.client.api.sla import JobUpTimeSlaVector
 from apache.aurora.client.cli.client import AuroraCommandLine
 
 from .util import AuroraClientCommandTest, FakeAuroraCommandContext
@@ -25,7 +26,7 @@ class TestGetTaskUpCountCommand(AuroraClientCommandTest):
   @classmethod
   def setup_mock_sla_uptime_vector(cls, mock_context, upcount):
     api = mock_context.get_api('west')
-    response = Mock()
+    response = create_autospec(spec=JobUpTimeSlaVector, instance=True)
     response.get_task_up_count.return_value = upcount
     api.sla_get_job_uptime_vector.return_value = response
 
@@ -62,7 +63,7 @@ class TestGetJobUptimeCommand(AuroraClientCommandTest):
   @classmethod
   def setup_mock_sla_uptime_vector(cls, mock_context, uptime):
     api = mock_context.get_api('west')
-    response = Mock()
+    response = create_autospec(spec=JobUpTimeSlaVector, instance=True)
     response.get_job_uptime.return_value = uptime
     api.sla_get_job_uptime_vector.return_value = response
 

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 6b2f18b..e531fa0 100644
--- a/src/test/python/apache/aurora/client/cli/test_status.py
+++ b/src/test/python/apache/aurora/client/cli/test_status.py
@@ -107,15 +107,16 @@ class TestJobStatus(AuroraClientCommandTest):
   @classmethod
   def create_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = ScheduleStatusResult(
-      tasks=set(cls.create_scheduled_tasks()))
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(tasks=set(cls.create_scheduled_tasks())))
     return resp
 
   @classmethod
   def create_status_null_metadata(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = ScheduleStatusResult(
-      tasks=set(cls.create_mock_scheduled_task_no_metadata()))
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(
+            tasks=set(cls.create_mock_scheduled_task_no_metadata())))
     return resp
 
   @classmethod
@@ -127,7 +128,7 @@ class TestJobStatus(AuroraClientCommandTest):
   @classmethod
   def create_empty_status(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = ScheduleStatusResult(tasks=None)
+    resp.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=None))
     return resp
 
   def get_task_status_json(cls):
@@ -172,14 +173,14 @@ class TestJobStatus(AuroraClientCommandTest):
       create_scheduled_task(0, 123456),
       create_scheduled_task(1, 234567)
     ]
-    resp.result.scheduleStatusResult = scheduleStatus
+    resp.result = Result(scheduleStatusResult=scheduleStatus)
     return resp
 
   @classmethod
   def create_status_with_metadata(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = ScheduleStatusResult(
-      tasks=set(cls.create_mock_scheduled_task_with_metadata()))
+    resp.result = Result(scheduleStatusResult=ScheduleStatusResult(
+        tasks=set(cls.create_mock_scheduled_task_with_metadata())))
     return resp
 
   @classmethod
@@ -189,7 +190,7 @@ class TestJobStatus(AuroraClientCommandTest):
   @classmethod
   def create_nojobs_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = ScheduleStatusResult(tasks=set())
+    resp.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=set()))
     return resp
 
   def test_successful_status_shallow(self):
@@ -219,8 +220,7 @@ class TestJobStatus(AuroraClientCommandTest):
   def test_successful_status_deep(self):
     """Test the status command more deeply: in a request with a fully specified
     job, it should end up doing a query using getTasksWithoutConfigs."""
-    (mock_api, mock_scheduler_proxy) = self.create_mock_api()
-    mock_scheduler_proxy.query.return_value = self.create_status_response()
+    _, 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),
@@ -350,7 +350,6 @@ class TestJobStatus(AuroraClientCommandTest):
 
   def test_successful_status_deep_null_metadata(self):
     (mock_api, mock_scheduler_proxy) = self.create_mock_api()
-    mock_scheduler_proxy.query.return_value = self.create_status_null_metadata()
     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),

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_supdate.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_supdate.py b/src/test/python/apache/aurora/client/cli/test_supdate.py
index bf979e2..8943f8c 100644
--- a/src/test/python/apache/aurora/client/cli/test_supdate.py
+++ b/src/test/python/apache/aurora/client/cli/test_supdate.py
@@ -338,7 +338,7 @@ class TestUpdateCommand(AuroraClientCommandTest):
           "  Instance 2 at YYYY-MM-DD HH:MM:SS: INSTANCE_UPDATING",
           "  Instance 1 at YYYY-MM-DD HH:MM:SS: INSTANCE_UPDATED",
           "  Instance 2 at YYYY-MM-DD HH:MM:SS: INSTANCE_UPDATED"]
-      mock_context.get_api("west").query_job_updates.assert_called_with(jobKey=AuroraJobKey(
+      mock_context.get_api("west").query_job_updates.assert_called_with(job_key=AuroraJobKey(
           'west', 'mcc', 'test', 'hello'))
 
   def test_update_status_json(self):
@@ -353,7 +353,7 @@ class TestUpdateCommand(AuroraClientCommandTest):
       cmd = AuroraCommandLine()
       result = cmd.execute(["beta-update", "status", "--write-json", "west/mcc/test/hello"])
       assert result == EXIT_OK
-      mock_context.get_api("west").query_job_updates.assert_called_with(jobKey=AuroraJobKey(
+      mock_context.get_api("west").query_job_updates.assert_called_with(job_key=AuroraJobKey(
           'west', 'mcc', 'test', 'hello'))
       mock_context.get_api("west").get_job_update_details.assert_called_with('hello')
       assert mock_context.get_out_str() == textwrap.dedent("""\

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/cli/test_task_run.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_task_run.py b/src/test/python/apache/aurora/client/cli/test_task_run.py
index 8458606..8544617 100644
--- a/src/test/python/apache/aurora/client/cli/test_task_run.py
+++ b/src/test/python/apache/aurora/client/cli/test_task_run.py
@@ -24,6 +24,7 @@ from .util import AuroraClientCommandTest
 from gen.apache.aurora.api.ttypes import (
     JobKey,
     ResponseCode,
+    Result,
     ScheduleStatus,
     ScheduleStatusResult,
     TaskQuery
@@ -41,8 +42,8 @@ class TestRunCommand(AuroraClientCommandTest):
   @classmethod
   def create_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    resp.result.scheduleStatusResult.tasks = cls.create_scheduled_tasks()
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(tasks=cls.create_scheduled_tasks()))
     return resp
 
   @classmethod
@@ -116,15 +117,14 @@ class TestSshCommand(AuroraClientCommandTest):
   @classmethod
   def create_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    resp.result.scheduleStatusResult.tasks = cls.create_scheduled_tasks()
+    resp.result = Result(
+        scheduleStatusResult=ScheduleStatusResult(tasks=cls.create_scheduled_tasks()))
     return resp
 
   @classmethod
   def create_nojob_status_response(cls):
     resp = cls.create_simple_success_response()
-    resp.result.scheduleStatusResult = ScheduleStatusResult()
-    resp.result.scheduleStatusResult.tasks = []
+    resp.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=[]))
     return resp
 
   @classmethod

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 840cde9..a5e59e4 100644
--- a/src/test/python/apache/aurora/client/cli/test_update.py
+++ b/src/test/python/apache/aurora/client/cli/test_update.py
@@ -14,7 +14,7 @@
 import contextlib
 import functools
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.api.health_check import Retriable, StatusHealthCheck
@@ -33,8 +33,10 @@ from gen.apache.aurora.api.ttypes import (
     AddInstancesConfig,
     AssignedTask,
     JobKey,
+    Lock,
     PopulateJobResult,
     ResponseCode,
+    Result,
     ScheduledTask,
     ScheduleStatus,
     ScheduleStatusResult,
@@ -119,23 +121,23 @@ class TestUpdateCommand(AuroraClientCommandTest):
   @classmethod
   def setup_populate_job_config(cls, api, count=20):
     populate = cls.create_simple_success_response()
-    populate.result.populateJobResult = Mock(spec=PopulateJobResult)
-    api.populateJobConfig.return_value = populate
     configs = [TaskConfig(
         numCpus=1.0,
         ramMb=1,
         diskMb=1,
         job=JobKey(role='bozo', environment='test', name='hello')) for i in range(count)]
-    populate.result.populateJobResult.populatedDEPRECATED = set(configs)
+    populate.result = Result(populateJobResult=PopulateJobResult(
+        populatedDEPRECATED=set(configs)
+    ))
+    api.populateJobConfig.return_value = populate
     return populate
 
   @classmethod
   def create_acquire_lock_response(cls, code, msg, token, rolling):
     """Set up the response to a startUpdate API call."""
     start_update_response = cls.create_blank_response(code, msg)
-    start_update_response.result.acquireLockResult = Mock(spec=AcquireLockResult)
-    start_update_response.result.acquireLockResult.lock = "foo"
-    start_update_response.result.acquireLockResult.updateToken = 'token'
+    start_update_response.result = Result(acquireLockResult=AcquireLockResult(
+        lock=Lock(key='foo', token='token')))
     return start_update_response
 
   @classmethod
@@ -150,8 +152,6 @@ class TestUpdateCommand(AuroraClientCommandTest):
     status_response = cls.create_simple_success_response()
     scheduler.getTasksStatus.return_value = status_response
     scheduler.getTasksWithoutConfigs.return_value = status_response
-    schedule_status = Mock(spec=ScheduleStatusResult)
-    status_response.result.scheduleStatusResult = schedule_status
     task_config = TaskConfig(
         numCpus=1.0,
         ramMb=10,
@@ -159,33 +159,34 @@ class TestUpdateCommand(AuroraClientCommandTest):
         job=JobKey(role='bozo', environment='test', name='hello'))
 
     # This should be a list of ScheduledTask's.
-    schedule_status.tasks = []
+    tasks = []
     for i in range(20):
-      task_status = Mock(spec=ScheduledTask)
-      task_status.assignedTask = Mock(spec=AssignedTask)
+      task_status = create_autospec(spec=ScheduledTask, instance=True)
+      task_status.assignedTask = create_autospec(spec=AssignedTask, instance=True)
       task_status.assignedTask.instanceId = i
       task_status.assignedTask.taskId = "Task%s" % i
       task_status.assignedTask.slaveId = "Slave%s" % i
       task_status.slaveHost = "Slave%s" % i
       task_status.assignedTask.task = task_config
-      schedule_status.tasks.append(task_status)
+      tasks.append(task_status)
+    status_response.result = Result(scheduleStatusResult=ScheduleStatusResult(tasks=tasks))
 
   @classmethod
   def setup_health_checks(cls, mock_api):
-    mock_health_check = Mock(spec=StatusHealthCheck)
+    mock_health_check = create_autospec(spec=StatusHealthCheck, instance=True)
     mock_health_check.health.return_value = Retriable.alive()
     return mock_health_check
 
   @classmethod
   def setup_quota_check(cls):
-    mock_quota_check = Mock(spec=QuotaCheck)
+    mock_quota_check = create_autospec(spec=QuotaCheck, instance=True)
     mock_quota_check.validate_quota_from_requested.return_value = (
         cls.create_simple_success_response())
     return mock_quota_check
 
   @classmethod
   def setup_job_monitor(cls):
-    mock_job_monitor = Mock(spec=JobMonitor)
+    mock_job_monitor = create_autospec(spec=JobMonitor, instance=True)
     mock_job_monitor.wait_until.return_value = True
     return mock_job_monitor
 
@@ -396,7 +397,7 @@ class TestUpdateCommand(AuroraClientCommandTest):
             jobKeys=[JobKey(role='bozo', environment='test', name='hello')],
             instanceIds=frozenset([19]),
             statuses=ACTIVE_STATES),
-        'foo')
+        Lock(key='foo', token='token'))
 
   @classmethod
   def assert_correct_status_calls(cls, api):

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/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 796c4f9..154fb3a 100644
--- a/src/test/python/apache/aurora/client/cli/util.py
+++ b/src/test/python/apache/aurora/client/cli/util.py
@@ -15,7 +15,7 @@
 import textwrap
 import unittest
 
-from mock import Mock
+from mock import create_autospec
 
 from apache.aurora.client.cli.context import AuroraCommandContext
 from apache.aurora.client.hooks.hooked_api import HookedAuroraClientAPI
@@ -23,6 +23,8 @@ from apache.aurora.common.aurora_job_key import AuroraJobKey
 from apache.aurora.common.cluster import Cluster
 from apache.aurora.common.clusters import Clusters
 
+from ..api.api_util import SchedulerProxyApiSpec, SchedulerThriftApiSpec
+
 from gen.apache.aurora.api.ttypes import (
     AssignedTask,
     ExecutorConfig,
@@ -30,6 +32,7 @@ from gen.apache.aurora.api.ttypes import (
     JobKey,
     Response,
     ResponseCode,
+    ResponseDetail,
     Result,
     ScheduledTask,
     ScheduleStatus,
@@ -57,16 +60,10 @@ class FakeAuroraCommandContext(AuroraCommandContext):
   def create_mock_api(cls):
     """Builds up a mock API object, with a mock SchedulerProxy.
     Returns the API and the proxy"""
-    # This looks strange, but we set up the same object to use as both
-    # the SchedulerProxy and the SchedulerClient. These tests want to observe
-    # what API calls get made against the scheduler, and both of these objects
-    # delegate calls to the scheduler. It doesn't matter which one is used:
-    # what we care about is that the right API calls get made.
-    mock_api = Mock(spec=HookedAuroraClientAPI)
-    mock_scheduler_proxy = Mock()
+    mock_scheduler_proxy = create_autospec(spec=SchedulerProxyApiSpec, instance=True)
     mock_scheduler_proxy.url = "http://something_or_other"
     mock_scheduler_proxy.scheduler_client.return_value = mock_scheduler_proxy
-    mock_api = Mock(spec=HookedAuroraClientAPI)
+    mock_api = create_autospec(spec=HookedAuroraClientAPI)
     mock_api.scheduler_proxy = mock_scheduler_proxy
     return mock_api
 
@@ -109,14 +106,11 @@ class AuroraClientCommandTest(unittest.TestCase):
 
   @classmethod
   def create_blank_response(cls, code, msg):
-    response = Mock(spec=Response)
-    response.responseCode = code
-    mock_msg = Mock()
-    mock_msg.message = msg
-    response.details = [mock_msg]
-    response.messageDEPRECATED = msg
-    response.result = Mock(spec=Result)
-    return response
+    return Response(
+        responseCode=code,
+        details=[ResponseDetail(message=msg)],
+        messageDEPRECATED=msg
+    )
 
   @classmethod
   def create_simple_success_response(cls):
@@ -129,29 +123,28 @@ class AuroraClientCommandTest(unittest.TestCase):
   @classmethod
   def create_mock_api(cls):
     """Builds up a mock API object, with a mock SchedulerProxy"""
-    mock_scheduler = Mock()
+    mock_scheduler = create_autospec(spec=SchedulerThriftApiSpec, instance=True)
     mock_scheduler.url = "http://something_or_other"
-    mock_scheduler_client = Mock()
-    mock_scheduler_client.scheduler.return_value = mock_scheduler
+    mock_scheduler_client = create_autospec(spec=SchedulerProxyApiSpec, instance=True)
+    #mock_scheduler_client.scheduler.return_value = mock_scheduler
     mock_scheduler_client.url = "http://something_or_other"
-    mock_api = Mock(spec=HookedAuroraClientAPI)
+    mock_api = create_autospec(spec=HookedAuroraClientAPI, instance=True)
     mock_api.scheduler_proxy = mock_scheduler_client
-    return (mock_api, mock_scheduler_client)
+    return mock_api, mock_scheduler_client
 
   @classmethod
   def create_mock_api_factory(cls):
     """Create a collection of mocks for a test that wants to mock out the client API
     by patching the api factory."""
     mock_api, mock_scheduler_client = cls.create_mock_api()
-    mock_api_factory = Mock()
-    mock_api_factory.return_value = mock_api
+    mock_api_factory = lambda: mock_api
     return mock_api_factory, mock_scheduler_client
 
   @classmethod
   def create_status_call_result(cls, mock_task=None):
     status_response = cls.create_simple_success_response()
-    schedule_status = Mock(spec=ScheduleStatusResult)
-    status_response.result.scheduleStatusResult = schedule_status
+    schedule_status = create_autospec(spec=ScheduleStatusResult, instance=True)
+    status_response.result = Result(scheduleStatusResult=schedule_status)
     # This should be a list of ScheduledTask's.
     schedule_status.tasks = []
     if mock_task is None:
@@ -163,15 +156,15 @@ class AuroraClientCommandTest(unittest.TestCase):
 
   @classmethod
   def create_mock_task(cls, instance_id, status=ScheduleStatus.RUNNING):
-    mock_task = Mock(spec=ScheduledTask)
-    mock_task.assignedTask = Mock(spec=AssignedTask)
+    mock_task = create_autospec(spec=ScheduledTask, instance=True)
+    mock_task.assignedTask = create_autospec(spec=AssignedTask, instance=True)
     mock_task.assignedTask.instanceId = instance_id
     mock_task.assignedTask.taskId = "Task%s" % instance_id
     mock_task.assignedTask.slaveId = "Slave%s" % instance_id
-    mock_task.assignedTask.task = Mock(spec=TaskConfig)
+    mock_task.assignedTask.task = create_autospec(spec=TaskConfig, instance=True)
     mock_task.slaveHost = "Slave%s" % instance_id
     mock_task.status = status
-    mock_task_event = Mock(spec=TaskEvent)
+    mock_task_event = create_autospec(spec=TaskEvent, instance=True)
     mock_task_event.timestamp = 1000
     mock_task.taskEvents = [mock_task_event]
     return mock_task
@@ -188,7 +181,7 @@ class AuroraClientCommandTest(unittest.TestCase):
       task.assignedTask.task = TaskConfig()
       task.assignedTask.task.maxTaskFailures = 1
       task.assignedTask.task.executorConfig = ExecutorConfig()
-      task.assignedTask.task.executorConfig.data = Mock()
+      task.assignedTask.task.executorConfig.data = 'fake data'
       task.assignedTask.task.metadata = []
       task.assignedTask.task.job = JobKey(role=cls.TEST_ROLE, environment=cls.TEST_ENV, name=name)
       task.assignedTask.task.owner = Identity(role=cls.TEST_ROLE)

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/commands/test_admin.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/commands/test_admin.py b/src/test/python/apache/aurora/client/commands/test_admin.py
index cae5395..7dd61cd 100644
--- a/src/test/python/apache/aurora/client/commands/test_admin.py
+++ b/src/test/python/apache/aurora/client/commands/test_admin.py
@@ -14,7 +14,7 @@
 
 import contextlib
 
-from mock import Mock, patch, PropertyMock
+from mock import create_autospec, patch, PropertyMock
 
 from apache.aurora.client.api import AuroraClientAPI
 from apache.aurora.client.api.scheduler_client import SchedulerClient, SchedulerProxy
@@ -52,7 +52,10 @@ class TestQueryCommand(AuroraClientCommandTest):
 
   @classmethod
   def setup_mock_options(cls, force=False, shards=None, states='RUNNING', listformat=None):
-    mock_options = Mock(spec=['force', 'shards', 'states', 'listformat', 'verbosity'])
+    mock_options = create_autospec(
+        spec=['force', 'shards', 'states', 'listformat', 'verbosity'],
+        spec_set=False,
+        instance=True)
     mock_options.force = force
     mock_options.shards = shards
     mock_options.states = states
@@ -133,7 +136,7 @@ class TestIncreaseQuotaCommand(AuroraClientCommandTest):
     with contextlib.nested(
         patch('twitter.common.app.get_options', return_value=mock_options),
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-            new=Mock(spec=AuroraClientAPI)),
+            new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS)
     ) as (_, api, _):
 
@@ -169,7 +172,7 @@ class TestSetQuotaCommand(AuroraClientCommandTest):
     with contextlib.nested(
         patch('twitter.common.app.get_options', return_value=mock_options),
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS)
     ) as (_, api, _):
 
@@ -208,7 +211,7 @@ class TestGetLocksCommand(AuroraClientCommandTest):
     with contextlib.nested(
         patch('twitter.common.app.get_options', return_value=mock_options),
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('apache.aurora.client.commands.admin.print_results'),
     ) as (_, api, _, mock_print_results):
@@ -228,8 +231,8 @@ class TestGetSchedulerCommand(AuroraClientCommandTest):
   def test_get_scheduler(self):
     """Tests successful execution of the get_scheduler command."""
     mock_options = self.setup_mock_options()
-    mock_proxy = Mock(spec=SchedulerProxy)
-    mock_scheduler_client = Mock(spec=SchedulerClient)
+    mock_proxy = create_autospec(spec=SchedulerProxy, instance=True)
+    mock_scheduler_client = create_autospec(spec=SchedulerClient, instance=True)
     mock_raw_url = PropertyMock(return_value="url")
     mock_proxy.scheduler_client.return_value = mock_scheduler_client
     mock_scheduler_client.raw_url = mock_raw_url
@@ -237,7 +240,7 @@ class TestGetSchedulerCommand(AuroraClientCommandTest):
     with contextlib.nested(
         patch('twitter.common.app.get_options', return_value=mock_options),
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
     ) as (_, api, _):
 

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/commands/test_admin_sla.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/commands/test_admin_sla.py b/src/test/python/apache/aurora/client/commands/test_admin_sla.py
index a565318..74fc79c 100644
--- a/src/test/python/apache/aurora/client/commands/test_admin_sla.py
+++ b/src/test/python/apache/aurora/client/commands/test_admin_sla.py
@@ -15,7 +15,7 @@
 import contextlib
 from collections import defaultdict
 
-from mock import Mock, patch
+from mock import create_autospec, patch
 from twitter.common.contextutil import temporary_file
 
 from apache.aurora.client.api import AuroraClientAPI
@@ -34,9 +34,9 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
   @classmethod
   def setup_mock_options(cls, exclude=None, include=None, override=None,
                          exclude_list=None, include_list=None, list_jobs=False, grouping=None):
-    mock_options = Mock(spec=['exclude_filename', 'exclude_hosts', 'include_filename',
+    mock_options = create_autospec(spec=['exclude_filename', 'exclude_hosts', 'include_filename',
         'include_hosts', 'override_filename', 'list_jobs', 'verbosity', 'disable_all_hooks',
-        'min_instance_count', 'grouping'])
+        'min_instance_count', 'grouping'], instance=True)
 
     mock_options.exclude_filename = exclude
     mock_options.exclude_hosts = exclude_list
@@ -61,7 +61,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
 
   @classmethod
   def create_mock_vector(cls, result):
-    mock_vector = Mock(spec=DomainUpTimeSlaVector)
+    mock_vector = create_autospec(spec=DomainUpTimeSlaVector, instance=True)
     mock_vector.get_safe_hosts.return_value = result
     return mock_vector
 
@@ -71,7 +71,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_vector = self.create_mock_vector(self.create_hosts(3, 80, 100))
     with contextlib.nested(
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-            new=Mock(spec=AuroraClientAPI)),
+            new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.print_results'),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -96,7 +96,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
       mock_options = self.setup_mock_options(exclude=fp.name)
       with contextlib.nested(
           patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.client.commands.admin.print_results'),
           patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)
@@ -119,7 +119,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_options = self.setup_mock_options(exclude_list=','.join(['h0', 'h1']))
     with contextlib.nested(
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-            new=Mock(spec=AuroraClientAPI)),
+            new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.print_results'),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -146,7 +146,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
       mock_options = self.setup_mock_options(include=fp.name)
       with contextlib.nested(
           patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.client.commands.admin.print_results'),
           patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)
@@ -172,7 +172,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_options = self.setup_mock_options(include_list=','.join(hosts))
     with contextlib.nested(
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-            new=Mock(spec=AuroraClientAPI)),
+            new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.print_results'),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -200,7 +200,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
       mock_options = self.setup_mock_options(override=fp.name)
       with contextlib.nested(
           patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.client.commands.admin.print_results'),
           patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)
@@ -225,7 +225,7 @@ class TestAdminSlaListSafeDomainCommand(AuroraClientCommandTest):
     mock_vector = self.create_mock_vector(self.create_hosts(3, 50, 100))
     with contextlib.nested(
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-            new=Mock(spec=AuroraClientAPI)),
+            new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.print_results'),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -299,16 +299,20 @@ class TestAdminSlaProbeHostsCommand(AuroraClientCommandTest):
 
   @classmethod
   def setup_mock_options(cls, hosts=None, filename=None, grouping=None):
-    mock_options = Mock(spec=['hosts', 'filename', 'verbosity', 'min_instance_count', 'grouping'])
+    mock_options = create_autospec(
+        spec=['hosts', 'filename', 'verbosity', 'min_instance_count', 'grouping'],
+        spec_set=False,
+        instance=True)
     mock_options.hosts = hosts
     mock_options.filename = filename
     mock_options.verbosity = False
     mock_options.grouping = grouping or DEFAULT_GROUPING
+    mock_options.min_instance_count = 1
     return mock_options
 
   @classmethod
   def create_mock_vector(cls, result):
-    mock_vector = Mock(spec=DomainUpTimeSlaVector)
+    mock_vector = create_autospec(spec=DomainUpTimeSlaVector, instance=True)
     mock_vector.probe_hosts.return_value = result
     return mock_vector
 
@@ -328,7 +332,7 @@ class TestAdminSlaProbeHostsCommand(AuroraClientCommandTest):
     mock_vector = self.create_mock_probe_hosts_vector([self.create_probe_hosts(2, 80, True, 0)])
     with contextlib.nested(
         patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-            new=Mock(spec=AuroraClientAPI)),
+            new=create_autospec(spec=AuroraClientAPI)),
         patch('apache.aurora.client.commands.admin.print_results'),
         patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
         patch('twitter.common.app.get_options', return_value=mock_options)
@@ -358,7 +362,7 @@ class TestAdminSlaProbeHostsCommand(AuroraClientCommandTest):
       mock_options = self.setup_mock_options(filename=fp.name)
       with contextlib.nested(
           patch('apache.aurora.client.commands.admin.AuroraClientAPI',
-              new=Mock(spec=AuroraClientAPI)),
+              new=create_autospec(spec=AuroraClientAPI)),
           patch('apache.aurora.client.commands.admin.print_results'),
           patch('apache.aurora.client.commands.admin.CLUSTERS', new=self.TEST_CLUSTERS),
           patch('twitter.common.app.get_options', return_value=mock_options)

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/d01f0c38/src/test/python/apache/aurora/client/commands/test_cancel_update.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/commands/test_cancel_update.py b/src/test/python/apache/aurora/client/commands/test_cancel_update.py
index 5d2a789..e827b38 100644
--- a/src/test/python/apache/aurora/client/commands/test_cancel_update.py
+++ b/src/test/python/apache/aurora/client/commands/test_cancel_update.py
@@ -22,7 +22,7 @@ from apache.aurora.common.aurora_job_key import AuroraJobKey
 
 from .util import AuroraClientCommandTest
 
-from gen.apache.aurora.api.ttypes import JobKey, ScheduleStatus, ScheduleStatusResult, TaskQuery
+from gen.apache.aurora.api.ttypes import JobKey, TaskQuery
 
 
 class TestClientCancelUpdateCommand(AuroraClientCommandTest):
@@ -41,23 +41,10 @@ class TestClientCancelUpdateCommand(AuroraClientCommandTest):
   @classmethod
   def setup_mock_api_factory(cls):
     mock_api_factory, mock_api = cls.create_mock_api_factory()
-    mock_api_factory.return_value.cancel_update.return_value = cls.get_cancel_update_response()
+    mock_api_factory('fake').cancel_update.return_value = cls.get_cancel_update_response()
     return mock_api_factory
 
   @classmethod
-  def create_mock_status_query_result(cls, scheduleStatus):
-    mock_query_result = cls.create_simple_success_response()
-    mock_query_result.result.scheduleStatusResult = Mock(spec=ScheduleStatusResult)
-    if scheduleStatus == ScheduleStatus.INIT:
-      # status query result for before job is launched.
-      mock_query_result.result.scheduleStatusResult.tasks = []
-    else:
-      mock_task_one = cls.create_mock_task('hello', 0, 1000, scheduleStatus)
-      mock_task_two = cls.create_mock_task('hello', 1, 1004, scheduleStatus)
-      mock_query_result.result.scheduleStatusResult.tasks = [mock_task_one, mock_task_two]
-    return mock_query_result
-
-  @classmethod
   def get_cancel_update_response(cls):
     return cls.create_simple_success_response()
 
@@ -66,7 +53,7 @@ class TestClientCancelUpdateCommand(AuroraClientCommandTest):
     # Running cancel update should result in calling the API cancel_update
     # method once, with an AuroraJobKey parameter.
     assert mock_api.cancel_update.call_count == 1
-    assert mock_api.cancel_update.called_with(
+    mock_api.cancel_update.assert_called_with(
         AuroraJobKey(cls.TEST_CLUSTER, cls.TEST_ROLE, cls.TEST_ENV, cls.TEST_JOB),
         config=None)
 
@@ -81,9 +68,8 @@ class TestClientCancelUpdateCommand(AuroraClientCommandTest):
         patch('apache.aurora.client.commands.core.make_client_factory',
             return_value=mock_api_factory),
         patch('twitter.common.app.get_options', return_value=mock_options),
-        patch('apache.aurora.client.commands.core.get_job_config', return_value=mock_config)) as (
-            mock_make_client_factory, options, mock_get_job_config):
-      mock_api = mock_api_factory.return_value
+        patch('apache.aurora.client.commands.core.get_job_config', return_value=mock_config)):
+      mock_api = mock_api_factory('fake')
 
       cancel_update(['west/mchucarroll/test/hello'], mock_options)
       self.assert_cancel_update_called(mock_api)


Mime
View raw message