Add environment test for Docker.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4406fb54 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4406fb54 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4406fb54 Branch: refs/heads/master Commit: 4406fb546b3f154bcf2beca49508b29656a3c3a5 Parents: 1ecab99 Author: Timothy Chen <[email protected]> Authored: Tue Jun 24 11:28:34 2014 -0700 Committer: Benjamin Hindman <[email protected]> Committed: Mon Aug 4 15:08:15 2014 -0700 ---------------------------------------------------------------------- src/Makefile.am | 1 + src/docker/docker.cpp | 14 +++ src/docker/docker.hpp | 4 + src/slave/containerizer/docker.cpp | 10 +-- src/tests/docker_containerizer_tests.cpp | 121 ++++++++++++++++++++++++++ src/tests/environment.cpp | 10 ++- 6 files changed, 152 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/4406fb54/src/Makefile.am ---------------------------------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index 7507d72..aad5440 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1045,6 +1045,7 @@ mesos_tests_SOURCES = \ tests/containerizer.cpp \ tests/containerizer_tests.cpp \ tests/credentials_tests.cpp \ + tests/docker_containerizer_tests.cpp \ tests/environment.cpp \ tests/examples_tests.cpp \ tests/exception_tests.cpp \ http://git-wip-us.apache.org/repos/asf/mesos/blob/4406fb54/src/docker/docker.cpp ---------------------------------------------------------------------- diff --git a/src/docker/docker.cpp b/src/docker/docker.cpp index 976a660..53c0805 100644 --- a/src/docker/docker.cpp +++ b/src/docker/docker.cpp @@ -21,6 +21,20 @@ using std::string; using std::vector; +Try<Nothing> Docker::validateDocker(const Docker &docker) +{ + Future<list<Docker::Container> > containers = docker.ps(); + + if (!containers.await(Seconds(3))) { + return Error("Failed to use Docker: Timed out"); + } else if (containers.isFailed()) { + return Error("Failed to use Docker: " + containers.failure()); + } + + return Nothing(); +} + + string Docker::Container::id() const { map<string, JSON::Value>::const_iterator entry = http://git-wip-us.apache.org/repos/asf/mesos/blob/4406fb54/src/docker/docker.hpp ---------------------------------------------------------------------- diff --git a/src/docker/docker.hpp b/src/docker/docker.hpp index 3bed71d..a43fa58 100644 --- a/src/docker/docker.hpp +++ b/src/docker/docker.hpp @@ -26,12 +26,16 @@ #include <process/subprocess.hpp> #include <stout/json.hpp> +#include <stout/nothing.hpp> #include <stout/option.hpp> // Abstraction for working with Docker (modeled on CLI). class Docker { public: + // Validate Docker support + static Try<Nothing> validateDocker(const Docker& docker); + class Container { public: http://git-wip-us.apache.org/repos/asf/mesos/blob/4406fb54/src/slave/containerizer/docker.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/docker.cpp b/src/slave/containerizer/docker.cpp index 3d62390..f9cfa9f 100644 --- a/src/slave/containerizer/docker.cpp +++ b/src/slave/containerizer/docker.cpp @@ -154,13 +154,9 @@ Try<DockerContainerizer*> DockerContainerizer::create( bool local, const Docker& docker) { - // Try out the Docker command so that - Future<list<Docker::Container> > containers = docker.ps(); - - if (!containers.await(Seconds(3))) { - return Error("Failed to use Docker: Timed out"); - } else if (containers.isFailed()) { - return Error("Failed to use Docker: " + containers.failure()); + Try<Nothing> validation = Docker::validateDocker(docker); + if (validation.isError()) { + return Error(validation.error()); } return new DockerContainerizer(flags, local, docker); http://git-wip-us.apache.org/repos/asf/mesos/blob/4406fb54/src/tests/docker_containerizer_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/docker_containerizer_tests.cpp b/src/tests/docker_containerizer_tests.cpp new file mode 100644 index 0000000..8cbde0b --- /dev/null +++ b/src/tests/docker_containerizer_tests.cpp @@ -0,0 +1,121 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <process/future.hpp> + +#include "tests/mesos.hpp" + +#include "slave/slave.hpp" +#include "slave/containerizer/docker.hpp" + +using namespace mesos; +using namespace mesos::internal; +using namespace mesos::internal::tests; + +using mesos::internal::master::Master; + +using mesos::internal::slave::Slave; + +using process::Future; +using process::PID; + +using std::vector; +using std::list; + +using testing::_; +using testing::Eq; +using testing::Return; + +class DockerContainerizerTest : public MesosTest {}; + +TEST_F(DockerContainerizerTest, DOCKER_Launch) { + Try<PID<Master> > master = StartMaster(); + ASSERT_SOME(master); + + slave::Flags flags = CreateSlaveFlags(); + flags.isolation.clear(); + flags.containerizers = "docker"; + + Try<PID<Slave> > slave = StartSlave(flags); + ASSERT_SOME(slave); + + MockScheduler sched; + MesosSchedulerDriver driver( + &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); + + Future<FrameworkID> frameworkId; + EXPECT_CALL(sched, registered(&driver, _, _)) + .WillOnce(FutureArg<1>(&frameworkId)); + + Future<vector<Offer> > offers; + EXPECT_CALL(sched, resourceOffers(&driver, _)) + .WillOnce(FutureArg<1>(&offers)) + .WillRepeatedly(Return()); // Ignore subsequent offers. + + driver.start(); + + AWAIT_READY(offers); + EXPECT_NE(0u, offers.get().size()); + + const Offer& offer = offers.get()[0]; + + TaskInfo task; + task.set_name(""); + task.mutable_task_id()->set_value("1"); + task.mutable_slave_id()->CopyFrom(offer.slave_id()); + task.mutable_resources()->CopyFrom(offer.resources()); + + CommandInfo command; + + CommandInfo::ContainerInfo* containerInfo = + task.mutable_command()->mutable_container(); + + containerInfo->set_image("docker://busybox"); + + command.set_value("sleep 30"); + + task.mutable_command()->CopyFrom(command); + + Future<TaskStatus> statusRunning; + + vector<TaskInfo> tasks; + tasks.push_back(task); + + EXPECT_CALL(sched, statusUpdate(&driver, _)) + .WillOnce(FutureArg<1>(&statusRunning)); + + driver.launchTasks(offers.get()[0].id(), tasks); + + AWAIT_READY(statusRunning); + ASSERT_EQ(TASK_RUNNING, statusRunning.get().state()); + + Docker docker("docker"); + Future<list<Docker::Container> > containers = docker.ps(); + + AWAIT_READY(containers); + + ASSERT_TRUE(containers.get().size() > 0); + + driver.stop(); + driver.join(); + + Shutdown(); +} http://git-wip-us.apache.org/repos/asf/mesos/blob/4406fb54/src/tests/environment.cpp ---------------------------------------------------------------------- diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp index 551698f..5c14cca 100644 --- a/src/tests/environment.cpp +++ b/src/tests/environment.cpp @@ -25,6 +25,8 @@ #include <list> #include <string> +#include "docker/docker.hpp" + #include <process/gmock.hpp> #include <process/gtest.hpp> @@ -70,6 +72,7 @@ Environment* environment; // 'CGROUPS_' : Disable test if cgroups support isn't present. // 'NOHIERARCHY_' : Disable test if there is already a cgroups // hierarchy mounted. +// 'DOCKER_': Disable test if Docker is not supported. // // These flags can be composed in any order, but must come after // 'DISABLED_'. In addition, we disable tests that attempt to use the @@ -127,6 +130,12 @@ static bool enable(const ::testing::TestInfo& test) } #endif + if (strings::contains(name, "DOCKER_")) { + Docker docker("docker"); + Try<Nothing> validate = Docker::validateDocker(docker); + return !validate.isError(); + } + // Filter out benchmark tests when we run 'make check'. if (strings::contains(name, "BENCHMARK_") && !flags.benchmark) { return false; @@ -332,4 +341,3 @@ Try<string> Environment::mkdtemp() } // namespace tests { } // namespace internal { } // namespace mesos { -
