Revert "Updated the balloon tests to test the memory threshold." This reverts commit ebba5c109d17fac2a18c16467097846f398e7217.
Conflicts: src/examples/balloon_framework.cpp src/tests/script.cpp Review: https://reviews.apache.org/r/14862 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8367d94e Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8367d94e Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8367d94e Branch: refs/heads/master Commit: 8367d94e2184dd5777606f4edc66d39a514b9a7e Parents: be9c22f Author: Benjamin Mahler <bmah...@twitter.com> Authored: Tue Oct 22 18:47:49 2013 -0700 Committer: Benjamin Mahler <bmah...@twitter.com> Committed: Wed Oct 23 12:14:01 2013 -0700 ---------------------------------------------------------------------- src/examples/balloon_executor.cpp | 54 +++++++++++++++---------------- src/examples/balloon_framework.cpp | 50 ++++++++++++---------------- src/tests/balloon_framework_test.sh | 11 ++----- src/tests/cgroups_isolator_tests.cpp | 37 +++------------------ src/tests/examples_tests.cpp | 12 +++---- src/tests/script.cpp | 17 ++-------- src/tests/script.hpp | 39 +++------------------- 7 files changed, 63 insertions(+), 157 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/examples/balloon_executor.cpp ---------------------------------------------------------------------- diff --git a/src/examples/balloon_executor.cpp b/src/examples/balloon_executor.cpp index 358afaf..ad1d861 100644 --- a/src/examples/balloon_executor.cpp +++ b/src/examples/balloon_executor.cpp @@ -26,50 +26,51 @@ #include <iostream> #include <string> -#include <vector> #include <mesos/executor.hpp> -#include <stout/bytes.hpp> #include <stout/duration.hpp> #include <stout/numify.hpp> #include <stout/os.hpp> using namespace mesos; -using std::string; -using std::vector; + +// The amount of memory in MB each balloon step consumes. +const static size_t BALLOON_STEP_MB = 64; // This function will increase the memory footprint gradually. The parameter -// limit specifies the upper limit of the memory footprint. The -// parameter step specifies the step size. -static void balloon(const Bytes& limit, const Bytes& step) +// limit specifies the upper limit (in MB) of the memory footprint. The +// parameter step specifies the step size (in MB). +static void balloon(size_t limit) { - for (size_t i = 0; i < limit.bytes() / step.bytes(); i++) { - std::cout << "Increasing memory footprint by " << step << std::endl; + size_t chunk = BALLOON_STEP_MB * 1024 * 1024; + for (size_t i = 0; i < limit / BALLOON_STEP_MB; i++) { + std::cout << "Increasing memory footprint by " + << BALLOON_STEP_MB << " MB" << std::endl; // Allocate page-aligned virtual memory. void* buffer = NULL; - if (posix_memalign(&buffer, getpagesize(), step.bytes()) != 0) { + if (posix_memalign(&buffer, getpagesize(), chunk) != 0) { perror("Failed to allocate page-aligned memory, posix_memalign"); abort(); } // We use mlock and memset here to make sure that the memory // actually gets paged in and thus accounted for. - if (mlock(buffer, step.bytes()) != 0) { + if (mlock(buffer, chunk) != 0) { perror("Failed to lock memory, mlock"); abort(); } - if (memset(buffer, 1, step.bytes()) != buffer) { + if (memset(buffer, 1, chunk) != buffer) { perror("Failed to fill memory, memset"); abort(); } // Try not to increase the memory footprint too fast. - os::sleep(Milliseconds(50)); + os::sleep(Seconds(1)); } } @@ -108,21 +109,18 @@ public: driver->sendStatusUpdate(status); - // Get the balloon step and limit. - vector<string> split = strings::split(task.data(), ","); - - Try<Bytes> step = Bytes::parse(split[0]); - assert(step.isSome()); - - Try<Bytes> limit = Bytes::parse(split[1]); + // Get the balloon limit (in MB). + Try<size_t> limit = numify<size_t>(task.data()); assert(limit.isSome()); + size_t balloonLimit = limit.get(); - // Artificially increase the memory usage gradually. The limit - // can be larger than the amount of memory allocated to this - // executor. In that case, the isolator (e.g. cgroups) should be - // able to detect that and the task should not be able to reach - // TASK_FINISHED state. - balloon(limit.get(), step.get()); + // Artificially increase the memory usage gradually. The + // balloonLimit specifies the upper limit. The balloonLimit can be + // larger than the amount of memory allocated to this executor. In + // that case, the isolator (e.g. cgroups) should be able to detect + // that and the task should not be able to reach TASK_FINISHED + // state. + balloon(balloonLimit); std::cout << "Finishing task " << task.task_id().value() << std::endl; @@ -137,7 +135,7 @@ public: std::cout << "Kill task " << taskId.value() << std::endl; } - virtual void frameworkMessage(ExecutorDriver* driver, const string& data) + virtual void frameworkMessage(ExecutorDriver* driver, const std::string& data) { std::cout << "Framework message: " << data << std::endl; } @@ -147,7 +145,7 @@ public: std::cout << "Shutdown" << std::endl; } - virtual void error(ExecutorDriver* driver, const string& message) + virtual void error(ExecutorDriver* driver, const std::string& message) { std::cout << "Error message: " << message << std::endl; } http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/examples/balloon_framework.cpp ---------------------------------------------------------------------- diff --git a/src/examples/balloon_framework.cpp b/src/examples/balloon_framework.cpp index f5eda5e..d7abf1f 100644 --- a/src/examples/balloon_framework.cpp +++ b/src/examples/balloon_framework.cpp @@ -28,8 +28,6 @@ #include <mesos/scheduler.hpp> -#include <stout/bytes.hpp> -#include <stout/exit.hpp> #include <stout/numify.hpp> #include <stout/os.hpp> #include <stout/stringify.hpp> @@ -46,18 +44,15 @@ using std::endl; using std::string; // The amount of memory in MB the executor itself takes. -const static Bytes EXECUTOR_MEMORY = Megabytes(64); +const static size_t EXECUTOR_MEMORY_MB = 64; class BalloonScheduler : public Scheduler { public: - BalloonScheduler( - const ExecutorInfo& _executor, - const Bytes& _balloonStep, - const Bytes& _balloonLimit) + BalloonScheduler(const ExecutorInfo& _executor, + size_t _balloonLimit) : executor(_executor), - balloonStep(_balloonStep), balloonLimit(_balloonLimit), taskLaunched(false) {} @@ -91,7 +86,7 @@ public: // We just launch one task. if (!taskLaunched) { double mem = getScalarResource(offer, "mem"); - assert(mem > EXECUTOR_MEMORY.megabytes()); + assert(mem > EXECUTOR_MEMORY_MB); std::vector<TaskInfo> tasks; std::cout << "Starting the task" << std::endl; @@ -101,15 +96,14 @@ public: task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offer.slave_id()); task.mutable_executor()->MergeFrom(executor); - task.set_data(stringify(balloonStep) + "," + stringify(balloonLimit)); + task.set_data(stringify<size_t>(balloonLimit)); // Use up all the memory from the offer. Resource* resource; resource = task.add_resources(); resource->set_name("mem"); resource->set_type(Value::SCALAR); - resource->mutable_scalar()->set_value( - mem - EXECUTOR_MEMORY.megabytes()); + resource->mutable_scalar()->set_value(mem - EXECUTOR_MEMORY_MB); tasks.push_back(task); driver->launchTasks(offer.id(), tasks); @@ -171,33 +165,29 @@ public: private: const ExecutorInfo executor; - const Bytes balloonStep; - const Bytes balloonLimit; + const size_t balloonLimit; bool taskLaunched; }; int main(int argc, char** argv) { - if (argc != 4) { - EXIT(1) << "Usage: " << argv[0] - << " <master> <balloon step> <balloon limit>"; + if (argc != 3) { + std::cerr << "Usage: " << argv[0] + << " <master> <balloon limit in MB>" << std::endl; + return -1; } - // Parse the balloon step. - Try<Bytes> step = Bytes::parse(argv[2]); - if (step.isError()) { - EXIT(1) << "Balloon memory step is invalid: " << step.error(); - } - - // Parse the balloon limit. - Try<Bytes> limit = Bytes::parse(argv[3]); + // Verify the balloon limit. + Try<size_t> limit = numify<size_t>(argv[2]); if (limit.isError()) { - EXIT(1) << "Balloon memory limit is invalid: " << limit.error(); + std::cerr << "Balloon limit is not a valid number" << std::endl; + return -1; } - if (limit.get() < EXECUTOR_MEMORY) { - EXIT(1) << "Please use an executor limit smaller than " << EXECUTOR_MEMORY; + if (limit.get() < EXECUTOR_MEMORY_MB) { + std::cerr << "Please use a balloon limit bigger than " + << EXECUTOR_MEMORY_MB << " MB" << std::endl; } // Find this executable's directory to locate executor. @@ -216,9 +206,9 @@ int main(int argc, char** argv) Resource* mem = executor.add_resources(); mem->set_name("mem"); mem->set_type(Value::SCALAR); - mem->mutable_scalar()->set_value(EXECUTOR_MEMORY.megabytes()); + mem->mutable_scalar()->set_value(EXECUTOR_MEMORY_MB); - BalloonScheduler scheduler(executor, step.get(), limit.get()); + BalloonScheduler scheduler(executor, limit.get()); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/tests/balloon_framework_test.sh ---------------------------------------------------------------------- diff --git a/src/tests/balloon_framework_test.sh b/src/tests/balloon_framework_test.sh index 33946a5..213743f 100755 --- a/src/tests/balloon_framework_test.sh +++ b/src/tests/balloon_framework_test.sh @@ -3,12 +3,6 @@ # This script runs the balloon framework on a cluster using the cgroups # isolator and checks that the framework returns a status of 1. -if [ $# -ne 3 ]; then - echo "usage: `basename $0` cgroups_oom_buffer balloon_step balloon_limit" - echo "example: `basename $0` 127MB 32MB 1GB" - exit 1 -fi - source ${MESOS_SOURCE_DIR}/support/colors.sh source ${MESOS_SOURCE_DIR}/support/atexit.sh @@ -96,8 +90,7 @@ ${SLAVE} \ --isolation=cgroups \ --cgroups_hierarchy=${TEST_CGROUP_HIERARCHY} \ --cgroups_root=${TEST_CGROUP_ROOT} \ - --resources="cpus:1;mem:96" \ - --cgroups_oom_buffer=${1} & + --resources="cpus:1;mem:96" & SLAVE_PID=${!} echo "${GREEN}Launched slave at ${SLAVE_PID}${NORMAL}" sleep 2 @@ -111,7 +104,7 @@ if [[ ${STATUS} -ne 0 ]]; then fi # The main event! -${BALLOON_FRAMEWORK} localhost:5432 ${2} ${3} +${BALLOON_FRAMEWORK} localhost:5432 1024 STATUS=${?} # Make sure the balloon framework "failed". http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/tests/cgroups_isolator_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/cgroups_isolator_tests.cpp b/src/tests/cgroups_isolator_tests.cpp index cdac4a9..1f5ce76 100644 --- a/src/tests/cgroups_isolator_tests.cpp +++ b/src/tests/cgroups_isolator_tests.cpp @@ -35,39 +35,10 @@ using namespace mesos::internal::slave; using std::map; -// Run the balloon framework under the cgroups isolator with a few -// configurations. - -// No memory buffer on the slave. -// Step with 64MB, limit 1GB. -// This should behave as if there's only a hard threshold. -TEST_SCRIPT_3(CgroupsIsolatorTest, - ROOT_CGROUPS_BalloonFramework_NoBuffer, - "balloon_framework_test.sh", - stringify(Megabytes(0)), - stringify(Megabytes(64)), - stringify(Gigabytes(1))) - - -// 128MB memory buffer on the slave, step with 32 MB, limit 1GB. -// This ensures we'll have time to act on the threshold notification. -TEST_SCRIPT_3(CgroupsIsolatorTest, - ROOT_CGROUPS_BalloonFramework_Threshold, - "balloon_framework_test.sh", - stringify(Megabytes(128)), - stringify(Megabytes(32)), - stringify(Gigabytes(1))) - - -// 1MB memory buffer on the slave, step with 64 MB, limit 1GB. -// This ensures the OOM occurs before we can act on the threshold -// notification. -TEST_SCRIPT_3(CgroupsIsolatorTest, - ROOT_CGROUPS_BalloonFramework_OOM, - "balloon_framework_test.sh", - stringify(Megabytes(1)), - stringify(Megabytes(128)), - stringify(Gigabytes(1))) +// Run the balloon framework under the cgroups isolator. +TEST_SCRIPT(CgroupsIsolatorTest, + ROOT_CGROUPS_BalloonFramework, + "balloon_framework_test.sh") #define GROW_USAGE(delta, cpuset, usage) \ http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/tests/examples_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/examples_tests.cpp b/src/tests/examples_tests.cpp index d7429bb..28ff0f3 100644 --- a/src/tests/examples_tests.cpp +++ b/src/tests/examples_tests.cpp @@ -22,16 +22,14 @@ // Run each of the sample frameworks in local mode. -TEST_SCRIPT_0(ExamplesTest, TestFramework, "test_framework_test.sh") -TEST_SCRIPT_0(ExamplesTest, - NoExecutorFramework, - "no_executor_framework_test.sh") +TEST_SCRIPT(ExamplesTest, TestFramework, "test_framework_test.sh") +TEST_SCRIPT(ExamplesTest, NoExecutorFramework, "no_executor_framework_test.sh") #ifdef MESOS_HAS_JAVA -TEST_SCRIPT_0(ExamplesTest, JavaFramework, "java_framework_test.sh") -TEST_SCRIPT_0(ExamplesTest, JavaException, "java_exception_test.sh") +TEST_SCRIPT(ExamplesTest, JavaFramework, "java_framework_test.sh") +TEST_SCRIPT(ExamplesTest, JavaException, "java_exception_test.sh") #endif #ifdef MESOS_HAS_PYTHON -TEST_SCRIPT_0(ExamplesTest, PythonFramework, "python_framework_test.sh") +TEST_SCRIPT(ExamplesTest, PythonFramework, "python_framework_test.sh") #endif http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/tests/script.cpp ---------------------------------------------------------------------- diff --git a/src/tests/script.cpp b/src/tests/script.cpp index aa82f78..b3bbf87 100644 --- a/src/tests/script.cpp +++ b/src/tests/script.cpp @@ -23,7 +23,6 @@ #include <sys/wait.h> // For wait (and associated macros). #include <string> -#include <vector> #include <stout/check.hpp> #include <stout/os.hpp> @@ -36,16 +35,13 @@ #include "tests/script.hpp" using std::string; -using std::vector; namespace mesos { namespace internal { namespace tests { -void execute(const string& script, const vector<string>& arguments) +void execute(const string& script) { - CHECK_LT(arguments.size(), static_cast<size_t>(ARG_MAX)); - // Create a temporary directory for the test. Try<string> directory = environment->mkdtemp(); @@ -128,17 +124,8 @@ void execute(const string& script, const vector<string>& arguments) os::setenv("DEFAULT_PRINCIPAL", DEFAULT_CREDENTIAL.principal()); os::setenv("DEFAULT_SECRET", DEFAULT_CREDENTIAL.secret()); - // Construct the argument array. - const char** args = (const char**) new char*[arguments.size() + 1]; - args[0] = path.get().c_str(); - size_t index = 1; - foreach (const string& argument, arguments) { - args[index++] = argument.c_str(); - } - args[arguments.size() + 1] = NULL; - // Now execute the script. - execv(path.get().c_str(), (char* const*) args); + execl(path.get().c_str(), path.get().c_str(), (char*) NULL); std::cerr << "Failed to execute '" << script << "': " << strerror(errno) << std::endl; http://git-wip-us.apache.org/repos/asf/mesos/blob/8367d94e/src/tests/script.hpp ---------------------------------------------------------------------- diff --git a/src/tests/script.hpp b/src/tests/script.hpp index 980df20..f0c71e1 100644 --- a/src/tests/script.hpp +++ b/src/tests/script.hpp @@ -21,19 +21,12 @@ #include <gtest/gtest.h> -#include <string> -#include <vector> - -#include <stout/preprocessor.hpp> - namespace mesos { namespace internal { namespace tests { // Helper used by TEST_SCRIPT to execute the script. -void execute( - const std::string& script, - const std::vector<std::string>& arguments = std::vector<std::string>()); +void execute(const std::string& script); } // namespace tests { } // namespace internal { @@ -44,33 +37,9 @@ void execute( // script in temporary directory and pipe its output to '/dev/null' // unless the verbose option is specified. The "test" passes if the // script returns 0. -#define TEST_SCRIPT_0(test_case_name, test_name, script) \ - TEST(test_case_name, test_name) { \ - mesos::internal::tests::execute(script); \ - } - -#define TEST_SCRIPT_1(test_case_name, test_name, script, arg1) \ - TEST(test_case_name, test_name) { \ - std::vector<std::string> arguments; \ - arguments.push_back(arg1); \ - mesos::internal::tests::execute(script, arguments); \ - } - -#define TEST_SCRIPT_2(test_case_name, test_name, script, arg1, arg2) \ - TEST(test_case_name, test_name) { \ - std::vector<std::string> arguments; \ - arguments.push_back(arg1); \ - arguments.push_back(arg2); \ - mesos::internal::tests::execute(script, arguments); \ - } - -#define TEST_SCRIPT_3(test_case_name, test_name, script, arg1, arg2, arg3) \ - TEST(test_case_name, test_name) { \ - std::vector<std::string> arguments; \ - arguments.push_back(arg1); \ - arguments.push_back(arg2); \ - arguments.push_back(arg3); \ - mesos::internal::tests::execute(script, arguments); \ +#define TEST_SCRIPT(test_case_name, test_name, script) \ + TEST(test_case_name, test_name) { \ + mesos::internal::tests::execute(script); \ } #endif // __TESTS_SCRIPT_HPP__