You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2015/04/25 23:33:31 UTC

[04/11] mesos git commit: Added SHUTDOWN scheduler call.

Added SHUTDOWN scheduler call.

Review: https://reviews.apache.org/r/32505


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2d447e76
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2d447e76
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2d447e76

Branch: refs/heads/master
Commit: 2d447e762a4a11e7b7f916b045acc90c65b51b90
Parents: 6a553a6
Author: Vinod Kone <vi...@gmail.com>
Authored: Mon Mar 23 18:02:46 2015 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Sat Apr 25 11:32:47 2015 -1000

----------------------------------------------------------------------
 include/mesos/scheduler/scheduler.proto |  16 ++++
 src/master/master.cpp                   |  52 +++++++++-
 src/master/master.hpp                   |   4 +
 src/messages/messages.proto             |  11 ++-
 src/scheduler/scheduler.cpp             |  24 +++++
 src/slave/slave.cpp                     |  84 +++++++++++++++-
 src/slave/slave.hpp                     |  33 ++++---
 src/tests/scheduler_tests.cpp           | 137 ++++++++++++++++++++++++---
 8 files changed, 324 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/include/mesos/scheduler/scheduler.proto
----------------------------------------------------------------------
diff --git a/include/mesos/scheduler/scheduler.proto b/include/mesos/scheduler/scheduler.proto
index 5a94884..7a77fe1 100644
--- a/include/mesos/scheduler/scheduler.proto
+++ b/include/mesos/scheduler/scheduler.proto
@@ -71,6 +71,8 @@ message Event {
     required bytes data = 3;
   }
 
+  // TODO(vinod): Consider splitting the lost slave and terminated
+  // executor into separate events.
   message Failure {
     optional SlaveID slave_id = 1;
 
@@ -122,6 +124,7 @@ message Call {
     ACKNOWLEDGE = 9;
     RECONCILE = 10;
     MESSAGE = 11;
+    SHUTDOWN = 13;
 
     // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for
     // already registered frameworks as a way of stopping offers from
@@ -169,6 +172,18 @@ message Call {
     optional SlaveID slave_id = 2;
   }
 
+  // Shuts down a custom executor. When the executor gets a shutdown
+  // event, it is expected to kill all its tasks (and send TASK_KILLED
+  // updates) and terminate. If the executor doesn’t terminate within
+  // a certain timeout (configurable via
+  // '--executor_shutdown_grace_period' slave flag), the slave will
+  // forcefully destroy the container (executor and its tasks) and
+  // transition its active tasks to TASK_LOST.
+  message Shutdown {
+    required ExecutorID executor_id = 1;
+    required SlaveID slave_id = 2;
+  }
+
   message Acknowledge {
     required SlaveID slave_id = 1;
     required TaskID task_id = 2;
@@ -212,4 +227,5 @@ message Call {
   optional Acknowledge acknowledge = 7;
   optional Reconcile reconcile = 8;
   optional Message message = 9;
+  optional Shutdown shutdown = 11;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index cc20be9..d443c80 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -1611,6 +1611,13 @@ void Master::receive(
       reconcile(framework, call.reconcile());
       break;
 
+    case scheduler::Call::SHUTDOWN:
+      if (!call.has_shutdown()) {
+        drop(from, call, "Expecting 'shutdown' to be present");
+      }
+      shutdown(framework, call.shutdown());
+      break;
+
     case scheduler::Call::KILL:
       if (!call.has_kill()) {
         drop(from, call, "Expecting 'kill' to be present");
@@ -3484,13 +3491,52 @@ void Master::exitedExecutor(
 
   LOG(INFO) << "Executor " << executorId
             << " of framework " << frameworkId
-            << " on slave " << *slave << " "
+            << " on slave " << *slave << ": "
             << WSTRINGIFY(status);
 
   removeExecutor(slave, frameworkId, executorId);
 
-  // TODO(benh): Send the framework its executor's exit status?
-  // Or maybe at least have something like Scheduler::executorLost?
+  // TODO(vinod): Reliably forward this message to the scheduler.
+  Framework* framework = getFramework(frameworkId);
+  if (framework == NULL) {
+    LOG(WARNING)
+      << "Not forwarding exited executor message for executor '" << executorId
+      << "' of framework " << frameworkId << " on slave " << *slave
+      << " because the framework is unknown";
+
+    return;
+  }
+
+  ExitedExecutorMessage message;
+  message.mutable_executor_id()->CopyFrom(executorId);
+  message.mutable_framework_id()->CopyFrom(frameworkId);
+  message.mutable_slave_id()->CopyFrom(slaveId);
+  message.set_status(status);
+
+  send(framework->pid, message);
+}
+
+
+void Master::shutdown(
+    Framework* framework,
+    const scheduler::Call::Shutdown& shutdown)
+{
+  CHECK_NOTNULL(framework);
+
+  if (!slaves.registered.contains(shutdown.slave_id())) {
+    LOG(WARNING) << "Unable to shutdown executor '" << shutdown.executor_id()
+                 << "' of framework " << framework->id()
+                 << " of unknown slave " << shutdown.slave_id();
+    return;
+  }
+
+  Slave* slave = slaves.registered[shutdown.slave_id()];
+  CHECK_NOTNULL(slave);
+
+  ShutdownExecutorMessage message;
+  message.mutable_executor_id()->CopyFrom(shutdown.executor_id());
+  message.mutable_framework_id()->CopyFrom(framework->id());
+  send(slave->pid, message);
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 5d14a53..bf1661a 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -461,6 +461,10 @@ private:
       Framework* framework,
       const scheduler::Call::Kill& kill);
 
+  void shutdown(
+      Framework* framework,
+      const scheduler::Call::Shutdown& shutdown);
+
   bool elected() const
   {
     return leader.isSome() && leader.get() == info_;

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/messages/messages.proto
----------------------------------------------------------------------
diff --git a/src/messages/messages.proto b/src/messages/messages.proto
index bdf474b..98d859f 100644
--- a/src/messages/messages.proto
+++ b/src/messages/messages.proto
@@ -309,9 +309,14 @@ message ShutdownFrameworkMessage {
 }
 
 
-// Tells the executor to initiate a shut down by invoking
-// Executor::shutdown.
-message ShutdownExecutorMessage {}
+// Tells a slave (and consequently executor) to shutdown an executor.
+message ShutdownExecutorMessage {
+  // TODO(vinod): Make these fields required. These are made optional
+  // for backwards compatibility between 0.23.0 slave and pre 0.23.0
+  // executor driver.
+  optional ExecutorID executor_id = 1;
+  optional FrameworkID framework_id = 2;
+}
 
 
 message UpdateFrameworkMessage {

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/scheduler/scheduler.cpp
----------------------------------------------------------------------
diff --git a/src/scheduler/scheduler.cpp b/src/scheduler/scheduler.cpp
index 2bbb221..7d53d51 100644
--- a/src/scheduler/scheduler.cpp
+++ b/src/scheduler/scheduler.cpp
@@ -292,6 +292,15 @@ public:
         break;
       }
 
+      case Call::SHUTDOWN: {
+        if (!call.has_shutdown()) {
+          drop(call, "Expecting 'shutdown' to be present");
+          return;
+        }
+        send(master.get(), call);
+        break;
+      }
+
       case Call::ACKNOWLEDGE: {
         if (!call.has_acknowledge()) {
           drop(call, "Expecting 'acknowledge' to be present");
@@ -345,6 +354,7 @@ protected:
     install<RescindResourceOfferMessage>(&MesosProcess::receive);
     install<StatusUpdateMessage>(&MesosProcess::receive);
     install<LostSlaveMessage>(&MesosProcess::receive);
+    install<ExitedExecutorMessage>(&MesosProcess::receive);
     install<ExecutorToFrameworkMessage>(&MesosProcess::receive);
     install<FrameworkErrorMessage>(&MesosProcess::receive);
 
@@ -657,6 +667,20 @@ protected:
     receive(from, event);
   }
 
+  void receive(const UPID& from, const ExitedExecutorMessage& message)
+  {
+    Event event;
+    event.set_type(Event::FAILURE);
+
+    Event::Failure* failure = event.mutable_failure();
+
+    failure->mutable_slave_id()->CopyFrom(message.slave_id());
+    failure->mutable_executor_id()->CopyFrom(message.executor_id());
+    failure->set_status(message.status());
+
+    receive(from, event);
+  }
+
   void receive(const UPID& from, const ExecutorToFrameworkMessage& _message)
   {
     Event event;

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index f68a005..e531283 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -382,6 +382,11 @@ void Slave::initialize()
       &KillTaskMessage::framework_id,
       &KillTaskMessage::task_id);
 
+  install<ShutdownExecutorMessage>(
+      &Slave::shutdownExecutor,
+      &ShutdownExecutorMessage::framework_id,
+      &ShutdownExecutorMessage::executor_id);
+
   install<ShutdownFrameworkMessage>(
       &Slave::shutdownFramework,
       &ShutdownFrameworkMessage::framework_id);
@@ -1792,7 +1797,7 @@ void Slave::shutdownFramework(
 
         if (executor->state == Executor::REGISTERING ||
             executor->state == Executor::RUNNING) {
-          shutdownExecutor(framework, executor);
+          _shutdownExecutor(framework, executor);
         } else if (executor->state == Executor::TERMINATED) {
           // NOTE: We call remove here to ensure we can remove an
           // executor (of a terminating framework) that is terminated
@@ -2578,7 +2583,7 @@ void Slave::statusUpdate(StatusUpdate update, const UPID& pid)
                << " of framework " << update.framework_id()
                << " which is not allowed. Shutting down the executor";
 
-    shutdownExecutor(framework, executor);
+    _shutdownExecutor(framework, executor);
 
     return;
   }
@@ -3273,6 +3278,7 @@ void Slave::executorTerminated(
       // Only send ExitedExecutorMessage if it is not a Command
       // Executor because the master doesn't store them; they are
       // generated by the slave.
+      // TODO(vinod): Reliably forward this message to the master.
       if (!executor->isCommandExecutor()) {
         ExitedExecutorMessage message;
         message.mutable_slave_id()->MergeFrom(info.id());
@@ -3455,7 +3461,76 @@ void _unmonitor(
 }
 
 
-void Slave::shutdownExecutor(Framework* framework, Executor* executor)
+void Slave::shutdownExecutor(
+    const UPID& from,
+    const FrameworkID& frameworkId,
+    const ExecutorID& executorId)
+{
+  if (from && master != from) {
+    LOG(WARNING) << "Ignoring shutdown executor message for executor '"
+                 << executorId << "' of framework " << frameworkId
+                 << " from " << from << " because it is not from the"
+                 << " registered master ("
+                 << (master.isSome() ? stringify(master.get()) : "None") << ")";
+    return;
+  }
+
+  LOG(INFO) << "Asked to shut down executor '" << executorId
+            << "' of framework "<< frameworkId << " by " << from;
+
+  CHECK(state == RECOVERING || state == DISCONNECTED ||
+        state == RUNNING || state == TERMINATING)
+    << state;
+
+  if (state == RECOVERING || state == DISCONNECTED) {
+    LOG(WARNING) << "Ignoring shutdown executor message for executor '"
+                 << executorId << "' of framework " << frameworkId
+                 << " because the slave has not yet registered with the master";
+    return;
+  }
+
+  Framework* framework = getFramework(frameworkId);
+  if (framework == NULL) {
+    LOG(WARNING) << "Cannot shut down executor '" << executorId
+                 << "' of unknown framework " << frameworkId;
+    return;
+  }
+
+  CHECK(framework->state == Framework::RUNNING ||
+        framework->state == Framework::TERMINATING)
+    << framework->state;
+
+  if (framework->state == Framework::TERMINATING) {
+    LOG(WARNING) << "Ignoring shutdown executor '" << executorId
+                 << "' of framework " << frameworkId
+                 << " because the framework is terminating";
+    return;
+  }
+
+  if (!framework->executors.contains(executorId)) {
+    LOG(WARNING) << "Ignoring shutdown of unknown executor '" << executorId
+                 << "' of framework " << frameworkId;
+  }
+
+  Executor* executor = framework->executors[executorId];
+  CHECK(executor->state == Executor::REGISTERING ||
+        executor->state == Executor::RUNNING ||
+        executor->state == Executor::TERMINATING ||
+        executor->state == Executor::TERMINATED)
+    << executor->state;
+
+  if (executor->state == Executor::TERMINATING ||
+      executor->state == Executor::TERMINATED) {
+    LOG(WARNING) << "Ignoring shutdown executor '" << executorId
+                 << "' of framework " << frameworkId
+                 << " because the executor is terminating/terminated";
+  }
+
+  _shutdownExecutor(framework, executor);
+}
+
+
+void Slave::_shutdownExecutor(Framework* framework, Executor* executor)
 {
   CHECK_NOTNULL(framework);
   CHECK_NOTNULL(executor);
@@ -3467,7 +3542,6 @@ void Slave::shutdownExecutor(Framework* framework, Executor* executor)
         framework->state == Framework::TERMINATING)
     << framework->state;
 
-
   CHECK(executor->state == Executor::REGISTERING ||
         executor->state == Executor::RUNNING)
     << executor->state;
@@ -3774,7 +3848,7 @@ Future<Nothing> Slave::_recover()
                     << "' of framework " << framework->id()
                     << " to " << executor->pid;
 
-          shutdownExecutor(framework, executor);
+          _shutdownExecutor(framework, executor);
         } else {
           LOG(INFO) << "Killing executor '" << executor->id
                     << "' of framework " << framework->id()

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index d214ddb..1b8c512 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -125,6 +125,11 @@ public:
       const FrameworkID& frameworkId,
       const TaskID& taskId);
 
+  void shutdownExecutor(
+      const process::UPID& from,
+      const FrameworkID& frameworkId,
+      const ExecutorID& executorId);
+
   void shutdownFramework(
       const process::UPID& from,
       const FrameworkID& frameworkId);
@@ -240,13 +245,6 @@ public:
   // and os calls.
   void _checkDiskUsage(const process::Future<double>& usage);
 
-  // Shut down an executor. This is a two phase process. First, an
-  // executor receives a shut down message (shut down phase), then
-  // after a configurable timeout the slave actually forces a kill
-  // (kill phase, via the isolator) if the executor has not
-  // exited.
-  void shutdownExecutor(Framework* framework, Executor* executor);
-
   // Invoked whenever the detector detects a change in masters.
   // Made public for testing purposes.
   void detected(const process::Future<Option<MasterInfo> >& pid);
@@ -299,13 +297,6 @@ public:
       const FrameworkID& frameworkId,
       const TaskInfo& task);
 
-  // Handle the second phase of shutting down an executor for those
-  // executors that have not properly shutdown within a timeout.
-  void shutdownExecutorTimeout(
-      const FrameworkID& frameworkId,
-      const ExecutorID& executorId,
-      const ContainerID& containerId);
-
   // Shuts down the executor if it did not register yet.
   void registerExecutorTimeout(
       const FrameworkID& frameworkId,
@@ -360,6 +351,20 @@ private:
   void _authenticate();
   void authenticationTimeout(process::Future<bool> future);
 
+  // Shut down an executor. This is a two phase process. First, an
+  // executor receives a shut down message (shut down phase), then
+  // after a configurable timeout the slave actually forces a kill
+  // (kill phase, via the isolator) if the executor has not
+  // exited.
+  void _shutdownExecutor(Framework* framework, Executor* executor);
+
+  // Handle the second phase of shutting down an executor for those
+  // executors that have not properly shutdown within a timeout.
+  void shutdownExecutorTimeout(
+      const FrameworkID& frameworkId,
+      const ExecutorID& executorId,
+      const ContainerID& containerId);
+
   // Inner class used to namespace HTTP route handlers (see
   // slave/http.cpp for implementations).
   class Http

http://git-wip-us.apache.org/repos/asf/mesos/blob/2d447e76/src/tests/scheduler_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/scheduler_tests.cpp b/src/tests/scheduler_tests.cpp
index a1e49af..a59b146 100644
--- a/src/tests/scheduler_tests.cpp
+++ b/src/tests/scheduler_tests.cpp
@@ -24,6 +24,7 @@
 
 #include <mesos/executor.hpp>
 #include <mesos/scheduler.hpp>
+#include <mesos/type_utils.hpp>
 
 #include <process/clock.hpp>
 #include <process/future.hpp>
@@ -108,14 +109,14 @@ ACTION_P(Enqueue, queue)
 
 TEST_F(SchedulerTest, TaskRunning)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
   MockExecutor exec(DEFAULT_EXECUTOR_ID);
 
   TestContainerizer containerizer(&exec);
 
-  Try<PID<Slave> > slave = StartSlave(&containerizer);
+  Try<PID<Slave>> slave = StartSlave(&containerizer);
   ASSERT_SOME(slave);
 
   Callbacks callbacks;
@@ -213,14 +214,14 @@ TEST_F(SchedulerTest, TaskRunning)
 
 TEST_F(SchedulerTest, ReconcileTask)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
   MockExecutor exec(DEFAULT_EXECUTOR_ID);
 
   TestContainerizer containerizer(&exec);
 
-  Try<PID<Slave> > slave = StartSlave(&containerizer);
+  Try<PID<Slave>> slave = StartSlave(&containerizer);
   ASSERT_SOME(slave);
 
   Callbacks callbacks;
@@ -442,6 +443,118 @@ TEST_F(SchedulerTest, KillTask)
 }
 
 
+TEST_F(SchedulerTest, ShutdownExecutor)
+{
+  Try<PID<Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+  TestContainerizer containerizer(&exec);
+
+  Try<PID<Slave>> slave = StartSlave(&containerizer);
+  ASSERT_SOME(slave);
+
+  Callbacks callbacks;
+
+  Future<Nothing> connected;
+  EXPECT_CALL(callbacks, connected())
+    .WillOnce(FutureSatisfy(&connected));
+
+  scheduler::Mesos mesos(
+      master.get(),
+      DEFAULT_CREDENTIAL,
+      lambda::bind(&Callbacks::connected, lambda::ref(callbacks)),
+      lambda::bind(&Callbacks::disconnected, lambda::ref(callbacks)),
+      lambda::bind(&Callbacks::received, lambda::ref(callbacks), lambda::_1));
+
+  AWAIT_READY(connected);
+
+  Queue<Event> events;
+
+  EXPECT_CALL(callbacks, received(_))
+    .WillRepeatedly(Enqueue(&events));
+
+  {
+    Call call;
+    call.mutable_framework_info()->CopyFrom(DEFAULT_FRAMEWORK_INFO);
+    call.set_type(Call::REGISTER);
+
+    mesos.send(call);
+  }
+
+  Future<Event> event = events.get();
+  AWAIT_READY(event);
+  EXPECT_EQ(Event::REGISTERED, event.get().type());
+
+  FrameworkID id(event.get().registered().framework_id());
+
+  event = events.get();
+  AWAIT_READY(event);
+  EXPECT_EQ(Event::OFFERS, event.get().type());
+  EXPECT_NE(0, event.get().offers().offers().size());
+
+  EXPECT_CALL(exec, registered(_, _, _, _))
+    .Times(1);
+
+  EXPECT_CALL(exec, launchTask(_, _))
+    .WillOnce(SendStatusUpdateFromTask(TASK_FINISHED));
+
+  Offer offer = event.get().offers().offers(0);
+  TaskInfo taskInfo = createTask(offer,"", DEFAULT_EXECUTOR_ID);
+
+  {
+    Call call;
+    call.mutable_framework_info()->CopyFrom(DEFAULT_FRAMEWORK_INFO);
+    call.mutable_framework_info()->mutable_id()->CopyFrom(id);
+    call.set_type(Call::ACCEPT);
+
+    Call::Accept* accept = call.mutable_accept();
+    accept->add_offer_ids()->CopyFrom(offer.id());
+
+    Offer::Operation* operation = accept->add_operations();
+    operation->set_type(Offer::Operation::LAUNCH);
+    operation->mutable_launch()->add_task_infos()->CopyFrom(taskInfo);
+
+    mesos.send(call);
+  }
+
+  event = events.get();
+  AWAIT_READY(event);
+  EXPECT_EQ(Event::UPDATE, event.get().type());
+  EXPECT_EQ(TASK_FINISHED, event.get().update().status().state());
+
+  Future<Nothing> shutdown;
+  EXPECT_CALL(exec, shutdown(_))
+    .WillOnce(FutureSatisfy(&shutdown));
+
+  {
+    Call call;
+    call.mutable_framework_info()->CopyFrom(DEFAULT_FRAMEWORK_INFO);
+    call.mutable_framework_info()->mutable_id()->CopyFrom(id);
+    call.set_type(Call::SHUTDOWN);
+
+    Call::Shutdown* shutdown = call.mutable_shutdown();
+    shutdown->mutable_executor_id()->CopyFrom(DEFAULT_EXECUTOR_ID);
+    shutdown->mutable_slave_id()->CopyFrom(offer.slave_id());
+
+    mesos.send(call);
+  }
+
+  AWAIT_READY(shutdown);
+  containerizer.destroy(id, DEFAULT_EXECUTOR_ID);
+
+  // Executor termination results in a 'FAILURE' event.
+  event = events.get();
+  AWAIT_READY(event);
+  EXPECT_EQ(Event::FAILURE, event.get().type());
+  ExecutorID executorId(DEFAULT_EXECUTOR_ID);
+  EXPECT_EQ(executorId, event.get().failure().executor_id());
+
+  Shutdown(); // Must shutdown before 'containerizer' gets deallocated.
+}
+
+
 // TODO(benh): Write test for sending Call::Acknowledgement through
 // master to slave when Event::Update was generated locally.
 
@@ -451,7 +564,7 @@ class MesosSchedulerDriverTest : public MesosTest {};
 
 TEST_F(MesosSchedulerDriverTest, MetricsEndpoint)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
   MockScheduler sched;
@@ -503,12 +616,12 @@ ACTION(StopAndAbort)
 // abort(), no pending acknowledgements are sent.
 TEST_F(MesosSchedulerDriverTest, DropAckIfStopCalledBeforeAbort)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
   MockExecutor exec(DEFAULT_EXECUTOR_ID);
   TestContainerizer containerizer(&exec);
-  Try<PID<Slave> > slave = StartSlave(&containerizer);
+  Try<PID<Slave>> slave = StartSlave(&containerizer);
   ASSERT_SOME(slave);
 
   MockScheduler sched;
@@ -562,12 +675,12 @@ TEST_F(MesosSchedulerDriverTest, DropAckIfStopCalledBeforeAbort)
 // the call to 'acknowledgeStatusUpdate' sends the ack to the master.
 TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgements)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
   MockExecutor exec(DEFAULT_EXECUTOR_ID);
   TestContainerizer containerizer(&exec);
-  Try<PID<Slave> > slave = StartSlave(&containerizer);
+  Try<PID<Slave>> slave = StartSlave(&containerizer);
   ASSERT_SOME(slave);
 
   MockScheduler sched;
@@ -628,10 +741,10 @@ TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgements)
 // resources.
 TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgementsMasterGeneratedUpdate)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
-  Try<PID<Slave> > slave = StartSlave();
+  Try<PID<Slave>> slave = StartSlave();
   ASSERT_SOME(slave);
 
   MockScheduler sched;
@@ -696,7 +809,7 @@ TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgementsMasterGeneratedUpdate)
 // generate a status with no slave id by performing reconciliation.
 TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgementsUnsetSlaveID)
 {
-  Try<PID<Master> > master = StartMaster();
+  Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
 
   MockScheduler sched;