This is an automated email from the ASF dual-hosted git repository. qianzhang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mesos.git
commit a6445fa92e5b7e6ac3b9c9ef634b442d3310090c Author: Qian Zhang <[email protected]> AuthorDate: Thu Sep 19 16:33:46 2019 +0800 Added the test `GarbageCollectorIntegrationTest.ROOT_OrphanContainer`. Review: https://reviews.apache.org/r/71518 --- src/tests/gc_tests.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/src/tests/gc_tests.cpp b/src/tests/gc_tests.cpp index 2ea4bcb..15bb541 100644 --- a/src/tests/gc_tests.cpp +++ b/src/tests/gc_tests.cpp @@ -1531,6 +1531,114 @@ TEST_F(GarbageCollectorIntegrationTest, ROOT_DanglingMount) driver.stop(); driver.join(); } + + +// This is a regression test for MESOS-9966. It enables the agent +// flag `--gc_non_executor_container_sandboxes` and launches a +// nested container with checkpointing disabled, and then verifies +// that agent can recover successfully. +// +// TODO(qianzhang): For now, this test is Linux specific because +// the POSIX launcher is not able to destroy orphan containers +// after recovery, see MESOS-8771 for details. +TEST_F(GarbageCollectorIntegrationTest, ROOT_OrphanContainer) +{ + Try<Owned<cluster::Master>> master = StartMaster(); + ASSERT_SOME(master); + + // Turn on GC of nested container sandboxes by default. + slave::Flags flags = CreateSlaveFlags(); + flags.gc_non_executor_container_sandboxes = true; + flags.launcher = "linux"; + + Owned<MasterDetector> detector = master.get()->createDetector(); + Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags, false); + ASSERT_SOME(slave); + + auto scheduler = std::make_shared<v1::MockHTTPScheduler>(); + + // Disable checkpointing so the container launched by the framework will be + // orphan after agent restarts. + v1::FrameworkInfo frameworkInfo = v1::DEFAULT_FRAMEWORK_INFO; + frameworkInfo.set_checkpoint(false); + + EXPECT_CALL(*scheduler, connected(_)) + .WillOnce(v1::scheduler::SendSubscribe(frameworkInfo)); + + Future<v1::scheduler::Event::Subscribed> subscribed; + EXPECT_CALL(*scheduler, subscribed(_, _)) + .WillOnce(FutureArg<1>(&subscribed)); + + Future<v1::scheduler::Event::Offers> offers; + EXPECT_CALL(*scheduler, offers(_, _)) + .WillOnce(FutureArg<1>(&offers)) + .WillRepeatedly(Return()); + + EXPECT_CALL(*scheduler, heartbeat(_)) + .WillRepeatedly(Return()); // Ignore heartbeats. + + v1::scheduler::TestMesos mesos( + master.get()->pid, + ContentType::PROTOBUF, + scheduler); + + AWAIT_READY(subscribed); + v1::FrameworkID frameworkId(subscribed->framework_id()); + + AWAIT_READY(offers); + ASSERT_FALSE(offers->offers().empty()); + + const v1::Offer& offer = offers->offers(0); + const v1::AgentID& agentId = offer.agent_id(); + + v1::Resources resources = + v1::Resources::parse("cpus:0.1;mem:32;disk:32").get(); + + v1::ExecutorInfo executorInfo = v1::createExecutorInfo( + v1::DEFAULT_EXECUTOR_ID, + None(), + resources, + v1::ExecutorInfo::DEFAULT, + frameworkId); + + v1::TaskInfo taskInfo = + v1::createTask(agentId, resources, SLEEP_COMMAND(1000)); + + Future<v1::scheduler::Event::Update> startingUpdate; + Future<v1::scheduler::Event::Update> runningUpdate; + EXPECT_CALL(*scheduler, update(_, _)) + .WillOnce(DoAll( + FutureArg<1>(&startingUpdate), + v1::scheduler::SendAcknowledge(frameworkId, agentId))) + .WillOnce(FutureArg<1>(&runningUpdate)) + .WillRepeatedly(Return()); + + mesos.send( + v1::createCallAccept( + frameworkId, + offer, + {v1::LAUNCH_GROUP( + executorInfo, v1::createTaskGroupInfo({taskInfo}))})); + + AWAIT_READY(startingUpdate); + + ASSERT_EQ(v1::TASK_STARTING, startingUpdate->status().state()); + EXPECT_EQ(taskInfo.task_id(), startingUpdate->status().task_id()); + EXPECT_TRUE(startingUpdate->status().has_timestamp()); + + AWAIT_READY(runningUpdate); + + // Restart the agent. + Future<SlaveReregisteredMessage> slaveReregisteredMessage = + FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _); + + slave.get()->terminate(); + + slave = StartSlave(detector.get(), flags, false); + ASSERT_SOME(slave); + + AWAIT_READY(slaveReregisteredMessage); +} #endif // __linux__ } // namespace tests {
