Added slave run task hook tests. Review: https://reviews.apache.org/r/31028
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e2d6c86b Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e2d6c86b Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e2d6c86b Branch: refs/heads/master Commit: e2d6c86b8af2ff28a8591d9c8a2dbb2568c779d3 Parents: 8dd1bb1 Author: Niklas Nielsen <[email protected]> Authored: Mon Apr 20 14:37:19 2015 -0700 Committer: Adam B <[email protected]> Committed: Mon Apr 20 14:37:19 2015 -0700 ---------------------------------------------------------------------- src/examples/test_hook_module.cpp | 25 +++++++++ src/tests/hook_tests.cpp | 96 ++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/e2d6c86b/src/examples/test_hook_module.cpp ---------------------------------------------------------------------- diff --git a/src/examples/test_hook_module.cpp b/src/examples/test_hook_module.cpp index 64fb503..b25830a 100644 --- a/src/examples/test_hook_module.cpp +++ b/src/examples/test_hook_module.cpp @@ -62,6 +62,31 @@ public: return labels; } + // TODO(nnielsen): Split hook tests into multiple modules to avoid + // interference. + virtual Result<Labels> slaveRunTaskLabelDecorator( + const TaskInfo& taskInfo, + const FrameworkInfo& frameworkInfo, + const SlaveInfo& slaveInfo) + { + LOG(INFO) << "Executing 'slaveRunTaskLabelDecorator' hook"; + + Labels labels; + + // Set one known label. + Label* newLabel = labels.add_labels(); + newLabel->set_key("baz"); + newLabel->set_value("qux"); + + // Remove label which was set by test. + foreach (const Label& oldLabel, taskInfo.labels().labels()) { + if (oldLabel.key() != "foo") { + labels.add_labels()->CopyFrom(oldLabel); + } + } + + return labels; + } // In this hook, we create a new environment variable "FOO" and set // it's value to "bar". http://git-wip-us.apache.org/repos/asf/mesos/blob/e2d6c86b/src/tests/hook_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/hook_tests.cpp b/src/tests/hook_tests.cpp index fdfcd38..9681905 100644 --- a/src/tests/hook_tests.cpp +++ b/src/tests/hook_tests.cpp @@ -61,6 +61,7 @@ using std::string; using std::vector; using testing::_; +using testing::DoAll; using testing::Return; namespace mesos { @@ -333,6 +334,101 @@ TEST_F(HookTest, DISABLED_VerifySlaveLaunchExecutorHook) EXPECT_FALSE(os::stat::isfile(path.get())); } + +// This test verifies that the slave run task label decorator can add +// and remove labels from a task during the launch sequence. A task +// with two labels ("foo":"bar" and "bar":"baz") is launched and will +// get modified by the slave hook to strip the "foo":"bar" pair and +// add a new "baz":"qux" pair. +TEST_F(HookTest, VerifySlaveRunTaskHook) +{ + Try<PID<Master>> master = StartMaster(); + ASSERT_SOME(master); + + MockExecutor exec(DEFAULT_EXECUTOR_ID); + + TestContainerizer containerizer(&exec); + + Try<PID<Slave>> slave = StartSlave(&containerizer); + ASSERT_SOME(slave); + + MockScheduler sched; + MesosSchedulerDriver driver( + &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); + + EXPECT_CALL(sched, registered(&driver, _, _)); + + Future<vector<Offer>> offers; + EXPECT_CALL(sched, resourceOffers(&driver, _)) + .WillOnce(FutureArg<1>(&offers)) + .WillRepeatedly(Return()); // Ignore subsequent offers. + + driver.start(); + + AWAIT_READY(offers); + ASSERT_EQ(1u, offers.get().size()); + + TaskInfo task; + task.set_name(""); + task.mutable_task_id()->set_value("1"); + task.mutable_slave_id()->CopyFrom(offers.get()[0].slave_id()); + task.mutable_resources()->CopyFrom(offers.get()[0].resources()); + task.mutable_executor()->CopyFrom(DEFAULT_EXECUTOR_INFO); + + // Add two labels: (1) will be removed by the hook to ensure that + // runTaskHook can remove labels (2) will be preserved to ensure + // that the framework can add labels to the task and have those be + // available by the end of the launch task sequence when hooks are + // used (to protect against hooks removing labels completely). + Labels* labels = task.mutable_labels(); + Label* label1 = labels->add_labels(); + label1->set_key("foo"); + label1->set_value("bar"); + + Label* label2 = labels->add_labels(); + label2->set_key("bar"); + label2->set_value("baz"); + + vector<TaskInfo> tasks; + tasks.push_back(task); + + EXPECT_CALL(exec, registered(_, _, _, _)); + + Future<TaskInfo> taskInfo; + EXPECT_CALL(exec, launchTask(_, _)) + .WillOnce(DoAll( + FutureArg<1>(&taskInfo), + SendStatusUpdateFromTask(TASK_RUNNING))); + + driver.launchTasks(offers.get()[0].id(), tasks); + + AWAIT_READY(taskInfo); + + // The master hook will hang an extra label off. + const Labels& labels_ = taskInfo.get().labels(); + + ASSERT_EQ(3, labels_.labels_size()); + + // The slave run task hook will prepend a new "baz":"qux" label. + EXPECT_EQ(labels_.labels(0).key(), "baz"); + EXPECT_EQ(labels_.labels(0).value(), "qux"); + + // Master launch task hook will still hang off test label. + EXPECT_EQ(labels_.labels(1).key(), testLabelKey); + EXPECT_EQ(labels_.labels(1).value(), testLabelValue); + + // And lastly, we only expect the "foo":"bar" pair to be stripped by + // the module. The last pair should be the original "bar":"baz" + // pair set by the test. + EXPECT_EQ(labels_.labels(2).key(), "bar"); + EXPECT_EQ(labels_.labels(2).value(), "baz"); + + driver.stop(); + driver.join(); + + Shutdown(); // Must shutdown before 'containerizer' gets deallocated. +} + } // namespace tests { } // namespace internal { } // namespace mesos {
