Fix unit tests that were broken by the additional TASK_STARTING update.

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


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

Branch: refs/heads/master
Commit: 37053061e4123009e4e062529fab930f476d55af
Parents: de11f0f
Author: Benno Evers <bev...@mesosphere.com>
Authored: Wed Oct 18 12:15:27 2017 -0700
Committer: Alexander Rukletsov <al...@apache.org>
Committed: Wed Oct 18 12:15:27 2017 -0700

----------------------------------------------------------------------
 src/tests/api_tests.cpp                         | 100 +++---
 src/tests/check_tests.cpp                       | 155 ++++++++-
 src/tests/command_executor_tests.cpp            |  36 ++-
 src/tests/container_logger_tests.cpp            |  25 ++
 .../containerizer/cgroups_isolator_tests.cpp    |  95 +++++-
 src/tests/containerizer/cni_isolator_tests.cpp  |  99 +++++-
 src/tests/containerizer/cpu_isolator_tests.cpp  |  10 +
 .../docker_containerizer_tests.cpp              |  97 +++++-
 .../docker_volume_isolator_tests.cpp            |  40 ++-
 .../environment_secret_isolator_tests.cpp       |  10 +-
 .../linux_filesystem_isolator_tests.cpp         |  40 ++-
 .../containerizer/memory_isolator_tests.cpp     |   5 +
 .../containerizer/memory_pressure_tests.cpp     |  23 +-
 .../nested_mesos_containerizer_tests.cpp        |   5 +
 src/tests/containerizer/port_mapping_tests.cpp  |  10 +-
 .../posix_rlimits_isolator_tests.cpp            |  24 +-
 .../containerizer/provisioner_appc_tests.cpp    |   6 +
 .../containerizer/provisioner_docker_tests.cpp  |  46 ++-
 .../containerizer/runtime_isolator_tests.cpp    |  45 +++
 .../volume_host_path_isolator_tests.cpp         |   5 +
 src/tests/default_executor_tests.cpp            | 324 ++++++++++++++-----
 src/tests/disk_quota_tests.cpp                  |  50 ++-
 src/tests/fault_tolerance_tests.cpp             |   6 +
 src/tests/gc_tests.cpp                          |   6 +
 src/tests/health_check_tests.cpp                | 115 ++++++-
 src/tests/hook_tests.cpp                        |  13 +
 src/tests/master_tests.cpp                      |  92 +++++-
 src/tests/master_validation_tests.cpp           |   6 +
 src/tests/oversubscription_tests.cpp            |  12 +-
 src/tests/partition_tests.cpp                   |  66 +++-
 src/tests/persistent_volume_endpoints_tests.cpp |  13 +-
 src/tests/persistent_volume_tests.cpp           | 108 +++++--
 src/tests/reconciliation_tests.cpp              |  15 +-
 src/tests/reservation_endpoints_tests.cpp       |  44 ++-
 src/tests/role_tests.cpp                        |  10 +-
 src/tests/scheduler_tests.cpp                   |  52 ++-
 src/tests/slave_authorization_tests.cpp         |  19 +-
 src/tests/slave_recovery_tests.cpp              | 268 ++++++++++-----
 src/tests/slave_tests.cpp                       | 103 +++---
 src/tests/teardown_tests.cpp                    |  15 +-
 40 files changed, 1826 insertions(+), 387 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/api_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/api_tests.cpp b/src/tests/api_tests.cpp
index 0e99e7b..ce3aafd 100644
--- a/src/tests/api_tests.cpp
+++ b/src/tests/api_tests.cpp
@@ -2275,7 +2275,8 @@ TEST_P(MasterAPITest, EventAuthorizationFiltering)
 
   Future<v1::scheduler::Event::Offers> offers1;
   EXPECT_CALL(*scheduler, offers(_, _))
-    .WillOnce(FutureArg<1>(&offers1));
+    .WillOnce(FutureArg<1>(&offers1))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
 
   {
     v1::scheduler::Call call;
@@ -2299,6 +2300,8 @@ TEST_P(MasterAPITest, EventAuthorizationFiltering)
   AWAIT_READY(offers1);
   ASSERT_FALSE(offers1->offers().empty());
 
+  v1::AgentID agentId(offers1->offers()[0].agent_id());
+
   v1::master::Call v1Call;
   v1Call.set_type(v1::master::Call::SUBSCRIBE);
 
@@ -2351,9 +2354,11 @@ TEST_P(MasterAPITest, EventAuthorizationFiltering)
   Future<Result<v1::master::Event>> event = decoder.read();
   EXPECT_TRUE(event.isPending());
 
-  Future<mesos::v1::scheduler::Event::Update> update;
+  Future<mesos::v1::scheduler::Event::Update> updateRunning1;
   EXPECT_CALL(*scheduler, update(_, _))
-    .WillOnce(FutureArg<1>(&update));
+    .WillOnce(DoAll(
+      FutureArg<1>(&updateRunning1),
+      v1::scheduler::SendAcknowledge(frameworkId, agentId)));
 
   EXPECT_CALL(executor1, registered(_, _, _, _));
   EXPECT_CALL(executor2, registered(_, _, _, _));
@@ -2399,21 +2404,8 @@ TEST_P(MasterAPITest, EventAuthorizationFiltering)
   ASSERT_EQ(v1::master::Event::TASK_ADDED, event->get().type());
   ASSERT_EQ(task1.task_id(), event->get().task_added().task().task_id());
 
-  AWAIT_READY(update);
-
-  {
-    v1::scheduler::Call call;
-    call.mutable_framework_id()->CopyFrom(frameworkId);
-    call.set_type(v1::scheduler::Call::ACKNOWLEDGE);
-
-    v1::scheduler::Call::Acknowledge* acknowledge =
-      call.mutable_acknowledge();
-    acknowledge->mutable_task_id()->CopyFrom(task1.task_id());
-    acknowledge->mutable_agent_id()->CopyFrom(offer1.agent_id());
-    acknowledge->set_uuid(update->status().uuid());
-
-    mesos.send(call);
-  }
+  AWAIT_READY(updateRunning1);
+  EXPECT_EQ(updateRunning1->status().state(), TASK_RUNNING);
 
   event = decoder.read();
 
@@ -2446,8 +2438,9 @@ TEST_P(MasterAPITest, EventAuthorizationFiltering)
 
   const v1::Offer& offer2 = offers2->offers(0);
 
+  Future<mesos::v1::scheduler::Event::Update> updateRunning2;
   EXPECT_CALL(*scheduler, update(_, _))
-    .WillOnce(FutureArg<1>(&update))
+    .WillOnce(FutureArg<1>(&updateRunning2))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
 
   Future<TaskInfo> execTask2;
@@ -2484,7 +2477,7 @@ TEST_P(MasterAPITest, EventAuthorizationFiltering)
     mesos.send(call);
   }
 
-  AWAIT_READY(update);
+  AWAIT_READY(updateRunning2);
 
   event = decoder.read();
   EXPECT_TRUE(event.isPending());
@@ -4179,9 +4172,9 @@ TEST_P(AgentAPITest, GetContainers)
   EXPECT_CALL(exec, launchTask(_, _))
     .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
 
-  Future<TaskStatus> status;
+  Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&statusRunning));
 
   // No tasks launched, we should expect zero containers in Response.
   {
@@ -4201,8 +4194,8 @@ TEST_P(AgentAPITest, GetContainers)
 
   driver.launchTasks(offer.id(), {task});
 
-  AWAIT_READY(status);
-  EXPECT_EQ(TASK_RUNNING, status->state());
+  AWAIT_READY(statusRunning);
+  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
   ResourceStatistics statistics;
   statistics.set_mem_limit_bytes(2048);
@@ -4431,8 +4424,10 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, 
GetFrameworks)
   command.set_value("sleep 1000");
   task.mutable_command()->MergeFrom(command);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   ContentType contentType = GetParam();
@@ -4454,6 +4449,9 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, 
GetFrameworks)
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -4534,8 +4532,10 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, 
GetExecutors)
   command.set_value("sleep 1000");
   task.mutable_command()->MergeFrom(command);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   ContentType contentType = GetParam();
@@ -4557,6 +4557,9 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, 
GetExecutors)
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -4641,8 +4644,10 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, GetTasks)
   command.set_value("sleep 1000");
   task.mutable_command()->MergeFrom(command);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   ContentType contentType = GetParam();
@@ -4667,6 +4672,9 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, GetTasks)
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -4804,8 +4812,10 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, GetState)
   command.set_value("sleep 1000");
   task.mutable_command()->MergeFrom(command);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   ContentType contentType = GetParam();
@@ -4831,6 +4841,9 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, GetState)
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -5540,14 +5553,15 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(AgentAPITest, 
LaunchNestedContainerSession)
 
   Future<TaskStatus> status;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&status))
+    .WillRepeatedly(Return());
 
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   // Launch a nested container session that runs a command
   // that writes something to stdout and stderr and exits.
@@ -5661,14 +5675,15 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(
 
   Future<TaskStatus> status;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&status))
+    .WillRepeatedly(Return());
 
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   // Attempt to launch a nested container which does nothing.
 
@@ -5757,14 +5772,15 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(
 
   Future<TaskStatus> status;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&status))
+    .WillRepeatedly(Return());
 
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   // Launch a nested container session that runs a command
   // that writes something to stdout and stderr and exits.
@@ -5874,14 +5890,15 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(
 
   Future<TaskStatus> status;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&status))
+    .WillRepeatedly(Return());
 
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   // Launch a nested container session that runs `cat` so that it never exits.
 
@@ -6178,14 +6195,15 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(
 
   Future<TaskStatus> status;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&status))
+    .WillRepeatedly(Return());
 
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   // Launch a nested container session which runs a shell.
 
@@ -6784,16 +6802,22 @@ TEST_P_TEMP_DISABLED_ON_WINDOWS(
 
   const Offer& offer = offers.get()[0];
 
-  Future<TaskStatus> status;
+  Future<TaskStatus> statusStarting;
+  Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&statusStarting))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillRepeatedly(Return());
 
   TaskInfo taskInfo = createTask(offer, "sleep 1000");
 
   driver.acceptOffers({offer.id()}, {LAUNCH({taskInfo})});
 
-  AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  AWAIT_READY(statusStarting);
+  ASSERT_EQ(TASK_STARTING, statusStarting->state());
+
+  AWAIT_READY(statusRunning);
+  ASSERT_EQ(TASK_RUNNING, statusRunning->state());
 
   Future<hashset<ContainerID>> containerIds = containerizer->containers();
   AWAIT_READY(containerIds);

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/check_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/check_tests.cpp b/src/tests/check_tests.cpp
index fd15a47..9a56c00 100644
--- a/src/tests/check_tests.cpp
+++ b/src/tests/check_tests.cpp
@@ -288,12 +288,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateExplicitReconciliation;
   Future<Event::Update> updateImplicitReconciliation;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateExplicitReconciliation))
@@ -322,6 +324,9 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -437,12 +442,14 @@ TEST_F(CommandExecutorCheckTest, CommandCheckStatusChange)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateCheckResultChanged;
   Future<Event::Update> updateCheckResultBack;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateCheckResultChanged))
@@ -464,6 +471,9 @@ TEST_F(CommandExecutorCheckTest, CommandCheckStatusChange)
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   ASSERT_EQ(TASK_RUNNING, updateTaskRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateTaskRunning->status().task_id());
@@ -557,10 +567,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -590,6 +602,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -660,10 +680,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -687,6 +709,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -781,11 +811,13 @@ TEST_F(CommandExecutorCheckTest, CommandCheckTimeout)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateCheckResultTimeout;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateCheckResultTimeout))
@@ -807,6 +839,12 @@ TEST_F(CommandExecutorCheckTest, CommandCheckTimeout)
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  ASSERT_EQ(TASK_STARTING, updateTaskStarting->status().state());
+  EXPECT_EQ(taskInfo.task_id(), updateTaskStarting->status().task_id());
+
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   ASSERT_EQ(TASK_RUNNING, updateTaskRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateTaskRunning->status().task_id());
@@ -886,12 +924,14 @@ TEST_F(CommandExecutorCheckTest, 
CommandCheckAndHealthCheckNoShadowing)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateHealthResult;
   Future<Event::Update> updateImplicitReconciliation;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateHealthResult))
@@ -928,6 +968,9 @@ TEST_F(CommandExecutorCheckTest, 
CommandCheckAndHealthCheckNoShadowing)
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   ASSERT_EQ(TASK_RUNNING, updateTaskRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateTaskRunning->status().task_id());
@@ -1038,9 +1081,11 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(CommandExecutorCheckTest, HTTPCheckDelivered)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<v1::scheduler::Event::Update> updateTaskStarting;
   Future<v1::scheduler::Event::Update> updateTaskRunning;
   Future<v1::scheduler::Event::Update> updateCheckResult;
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -1069,6 +1114,9 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(CommandExecutorCheckTest, 
HTTPCheckDelivered)
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -1171,9 +1219,11 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(CommandExecutorCheckTest, TCPCheckDelivered)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<v1::scheduler::Event::Update> updateTaskStarting;
   Future<v1::scheduler::Event::Update> updateTaskRunning;
   Future<v1::scheduler::Event::Update> updateCheckResult;
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -1201,6 +1251,14 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(CommandExecutorCheckTest, TCPCheckDelivered)
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -1381,12 +1439,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateExplicitReconciliation;
   Future<Event::Update> updateImplicitReconciliation;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateExplicitReconciliation))
@@ -1415,6 +1475,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -1575,12 +1643,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateCheckResultChanged;
   Future<Event::Update> updateCheckResultBack;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateCheckResultChanged))
@@ -1602,6 +1672,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  ASSERT_EQ(TASK_STARTING, updateTaskStarting->status().state());
+  EXPECT_EQ(taskInfo.task_id(), updateTaskStarting->status().task_id());
+
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   ASSERT_EQ(TASK_RUNNING, updateTaskRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateTaskRunning->status().task_id());
@@ -1736,10 +1812,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -1769,6 +1847,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -1881,10 +1967,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -1936,6 +2024,14 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -2049,11 +2145,13 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(DefaultExecutorCheckTest, CommandCheckTimeout)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateCheckResultTimeout;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateCheckResultTimeout))
@@ -2075,6 +2173,12 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(DefaultExecutorCheckTest, CommandCheckTimeout)
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  ASSERT_EQ(TASK_STARTING, updateTaskStarting->status().state());
+  EXPECT_EQ(taskInfo.task_id(), updateTaskStarting->status().task_id());
+
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   ASSERT_EQ(TASK_RUNNING, updateTaskRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateTaskRunning->status().task_id());
@@ -2197,12 +2301,14 @@ TEST_F(DefaultExecutorCheckTest, 
CommandCheckAndHealthCheckNoShadowing)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<Event::Update> updateTaskStarting;
   Future<Event::Update> updateTaskRunning;
   Future<Event::Update> updateCheckResult;
   Future<Event::Update> updateHealthResult;
   Future<Event::Update> updateImplicitReconciliation;
 
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillOnce(FutureArg<1>(&updateHealthResult))
@@ -2236,6 +2342,9 @@ TEST_F(DefaultExecutorCheckTest, 
CommandCheckAndHealthCheckNoShadowing)
 
   launchTask(&mesos, offer, taskInfo);
 
+  AWAIT_READY(updateTaskStarting);
+  acknowledge(&mesos, frameworkId, updateTaskStarting->status());
+
   AWAIT_READY(updateTaskRunning);
   ASSERT_EQ(TASK_RUNNING, updateTaskRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateTaskRunning->status().task_id());
@@ -2370,11 +2479,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
-  Future<v1::scheduler::Event::Update> updates[4];
+  constexpr int EXPECTED_UPDATE_COUNT = 5;
+  Future<v1::scheduler::Event::Update> updates[EXPECTED_UPDATE_COUNT];
 
   {
     testing::InSequence dummy;
-    for (int i = 0; i < 4; i++) {
+    for (int i = 0; i < EXPECTED_UPDATE_COUNT; i++) {
       EXPECT_CALL(*scheduler, update(_, _))
         .WillOnce(FutureArg<1>(&updates[i]));
     }
@@ -2401,12 +2511,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
-  enum class Stage { INITIAL, RUNNING, CHECKED };
+  enum class Stage { STARTING, INITIAL, RUNNING, CHECKED };
   hashmap<v1::TaskID, Stage> taskStages;
-  taskStages.put(taskInfo1.task_id(), Stage::INITIAL);
-  taskStages.put(taskInfo2.task_id(), Stage::INITIAL);
+  taskStages.put(taskInfo1.task_id(), Stage::STARTING);
+  taskStages.put(taskInfo2.task_id(), Stage::STARTING);
 
-  for (int i = 0; i < 4; i++ ) {
+  for (int i = 0; i < EXPECTED_UPDATE_COUNT; i++ ) {
     AWAIT_READY(updates[i]);
 
     const v1::TaskStatus& taskStatus = updates[i]->status();
@@ -2415,8 +2525,17 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
     ASSERT_SOME(taskStage);
 
     switch (taskStage.get()) {
+      case Stage::STARTING: {
+        v1::TaskState state = taskStatus.state();
+        ASSERT_TRUE(state == v1::TASK_STARTING);
+
+        taskStages.put(taskStatus.task_id(), Stage::INITIAL);
+
+        break;
+      }
       case Stage::INITIAL: {
-        ASSERT_EQ(TASK_RUNNING, taskStatus.state());
+        v1::TaskState state = taskStatus.state();
+        ASSERT_TRUE(state == v1::TASK_RUNNING);
         ASSERT_TRUE(taskStatus.check_status().has_tcp());
         ASSERT_FALSE(taskStatus.check_status().tcp().has_succeeded());
 
@@ -2513,9 +2632,11 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(DefaultExecutorCheckTest, HTTPCheckDelivered)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<v1::scheduler::Event::Update> updateTaskStarting;
   Future<v1::scheduler::Event::Update> updateTaskRunning;
   Future<v1::scheduler::Event::Update> updateCheckResult;
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -2544,6 +2665,14 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(DefaultExecutorCheckTest, HTTPCheckDelivered)
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+
+  // Acknowledge (to be able to get the next update).
+  acknowledge(&mesos, frameworkId, taskStarting);
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 
@@ -2662,9 +2791,11 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(DefaultExecutorCheckTest, TCPCheckDelivered)
   const v1::Offer& offer = offers->offers(0);
   const v1::AgentID& agentId = offer.agent_id();
 
+  Future<v1::scheduler::Event::Update> updateTaskStarting;
   Future<v1::scheduler::Event::Update> updateTaskRunning;
   Future<v1::scheduler::Event::Update> updateCheckResult;
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(FutureArg<1>(&updateTaskStarting))
     .WillOnce(FutureArg<1>(&updateTaskRunning))
     .WillOnce(FutureArg<1>(&updateCheckResult))
     .WillRepeatedly(Return()); // Ignore subsequent updates.
@@ -2692,6 +2823,16 @@ 
TEST_F_TEMP_DISABLED_ON_WINDOWS(DefaultExecutorCheckTest, TCPCheckDelivered)
 
   launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
 
+  AWAIT_READY(updateTaskStarting);
+  const v1::TaskStatus& taskStarting = updateTaskStarting->status();
+
+  ASSERT_EQ(TASK_STARTING, taskStarting.state());
+  EXPECT_EQ(taskInfo.task_id(), taskStarting.task_id());
+
+  // Acknowledge (to be able to get the next update).
+  acknowledge(&mesos, frameworkId, taskStarting);
+
+
   AWAIT_READY(updateTaskRunning);
   const v1::TaskStatus& taskRunning = updateTaskRunning->status();
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/command_executor_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/command_executor_tests.cpp 
b/src/tests/command_executor_tests.cpp
index 2c1d467..6d6f916 100644
--- a/src/tests/command_executor_tests.cpp
+++ b/src/tests/command_executor_tests.cpp
@@ -125,12 +125,17 @@ TEST_P(CommandExecutorTest, NoTaskKillingCapability)
       offers->front().resources(),
       SLEEP_COMMAND(1000));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(_, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers->front().id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -193,12 +198,17 @@ TEST_P(CommandExecutorTest, TaskKillingCapability)
       offers->front().resources(),
        SLEEP_COMMAND(1000));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(_, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers->front().id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -296,12 +306,14 @@ TEST_P(CommandExecutorTest, 
NoTransitionFromKillingToRunning)
   vector<TaskInfo> tasks;
   tasks.push_back(task);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusHealthy;
   Future<TaskStatus> statusKilling;
   Future<TaskStatus> statusKilled;
 
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusHealthy))
     .WillOnce(FutureArg<1>(&statusKilling))
@@ -309,6 +321,9 @@ TEST_P(CommandExecutorTest, 
NoTransitionFromKillingToRunning)
 
   driver.launchTasks(offers->front().id(), tasks);
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -385,10 +400,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(HTTPCommandExecutorTest, 
TerminateWithACK)
       offers->front().resources(),
       "sleep 1");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
 
   EXPECT_CALL(sched, statusUpdate(_, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
@@ -398,7 +415,11 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(HTTPCommandExecutorTest, 
TerminateWithACK)
 
   driver.launchTasks(offers->front().id(), {task});
 
-  // Scheduler should first receive TASK_RUNNING followed by TASK_FINISHED.
+  // Scheduler should first receive TASK_STARTING, followed by TASK_RUNNING
+  // and TASK_FINISHED.
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -461,9 +482,10 @@ TEST_F(HTTPCommandExecutorTest, ExplicitAcknowledgements)
       offers->front().resources(),
       SLEEP_COMMAND(1000));
 
-  Future<TaskStatus> statusRunning;
+  Future<TaskStatus> statusStarting;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&statusRunning));
+    .WillOnce(FutureArg<1>(&statusStarting))
+    .WillRepeatedly(Return()); // Ignore subsequent updates.
 
   // Ensure no status update acknowledgements are sent from the driver
   // to the master until the explicit acknowledgement is sent.
@@ -475,9 +497,9 @@ TEST_F(HTTPCommandExecutorTest, ExplicitAcknowledgements)
 
   driver.launchTasks(offers->front().id(), {task});
 
-  AWAIT_READY(statusRunning);
-  EXPECT_TRUE(statusRunning->has_slave_id());
-  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+  AWAIT_READY(statusStarting);
+  EXPECT_TRUE(statusStarting->has_slave_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
 
   // Now send the acknowledgement.
   Future<mesos::scheduler::Call> acknowledgement = FUTURE_CALL(
@@ -486,7 +508,7 @@ TEST_F(HTTPCommandExecutorTest, ExplicitAcknowledgements)
       _,
       master.get()->pid);
 
-  driver.acknowledgeStatusUpdate(statusRunning.get());
+  driver.acknowledgeStatusUpdate(statusStarting.get());
 
   AWAIT_READY(acknowledgement);
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/container_logger_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/container_logger_tests.cpp 
b/src/tests/container_logger_tests.cpp
index fb8e441..b65cf6a 100644
--- a/src/tests/container_logger_tests.cpp
+++ b/src/tests/container_logger_tests.cpp
@@ -188,15 +188,20 @@ TEST_F(ContainerLoggerTest, DefaultToSandbox)
   // We'll start a task that outputs to stdout.
   TaskInfo task = createTask(offers.get()[0], "echo 'Hello World!'");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(Return());       // Ignore subsequent updates.
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -296,15 +301,20 @@ TEST_F(ContainerLoggerTest, LOGROTATE_RotateInSandbox)
       "i=0; while [ $i -lt 11264 ]; "
       "do printf '%-1024d\\n' $i; i=$((i+1)); done");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(Return());       // Ignore subsequent updates.
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -447,15 +457,20 @@ TEST_F(ContainerLoggerTest, LOGROTATE_CustomRotateOptions)
   variable->set_name("CONTAINER_LOGGER_LOGROTATE_STDOUT_OPTIONS");
   variable->set_value(customConfig);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(Return());       // Ignore subsequent updates.
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -545,15 +560,20 @@ TEST_F(ContainerLoggerTest, LOGROTATE_ModuleFDOwnership)
   // Start a task that will keep running until the end of the test.
   TaskInfo task = createTask(offers.get()[0], "sleep 100");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusKilled;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusKilled))
     .WillRepeatedly(Return());       // Ignore subsequent updates.
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -680,15 +700,20 @@ TEST_P(UserContainerLoggerTest, 
ROOT_LOGROTATE_RotateWithSwitchUserTrueOrFalse)
   // Start the task as a non-root user.
   task.mutable_command()->set_user("nobody");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(Return());       // Ignore subsequent updates.
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/containerizer/cgroups_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/cgroups_isolator_tests.cpp 
b/src/tests/containerizer/cgroups_isolator_tests.cpp
index 3fc9341..ee1e5e6 100644
--- a/src/tests/containerizer/cgroups_isolator_tests.cpp
+++ b/src/tests/containerizer/cgroups_isolator_tests.cpp
@@ -179,12 +179,18 @@ TEST_F(CgroupsIsolatorTest, 
ROOT_CGROUPS_PERF_NET_CLS_UserCgroup)
   container->set_type(ContainerInfo::MESOS);
   container->mutable_mesos()->mutable_image()->CopyFrom(image);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&statusRunning));
+    .WillOnce(FutureArg<1>(&statusStarting))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillRepeatedly(Return());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -320,12 +326,17 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_RevocableCpu)
       cpus,
       "sleep 120");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers2.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -416,12 +427,17 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_CFS_EnableCfs)
       Resources::parse("cpus:0.5").get(),
       command);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -530,8 +546,13 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_LimitSwap)
       v1::Resources::parse("cpus:0.1;mem:32;disk:32").get(),
       v1::createCommandInfo("ls", {"ls", "-al", "/"}));
 
+  Future<Event::Update> updateStarting;
   Future<Event::Update> updateRunning;
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(DoAll(FutureArg<1>(&updateStarting),
+                    v1::scheduler::SendAcknowledge(
+                        frameworkId,
+                        offer.agent_id())))
     .WillOnce(DoAll(FutureArg<1>(&updateRunning),
                     v1::scheduler::SendAcknowledge(
                         frameworkId,
@@ -543,6 +564,10 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_LimitSwap)
 
   mesos.send(v1::createCallAccept(frameworkId, offer, {launchGroup}));
 
+  AWAIT_READY(updateStarting);
+  ASSERT_EQ(v1::TASK_STARTING, updateStarting->status().state());
+  EXPECT_EQ(taskInfo.task_id(), updateStarting->status().task_id());
+
   AWAIT_READY(updateRunning);
   ASSERT_EQ(v1::TASK_RUNNING, updateRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateRunning->status().task_id());
@@ -617,12 +642,17 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_PidsAndTids)
       offers.get()[0].resources(),
       command);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -801,15 +831,20 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_NET_CLS_Isolate)
   // explicitly killing this task to perform the cleanup test.
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
-  Future<TaskStatus> status;
+  Future<TaskStatus> statusStarting;
+  Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&statusStarting))
+    .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   // Capture the update to verify that the task has been launched.
-  AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  AWAIT_READY(statusStarting);
+  ASSERT_EQ(TASK_STARTING, statusStarting->state());
+
+  AWAIT_READY(statusRunning);
+  ASSERT_EQ(TASK_RUNNING, statusRunning->state());
 
   // Task is ready.  Make sure there is exactly 1 container in the hashset.
   Future<hashset<ContainerID>> containers = containerizer->containers();
@@ -857,7 +892,7 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_NET_CLS_Isolate)
   Future<Nothing> gcSchedule = FUTURE_DISPATCH(
       _, &slave::GarbageCollectorProcess::schedule);
 
-  driver.killTask(status->task_id());
+  driver.killTask(statusRunning->task_id());
 
   AWAIT_READY(gcSchedule);
 
@@ -927,14 +962,19 @@ TEST_F(CgroupsIsolatorTest, 
ROOT_CGROUPS_NET_CLS_ContainerStatus)
   // Create a task to be launched in the mesos-container.
   TaskInfo task = createTask(offers.get()[0], "sleep 1000");
 
-  Future<TaskStatus> status;
+  Future<TaskStatus> statusStarting;
+  Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(_, _))
-    .WillOnce(FutureArg<1>(&status));
+    .WillOnce(FutureArg<1>(&statusStarting))
+    .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
-  AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  AWAIT_READY(statusStarting);
+  ASSERT_EQ(TASK_STARTING, statusStarting->state());
+
+  AWAIT_READY(statusRunning);
+  ASSERT_EQ(TASK_RUNNING, statusRunning->state());
 
   // Task is ready. Verify `ContainerStatus` is present in slave state.
   Future<Response> response = process::http::get(
@@ -1017,12 +1057,17 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_PERF_Sample)
 
   TaskInfo task = createTask(offers.get()[0], "sleep 120");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -1131,8 +1176,10 @@ TEST_F(CgroupsIsolatorTest, 
ROOT_CGROUPS_PERF_PerfForward)
   AWAIT_READY(offers1);
   ASSERT_FALSE(offers1->empty());
 
+  Future<TaskStatus> statusStarting1;
   Future<TaskStatus> statusRunning1;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting1))
     .WillOnce(FutureArg<1>(&statusRunning1))
     .WillRepeatedly(Return());
 
@@ -1147,6 +1194,9 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_PERF_PerfForward)
 
   driver.launchTasks(offers1.get()[0].id(), {task1}, filters);
 
+  AWAIT_READY(statusStarting1);
+  EXPECT_EQ(TASK_STARTING, statusStarting1->state());
+
   AWAIT_READY(statusRunning1);
   EXPECT_EQ(TASK_RUNNING, statusRunning1->state());
 
@@ -1203,13 +1253,18 @@ TEST_F(CgroupsIsolatorTest, 
ROOT_CGROUPS_PERF_PerfForward)
   // Start a new container which will start reporting perf statistics.
   TaskInfo task2 = createTask(offers2.get()[0], "sleep 1000");
 
+  Future<TaskStatus> statusStarting2;
   Future<TaskStatus> statusRunning2;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting2))
     .WillOnce(FutureArg<1>(&statusRunning2))
     .WillRepeatedly(Return()); // Ignore subsequent offers.
 
   driver.launchTasks(offers2.get()[0].id(), {task2});
 
+  AWAIT_READY(statusStarting2);
+  EXPECT_EQ(TASK_STARTING, statusStarting2->state());
+
   AWAIT_READY(statusRunning2);
   EXPECT_EQ(TASK_RUNNING, statusRunning2->state());
 
@@ -1292,8 +1347,10 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryForward)
   AWAIT_READY(offers1);
   ASSERT_FALSE(offers1->empty());
 
+  Future<TaskStatus> statusStarting1;
   Future<TaskStatus> statusRunning1;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting1))
     .WillOnce(FutureArg<1>(&statusRunning1))
     .WillRepeatedly(Return());
 
@@ -1308,6 +1365,9 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryForward)
 
   driver.launchTasks(offers1.get()[0].id(), {task1}, filters);
 
+  AWAIT_READY(statusStarting1);
+  EXPECT_EQ(TASK_STARTING, statusStarting1->state());
+
   AWAIT_READY(statusRunning1);
   EXPECT_EQ(TASK_RUNNING, statusRunning1->state());
 
@@ -1361,13 +1421,18 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryForward)
   // Start a new container which will start reporting memory statistics.
   TaskInfo task2 = createTask(offers2.get()[0], "sleep 1000");
 
+  Future<TaskStatus> statusStarting2;
   Future<TaskStatus> statusRunning2;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting2))
     .WillOnce(FutureArg<1>(&statusRunning2))
     .WillRepeatedly(Return()); // Ignore subsequent offers.
 
   driver.launchTasks(offers2.get()[0].id(), {task2});
 
+  AWAIT_READY(statusStarting2);
+  EXPECT_EQ(TASK_STARTING, statusStarting2->state());
+
   AWAIT_READY(statusRunning2);
   EXPECT_EQ(TASK_RUNNING, statusRunning2->state());
 
@@ -1448,8 +1513,10 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryBackward)
   AWAIT_READY(offers1);
   ASSERT_FALSE(offers1->empty());
 
+  Future<TaskStatus> statusStarting1;
   Future<TaskStatus> statusRunning1;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting1))
     .WillOnce(FutureArg<1>(&statusRunning1))
     .WillRepeatedly(Return());
 
@@ -1464,6 +1531,9 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryBackward)
 
   driver.launchTasks(offers1.get()[0].id(), {task1}, filters);
 
+  AWAIT_READY(statusStarting1);
+  EXPECT_EQ(TASK_STARTING, statusStarting1->state());
+
   AWAIT_READY(statusRunning1);
   EXPECT_EQ(TASK_RUNNING, statusRunning1->state());
 
@@ -1517,13 +1587,18 @@ TEST_F(CgroupsIsolatorTest, ROOT_CGROUPS_MemoryBackward)
 
   TaskInfo task2 = createTask(offers2.get()[0], "sleep 1000");
 
+  Future<TaskStatus> statusStarting2;
   Future<TaskStatus> statusRunning2;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting2))
     .WillOnce(FutureArg<1>(&statusRunning2))
     .WillRepeatedly(Return()); // Ignore subsequent offers.
 
   driver.launchTasks(offers2.get()[0].id(), {task2});
 
+  AWAIT_READY(statusStarting2);
+  EXPECT_EQ(TASK_STARTING, statusStarting2->state());
+
   AWAIT_READY(statusRunning2);
   EXPECT_EQ(TASK_RUNNING, statusRunning2->state());
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/containerizer/cni_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/cni_isolator_tests.cpp 
b/src/tests/containerizer/cni_isolator_tests.cpp
index e673d91..5a2af59 100644
--- a/src/tests/containerizer/cni_isolator_tests.cpp
+++ b/src/tests/containerizer/cni_isolator_tests.cpp
@@ -264,14 +264,20 @@ TEST_F(CniIsolatorTest, 
ROOT_INTERNET_CURL_LaunchCommandTask)
   // Make sure the container join the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -346,12 +352,18 @@ TEST_F(CniIsolatorTest, ROOT_VerifyCheckpointedInfo)
   // Make sure the container join the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -544,26 +556,37 @@ TEST_F(CniIsolatorTest, ROOT_SlaveRecovery)
   // Make sure the container join the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusKilled;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusKilled));
 
   EXPECT_CALL(sched, offerRescinded(&driver, _))
     .Times(AtMost(1));
 
-  Future<Nothing> ack =
+  Future<Nothing> ackRunning =
+    FUTURE_DISPATCH(_, &Slave::_statusUpdateAcknowledgement);
+
+  Future<Nothing> ackStarting =
     FUTURE_DISPATCH(_, &Slave::_statusUpdateAcknowledgement);
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
+  AWAIT_READY(ackStarting);
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
   // Wait for the ACK to be checkpointed.
-  AWAIT_READY(ack);
+  AWAIT_READY(ackRunning);
 
   // Stop the slave after TASK_RUNNING is received.
   slave.get()->terminate();
@@ -644,14 +667,20 @@ TEST_F(CniIsolatorTest, ROOT_EnvironmentLibprocessIP)
   // Make sure the container joins the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -722,14 +751,20 @@ TEST_F(CniIsolatorTest, 
ROOT_INTERNET_CURL_LaunchContainerInHostNetwork)
   container->set_type(ContainerInfo::MESOS);
   container->mutable_mesos()->mutable_image()->CopyFrom(image);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -853,15 +888,26 @@ TEST_F(CniIsolatorTest, ROOT_DynamicAddDelofCniConfig)
   // Make sure the container is able to join mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
-  Future<Nothing> ack =
+  Future<Nothing> ackRunning =
+    FUTURE_DISPATCH(_, &Slave::_statusUpdateAcknowledgement);
+
+  Future<Nothing> ackStarting =
     FUTURE_DISPATCH(_, &Slave::_statusUpdateAcknowledgement);
 
   driver.launchTasks(offer2.id(), {task}, filters);
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
+  AWAIT_READY(ackStarting);
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -869,7 +915,7 @@ TEST_F(CniIsolatorTest, ROOT_DynamicAddDelofCniConfig)
   // To avoid having the agent resending the `TASK_RUNNING` update, which can
   // happen due to clock manipulation below, wait for the status update
   // acknowledgement to reach the agent.
-  AWAIT_READY(ack);
+  AWAIT_READY(ackRunning);
 
   // Testing dynamic deletion of CNI networks.
   rm = os::rm(path::join(cniConfigDir, "mockConfig"));
@@ -977,14 +1023,20 @@ TEST_F(CniIsolatorTest, ROOT_OverrideHostname)
   // Make sure the container joins the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -1095,14 +1147,20 @@ TEST_F(CniIsolatorTest, ROOT_VerifyResolverConfig)
   // Make sure the container joins the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -1212,14 +1270,20 @@ TEST_F(CniIsolatorTest, 
ROOT_INTERNET_VerifyResolverConfig)
   // Make sure the container joins the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -1299,14 +1363,20 @@ TEST_F(CniIsolatorTest, 
ROOT_INTERNET_CURL_ReadOnlyBindMounts)
   container->set_type(ContainerInfo::MESOS);
   container->mutable_mesos()->mutable_image()->CopyFrom(image);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -1486,9 +1556,14 @@ TEST_P(DefaultExecutorCniTest, ROOT_VerifyContainerIP)
       v1::Resources::parse("cpus:0.1;mem:32;disk:32").get(),
       command);
 
+  Future<Event::Update> updateStarting;
   Future<Event::Update> updateRunning;
   Future<Event::Update> updateFinished;
   EXPECT_CALL(*scheduler, update(_, _))
+    .WillOnce(DoAll(FutureArg<1>(&updateStarting),
+                    v1::scheduler::SendAcknowledge(
+                        frameworkId,
+                        offer.agent_id())))
     .WillOnce(DoAll(FutureArg<1>(&updateRunning),
                     v1::scheduler::SendAcknowledge(
                         frameworkId,
@@ -1501,6 +1576,10 @@ TEST_P(DefaultExecutorCniTest, ROOT_VerifyContainerIP)
 
   mesos.send(v1::createCallAccept(frameworkId, offer, {launchGroup}));
 
+  AWAIT_READY(updateStarting);
+  ASSERT_EQ(v1::TASK_STARTING, updateStarting->status().state());
+  EXPECT_EQ(taskInfo.task_id(), updateStarting->status().task_id());
+
   AWAIT_READY(updateRunning);
   ASSERT_EQ(v1::TASK_RUNNING, updateRunning->status().state());
   EXPECT_EQ(taskInfo.task_id(), updateRunning->status().task_id());
@@ -1665,12 +1744,18 @@ TEST_F(CniIsolatorPortMapperTest, 
ROOT_INTERNET_CURL_PortMapper)
   // Set the container for the task.
   task.mutable_container()->CopyFrom(container);
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(300));
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
@@ -1898,14 +1983,20 @@ TEST_P(DefaultContainerDNSCniTest, 
ROOT_VerifyDefaultDNS)
   // Make sure the container joins the mock CNI network.
   container->add_network_infos()->set_name("__MESOS_TEST__");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished));
 
   driver.launchTasks(offer.id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(task.task_id(), statusStarting->task_id());
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(task.task_id(), statusRunning->task_id());
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/containerizer/cpu_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/cpu_isolator_tests.cpp 
b/src/tests/containerizer/cpu_isolator_tests.cpp
index 153990d..846b2e2 100644
--- a/src/tests/containerizer/cpu_isolator_tests.cpp
+++ b/src/tests/containerizer/cpu_isolator_tests.cpp
@@ -114,12 +114,17 @@ TEST_P(CpuIsolatorTest, ROOT_UserCpuUsage)
       offers.get()[0],
       "while true ; do true ; done & sleep 60");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -206,12 +211,17 @@ TEST_P(CpuIsolatorTest, ROOT_SystemCpuUsage)
       offers.get()[0],
       "cat /dev/urandom > /dev/null & sleep 60");
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY(statusRunning);
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/37053061/src/tests/containerizer/docker_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/docker_containerizer_tests.cpp 
b/src/tests/containerizer/docker_containerizer_tests.cpp
index 45f0d1d..419be5d 100644
--- a/src/tests/containerizer/docker_containerizer_tests.cpp
+++ b/src/tests/containerizer/docker_containerizer_tests.cpp
@@ -509,14 +509,18 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Launch)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   ASSERT_TRUE(statusRunning->has_data());
@@ -659,13 +663,17 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Kill)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusRunning);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -787,13 +795,17 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_TaskKillingCapability)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning));
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -913,14 +925,18 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Usage)
   EXPECT_CALL(dockerContainerizer, update(_, _))
     .WillRepeatedly(Return(Nothing()));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -1054,8 +1070,10 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Update)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
@@ -1063,6 +1081,9 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Update)
 
   AWAIT_READY(containerId);
 
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -1656,9 +1677,11 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_LaunchWithPersistentVolumes)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(DoDefault());
@@ -1670,6 +1693,10 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_LaunchWithPersistentVolumes)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+
+  AWAIT_READY_FOR(statusStarting, Seconds(60));
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
+
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -1810,8 +1837,10 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_RecoverPersistentVolumes)
                     Invoke(dockerContainerizer.get(),
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
@@ -1822,6 +1851,8 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_RecoverPersistentVolumes)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY_FOR(statusStarting, Seconds(60));
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -1974,8 +2005,10 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_RecoverOrphanedPersistentVolumes)
                     Invoke(dockerContainerizer.get(),
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
@@ -1986,6 +2019,8 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_RecoverOrphanedPersistentVolumes)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -2138,9 +2173,11 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Logs)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(DoDefault());
@@ -2149,6 +2186,8 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Logs)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   AWAIT_READY_FOR(statusFinished, Seconds(60));
@@ -2272,9 +2311,11 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Default_CMD)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(DoDefault());
@@ -2283,6 +2324,8 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Default_CMD)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   AWAIT_READY_FOR(statusFinished, Seconds(60));
@@ -2407,9 +2450,11 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_Default_CMD_Override)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(DoDefault());
@@ -2418,6 +2463,8 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_Default_CMD_Override)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   AWAIT_READY_FOR(statusFinished, Seconds(60));
@@ -2546,9 +2593,11 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_Default_CMD_Args)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(DoDefault());
@@ -2557,6 +2606,8 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_Default_CMD_Args)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   AWAIT_READY_FOR(statusFinished, Seconds(60));
@@ -2721,11 +2772,11 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_SlaveRecoveryTaskContainer)
   ASSERT_EQ(1, reregister.updates_size());
   const StatusUpdate& update = reregister.updates(0);
   ASSERT_EQ(task.task_id(), update.status().task_id());
-  ASSERT_EQ(TASK_RUNNING, update.status().state());
+  ASSERT_EQ(TASK_STARTING, update.status().state());
 
   // Scheduler should receive the recovered update.
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   ASSERT_TRUE(exists(docker, containerId.get()));
 
@@ -2906,11 +2957,11 @@ TEST_F(DockerContainerizerTest,
   ASSERT_EQ(1, reregister.updates_size());
   const StatusUpdate& update = reregister.updates(0);
   ASSERT_EQ(task.task_id(), update.status().task_id());
-  ASSERT_EQ(TASK_RUNNING, update.status().state());
+  ASSERT_EQ(TASK_STARTING, update.status().state());
 
   // Scheduler should receive the recovered update.
   AWAIT_READY(status);
-  ASSERT_EQ(TASK_RUNNING, status->state());
+  ASSERT_EQ(TASK_STARTING, status->state());
 
   ASSERT_TRUE(exists(docker, containerId.get()));
 
@@ -3022,9 +3073,11 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_NC_PortMapping)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusFinished;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusFinished))
     .WillRepeatedly(DoDefault());
@@ -3033,6 +3086,8 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_NC_PortMapping)
 
   AWAIT_READY_FOR(containerId, Seconds(60));
   AWAIT_READY(containerConfig);
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -3159,14 +3214,18 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_LaunchSandboxWithColon)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -4031,12 +4090,14 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_NoTransitionFromKillingToRunning)
                     Invoke(&containerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   Future<TaskStatus> statusHealthy;
   Future<TaskStatus> statusKilling;
   Future<TaskStatus> statusKilled;
 
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillOnce(FutureArg<1>(&statusHealthy))
     .WillOnce(FutureArg<1>(&statusKilling))
@@ -4045,6 +4106,8 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_NoTransitionFromKillingToRunning)
   driver.launchTasks(offers->front().id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -4160,14 +4223,18 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_CGROUPS_CFS_CgroupsEnableCFS)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   ASSERT_TRUE(statusRunning->has_data());
@@ -4299,14 +4366,18 @@ TEST_F(DockerContainerizerTest, 
ROOT_DOCKER_Non_Root_Sandbox)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
 
@@ -4455,14 +4526,18 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_DefaultDNS)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   ASSERT_TRUE(statusRunning->has_data());
@@ -4593,7 +4668,7 @@ TEST_F(DockerContainerizerIPv6Test, 
ROOT_DOCKER_LaunchIPv6HostNetwork)
   Future<vector<Offer>> offers;
   EXPECT_CALL(sched, resourceOffers(&driver, _))
     .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
+    .WillRepeatedly(Return());  // Ignore subsequent offers.
 
   driver.start();
 
@@ -4625,14 +4700,18 @@ TEST_F(DockerContainerizerIPv6Test, 
ROOT_DOCKER_LaunchIPv6HostNetwork)
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   ASSERT_TRUE(statusRunning->has_data());
@@ -4870,14 +4949,18 @@ TEST_F(
                     Invoke(&dockerContainerizer,
                            &MockDockerContainerizer::_launch)));
 
+  Future<TaskStatus> statusStarting;
   Future<TaskStatus> statusRunning;
   EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusStarting))
     .WillOnce(FutureArg<1>(&statusRunning))
     .WillRepeatedly(DoDefault());
 
   driver.launchTasks(offers.get()[0].id(), {task});
 
   AWAIT_READY_FOR(containerId, Seconds(60));
+  AWAIT_READY(statusStarting);
+  EXPECT_EQ(TASK_STARTING, statusStarting->state());
   AWAIT_READY_FOR(statusRunning, Seconds(60));
   EXPECT_EQ(TASK_RUNNING, statusRunning->state());
   ASSERT_TRUE(statusRunning->has_data());
@@ -4921,14 +5004,14 @@ TEST_F(
   // status as received in the status update message.
   for (int i = 0; i < 2; i++) {
     Result<JSON::String> protocol = parse->find<JSON::String>(
-        "frameworks[0].executors[0].tasks[0].statuses[0]"
+        "frameworks[0].executors[0].tasks[0].statuses[1]"
         ".container_status.network_infos[0].ip_addresses[" +
         stringify(i) + "].protocol");
 
     ASSERT_SOME(protocol);
 
     Result<JSON::String> ip = parse->find<JSON::String>(
-        "frameworks[0].executors[0].tasks[0].statuses[0]"
+        "frameworks[0].executors[0].tasks[0].statuses[1]"
         ".container_status.network_infos[0].ip_addresses[" +
         stringify(i) + "].ip_address");
 

Reply via email to