You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by al...@apache.org on 2017/05/11 10:16:47 UTC
[06/11] mesos git commit: Added a test that verifies a task's env var
is seen by its check.
Added a test that verifies a task's env var is seen by its check.
Review: https://reviews.apache.org/r/58718
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/721ee581
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/721ee581
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/721ee581
Branch: refs/heads/master
Commit: 721ee58196f1aaabeccf99324bebd78678198d60
Parents: e4940a5
Author: Alexander Rukletsov <al...@apache.org>
Authored: Mon Apr 24 16:38:41 2017 +0200
Committer: Alexander Rukletsov <al...@apache.org>
Committed: Thu May 11 12:15:55 2017 +0200
----------------------------------------------------------------------
src/tests/check_tests.cpp | 259 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 255 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/721ee581/src/tests/check_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/check_tests.cpp b/src/tests/check_tests.cpp
index ec0d5ee..13417da 100644
--- a/src/tests/check_tests.cpp
+++ b/src/tests/check_tests.cpp
@@ -505,6 +505,110 @@ TEST_F(CommandExecutorCheckTest, CommandCheckStatusChange)
}
+// Verifies that an environment variable set for the task is seen by its
+// command check.
+TEST_F_TEMP_DISABLED_ON_WINDOWS(
+ CommandExecutorCheckTest,
+ CommandCheckSeesParentsEnv)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ Owned<MasterDetector> detector = master.get()->createDetector();
+ Try<Owned<cluster::Slave>> agent = StartSlave(detector.get());
+ ASSERT_SOME(agent);
+
+ v1::FrameworkInfo frameworkInfo = v1::DEFAULT_FRAMEWORK_INFO;
+
+ auto scheduler = std::make_shared<v1::MockHTTPScheduler>();
+
+ Future<Nothing> connected;
+ EXPECT_CALL(*scheduler, connected(_))
+ .WillOnce(FutureSatisfy(&connected));
+
+ v1::scheduler::TestMesos mesos(
+ master.get()->pid,
+ ContentType::PROTOBUF,
+ scheduler);
+
+ AWAIT_READY(connected);
+
+ 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()); // Ignore subsequent offers.
+
+ EXPECT_CALL(*scheduler, heartbeat(_))
+ .WillRepeatedly(Return()); // Ignore heartbeats.
+
+ subscribe(&mesos, frameworkInfo);
+
+ AWAIT_READY(subscribed);
+
+ v1::FrameworkID frameworkId(subscribed->framework_id());
+
+ AWAIT_READY(offers);
+ EXPECT_NE(0, offers->offers().size());
+ const v1::Offer& offer = offers->offers(0);
+ const v1::AgentID agentId = offer.agent_id();
+
+ Future<Event::Update> updateTaskRunning;
+ Future<Event::Update> updateCheckResult;
+
+ EXPECT_CALL(*scheduler, update(_, _))
+ .WillOnce(FutureArg<1>(&updateTaskRunning))
+ .WillOnce(FutureArg<1>(&updateCheckResult))
+ .WillRepeatedly(Return()); // Ignore subsequent updates.
+
+ v1::Resources resources =
+ v1::Resources::parse("cpus:0.1;mem:32;disk:32").get();
+
+ const string envKey = "MESOS_CHECK_TASK_ENV";
+ const int32_t envValue = 42;
+
+ v1::TaskInfo taskInfo =
+ v1::createTask(agentId, resources, SLEEP_COMMAND(10000));
+
+ v1::Environment::Variable* variable =
+ taskInfo.mutable_command()->mutable_environment()->add_variables();
+ variable->set_name(envKey);
+ variable->set_value(stringify(envValue));
+
+ v1::CheckInfo* checkInfo = taskInfo.mutable_check();
+ checkInfo->set_type(v1::CheckInfo::COMMAND);
+ checkInfo->set_delay_seconds(0);
+ checkInfo->set_interval_seconds(0);
+
+ v1::CommandInfo* checkCommand =
+ checkInfo->mutable_command()->mutable_command();
+ checkCommand->set_value("exit $" + envKey);
+
+ launchTask(&mesos, offer, taskInfo);
+
+ AWAIT_READY(updateTaskRunning);
+ const v1::TaskStatus& taskRunning = updateTaskRunning->status();
+
+ ASSERT_EQ(TASK_RUNNING, taskRunning.state());
+ EXPECT_EQ(taskInfo.task_id(), taskRunning.task_id());
+
+ acknowledge(&mesos, frameworkId, taskRunning);
+
+ AWAIT_READY(updateCheckResult);
+ const v1::TaskStatus& checkResult = updateCheckResult->status();
+
+ ASSERT_EQ(TASK_RUNNING, checkResult.state());
+ ASSERT_EQ(
+ v1::TaskStatus::REASON_TASK_CHECK_STATUS_UPDATED,
+ checkResult.reason());
+ EXPECT_TRUE(checkResult.check_status().command().has_exit_code());
+ EXPECT_EQ(envValue, checkResult.check_status().command().exit_code());
+}
+
+
// Verifies that when a command check times out after a successful check,
// an empty check status update is delivered.
TEST_F(CommandExecutorCheckTest, CommandCheckTimeout)
@@ -1029,11 +1133,12 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(CommandExecutorCheckTest, TCPCheckDelivered)
// properly.
// 2. COMMAND check's status change is delivered. TODO(alexr): When check
// mocking is available, ensure only status changes are delivered.
-// 3. COMMAND check times out.
-// 4. COMMAND check and health check do not shadow each other; upon
+// 3. COMMAND check sees env vars set for the command itself.
+// 4. COMMAND check times out.
+// 5. COMMAND check and health check do not shadow each other; upon
// reconciliation both statuses are available.
-// 5. HTTP check works and is delivered.
-// 6. TCP check works and is delivered.
+// 6. HTTP check works and is delivered.
+// 7. TCP check works and is delivered.
// These are check tests with the default executor.
@@ -1424,6 +1529,152 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(
}
+// Verifies that an environment variable set for the task is seen by its
+// command check.
+TEST_F_TEMP_DISABLED_ON_WINDOWS(
+ DefaultExecutorCheckTest,
+ CommandCheckSeesParentsEnv)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ slave::Flags flags = CreateSlaveFlags();
+
+ Fetcher fetcher;
+
+ // We have to explicitly create a `Containerizer` in non-local mode,
+ // because `LaunchNestedContainerSession` (used by command checks)
+ // tries to start a IO switchboard, which doesn't work in local mode yet.
+ Try<MesosContainerizer*> _containerizer =
+ MesosContainerizer::create(flags, false, &fetcher);
+
+ ASSERT_SOME(_containerizer);
+
+ Owned<slave::Containerizer> containerizer(_containerizer.get());
+ Owned<MasterDetector> detector = master.get()->createDetector();
+
+ Try<Owned<cluster::Slave>> agent =
+ StartSlave(detector.get(), containerizer.get(), flags);
+ ASSERT_SOME(agent);
+
+ v1::FrameworkInfo frameworkInfo = v1::DEFAULT_FRAMEWORK_INFO;
+
+ const v1::Resources resources =
+ v1::Resources::parse("cpus:0.1;mem:32;disk:32").get();
+
+ v1::ExecutorInfo executorInfo;
+ executorInfo.set_type(v1::ExecutorInfo::DEFAULT);
+ executorInfo.mutable_executor_id()->CopyFrom(v1::DEFAULT_EXECUTOR_ID);
+ executorInfo.mutable_resources()->CopyFrom(resources);
+ executorInfo.mutable_shutdown_grace_period()->set_nanoseconds(
+ Seconds(10).ns());
+
+ auto scheduler = std::make_shared<v1::MockHTTPScheduler>();
+
+ Future<Nothing> connected;
+ EXPECT_CALL(*scheduler, connected(_))
+ .WillOnce(FutureSatisfy(&connected))
+ .WillRepeatedly(Return()); // Ignore teardown reconnections, see MESOS-6033.
+
+ v1::scheduler::TestMesos mesos(
+ master.get()->pid,
+ ContentType::PROTOBUF,
+ scheduler);
+
+ AWAIT_READY(connected);
+
+ 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()); // Ignore subsequent offers.
+
+ EXPECT_CALL(*scheduler, heartbeat(_))
+ .WillRepeatedly(Return()); // Ignore heartbeats.
+
+ subscribe(&mesos, frameworkInfo);
+
+ AWAIT_READY(subscribed);
+
+ v1::FrameworkID frameworkId(subscribed->framework_id());
+
+ // Update `executorInfo` with the subscribed `frameworkId`.
+ executorInfo.mutable_framework_id()->CopyFrom(frameworkId);
+
+ AWAIT_READY(offers);
+ EXPECT_NE(0, offers->offers().size());
+ const v1::Offer& offer = offers->offers(0);
+ const v1::AgentID agentId = offer.agent_id();
+
+ Future<Event::Update> updateTaskRunning;
+ Future<Event::Update> updateCheckResult;
+
+ EXPECT_CALL(*scheduler, update(_, _))
+ .WillOnce(FutureArg<1>(&updateTaskRunning))
+ .WillOnce(FutureArg<1>(&updateCheckResult))
+ .WillRepeatedly(Return()); // Ignore subsequent updates.
+
+ const string envKey = "MESOS_CHECK_TASK_ENV";
+ const int32_t envValue = 42;
+
+ v1::TaskInfo taskInfo =
+ v1::createTask(agentId, resources, SLEEP_COMMAND(10000));
+
+ v1::Environment::Variable* variable =
+ taskInfo.mutable_command()->mutable_environment()->add_variables();
+ variable->set_name(envKey);
+ variable->set_value(stringify(envValue));
+
+ v1::CheckInfo* checkInfo = taskInfo.mutable_check();
+ checkInfo->set_type(v1::CheckInfo::COMMAND);
+ checkInfo->set_delay_seconds(0);
+ checkInfo->set_interval_seconds(0);
+
+ v1::CommandInfo* checkCommand =
+ checkInfo->mutable_command()->mutable_command();
+ checkCommand->set_value("exit $" + envKey);
+
+ v1::TaskGroupInfo taskGroup;
+ taskGroup.add_tasks()->CopyFrom(taskInfo);
+
+ launchTaskGroup(&mesos, offer, executorInfo, taskGroup);
+
+ AWAIT_READY(updateTaskRunning);
+ const v1::TaskStatus& taskRunning = updateTaskRunning->status();
+
+ ASSERT_EQ(TASK_RUNNING, taskRunning.state());
+ EXPECT_EQ(taskInfo.task_id(), taskRunning.task_id());
+
+ acknowledge(&mesos, frameworkId, taskRunning);
+
+ AWAIT_READY(updateCheckResult);
+ const v1::TaskStatus& checkResult = updateCheckResult->status();
+
+ ASSERT_EQ(TASK_RUNNING, checkResult.state());
+ ASSERT_EQ(
+ v1::TaskStatus::REASON_TASK_CHECK_STATUS_UPDATED,
+ checkResult.reason());
+
+ EXPECT_TRUE(checkResult.check_status().command().has_exit_code());
+ EXPECT_EQ(envValue, checkResult.check_status().command().exit_code());
+
+ // Cleanup all mesos launched containers.
+ Future<hashset<ContainerID>> containerIds = containerizer->containers();
+ AWAIT_READY(containerIds);
+
+ EXPECT_CALL(*scheduler, disconnected(_));
+
+ teardown(&mesos, frameworkId);
+
+ foreach (const ContainerID& containerId, containerIds.get()) {
+ AWAIT_READY(containerizer->wait(containerId));
+ }
+}
+
+
// Verifies that when a command check times out after a successful check,
// an empty check status update is delivered.
//