You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2017/08/04 23:01:00 UTC
[1/3] mesos git commit: Made the rlimits isolator work with nested
containers.
Repository: mesos
Updated Branches:
refs/heads/master 13953dc4b -> 50a553dd1
Made the rlimits isolator work with nested containers.
Make the rlimits isolator support nesting. Without this patch rlimits
sets for tasks launched by the DefaultExecutor are silently ignored.
Review: https://reviews.apache.org/r/61387/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/21a3405a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/21a3405a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/21a3405a
Branch: refs/heads/master
Commit: 21a3405aaa189328a774f031d55c71df56fd0b4f
Parents: 13953dc
Author: Gastón Kleiman <ga...@mesosphere.io>
Authored: Fri Aug 4 15:29:47 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 4 15:44:02 2017 -0700
----------------------------------------------------------------------
.../mesos/isolators/posix/rlimits.cpp | 6 +
.../mesos/isolators/posix/rlimits.hpp | 2 +
.../posix_rlimits_isolator_tests.cpp | 178 +++++++++++++++++++
3 files changed, 186 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/21a3405a/src/slave/containerizer/mesos/isolators/posix/rlimits.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/posix/rlimits.cpp b/src/slave/containerizer/mesos/isolators/posix/rlimits.cpp
index 3fc2b3d..0136652 100644
--- a/src/slave/containerizer/mesos/isolators/posix/rlimits.cpp
+++ b/src/slave/containerizer/mesos/isolators/posix/rlimits.cpp
@@ -28,6 +28,12 @@ namespace mesos {
namespace internal {
namespace slave {
+bool PosixRLimitsIsolatorProcess::supportsNesting()
+{
+ return true;
+}
+
+
process::Future<Option<ContainerLaunchInfo>>
PosixRLimitsIsolatorProcess::prepare(
const ContainerID& containerId,
http://git-wip-us.apache.org/repos/asf/mesos/blob/21a3405a/src/slave/containerizer/mesos/isolators/posix/rlimits.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/posix/rlimits.hpp b/src/slave/containerizer/mesos/isolators/posix/rlimits.hpp
index ee36a24..0bce083 100644
--- a/src/slave/containerizer/mesos/isolators/posix/rlimits.hpp
+++ b/src/slave/containerizer/mesos/isolators/posix/rlimits.hpp
@@ -32,6 +32,8 @@ class PosixRLimitsIsolatorProcess : public MesosIsolatorProcess
public:
static Try<mesos::slave::Isolator*> create(const Flags& flags);
+ virtual bool supportsNesting();
+
virtual process::Future<Option<mesos::slave::ContainerLaunchInfo>> prepare(
const ContainerID& containerId,
const mesos::slave::ContainerConfig& containerConfig);
http://git-wip-us.apache.org/repos/asf/mesos/blob/21a3405a/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/posix_rlimits_isolator_tests.cpp b/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
index b7ccc7e..3d87a78 100644
--- a/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
+++ b/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
@@ -31,6 +31,8 @@
#include <mesos/mesos.hpp>
#include <mesos/scheduler.hpp>
+#include <stout/hashmap.hpp>
+
#include "slave/flags.hpp"
#include "tests/cluster.hpp"
#include "tests/environment.hpp"
@@ -338,6 +340,182 @@ TEST_F(PosixRLimitsIsolatorTest, TaskExceedingLimit)
driver.join();
}
+
+// This test confirms that rlimits are set for nested containers.
+TEST_F(PosixRLimitsIsolatorTest, NestedContainers)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "posix/rlimits";
+
+#ifndef USE_SSL_SOCKET
+ // Disable operator API authentication for the default executor.
+ // Executor authentication currently has SSL as a dependency, so we
+ // cannot require executors to authenticate with the agent operator
+ // API if Mesos was not built with SSL support.
+ flags.authenticate_http_readwrite = false;
+#endif // USE_SSL_SOCKET
+
+ Owned<MasterDetector> detector = master.get()->createDetector();
+
+ Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), 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(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ AWAIT_READY(frameworkId);
+
+ AWAIT_READY(offers);
+ ASSERT_NE(0u, offers->size());
+
+ Future<TaskStatus> taskStatuses[4];
+
+ {
+ // This variable doesn't have to be used explicitly.
+ testing::InSequence inSequence;
+
+ foreach (Future<TaskStatus>& taskStatus, taskStatuses) {
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&taskStatus));
+ }
+
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillRepeatedly(Return()); // Ignore subsequent updates.
+ }
+
+ Resources resources = Resources::parse("cpus:0.1;mem:32;disk:32").get();
+
+ const Offer& offer = offers->front();
+ const SlaveID& slaveId = offer.slave_id();
+
+ TaskInfo task1 = createTask(
+ slaveId,
+ resources,
+ "ULIMIT=`ulimit -t`;\n"
+ "if [ \"$ULIMIT\" != \"10000\" ]; then\n"
+ " exit 1;\n"
+ "fi");
+
+ {
+ TaskID taskId;
+ taskId.set_value("task1");
+
+ task1.mutable_task_id()->CopyFrom(taskId);
+
+ ContainerInfo* container = task1.mutable_container();
+ container->set_type(ContainerInfo::MESOS);
+
+ RLimitInfo rlimitInfo;
+ RLimitInfo::RLimit* cpuLimit = rlimitInfo.add_rlimits();
+ cpuLimit->set_type(RLimitInfo::RLimit::RLMT_CPU);
+ cpuLimit->set_soft(10000);
+ cpuLimit->set_hard(10000);
+
+ container->mutable_rlimit_info()->CopyFrom(rlimitInfo);
+ }
+
+ TaskInfo task2 = createTask(
+ slaveId,
+ resources,
+ "ULIMIT=`ulimit -t`;\n"
+ "if [ \"$ULIMIT\" != \"20000\" ]; then\n"
+ " exit 1;\n"
+ "fi");
+
+ {
+ TaskID taskId;
+ taskId.set_value("task2");
+
+ task2.mutable_task_id()->CopyFrom(taskId);
+
+ ContainerInfo* container = task2.mutable_container();
+ container->set_type(ContainerInfo::MESOS);
+
+ RLimitInfo rlimitInfo;
+ RLimitInfo::RLimit* cpuLimit = rlimitInfo.add_rlimits();
+ cpuLimit->set_type(RLimitInfo::RLimit::RLMT_CPU);
+ cpuLimit->set_soft(20000);
+ cpuLimit->set_hard(20000);
+
+ container->mutable_rlimit_info()->CopyFrom(rlimitInfo);
+ }
+
+ TaskGroupInfo taskGroup = createTaskGroupInfo({task1, task2});
+
+ ExecutorInfo executorInfo;
+ executorInfo.set_type(ExecutorInfo::DEFAULT);
+ executorInfo.mutable_executor_id()->CopyFrom(DEFAULT_EXECUTOR_ID);
+ executorInfo.mutable_framework_id()->CopyFrom(frameworkId.get());
+ executorInfo.mutable_resources()->CopyFrom(resources);
+
+ driver.acceptOffers(
+ {offer.id()},
+ {LAUNCH_GROUP(executorInfo, taskGroup)});
+
+ // We track the status updates of each task separately, to verify
+ // that they transition from TASK_RUNNING to TASK_FINISHED.
+ enum class Stage
+ {
+ INITIAL,
+ RUNNING,
+ FINISHED
+ };
+
+ hashmap<TaskID, Stage> taskStages;
+ taskStages[task1.task_id()] = Stage::INITIAL;
+ taskStages[task2.task_id()] = Stage::INITIAL;
+
+ foreach (const Future<TaskStatus>& taskStatus, taskStatuses) {
+ AWAIT_READY(taskStatus);
+
+ Option<Stage> taskStage = taskStages.get(taskStatus->task_id());
+ ASSERT_SOME(taskStage);
+
+ switch (taskStage.get()) {
+ case Stage::INITIAL: {
+ ASSERT_EQ(TASK_RUNNING, taskStatus->state())
+ << taskStatus->DebugString();
+
+ taskStages[taskStatus->task_id()] = Stage::RUNNING;
+ break;
+ }
+ case Stage::RUNNING: {
+ ASSERT_EQ(TASK_FINISHED, taskStatus->state())
+ << taskStatus->DebugString();
+
+ taskStages[taskStatus->task_id()] = Stage::FINISHED;
+ break;
+ }
+ case Stage::FINISHED: {
+ FAIL() << "Unexpected task update: " << taskStatus->DebugString();
+ break;
+ }
+ }
+ }
+
+ driver.stop();
+ driver.join();
+}
+
} // namespace tests {
} // namespace internal {
} // namespace mesos {
[3/3] mesos git commit: Made the capabilities isolator work with
nested containers.
Posted by ji...@apache.org.
Made the capabilities isolator work with nested containers.
Make the capabilities isolator support nesting. Without this patch
capabilities sets for tasks launched by the DefaultExecutor are silently
ignored.
Review: https://reviews.apache.org/r/61394/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/50a553dd
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/50a553dd
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/50a553dd
Branch: refs/heads/master
Commit: 50a553dd10a2adbf653d5ad751723294a14720a8
Parents: cbb2262
Author: Gastón Kleiman <ga...@mesosphere.io>
Authored: Fri Aug 4 15:51:27 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 4 15:51:27 2017 -0700
----------------------------------------------------------------------
.../mesos/isolators/linux/capabilities.cpp | 6 +
.../mesos/isolators/linux/capabilities.hpp | 2 +
.../linux_capabilities_isolator_tests.cpp | 147 +++++++++++++++++++
3 files changed, 155 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/50a553dd/src/slave/containerizer/mesos/isolators/linux/capabilities.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/linux/capabilities.cpp b/src/slave/containerizer/mesos/isolators/linux/capabilities.cpp
index f85a84d..21d851e 100644
--- a/src/slave/containerizer/mesos/isolators/linux/capabilities.cpp
+++ b/src/slave/containerizer/mesos/isolators/linux/capabilities.cpp
@@ -74,6 +74,12 @@ Try<Isolator*> LinuxCapabilitiesIsolatorProcess::create(const Flags& flags)
}
+bool LinuxCapabilitiesIsolatorProcess::supportsNesting()
+{
+ return true;
+}
+
+
Future<Option<ContainerLaunchInfo>> LinuxCapabilitiesIsolatorProcess::prepare(
const ContainerID& containerId,
const ContainerConfig& containerConfig)
http://git-wip-us.apache.org/repos/asf/mesos/blob/50a553dd/src/slave/containerizer/mesos/isolators/linux/capabilities.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/linux/capabilities.hpp b/src/slave/containerizer/mesos/isolators/linux/capabilities.hpp
index c3afe20..b9862a2 100644
--- a/src/slave/containerizer/mesos/isolators/linux/capabilities.hpp
+++ b/src/slave/containerizer/mesos/isolators/linux/capabilities.hpp
@@ -32,6 +32,8 @@ class LinuxCapabilitiesIsolatorProcess : public MesosIsolatorProcess
public:
static Try<mesos::slave::Isolator*> create(const Flags& flags);
+ virtual bool supportsNesting();
+
virtual process::Future<Option<mesos::slave::ContainerLaunchInfo>> prepare(
const ContainerID& containerId,
const mesos::slave::ContainerConfig& containerConfig);
http://git-wip-us.apache.org/repos/asf/mesos/blob/50a553dd/src/tests/containerizer/linux_capabilities_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/linux_capabilities_isolator_tests.cpp b/src/tests/containerizer/linux_capabilities_isolator_tests.cpp
index 8050876..6d95d60 100644
--- a/src/tests/containerizer/linux_capabilities_isolator_tests.cpp
+++ b/src/tests/containerizer/linux_capabilities_isolator_tests.cpp
@@ -41,6 +41,8 @@
#include <mesos/master/detector.hpp>
+#include <mesos/resources.hpp>
+
#include "linux/capabilities.hpp"
#include "master/detector/standalone.hpp"
@@ -328,6 +330,151 @@ TEST_P(LinuxCapabilitiesIsolatorTest, ROOT_Ping)
}
+// Parameterized test confirming the behavior of the capabilities
+// isolator with nested containers. We here use the fact has `ping`
+// has `NET_RAW` and `NET_ADMIN` in its file capabilities. This test
+// should be instantiated with above `TestParam` struct.
+TEST_P(LinuxCapabilitiesIsolatorTest, ROOT_NestedPing)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ slave::Flags flags = CreateSlaveFlags();
+ flags.isolation = "linux/capabilities";
+ flags.effective_capabilities = param.operator_effective;
+ flags.bounding_capabilities = param.operator_bounding;
+
+#ifndef USE_SSL_SOCKET
+ // Disable operator API authentication for the default executor. Executor
+ // authentication currently has SSL as a dependency, so we cannot require
+ // executors to authenticate with the agent operator API if Mesos was not
+ // built with SSL support.
+ flags.authenticate_http_readwrite = false;
+#endif // USE_SSL_SOCKET
+
+ if (param.useImage == TestParam::WITH_IMAGE) {
+ const string registry = path::join(sandbox.get(), "registry");
+ AWAIT_READY(DockerArchive::create(registry, "test_image"));
+
+ flags.docker_registry = registry;
+ flags.docker_store_dir = path::join(os::getcwd(), "store");
+ flags.image_providers = "docker";
+ flags.isolation += ",docker/runtime,filesystem/linux";
+ }
+
+ Owned<MasterDetector> detector = master.get()->createDetector();
+
+ Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), 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(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ AWAIT_READY(frameworkId);
+
+ AWAIT_READY(offers);
+ ASSERT_NE(0u, offers->size());
+
+ Resources resources = Resources::parse("cpus:0.1;mem:32;disk:32").get();
+
+ ExecutorInfo executorInfo;
+ executorInfo.set_type(ExecutorInfo::DEFAULT);
+ executorInfo.mutable_executor_id()->CopyFrom(DEFAULT_EXECUTOR_ID);
+ executorInfo.mutable_framework_id()->CopyFrom(frameworkId.get());
+ executorInfo.mutable_resources()->CopyFrom(resources);
+
+ const Offer& offer = offers->front();
+ const SlaveID& slaveId = offer.slave_id();
+
+ // We use 'ping' as the command since it has file capabilities
+ // (`NET_RAW` and `NET_ADMIN` in permitted set). This allows us to
+ // test if capabilities are properly set.
+ CommandInfo command;
+ command.set_shell(false);
+ command.set_value("/bin/ping");
+ command.add_arguments("ping");
+ command.add_arguments("-c");
+ command.add_arguments("1");
+ command.add_arguments("127.0.0.1");
+
+ TaskInfo task = createTask(slaveId, resources, command);
+
+ if (param.framework_effective.isSome() ||
+ param.framework_bounding.isSome()) {
+ ContainerInfo* container = task.mutable_container();
+ container->set_type(ContainerInfo::MESOS);
+
+ LinuxInfo* linux = container->mutable_linux_info();
+
+ if (param.framework_effective.isSome()) {
+ CapabilityInfo* capabilities = linux->mutable_effective_capabilities();
+ capabilities->CopyFrom(param.framework_effective.get());
+ }
+
+ if (param.framework_bounding.isSome()) {
+ CapabilityInfo* capabilities = linux->mutable_bounding_capabilities();
+ capabilities->CopyFrom(param.framework_bounding.get());
+ }
+ }
+
+ if (param.useImage == TestParam::WITH_IMAGE) {
+ ContainerInfo* container = task.mutable_container();
+ container->set_type(ContainerInfo::MESOS);
+
+ Image* image = container->mutable_mesos()->mutable_image();
+ image->set_type(Image::DOCKER);
+ image->mutable_docker()->set_name("test_image");
+ }
+
+ Queue<TaskStatus> statuses;
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillRepeatedly(PushTaskStatus<1>(&statuses));
+
+ TaskGroupInfo taskGroup = createTaskGroupInfo({task});
+
+ driver.acceptOffers({offer.id()}, {LAUNCH_GROUP(executorInfo, taskGroup)});
+
+ // Wait for the terminal status update.
+ for (;;) {
+ Future<TaskStatus> status = statuses.get();
+ AWAIT_READY(status);
+
+ TaskState state = status->state();
+ if (protobuf::isTerminalState(state)) {
+ switch (param.result) {
+ case TestParam::SUCCESS:
+ EXPECT_EQ(TASK_FINISHED, state) << status->DebugString();
+ break;
+ case TestParam::FAILURE:
+ EXPECT_EQ(TASK_FAILED, state) << status->DebugString();
+ break;
+ }
+ break;
+ }
+ }
+
+ driver.stop();
+ driver.join();
+}
+
+
// TODO(jieyu): We used DAC_READ_SEARCH capability below so that test
// results won't be affected even if the executable (e.g., command
// executor) to launch is not accessible (e.g., under someone's home
[2/3] mesos git commit: Fixed some style issues in posix rlimits
isolator tests.
Posted by ji...@apache.org.
Fixed some style issues in posix rlimits isolator tests.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/cbb2262d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/cbb2262d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/cbb2262d
Branch: refs/heads/master
Commit: cbb2262dbe45f9303281518e58baf907db6ee4af
Parents: 21a3405
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Aug 4 15:46:29 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Aug 4 15:46:29 2017 -0700
----------------------------------------------------------------------
.../posix_rlimits_isolator_tests.cpp | 35 ++++++++++----------
1 file changed, 18 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/cbb2262d/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/posix_rlimits_isolator_tests.cpp b/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
index 3d87a78..bf25049 100644
--- a/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
+++ b/src/tests/containerizer/posix_rlimits_isolator_tests.cpp
@@ -79,8 +79,8 @@ TEST_F(PosixRLimitsIsolatorTest, InvalidLimits)
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
driver.start();
@@ -106,7 +106,7 @@ TEST_F(PosixRLimitsIsolatorTest, InvalidLimits)
Future<TaskStatus> taskStatus;
EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&taskStatus));
+ .WillOnce(FutureArg<1>(&taskStatus));
driver.launchTasks(offers.get()[0].id(), {task});
@@ -122,7 +122,8 @@ TEST_F(PosixRLimitsIsolatorTest, InvalidLimits)
// This test confirms that setting no values for the soft and hard
// limits implies an unlimited resource.
-TEST_F(PosixRLimitsIsolatorTest, UnsetLimits) {
+TEST_F(PosixRLimitsIsolatorTest, UnsetLimits)
+{
Try<Owned<cluster::Master>> master = StartMaster();
ASSERT_SOME(master);
@@ -147,8 +148,8 @@ TEST_F(PosixRLimitsIsolatorTest, UnsetLimits) {
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
driver.start();
@@ -181,8 +182,8 @@ TEST_F(PosixRLimitsIsolatorTest, UnsetLimits) {
Future<TaskStatus> statusRunning;
Future<TaskStatus> statusFinal;
EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&statusRunning))
- .WillOnce(FutureArg<1>(&statusFinal));
+ .WillOnce(FutureArg<1>(&statusRunning))
+ .WillOnce(FutureArg<1>(&statusFinal));
driver.launchTasks(offers.get()[0].id(), {task});
@@ -227,8 +228,8 @@ TEST_F(PosixRLimitsIsolatorTest, BothSoftAndHardLimitSet)
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
driver.start();
@@ -252,7 +253,7 @@ TEST_F(PosixRLimitsIsolatorTest, BothSoftAndHardLimitSet)
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&status));
+ .WillOnce(FutureArg<1>(&status));
driver.launchTasks(offers.get()[0].id(), {task});
@@ -294,8 +295,8 @@ TEST_F(PosixRLimitsIsolatorTest, TaskExceedingLimit)
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
driver.start();
@@ -377,8 +378,8 @@ TEST_F(PosixRLimitsIsolatorTest, NestedContainers)
Future<vector<Offer>> offers;
EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
driver.start();
@@ -395,11 +396,11 @@ TEST_F(PosixRLimitsIsolatorTest, NestedContainers)
foreach (Future<TaskStatus>& taskStatus, taskStatuses) {
EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&taskStatus));
+ .WillOnce(FutureArg<1>(&taskStatus));
}
EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillRepeatedly(Return()); // Ignore subsequent updates.
+ .WillRepeatedly(Return()); // Ignore subsequent updates.
}
Resources resources = Resources::parse("cpus:0.1;mem:32;disk:32").get();