You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2014/02/28 07:54:50 UTC
git commit: Added a test for CFS cpu limits in the cpu isolator.
Repository: mesos
Updated Branches:
refs/heads/master bb6f1e01e -> 5c1d2fb91
Added a test for CFS cpu limits in the cpu isolator.
Review: https://reviews.apache.org/r/18276
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5c1d2fb9
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5c1d2fb9
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5c1d2fb9
Branch: refs/heads/master
Commit: 5c1d2fb91be90c337e64647b04607dac99b36fc4
Parents: bb6f1e0
Author: Ian Downes <ia...@gmail.com>
Authored: Thu Feb 27 22:32:48 2014 -0800
Committer: Vinod Kone <vi...@twitter.com>
Committed: Thu Feb 27 22:47:40 2014 -0800
----------------------------------------------------------------------
src/tests/isolator_tests.cpp | 97 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5c1d2fb9/src/tests/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/isolator_tests.cpp b/src/tests/isolator_tests.cpp
index 13f425b..2aa06ca 100644
--- a/src/tests/isolator_tests.cpp
+++ b/src/tests/isolator_tests.cpp
@@ -38,6 +38,9 @@
#include "slave/flags.hpp"
#include "slave/slave.hpp"
+#ifdef __linux__
+#include "slave/containerizer/cgroups_launcher.hpp"
+#endif // __linux__
#include "slave/containerizer/isolator.hpp"
#include "slave/containerizer/launcher.hpp"
@@ -59,6 +62,7 @@ using namespace process;
using mesos::internal::master::Master;
#ifdef __linux__
using mesos::internal::slave::CgroupsCpushareIsolatorProcess;
+using mesos::internal::slave::CgroupsLauncher;
using mesos::internal::slave::CgroupsMemIsolatorProcess;
#endif // __linux__
using mesos::internal::slave::Isolator;
@@ -90,8 +94,11 @@ int execute(const std::string& command, int pipes[2])
execl("/bin/sh", "sh", "-c", command.c_str(), (char*) NULL);
- std::cerr << "Should not reach here!" << std::endl;
- abort();
+ const char* message = "Child failed to exec";
+ while (write(STDERR_FILENO, message, strlen(message)) == -1 &&
+ errno == EINTR);
+
+ _exit(1);
}
@@ -294,6 +301,92 @@ TYPED_TEST(CpuIsolatorTest, SystemCpuUsage)
}
+#ifdef __linux__
+class LimitedCpuIsolatorTest : public MesosTest {};
+
+TEST_F(LimitedCpuIsolatorTest, CgroupsCfs)
+{
+ Flags flags;
+
+ // Enable CFS to cap CPU utilization.
+ flags.cgroups_enable_cfs = true;
+
+ Try<Isolator*> isolator = CgroupsCpushareIsolatorProcess::create(flags);
+ CHECK_SOME(isolator);
+
+ Try<Launcher*> launcher = CgroupsLauncher::create(flags);
+ CHECK_SOME(launcher);
+
+ // Set the executor's resources to 0.5 cpu.
+ ExecutorInfo executorInfo;
+ executorInfo.mutable_resources()->CopyFrom(
+ Resources::parse("cpus:0.5").get());
+
+ ContainerID containerId;
+ containerId.set_value("mesos_test_cfs_cpu_limit");
+
+ AWAIT_READY(isolator.get()->prepare(containerId, executorInfo));
+
+ // Generate random numbers to max out a single core. We'll run this for 0.5
+ // seconds of wall time so it should consume approximately 250 ms of total
+ // cpu time when limited to 0.5 cpu. We use /dev/urandom to prevent blocking
+ // on Linux when there's insufficient entropy.
+ string command = "cat /dev/urandom > /dev/null & "
+ "export MESOS_TEST_PID=$! && "
+ "sleep 0.5 && "
+ "kill $MESOS_TEST_PID";
+
+ int pipes[2];
+ ASSERT_NE(-1, ::pipe(pipes));
+
+ lambda::function<int()> inChild = lambda::bind(&execute, command, pipes);
+
+ Try<pid_t> pid = launcher.get()->fork(containerId, inChild);
+ ASSERT_SOME(pid);
+
+ // Reap the forked child.
+ Future<Option<int> > status = process::reap(pid.get());
+
+ // Continue in the parent.
+ ::close(pipes[0]);
+
+ // Isolate the forked child.
+ AWAIT_READY(isolator.get()->isolate(containerId, pid.get()));
+
+ // Now signal the child to continue.
+ int buf;
+ ASSERT_LT(0, ::write(pipes[1], &buf, sizeof(buf)));
+ ::close(pipes[1]);
+
+ // Wait for the command to complete.
+ AWAIT_READY(process::reap(pid.get()));
+
+ Future<ResourceStatistics> usage = isolator.get()->usage(containerId);
+ AWAIT_READY(usage);
+
+ // Expect that no more than 300 ms of cpu time has been consumed. We also
+ // check that at least 50 ms of cpu time has been consumed so this test will
+ // fail if the host system is very heavily loaded. This behavior is correct
+ // because under such conditions we aren't actually testing the CFS cpu
+ // limiter.
+ double cpuTime = usage.get().cpus_system_time_secs() +
+ usage.get().cpus_user_time_secs();
+
+ EXPECT_GE(0.30, cpuTime);
+ EXPECT_LE(0.05, cpuTime);
+
+ // Ensure all processes are killed.
+ AWAIT_READY(launcher.get()->destroy(containerId));
+
+ // Let the isolator clean up.
+ AWAIT_READY(isolator.get()->cleanup(containerId));
+
+ delete isolator.get();
+ delete launcher.get();
+}
+#endif // __linux__
+
+
template <typename T>
class MemIsolatorTest : public MesosTest {};