Repository: mesos Updated Branches: refs/heads/master a640eb25a -> 3f6faa499
Exposed unknown container case from Containerizer::wait. This allows the caller to distinguish between a failure and waiting on an unknown container. This is important for the upcoming agent child container API, as the end-user would benefit from the distinction. Review: https://reviews.apache.org/r/52055 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/3f6faa49 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/3f6faa49 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/3f6faa49 Branch: refs/heads/master Commit: 3f6faa499c06ac608e02355cf0e72386a1477d46 Parents: a640eb2 Author: Benjamin Mahler <bmah...@apache.org> Authored: Fri Sep 16 18:14:11 2016 -0700 Committer: Benjamin Mahler <bmah...@apache.org> Committed: Wed Sep 21 15:02:04 2016 -0700 ---------------------------------------------------------------------- src/slave/containerizer/composing.cpp | 8 +- src/slave/containerizer/composing.hpp | 2 +- src/slave/containerizer/containerizer.hpp | 3 +- src/slave/containerizer/docker.cpp | 9 +- src/slave/containerizer/docker.hpp | 4 +- src/slave/containerizer/mesos/containerizer.cpp | 14 +-- src/slave/containerizer/mesos/containerizer.hpp | 4 +- src/slave/slave.cpp | 34 +++-- src/slave/slave.hpp | 6 +- src/tests/cluster.cpp | 2 +- src/tests/containerizer.cpp | 10 +- src/tests/containerizer.hpp | 7 +- .../composing_containerizer_tests.cpp | 26 +++- .../docker_containerizer_tests.cpp | 64 ++++++++-- .../containerizer/filesystem_isolator_tests.cpp | 125 ++++++++++++------- src/tests/containerizer/isolator_tests.cpp | 7 +- .../containerizer/mesos_containerizer_tests.cpp | 105 ++++++++++++---- src/tests/containerizer/port_mapping_tests.cpp | 5 +- src/tests/health_check_tests.cpp | 6 +- src/tests/hook_tests.cpp | 15 ++- src/tests/slave_recovery_tests.cpp | 22 +++- 21 files changed, 339 insertions(+), 139 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/composing.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/composing.cpp b/src/slave/containerizer/composing.cpp index 5ff3e65..9181309 100644 --- a/src/slave/containerizer/composing.cpp +++ b/src/slave/containerizer/composing.cpp @@ -80,7 +80,7 @@ public: Future<ContainerStatus> status( const ContainerID& containerId); - Future<ContainerTermination> wait( + Future<Option<ContainerTermination>> wait( const ContainerID& containerId); void destroy(const ContainerID& containerId); @@ -206,7 +206,7 @@ Future<ContainerStatus> ComposingContainerizer::status( } -Future<ContainerTermination> ComposingContainerizer::wait( +Future<Option<ContainerTermination>> ComposingContainerizer::wait( const ContainerID& containerId) { return dispatch(process, &ComposingContainerizerProcess::wait, containerId); @@ -436,11 +436,11 @@ Future<ContainerStatus> ComposingContainerizerProcess::status( } -Future<ContainerTermination> ComposingContainerizerProcess::wait( +Future<Option<ContainerTermination>> ComposingContainerizerProcess::wait( const ContainerID& containerId) { if (!containers_.contains(containerId)) { - return Failure("Container '" + containerId.value() + "' not found"); + return None(); } return containers_[containerId]->containerizer->wait(containerId); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/composing.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/composing.hpp b/src/slave/containerizer/composing.hpp index ef3c2ee..3df7604 100644 --- a/src/slave/containerizer/composing.hpp +++ b/src/slave/containerizer/composing.hpp @@ -72,7 +72,7 @@ public: virtual process::Future<ContainerStatus> status( const ContainerID& containerId); - virtual process::Future<mesos::slave::ContainerTermination> wait( + virtual process::Future<Option<mesos::slave::ContainerTermination>> wait( const ContainerID& containerId); virtual void destroy(const ContainerID& containerId); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/containerizer.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/containerizer.hpp b/src/slave/containerizer/containerizer.hpp index f13669d..5ee1107 100644 --- a/src/slave/containerizer/containerizer.hpp +++ b/src/slave/containerizer/containerizer.hpp @@ -122,9 +122,10 @@ public: // Wait on the 'ContainerTermination'. If the executor terminates, // the containerizer should also destroy the containerized context. + // Returns None if the container cannot be found. // The future may be failed if an error occurs during termination of // the executor or destruction of the container. - virtual process::Future<mesos::slave::ContainerTermination> wait( + virtual process::Future<Option<mesos::slave::ContainerTermination>> wait( const ContainerID& containerId) = 0; // Destroy a running container, killing all processes and releasing http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/docker.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/docker.cpp b/src/slave/containerizer/docker.cpp index 26a7e7c..2e02943 100644 --- a/src/slave/containerizer/docker.cpp +++ b/src/slave/containerizer/docker.cpp @@ -714,7 +714,7 @@ Future<ResourceStatistics> DockerContainerizer::usage( } -Future<ContainerTermination> DockerContainerizer::wait( +Future<Option<ContainerTermination>> DockerContainerizer::wait( const ContainerID& containerId) { return dispatch( @@ -1780,16 +1780,17 @@ Try<ResourceStatistics> DockerContainerizerProcess::cgroupsStatistics( } -Future<ContainerTermination> DockerContainerizerProcess::wait( +Future<Option<ContainerTermination>> DockerContainerizerProcess::wait( const ContainerID& containerId) { CHECK(!containerId.has_parent()); if (!containers_.contains(containerId)) { - return Failure("Unknown container: " + stringify(containerId)); + return None(); } - return containers_[containerId]->termination.future(); + return containers_.at(containerId)->termination.future() + .then(Option<ContainerTermination>::some); } http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/docker.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/docker.hpp b/src/slave/containerizer/docker.hpp index a378fa9..aa6a9d6 100644 --- a/src/slave/containerizer/docker.hpp +++ b/src/slave/containerizer/docker.hpp @@ -100,7 +100,7 @@ public: virtual process::Future<ResourceStatistics> usage( const ContainerID& containerId); - virtual process::Future<mesos::slave::ContainerTermination> wait( + virtual process::Future<Option<mesos::slave::ContainerTermination>> wait( const ContainerID& containerId); virtual void destroy(const ContainerID& containerId); @@ -150,7 +150,7 @@ public: virtual process::Future<ResourceStatistics> usage( const ContainerID& containerId); - virtual process::Future<mesos::slave::ContainerTermination> wait( + virtual process::Future<Option<mesos::slave::ContainerTermination>> wait( const ContainerID& containerId); virtual void destroy( http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/mesos/containerizer.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp index e54169b..01acd70 100644 --- a/src/slave/containerizer/mesos/containerizer.cpp +++ b/src/slave/containerizer/mesos/containerizer.cpp @@ -538,7 +538,7 @@ Future<ContainerStatus> MesosContainerizer::status( } -Future<ContainerTermination> MesosContainerizer::wait( +Future<Option<ContainerTermination>> MesosContainerizer::wait( const ContainerID& containerId) { return dispatch(process.get(), @@ -1398,19 +1398,19 @@ Future<Nothing> MesosContainerizerProcess::launch( } -Future<ContainerTermination> MesosContainerizerProcess::wait( +Future<Option<ContainerTermination>> MesosContainerizerProcess::wait( const ContainerID& containerId) { CHECK(!containerId.has_parent()); if (!containers_.contains(containerId)) { - // See the comments in destroy() for race conditions which lead - // to "unknown containers". - return Failure("Unknown container (could have already been destroyed): " + - stringify(containerId)); + // See the comments in destroy() for race conditions + // which lead to "unknown containers". + return None(); } - return containers_[containerId]->promise.future(); + return containers_.at(containerId)->promise.future() + .then(Option<ContainerTermination>::some); } http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/containerizer/mesos/containerizer.hpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/mesos/containerizer.hpp b/src/slave/containerizer/mesos/containerizer.hpp index 078ef4f..a29da73 100644 --- a/src/slave/containerizer/mesos/containerizer.hpp +++ b/src/slave/containerizer/mesos/containerizer.hpp @@ -101,7 +101,7 @@ public: virtual process::Future<ContainerStatus> status( const ContainerID& containerId); - virtual process::Future<mesos::slave::ContainerTermination> wait( + virtual process::Future<Option<mesos::slave::ContainerTermination>> wait( const ContainerID& containerId); virtual void destroy(const ContainerID& containerId); @@ -165,7 +165,7 @@ public: virtual process::Future<ContainerStatus> status( const ContainerID& containerId); - virtual process::Future<mesos::slave::ContainerTermination> wait( + virtual process::Future<Option<mesos::slave::ContainerTermination>> wait( const ContainerID& containerId); virtual process::Future<bool> exec( http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/slave.cpp ---------------------------------------------------------------------- diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp index 7a9a541a..11e9c8a 100644 --- a/src/slave/slave.cpp +++ b/src/slave/slave.cpp @@ -4465,7 +4465,7 @@ void Slave::executorLaunched( void Slave::executorTerminated( const FrameworkID& frameworkId, const ExecutorID& executorId, - const Future<ContainerTermination>& termination) + const Future<Option<ContainerTermination>>& termination) { int status; // A termination failure indicates the containerizer could not destroy a @@ -4481,14 +4481,20 @@ void Slave::executorTerminated( : "discarded"); // Set a special status for failure. status = -1; - } else if (!termination.get().has_status()) { + } else if (termination->isNone()) { + LOG(ERROR) << "Termination of executor '" << executorId + << "' of framework " << frameworkId + << " failed: unknown container"; + // Set a special status for failure. + status = -1; + } else if (!termination->get().has_status()) { LOG(INFO) << "Executor '" << executorId << "' of framework " << frameworkId << " has terminated with unknown status"; // Set a special status for None. status = -1; } else { - status = termination.get().status(); + status = termination->get().status(); LOG(INFO) << "Executor '" << executorId << "' of framework " << frameworkId << " " << WSTRINGIFY(status); @@ -5855,7 +5861,7 @@ Future<bool> Slave::authorizeSandboxAccess( void Slave::sendExecutorTerminatedStatusUpdate( const TaskID& taskId, - const Future<ContainerTermination>& termination, + const Future<Option<ContainerTermination>>& termination, const FrameworkID& frameworkId, const Executor* executor) { @@ -5866,8 +5872,9 @@ void Slave::sendExecutorTerminatedStatusUpdate( string message; // Determine the task state for the status update. - if (termination.isReady() && termination->has_state()) { - state = termination->state(); + if (termination.isReady() && + termination->isSome() && termination->get().has_state()) { + state = termination->get().state(); } else if (executor->pendingTermination.isSome() && executor->pendingTermination->has_state()) { state = executor->pendingTermination->state(); @@ -5877,8 +5884,9 @@ void Slave::sendExecutorTerminatedStatusUpdate( // Determine the task reason for the status update. // TODO(jieyu): Handle multiple reasons (MESOS-2657). - if (termination.isReady() && termination->reasons().size() > 0) { - reason = termination->reasons(0); + if (termination.isReady() && + termination->isSome() && termination->get().reasons().size() > 0) { + reason = termination->get().reasons(0); } else if (executor->pendingTermination.isSome() && executor->pendingTermination->reasons().size() > 0) { reason = executor->pendingTermination->reasons(0); @@ -5895,9 +5903,13 @@ void Slave::sendExecutorTerminatedStatusUpdate( } if (!termination.isReady()) { - messages.push_back("Abnormal executor termination"); - } else if (termination->has_message()) { - messages.push_back(termination->message()); + messages.push_back( + "Abnormal executor termination: " + + (termination.isFailed() ? termination.failure() : "discarded future")); + } else if (termination->isNone()) { + messages.push_back("Abnormal executor termination: unknown container"); + } else if (termination->get().has_message()) { + messages.push_back(termination->get().message()); } if (messages.empty()) { http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/slave/slave.hpp ---------------------------------------------------------------------- diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp index 02d2eca..20ca2fb 100644 --- a/src/slave/slave.hpp +++ b/src/slave/slave.hpp @@ -290,7 +290,8 @@ public: void executorTerminated( const FrameworkID& frameworkId, const ExecutorID& executorId, - const process::Future<mesos::slave::ContainerTermination>& termination); + const process::Future<Option< + mesos::slave::ContainerTermination>>& termination); // NOTE: Pulled these to public to make it visible for testing. // TODO(vinod): Make tests friends to this class instead. @@ -650,7 +651,8 @@ private: void sendExecutorTerminatedStatusUpdate( const TaskID& taskId, - const Future<mesos::slave::ContainerTermination>& termination, + const process::Future<Option< + mesos::slave::ContainerTermination>>& termination, const FrameworkID& frameworkId, const Executor* executor); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/cluster.cpp ---------------------------------------------------------------------- diff --git a/src/tests/cluster.cpp b/src/tests/cluster.cpp index f201b49..6a9d94b 100644 --- a/src/tests/cluster.cpp +++ b/src/tests/cluster.cpp @@ -551,7 +551,7 @@ Slave::~Slave() AWAIT_READY(containers); foreach (const ContainerID& containerId, containers.get()) { - process::Future<ContainerTermination> wait = + process::Future<Option<ContainerTermination>> wait = containerizer->wait(containerId); containerizer->destroy(containerId); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer.cpp b/src/tests/containerizer.cpp index bda3e6f..78e18e8 100644 --- a/src/tests/containerizer.cpp +++ b/src/tests/containerizer.cpp @@ -194,16 +194,17 @@ Future<bool> TestContainerizer::_launch( } -Future<ContainerTermination> TestContainerizer::_wait( - const ContainerID& containerId) +Future<Option<ContainerTermination>> TestContainerizer::_wait( + const ContainerID& containerId) const { // An unknown container is possible for tests where we "drop" the // 'launch' in order to verify recovery still works correctly. if (!promises.contains(containerId)) { - return Failure("Unknown container: " + stringify(containerId)); + return None(); } - return promises[containerId]->future(); + return promises.at(containerId)->future() + .then(Option<ContainerTermination>::some); } @@ -217,6 +218,7 @@ void TestContainerizer::destroy( << executorId << "' of framework " << frameworkId; return; } + _destroy(containers_[key]); } http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer.hpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer.hpp b/src/tests/containerizer.hpp index f1fd579..8f69972 100644 --- a/src/tests/containerizer.hpp +++ b/src/tests/containerizer.hpp @@ -103,7 +103,8 @@ public: MOCK_METHOD1( wait, - process::Future<mesos::slave::ContainerTermination>(const ContainerID&)); + process::Future<Option<mesos::slave::ContainerTermination>>( + const ContainerID&)); MOCK_METHOD1( destroy, @@ -127,8 +128,8 @@ private: const std::map<std::string, std::string>& environment, bool checkpoint); - process::Future<mesos::slave::ContainerTermination> _wait( - const ContainerID& containerId); + process::Future<Option<mesos::slave::ContainerTermination>> _wait( + const ContainerID& containerId) const; void _destroy(const ContainerID& containerID); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer/composing_containerizer_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer/composing_containerizer_tests.cpp b/src/tests/containerizer/composing_containerizer_tests.cpp index 51aab33..19e31b1 100644 --- a/src/tests/containerizer/composing_containerizer_tests.cpp +++ b/src/tests/containerizer/composing_containerizer_tests.cpp @@ -83,7 +83,7 @@ public: MOCK_METHOD1( wait, - process::Future<ContainerTermination>( + process::Future<Option<ContainerTermination>>( const ContainerID&)); MOCK_METHOD1( @@ -156,6 +156,30 @@ TEST_F(ComposingContainerizerTest, DestroyWhileLaunching) AWAIT_FAILED(launch); } + +// Ensures the containerizer responds correctly (returns None) +// to a request to wait on an unknown container. +TEST_F(ComposingContainerizerTest, WaitUnknownContainer) +{ + vector<Containerizer*> containerizers; + + MockContainerizer* mockContainerizer = new MockContainerizer(); + MockContainerizer* mockContainerizer2 = new MockContainerizer(); + + containerizers.push_back(mockContainerizer); + containerizers.push_back(mockContainerizer2); + + ComposingContainerizer containerizer(containerizers); + + ContainerID containerId; + containerId.set_value(UUID::random().toString()); + + Future<Option<ContainerTermination>> wait = containerizer.wait(containerId); + + AWAIT_READY(wait); + EXPECT_NONE(wait.get()); +} + } // namespace tests { } // namespace internal { } // namespace mesos { http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/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 cca3f80..08bacb9 100644 --- a/src/tests/containerizer/docker_containerizer_tests.cpp +++ b/src/tests/containerizer/docker_containerizer_tests.cpp @@ -274,13 +274,14 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Launch_Executor) ASSERT_TRUE(exists(docker, slaveId, containerId.get())); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); ASSERT_FALSE( exists(docker, slaveId, containerId.get(), ContainerState::RUNNING)); @@ -402,13 +403,14 @@ TEST_F(DockerContainerizerTest, DISABLED_ROOT_DOCKER_Launch_Executor_Bridged) ASSERT_TRUE(exists(docker, slaveId, containerId.get())); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); ASSERT_FALSE( exists(docker, slaveId, containerId.get(), ContainerState::RUNNING)); @@ -553,13 +555,14 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Launch) ASSERT_TRUE(exists(docker, slaveId, containerId.get())); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); ASSERT_FALSE( exists(docker, slaveId, containerId.get(), ContainerState::RUNNING)); @@ -664,7 +667,7 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Kill) EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&statusKilled)); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.killTask(task.task_id()); @@ -673,6 +676,7 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Kill) EXPECT_EQ(TASK_KILLED, statusKilled.get().state()); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); ASSERT_FALSE( exists(docker, slaveId, containerId.get(), ContainerState::RUNNING)); @@ -790,7 +794,7 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_TaskKillingCapability) .WillOnce(FutureArg<1>(&statusKilling)) .WillOnce(FutureArg<1>(&statusKilled)); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.killTask(task.task_id()); @@ -802,6 +806,7 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_TaskKillingCapability) EXPECT_EQ(TASK_KILLED, statusKilled->state()); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); ASSERT_FALSE( exists(docker, slaveId, containerId.get(), ContainerState::RUNNING)); @@ -939,12 +944,13 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Usage) EXPECT_LT(0, statistics.cpus_system_time_secs()); EXPECT_GT(statistics.mem_rss_bytes(), 0u); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); dockerContainerizer.destroy(containerId.get()); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); // Usage() should fail again since the container is destroyed. Future<ResourceStatistics> usage = @@ -1231,7 +1237,7 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_Recover) AWAIT_READY(recover); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId); ASSERT_FALSE(termination.isFailed()); @@ -1362,7 +1368,7 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_KillOrphanContainers) AWAIT_READY(recover); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId); ASSERT_FALSE(termination.isFailed()); @@ -1565,13 +1571,14 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_LaunchWithPersistentVolumes) AWAIT_READY(statusFinished); EXPECT_EQ(TASK_FINISHED, statusFinished.get().state()); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); ASSERT_FALSE( exists(docker, slaveId, containerId.get(), ContainerState::RUNNING)); @@ -1735,12 +1742,13 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_RecoverPersistentVolumes) // Wait until containerizer recover is complete. AWAIT_READY(_recover); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer->wait(containerId.get()); dockerContainerizer->destroy(containerId.get()); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); Try<fs::MountInfoTable> table = fs::MountInfoTable::read(); EXPECT_SOME(table); @@ -2612,13 +2620,14 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_SlaveRecoveryTaskContainer) ASSERT_TRUE(exists(docker, slaveId, containerId.get())); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer->wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); } @@ -2949,13 +2958,14 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_NC_PortMapping) // to stdout by the docker container running nc -l. EXPECT_TRUE(containsLine(lines, uuid)); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); } @@ -3057,13 +3067,14 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_LaunchSandboxWithColon) ASSERT_TRUE(exists(docker, slaveId, containerId.get())); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = dockerContainerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); } @@ -3756,6 +3767,33 @@ TEST_F(DockerContainerizerTest, ROOT_DOCKER_DockerInspectDiscard) driver.join(); } + +// Ensures the containerizer responds correctly (returns None) +// to a request to wait on an unknown container. +TEST_F(DockerContainerizerTest, ROOT_DOCKER_WaitUnknownContainer) +{ + slave::Flags flags = CreateSlaveFlags(); + + Fetcher fetcher; + + Try<DockerContainerizer*> create = + DockerContainerizer::create(flags, &fetcher); + + ASSERT_SOME(create); + + DockerContainerizer* containerizer = create.get(); + + AWAIT_READY(containerizer->recover(None())); + + ContainerID containerId; + containerId.set_value(UUID::random().toString()); + + Future<Option<ContainerTermination>> wait = containerizer->wait(containerId); + + AWAIT_READY(wait); + EXPECT_NONE(wait.get()); +} + } // namespace tests { } // namespace internal { } // namespace mesos { http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer/filesystem_isolator_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer/filesystem_isolator_tests.cpp b/src/tests/containerizer/filesystem_isolator_tests.cpp index df4642d..680d68b 100644 --- a/src/tests/containerizer/filesystem_isolator_tests.cpp +++ b/src/tests/containerizer/filesystem_isolator_tests.cpp @@ -288,12 +288,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ChangeRootFilesystem) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -807,12 +810,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_Metrics) containerizer.get()->destroy(containerId); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Executor was killed. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(9, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(9, wait->get().status()); } @@ -858,12 +864,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); EXPECT_SOME_EQ("abc\n", os::read(path::join(directory, "tmp", "file"))); } @@ -911,12 +920,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -962,12 +974,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHost) AWAIT_READY_FOR(launch, Seconds(60)); - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -1013,12 +1028,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHostSandboxMountPoint) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -1064,12 +1082,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_FileVolumeFromHostSandboxMountPoint) AWAIT_READY_FOR(launch, Seconds(60)); - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -1130,12 +1151,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithRootFilesystem) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file"))); } @@ -1202,12 +1226,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_PersistentVolumeWithoutRootFilesystem) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); EXPECT_SOME_EQ("abc\n", os::read(path::join(volume, "file"))); } @@ -1255,12 +1282,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithoutRootFilesystem) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -1308,14 +1338,16 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolumeWithRootFilesystem) AWAIT_READY_FOR(launch, Seconds(240)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); // Because destroy rootfs spents a lot of time, we use 30s as timeout here. AWAIT_READY_FOR(wait, Seconds(30)); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -1422,19 +1454,25 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_MultipleContainers) containerizer.get()->destroy(containerId1); // Wait on the containers. - Future<ContainerTermination> wait1 = containerizer.get()->wait(containerId1); - Future<ContainerTermination> wait2 = containerizer.get()->wait(containerId2); + Future<Option<ContainerTermination>> wait1 = + containerizer.get()->wait(containerId1); + + Future<Option<ContainerTermination>> wait2 = + containerizer.get()->wait(containerId2); AWAIT_READY_FOR(wait1, Seconds(60)); + ASSERT_SOME(wait1.get()); + AWAIT_READY_FOR(wait2, Seconds(60)); + ASSERT_SOME(wait2.get()); // Executor 1 was forcefully killed. - EXPECT_TRUE(wait1.get().has_status()); - EXPECT_EQ(9, wait1.get().status()); + EXPECT_TRUE(wait1->get().has_status()); + EXPECT_EQ(9, wait1->get().status()); // Executor 2 exited normally. - EXPECT_TRUE(wait2.get().has_status()); - EXPECT_EQ(0, wait2.get().status()); + EXPECT_TRUE(wait2->get().has_status()); + EXPECT_EQ(0, wait2->get().status()); } @@ -1493,12 +1531,15 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_SandboxEnvironmentVariable) AWAIT_READY_FOR(launch, Seconds(60)); // Wait on the container. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer/isolator_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer/isolator_tests.cpp b/src/tests/containerizer/isolator_tests.cpp index 56af742..b4d25e5 100644 --- a/src/tests/containerizer/isolator_tests.cpp +++ b/src/tests/containerizer/isolator_tests.cpp @@ -339,12 +339,13 @@ TEST_F(NamespacesPidIsolatorTest, ROOT_PidNamespace) ASSERT_TRUE(launch.get()); // Wait on the container. - Future<ContainerTermination> wait = containerizer->wait(containerId); + Future<Option<ContainerTermination>> wait = containerizer->wait(containerId); AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); // Check that the command was run in a different pid namespace. Try<ino_t> testPidNamespace = ns::getns(::getpid(), "pid"); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer/mesos_containerizer_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer/mesos_containerizer_tests.cpp b/src/tests/containerizer/mesos_containerizer_tests.cpp index 96e2450..d7455d2 100644 --- a/src/tests/containerizer/mesos_containerizer_tests.cpp +++ b/src/tests/containerizer/mesos_containerizer_tests.cpp @@ -220,12 +220,15 @@ TEST_F(MesosContainerizerIsolatorPreparationTest, ScriptSucceeds) AWAIT_READY(launch); // Wait for the child (preparation script + executor) to complete. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the child exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); // Check the preparation script actually ran. EXPECT_TRUE(os::exists(file)); @@ -270,12 +273,15 @@ TEST_F(MesosContainerizerIsolatorPreparationTest, ScriptFails) AWAIT_READY(launch); // Wait for the child (preparation script + executor) to complete. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the child failed to exit correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_NE(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_NE(0, wait->get().status()); // Check the preparation script actually ran. EXPECT_TRUE(os::exists(file)); @@ -331,12 +337,15 @@ TEST_F(MesosContainerizerIsolatorPreparationTest, MultipleScripts) AWAIT_READY(launch); // Wait for the child (preparation script(s) + executor) to complete. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the child failed to exit correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_NE(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_NE(0, wait->get().status()); // Check the failing preparation script has actually ran. EXPECT_TRUE(os::exists(file2)); @@ -412,12 +421,15 @@ TEST_F(MesosContainerizerIsolatorPreparationTest, ExecutorEnvironmentVariable) AWAIT_READY(launch); // Wait for the child (preparation script + executor) to complete. - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the child exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); // Check the preparation script actually ran. EXPECT_TRUE(os::exists(file)); @@ -480,12 +492,15 @@ TEST_F(MesosContainerizerExecuteTest, IoRedirection) AWAIT_READY(launch); // Wait on the container. - Future<ContainerTermination> wait = containerizer->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); // Check that std{err, out} was redirected. // NOTE: Fetcher uses GLOG, which outputs extra information to @@ -661,13 +676,16 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhileFetching) map<string, string>(), false); - Future<ContainerTermination> wait = containerizer.wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.wait(containerId); + AWAIT_READY(exec); containerizer.destroy(containerId); // The container should still exit even if fetch didn't complete. AWAIT_READY(wait); + EXPECT_SOME(wait.get()); } @@ -728,7 +746,8 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhilePreparing) map<string, string>(), false); - Future<ContainerTermination> wait = containerizer.wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.wait(containerId); AWAIT_READY(prepare); @@ -744,8 +763,9 @@ TEST_F(MesosContainerizerDestroyTest, DestroyWhilePreparing) promise.set(option); AWAIT_READY(wait); + ASSERT_SOME(wait.get()); - ContainerTermination termination = wait.get(); + ContainerTermination termination = wait->get(); EXPECT_FALSE(termination.has_status()); } @@ -849,13 +869,15 @@ TEST_F(MesosContainerizerProvisionerTest, ProvisionFailed) AWAIT_FAILED(launch); - Future<ContainerTermination> wait = containerizer.wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.wait(containerId); containerizer.destroy(containerId); AWAIT_READY(wait); + ASSERT_SOME(wait.get()); - ContainerTermination termination = wait.get(); + ContainerTermination termination = wait->get(); EXPECT_FALSE(termination.has_status()); } @@ -937,7 +959,8 @@ TEST_F(MesosContainerizerProvisionerTest, DestroyWhileProvisioning) map<string, string>(), false); - Future<ContainerTermination> wait = containerizer.wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.wait(containerId); AWAIT_READY(provision); @@ -948,8 +971,9 @@ TEST_F(MesosContainerizerProvisionerTest, DestroyWhileProvisioning) AWAIT_FAILED(launch); AWAIT_READY(wait); + ASSERT_SOME(wait.get()); - ContainerTermination termination = wait.get(); + ContainerTermination termination = wait->get(); EXPECT_FALSE(termination.has_status()); } @@ -1036,7 +1060,8 @@ TEST_F(MesosContainerizerProvisionerTest, IsolatorCleanupBeforePrepare) map<string, string>(), false); - Future<ContainerTermination> wait = containerizer.wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.wait(containerId); AWAIT_READY(provision); @@ -1047,8 +1072,9 @@ TEST_F(MesosContainerizerProvisionerTest, IsolatorCleanupBeforePrepare) AWAIT_FAILED(launch); AWAIT_READY(wait); + ASSERT_SOME(wait.get()); - ContainerTermination termination = wait.get(); + ContainerTermination termination = wait->get(); EXPECT_FALSE(termination.has_status()); } @@ -1121,7 +1147,8 @@ TEST_F(MesosContainerizerDestroyTest, LauncherDestroyFailure) AWAIT_READY(launch); - Future<ContainerTermination> wait = containerizer.wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.wait(containerId); containerizer.destroy(containerId); @@ -1239,6 +1266,34 @@ TEST_F(MesosLauncherStatusTest, ExecutorPIDTest) AWAIT_READY(launcher.get()->destroy(containerId)); } + +class MesosContainerizerWaitTest : public MesosTest {}; + + +// Ensures the containerizer responds correctly (returns None) +// to a request to wait on an unknown container. +TEST_F(MesosContainerizerWaitTest, WaitUnknownContainer) +{ + slave::Flags flags = CreateSlaveFlags(); + + Fetcher fetcher; + + Try<MesosContainerizer*> create = + MesosContainerizer::create(flags, true, &fetcher); + + ASSERT_SOME(create); + + MesosContainerizer* containerizer = create.get(); + + ContainerID containerId; + containerId.set_value(UUID::random().toString()); + + Future<Option<ContainerTermination>> wait = containerizer->wait(containerId); + + AWAIT_READY(wait); + EXPECT_NONE(wait.get()); +} + } // namespace tests { } // namespace internal { } // namespace mesos { http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/containerizer/port_mapping_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/containerizer/port_mapping_tests.cpp b/src/tests/containerizer/port_mapping_tests.cpp index ab8db58..99790d0 100644 --- a/src/tests/containerizer/port_mapping_tests.cpp +++ b/src/tests/containerizer/port_mapping_tests.cpp @@ -2197,7 +2197,8 @@ TEST_F(PortMappingMesosTest, ROOT_NetworkNamespaceHandleSymlink) EXPECT_TRUE(os::exists(symlink)); EXPECT_TRUE(os::stat::islink(symlink)); - Future<ContainerTermination> termination = containerizer->wait(containerId); + Future<Option<ContainerTermination>> termination = + containerizer->wait(containerId); driver.killTask(task.task_id()); @@ -2206,6 +2207,8 @@ TEST_F(PortMappingMesosTest, ROOT_NetworkNamespaceHandleSymlink) EXPECT_EQ(TASK_KILLED, status2.get().state()); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); + EXPECT_FALSE(os::exists(symlink)); driver.stop(); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/health_check_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/health_check_tests.cpp b/src/tests/health_check_tests.cpp index 30b5a2f..e6b02f2 100644 --- a/src/tests/health_check_tests.cpp +++ b/src/tests/health_check_tests.cpp @@ -580,13 +580,14 @@ TEST_F(HealthCheckTest, ROOT_DOCKER_DockerHealthyTask) EXPECT_TRUE(statusHealth.get().has_healthy()); EXPECT_TRUE(statusHealth.get().healthy()); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = containerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); slave.get()->terminate(); slave->reset(); @@ -1003,13 +1004,14 @@ TEST_F(HealthCheckTest, ROOT_DOCKER_DockerHealthStatusChange) ASSERT_SOME(os::read(tmpPath)); EXPECT_EQ("bar", os::read(tmpPath).get()); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = containerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); slave.get()->terminate(); slave->reset(); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/hook_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/hook_tests.cpp b/src/tests/hook_tests.cpp index 602bb39..f837ca7 100644 --- a/src/tests/hook_tests.cpp +++ b/src/tests/hook_tests.cpp @@ -324,12 +324,15 @@ TEST_F(HookTest, VerifySlaveExecutorEnvironmentDecorator) ASSERT_TRUE(launch.get()); // Wait on the container. - process::Future<ContainerTermination> wait = containerizer->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer->wait(containerId); + AWAIT_READY(wait); + ASSERT_SOME(wait.get()); // Check the executor exited correctly. - EXPECT_TRUE(wait.get().has_status()); - EXPECT_EQ(0, wait.get().status()); + EXPECT_TRUE(wait->get().has_status()); + EXPECT_EQ(0, wait->get().status()); } @@ -712,13 +715,14 @@ TEST_F(HookTest, ROOT_DOCKER_VerifySlavePreLaunchDockerEnvironmentDecorator) AWAIT_READY_FOR(statusFinished, Seconds(60)); EXPECT_EQ(TASK_FINISHED, statusFinished.get().state()); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = containerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); Future<list<Docker::Container>> containers = docker.get()->ps(true, slave::DOCKER_NAME_PREFIX); @@ -928,13 +932,14 @@ TEST_F(HookTest, ROOT_DOCKER_VerifySlavePreLaunchDockerHook) AWAIT_READY_FOR(statusFinished, Seconds(60)); EXPECT_EQ(TASK_FINISHED, statusFinished.get().state()); - Future<ContainerTermination> termination = + Future<Option<ContainerTermination>> termination = containerizer.wait(containerId.get()); driver.stop(); driver.join(); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); Future<list<Docker::Container>> containers = docker.get()->ps(true, slave::DOCKER_NAME_PREFIX); http://git-wip-us.apache.org/repos/asf/mesos/blob/3f6faa49/src/tests/slave_recovery_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/slave_recovery_tests.cpp b/src/tests/slave_recovery_tests.cpp index 23cf9d8..618019c 100644 --- a/src/tests/slave_recovery_tests.cpp +++ b/src/tests/slave_recovery_tests.cpp @@ -1719,10 +1719,13 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework) AWAIT_READY(containers); foreach (const ContainerID& containerId, containers.get()) { - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); containerizer.get()->destroy(containerId); + AWAIT_READY(wait); + EXPECT_SOME(wait.get()); } } @@ -2652,10 +2655,13 @@ TYPED_TEST(SlaveRecoveryTest, RegisterDisconnectedSlave) AWAIT_READY(containers); foreach (const ContainerID& containerId, containers.get()) { - Future<ContainerTermination> wait = containerizer.get()->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer.get()->wait(containerId); containerizer.get()->destroy(containerId); + AWAIT_READY(wait); + EXPECT_SOME(wait.get()); } } @@ -3863,11 +3869,13 @@ TEST_F(MesosContainerizerSlaveRecoveryTest, ResourceStatistics) EXPECT_TRUE(usage.get().has_cpus_limit()); EXPECT_TRUE(usage.get().has_mem_limit_bytes()); - Future<ContainerTermination> wait = containerizer->wait(containerId); + Future<Option<ContainerTermination>> wait = + containerizer->wait(containerId); containerizer->destroy(containerId); AWAIT_READY(wait); + EXPECT_SOME(wait.get()); driver.stop(); driver.join(); @@ -4116,12 +4124,14 @@ TEST_F(MesosContainerizerSlaveRecoveryTest, CGROUPS_ROOT_PidNamespaceForward) EXPECT_NE(0u, offers2.get().size()); // Set up to wait on the container's termination. - Future<ContainerTermination> termination = containerizer->wait(containerId); + Future<Option<ContainerTermination>> termination = + containerizer->wait(containerId); // Destroy the container. containerizer->destroy(containerId); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); driver.stop(); driver.join(); @@ -4221,12 +4231,14 @@ TEST_F(MesosContainerizerSlaveRecoveryTest, CGROUPS_ROOT_PidNamespaceBackward) EXPECT_NE(0u, offers2.get().size()); // Set up to wait on the container's termination. - Future<ContainerTermination> termination = containerizer->wait(containerId); + Future<Option<ContainerTermination>> termination = + containerizer->wait(containerId); // Destroy the container. containerizer->destroy(containerId); AWAIT_READY(termination); + EXPECT_SOME(termination.get()); driver.stop(); driver.join();