Added test for hung 'docker inspect' call during container pull.

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


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

Branch: refs/heads/master
Commit: 28ab19b11ca369751f21e921cc4594e00ca667cb
Parents: 8c793a7
Author: Greg Mann <g...@mesosphere.io>
Authored: Fri Feb 23 16:41:51 2018 -0800
Committer: Greg Mann <gregorywm...@gmail.com>
Committed: Fri Feb 23 17:45:13 2018 -0800

----------------------------------------------------------------------
 .../docker_containerizer_tests.cpp              | 101 +++++++++++++++++++
 1 file changed, 101 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/28ab19b1/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 b84a750..a7cfd06 100644
--- a/src/tests/containerizer/docker_containerizer_tests.cpp
+++ b/src/tests/containerizer/docker_containerizer_tests.cpp
@@ -5193,6 +5193,107 @@ public:
   }
 };
 
+
+TEST_F_TEMP_DISABLED_ON_WINDOWS(
+    HungDockerTest, ROOT_DOCKER_InspectHungDuringPull)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  slave::Flags flags = CreateSlaveFlags();
+
+  // When the 'executor_registration_timeout' elapses, the agent will destroy
+  // the container whose 'docker pull' command is stuck. This should cause the
+  // launch to fail and the terminal task status update to be sent.
+  flags.executor_registration_timeout = Milliseconds(100);
+
+  MockDocker* mockDocker =
+    new MockDocker(flags.docker, tests::flags.docker_socket);
+  Shared<Docker> docker(mockDocker);
+
+  Fetcher fetcher(flags);
+
+  Try<ContainerLogger*> logger =
+    ContainerLogger::create(flags.container_logger);
+
+  ASSERT_SOME(logger);
+
+  MockDockerContainerizer dockerContainerizer(
+      flags,
+      &fetcher,
+      Owned<ContainerLogger>(logger.get()),
+      docker);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+
+  Try<Owned<cluster::Slave>> slave =
+    StartSlave(detector.get(), &dockerContainerizer, flags);
+  ASSERT_SOME(slave);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  Future<FrameworkID> frameworkId;
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .WillOnce(FutureArg<1>(&frameworkId));
+
+  Future<vector<Offer>> offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(frameworkId);
+
+  AWAIT_READY(offers);
+  ASSERT_FALSE(offers->empty());
+
+  // Causing the 'docker inspect' call preceding the container pull to hang
+  // should result in a TASK_FAILED update.
+  setDelayedCommands({"inspect"});
+
+  const Offer& offer = offers.get()[0];
+
+  TaskInfo task = createTask(
+      offer.slave_id(),
+      offer.resources(),
+      SLEEP_COMMAND(1000));
+
+  ContainerInfo containerInfo;
+  containerInfo.set_type(ContainerInfo::DOCKER);
+
+  // TODO(tnachen): Use local image to test if possible.
+  ContainerInfo::DockerInfo dockerInfo;
+  dockerInfo.set_image("alpine");
+  containerInfo.mutable_docker()->CopyFrom(dockerInfo);
+
+  task.mutable_container()->CopyFrom(containerInfo);
+
+  Future<ContainerID> containerId;
+  EXPECT_CALL(dockerContainerizer, launch(_, _, _, _))
+    .WillOnce(DoAll(FutureArg<0>(&containerId),
+                    Invoke(&dockerContainerizer,
+                           &MockDockerContainerizer::_launch)));
+
+  Future<TaskStatus> statusFailed;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusFailed))
+    .WillRepeatedly(DoDefault());
+
+  driver.launchTasks(offers.get()[0].id(), {task});
+
+  AWAIT_READY(statusFailed);
+  EXPECT_EQ(TASK_FAILED, statusFailed->state());
+  EXPECT_EQ(
+      TaskStatus::REASON_CONTAINER_LAUNCH_FAILED,
+      statusFailed->reason());
+
+  driver.stop();
+  driver.join();
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

Reply via email to