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 2016/03/12 02:07:43 UTC

[1/4] mesos git commit: Created base docker image for test suite.

Repository: mesos
Updated Branches:
  refs/heads/master c81a52ec2 -> 24ce5bcbc


Created base docker image for test suite.

Review: https://reviews.apache.org/r/43956/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5c7b56d9
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5c7b56d9
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5c7b56d9

Branch: refs/heads/master
Commit: 5c7b56d9169de69c23e46767ab81a2e2591d8d88
Parents: c81a52e
Author: Gilbert Song <so...@gmail.com>
Authored: Fri Mar 11 17:07:24 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Mar 11 17:07:24 2016 -0800

----------------------------------------------------------------------
 src/Makefile.am                                 |   2 +
 src/tests/containerizer/docker_archive.hpp      | 234 +++++++++++++++++++
 .../containerizer/runtime_isolator_tests.cpp    |  60 +++++
 3 files changed, 296 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/5c7b56d9/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 8abef3b..70c32f0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -814,6 +814,7 @@ libmesos_no_3rdparty_la_SOURCES +=					\
   tests/utils.hpp							\
   tests/zookeeper.hpp							\
   tests/zookeeper_test_server.hpp					\
+  tests/containerizer/docker_archive.hpp				\
   tests/containerizer/isolator.hpp					\
   tests/containerizer/launcher.hpp					\
   tests/containerizer/memory_test_helper.hpp				\
@@ -1931,6 +1932,7 @@ if OS_LINUX
 mesos_tests_SOURCES +=						\
   tests/containerizer/cgroups_isolator_tests.cpp		\
   tests/containerizer/cgroups_tests.cpp				\
+  tests/containerizer/runtime_isolator_tests.cpp		\
   tests/containerizer/filesystem_isolator_tests.cpp		\
   tests/containerizer/fs_tests.cpp				\
   tests/containerizer/launch_tests.cpp				\

http://git-wip-us.apache.org/repos/asf/mesos/blob/5c7b56d9/src/tests/containerizer/docker_archive.hpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/docker_archive.hpp b/src/tests/containerizer/docker_archive.hpp
new file mode 100644
index 0000000..b36dbdb
--- /dev/null
+++ b/src/tests/containerizer/docker_archive.hpp
@@ -0,0 +1,234 @@
+// 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.
+
+#ifndef __TEST_DOCKER_ARCHIVE_HPP__
+#define __TEST_DOCKER_ARCHIVE_HPP__
+
+#include <process/collect.hpp>
+#include <process/future.hpp>
+#include <process/owned.hpp>
+
+#include <stout/error.hpp>
+#include <stout/json.hpp>
+#include <stout/nothing.hpp>
+#include <stout/os.hpp>
+#include <stout/path.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+#include "common/command_utils.hpp"
+
+#include "tests/containerizer/rootfs.hpp"
+
+using process::Failure;
+using process::Future;
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+// This represents a docker archive. It has the same format
+// as that tarball generated by doing a 'docker save'.
+class DockerArchive
+{
+public:
+  // Create a docker test image tarball in docker registry directory.
+  // Users can define own entrypoint/cmd as JSON array of JSON string
+  // (e.g., `[\"sh\", \"-c\"]`).
+  static Future<Nothing> create(
+      const std::string& directory,
+      const std::string& name,
+      const std::string& entrypoint = "null",
+      const std::string& cmd = "null")
+  {
+    Try<Nothing> mkdir = os::mkdir(directory, true);
+    if (mkdir.isError()) {
+      return Failure("Failed to create '" + directory + "': " + mkdir.error());
+    }
+
+    const std::string imagePath = path::join(directory, name);
+
+    mkdir = os::mkdir(imagePath);
+    if (mkdir.isError()) {
+      return Failure("Failed to create docker test image directory '" +
+                     imagePath + "': " + mkdir.error());
+    }
+
+    const std::string layerId =
+      "815b809d588c80fd6ddf4d6ac244ad1c01ae4cbe0f91cc7480e306671ee9c346";
+
+    const std::string layerPath = path::join(imagePath, layerId);
+
+    // Create docker test image `repositories`.
+    JSON::Value repositories = JSON::parse(strings::format(
+        R"~(
+        {
+            "%s": {
+                "latest": "%s"
+            }
+        })~",
+        name,
+        layerId).get()).get();
+
+    Try<Nothing> write = os::write(
+        path::join(imagePath, "repositories"),
+        stringify(repositories));
+
+    if (write.isError()) {
+      return Failure("Failed to save docker test image 'repositories': " +
+                     write.error());
+    }
+
+    mkdir = os::mkdir(layerPath);
+    if (mkdir.isError()) {
+      return Failure("Failed to create docker test image layer '" +
+                     layerId + "': " + mkdir.error());
+    }
+
+    JSON::Value manifest = JSON::parse(strings::format(
+        R"~(
+        {
+            "id": "815b809d588c80fd6ddf4d6ac244ad1c01ae4cbe0f91cc7480e306671ee9c346",
+            "created": "2016-03-02T17:16:00.167415955Z",
+            "container": "eb53609036555d26c39bdccfa9850426934bdfde96111d099041689b2251a377",
+            "container_config": {
+                "Hostname": "eb5360903655",
+                "Domainname": "",
+                "User": "",
+                "AttachStdin": false,
+                "AttachStdout": false,
+                "AttachStderr": false,
+                "Tty": false,
+                "OpenStdin": false,
+                "StdinOnce": false,
+                "Env": null,
+                "Cmd": [
+                    "/bin/sh",
+                    "-c",
+                    "#(nop) ADD file:81ba6f20bdb99e6c13c434a577069860b6656908031162083b1ac9c02c71dd9f in /"
+                ],
+                "Image": "",
+                "Volumes": null,
+                "WorkingDir": "",
+                "Entrypoint": null,
+                "OnBuild": null,
+                "Labels": null
+            },
+            "docker_version": "1.9.1",
+            "config": {
+                "Hostname": "eb5360903655",
+                "Domainname": "",
+                "User": "",
+                "AttachStdin": false,
+                "AttachStdout": false,
+                "AttachStderr": false,
+                "Tty": false,
+                "OpenStdin": false,
+                "StdinOnce": false,
+                "Env": null,
+                "Cmd": %s,
+                "Image": "",
+                "Volumes": null,
+                "WorkingDir": "",
+                "Entrypoint": %s,
+                "OnBuild": null,
+                "Labels": null
+            },
+            "architecture": "amd64",
+            "os": "linux"
+        })~",
+        entrypoint,
+        cmd).get()).get();
+
+    write = os::write(
+        path::join(layerPath, "json"),
+        stringify(manifest));
+
+    if (write.isError()) {
+      return Failure("Failed to save docker test image layer '" + layerId +
+                     "': " + write.error());
+    }
+
+    const std::string rootfsDir = path::join(layerPath, "layer");
+
+    mkdir = os::mkdir(rootfsDir);
+    if (mkdir.isError()) {
+      return Failure("Failed to create layer rootfs directory '" +
+                     rootfsDir + "': " + mkdir.error());
+    }
+
+    // Create one linux rootfs for the layer.
+    Try<process::Owned<Rootfs>> rootfs = LinuxRootfs::create(rootfsDir);
+    if (rootfs.isError()) {
+      return Failure("Failed to create docker test image rootfs: " +
+                     rootfs.error());
+    }
+
+    Future<Nothing> tarRootfs = command::tar(
+        Path("."),
+        Path(path::join(layerPath, "layer.tar")),
+        rootfsDir);
+
+    tarRootfs.await();
+
+    if (!tarRootfs.isReady()) {
+      return Failure(
+          "Failed to tar root filesystem: " +
+          (tarRootfs.isFailed() ? tarRootfs.failure() : "discarded"));
+    }
+
+    Try<Nothing> rmdir = os::rmdir(rootfsDir);
+    if (rmdir.isError()) {
+        return Failure("Failed to remove layer rootfs directory: " +
+                       rmdir.error());
+    }
+
+    write = os::write(
+        path::join(layerPath, "VERSION"),
+        "1.0");
+
+    if (write.isError()) {
+      return Failure("Failed to save layer version: " + write.error());
+    }
+
+    Future<Nothing> tarImage = command::tar(
+        Path("."),
+        Path(path::join(directory, name + ".tar")),
+        imagePath);
+
+    tarImage.await();
+
+    if (!tarImage.isReady()) {
+      return Failure(
+          "Failed to tar docker test image: " +
+          (tarImage.isFailed() ? tarImage.failure() : "discarded"));
+    }
+
+    rmdir = os::rmdir(imagePath);
+    if (rmdir.isError()) {
+      return Failure("Failed to remove image directory: " +
+                     rmdir.error());
+    }
+
+    return Nothing();
+  }
+};
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __TEST_DOCKER_ARCHIVE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5c7b56d9/src/tests/containerizer/runtime_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/runtime_isolator_tests.cpp b/src/tests/containerizer/runtime_isolator_tests.cpp
new file mode 100644
index 0000000..ed48fc7
--- /dev/null
+++ b/src/tests/containerizer/runtime_isolator_tests.cpp
@@ -0,0 +1,60 @@
+// 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 <gtest/gtest.h>
+
+#include <stout/os.hpp>
+#include <stout/path.hpp>
+#include <stout/try.hpp>
+
+#include <process/owned.hpp>
+
+#include "tests/mesos.hpp"
+
+#include "tests/containerizer/docker_archive.hpp"
+
+using std::string;
+
+using process::Future;
+using process::Owned;
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+#ifdef __linux__
+class DockerArchiveTest : public TemporaryDirectoryTest {};
+
+
+// This test verifies that a testing docker image is created as
+// a local archive under a given directory. This is a ROOT test
+// because permission is need to create linux root filesystem.
+TEST_F(DockerArchiveTest, ROOT_CreateDockerLocalTar)
+{
+  const string directory = path::join(os::getcwd(), "archives");
+
+  Future<Nothing> testImage = DockerArchive::create(directory, "alpine");
+  AWAIT_READY(testImage);
+
+  EXPECT_TRUE(os::exists(path::join(directory, "alpine.tar")));
+  EXPECT_FALSE(os::exists(path::join(directory, "alpine")));
+}
+
+#endif // __linux__
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {


[3/4] mesos git commit: Implemented runtime isolator default cmd test.

Posted by ji...@apache.org.
Implemented runtime isolator default cmd test.

Review: https://reviews.apache.org/r/44469/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2e478448
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2e478448
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2e478448

Branch: refs/heads/master
Commit: 2e4784487bd085d6f7f7b086a7117aaac512e923
Parents: ef3eb54
Author: Gilbert Song <so...@gmail.com>
Authored: Fri Mar 11 17:07:30 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Mar 11 17:07:30 2016 -0800

----------------------------------------------------------------------
 .../containerizer/runtime_isolator_tests.cpp    | 105 +++++++++++++++++++
 1 file changed, 105 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/2e478448/src/tests/containerizer/runtime_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/runtime_isolator_tests.cpp b/src/tests/containerizer/runtime_isolator_tests.cpp
index ed48fc7..6c2c3ed 100644
--- a/src/tests/containerizer/runtime_isolator_tests.cpp
+++ b/src/tests/containerizer/runtime_isolator_tests.cpp
@@ -19,17 +19,28 @@
 #include <stout/os.hpp>
 #include <stout/path.hpp>
 #include <stout/try.hpp>
+#include <stout/uuid.hpp>
 
 #include <process/owned.hpp>
 
+#include "tests/environment.hpp"
 #include "tests/mesos.hpp"
 
 #include "tests/containerizer/docker_archive.hpp"
 
+namespace master = mesos::internal::master;
+namespace slave = mesos::internal::slave;
+
 using std::string;
+using std::vector;
 
 using process::Future;
 using process::Owned;
+using process::PID;
+
+using master::Master;
+
+using slave::Slave;
 
 namespace mesos {
 namespace internal {
@@ -53,6 +64,100 @@ TEST_F(DockerArchiveTest, ROOT_CreateDockerLocalTar)
   EXPECT_FALSE(os::exists(path::join(directory, "alpine")));
 }
 
+
+class DockerRuntimeIsolatorTest : public MesosTest {};
+
+
+// This test verifies that docker image default cmd is executed correctly.
+// This corresponds to the case in runtime isolator logic table: sh=0,
+// value=0, argv=1, entrypoint=0, cmd=1.
+TEST_F(DockerRuntimeIsolatorTest, ROOT_DockerDefaultCmdLocalPuller)
+{
+  Try<PID<Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  Try<string> mkdtemp = environment->mkdtemp();
+  ASSERT_SOME(mkdtemp);
+
+  const string directory = path::join(mkdtemp.get(), "archives");
+
+  Future<Nothing> testImage =
+    DockerArchive::create(directory, "alpine", "null", "[\"sh\"]");
+
+  AWAIT_READY(testImage);
+
+  ASSERT_TRUE(os::exists(path::join(directory, "alpine.tar")));
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.isolation = "docker/runtime,filesystem/linux";
+  flags.image_providers = "docker";
+  flags.docker_registry = directory;
+
+  // Make docker store directory as a temparary directory. Because the
+  // manifest of the test image is changeable, the image cached on
+  // previous tests should never be used.
+  flags.docker_store_dir = path::join(flags.work_dir, "docker");
+
+  Try<PID<Slave>> slave = StartSlave(flags);
+  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->size());
+
+  const Offer& offer = offers.get()[0];
+
+  TaskInfo task;
+  task.set_name("test-task");
+  task.mutable_task_id()->set_value(UUID::random().toString());
+  task.mutable_slave_id()->CopyFrom(offer.slave_id());
+  task.mutable_resources()->CopyFrom(Resources::parse("cpus:1;mem:128").get());
+  task.mutable_command()->set_shell(false);
+  task.mutable_command()->add_arguments("-c");
+  task.mutable_command()->add_arguments("echo 'hello world'");
+
+  Image image;
+  image.set_type(Image::DOCKER);
+  image.mutable_docker()->set_name("alpine");
+
+  ContainerInfo* container = task.mutable_container();
+  container->set_type(ContainerInfo::MESOS);
+  container->mutable_mesos()->mutable_image()->CopyFrom(image);
+
+  Future<TaskStatus> statusRunning;
+  Future<TaskStatus> statusFinished;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillOnce(FutureArg<1>(&statusFinished));
+
+  driver.launchTasks(offer.id(), {task});
+
+  AWAIT_READY_FOR(statusRunning, Seconds(60));
+  EXPECT_EQ(task.task_id(), statusRunning->task_id());
+  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+  AWAIT_READY(statusFinished);
+  EXPECT_EQ(task.task_id(), statusFinished->task_id());
+  EXPECT_EQ(TASK_FINISHED, statusFinished->state());
+
+  driver.stop();
+  driver.join();
+
+  Shutdown();
+}
+
 #endif // __linux__
 
 } // namespace tests {


[2/4] mesos git commit: Implemented local puller shell command test.

Posted by ji...@apache.org.
Implemented local puller shell command test.

Review: https://reviews.apache.org/r/44467/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ef3eb548
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ef3eb548
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ef3eb548

Branch: refs/heads/master
Commit: ef3eb5481031e20f6d96c355deb62dcb041ab98b
Parents: 5c7b56d
Author: Gilbert Song <so...@gmail.com>
Authored: Fri Mar 11 17:07:27 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Mar 11 17:07:27 2016 -0800

----------------------------------------------------------------------
 .../containerizer/provisioner_docker_tests.cpp  | 88 +++++++++++++++++++-
 1 file changed, 86 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/ef3eb548/src/tests/containerizer/provisioner_docker_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/provisioner_docker_tests.cpp b/src/tests/containerizer/provisioner_docker_tests.cpp
index 5b685bf..9fd5ea9 100644
--- a/src/tests/containerizer/provisioner_docker_tests.cpp
+++ b/src/tests/containerizer/provisioner_docker_tests.cpp
@@ -34,9 +34,12 @@
 #include "slave/containerizer/mesos/provisioner/docker/registry_puller.hpp"
 #include "slave/containerizer/mesos/provisioner/docker/store.hpp"
 
+#include "tests/environment.hpp"
 #include "tests/mesos.hpp"
 #include "tests/utils.hpp"
 
+#include "tests/containerizer/docker_archive.hpp"
+
 namespace master = mesos::internal::master;
 namespace paths = mesos::internal::slave::docker::paths;
 namespace slave = mesos::internal::slave;
@@ -313,12 +316,92 @@ TEST_F(ProvisionerDockerLocalStoreTest, PullingSameImageSimutanuously)
 
 
 #ifdef __linux__
-class ProvisionerDockerRegistryPullerTest : public MesosTest {};
+class ProvisionerDockerPullerTest : public MesosTest {};
+
+
+// This test verifies that local docker image can be pulled and
+// provisioned correctly, and shell command should be executed.
+TEST_F(ProvisionerDockerPullerTest, ROOT_LocalPullerShellCommand)
+{
+  Try<PID<Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  Try<string> mkdtemp = environment->mkdtemp();
+  ASSERT_SOME(mkdtemp);
+
+  const string directory = path::join(mkdtemp.get(), "archives");
+
+  Future<Nothing> testImage = DockerArchive::create(directory, "alpine");
+  AWAIT_READY(testImage);
+
+  ASSERT_TRUE(os::exists(path::join(directory, "alpine.tar")));
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.isolation = "docker/runtime,filesystem/linux";
+  flags.image_providers = "docker";
+  flags.docker_registry = directory;
+  flags.docker_store_dir = path::join(flags.work_dir, "docker");
+
+  Try<PID<Slave>> slave = StartSlave(flags);
+  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->size());
+
+  const Offer& offer = offers.get()[0];
+
+  TaskInfo task = createTask(
+      offer.slave_id(),
+      Resources::parse("cpus:1;mem:128").get(),
+      "ls -al /");
+
+  Image image;
+  image.set_type(Image::DOCKER);
+  image.mutable_docker()->set_name("alpine");
+
+  ContainerInfo* container = task.mutable_container();
+  container->set_type(ContainerInfo::MESOS);
+  container->mutable_mesos()->mutable_image()->CopyFrom(image);
+
+  Future<TaskStatus> statusRunning;
+  Future<TaskStatus> statusFinished;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillOnce(FutureArg<1>(&statusFinished));
+
+  driver.launchTasks(offer.id(), {task});
+
+  AWAIT_READY_FOR(statusRunning, Seconds(60));
+  EXPECT_EQ(task.task_id(), statusRunning->task_id());
+  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+  AWAIT_READY(statusFinished);
+  EXPECT_EQ(task.task_id(), statusFinished->task_id());
+  EXPECT_EQ(TASK_FINISHED, statusFinished->state());
+
+  driver.stop();
+  driver.join();
+
+  Shutdown();
+}
 
 
 // TODO(jieyu): This is a ROOT test because of MESOS-4757. Remove the
 // ROOT restriction after MESOS-4757 is resolved.
-TEST_F(ProvisionerDockerRegistryPullerTest, ROOT_INTERNET_CURL_ShellCommand)
+TEST_F(ProvisionerDockerPullerTest, ROOT_INTERNET_CURL_ShellCommand)
 {
   Try<PID<Master>> master = StartMaster();
   ASSERT_SOME(master);
@@ -383,6 +466,7 @@ TEST_F(ProvisionerDockerRegistryPullerTest, ROOT_INTERNET_CURL_ShellCommand)
 
   Shutdown();
 }
+
 #endif
 
 } // namespace tests {


[4/4] mesos git commit: Implemented runtime isoaltor default entrypoint test.

Posted by ji...@apache.org.
Implemented runtime isoaltor default entrypoint test.

Review: https://reviews.apache.org/r/44470/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/24ce5bcb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/24ce5bcb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/24ce5bcb

Branch: refs/heads/master
Commit: 24ce5bcbcbb544df334e74c27b28073d597fa0ca
Parents: 2e47844
Author: Gilbert Song <so...@gmail.com>
Authored: Fri Mar 11 17:07:33 2016 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Mar 11 17:07:33 2016 -0800

----------------------------------------------------------------------
 .../containerizer/runtime_isolator_tests.cpp    | 165 +++++++++++++++++++
 1 file changed, 165 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/24ce5bcb/src/tests/containerizer/runtime_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/runtime_isolator_tests.cpp b/src/tests/containerizer/runtime_isolator_tests.cpp
index 6c2c3ed..d8a0004 100644
--- a/src/tests/containerizer/runtime_isolator_tests.cpp
+++ b/src/tests/containerizer/runtime_isolator_tests.cpp
@@ -158,6 +158,171 @@ TEST_F(DockerRuntimeIsolatorTest, ROOT_DockerDefaultCmdLocalPuller)
   Shutdown();
 }
 
+
+// This test verifies that docker image default entrypoint is executed
+// correctly using local puller. This corresponds to the case in runtime
+// isolator logic table: sh=0, value=0, argv=1, entrypoint=1, cmd=0.
+TEST_F(DockerRuntimeIsolatorTest, ROOT_DockerDefaultEntryptLocalPuller)
+{
+  Try<PID<Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  Try<string> mkdtemp = environment->mkdtemp();
+  ASSERT_SOME(mkdtemp);
+
+  const string directory = path::join(mkdtemp.get(), "archives");
+
+  Future<Nothing> testImage =
+    DockerArchive::create(directory, "alpine", "[\"echo\"]", "null");
+
+  AWAIT_READY(testImage);
+
+  ASSERT_TRUE(os::exists(path::join(directory, "alpine.tar")));
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.isolation = "docker/runtime,filesystem/linux";
+  flags.image_providers = "docker";
+  flags.docker_registry = directory;
+  flags.docker_store_dir = path::join(flags.work_dir, "docker");
+
+  Try<PID<Slave>> slave = StartSlave(flags);
+  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->size());
+
+  const Offer& offer = offers.get()[0];
+
+  TaskInfo task;
+  task.set_name("test-task");
+  task.mutable_task_id()->set_value(UUID::random().toString());
+  task.mutable_slave_id()->CopyFrom(offer.slave_id());
+  task.mutable_resources()->CopyFrom(Resources::parse("cpus:1;mem:128").get());
+  task.mutable_command()->set_shell(false);
+  task.mutable_command()->add_arguments("hello world");
+
+  Image image;
+  image.set_type(Image::DOCKER);
+  image.mutable_docker()->set_name("alpine");
+
+  ContainerInfo* container = task.mutable_container();
+  container->set_type(ContainerInfo::MESOS);
+  container->mutable_mesos()->mutable_image()->CopyFrom(image);
+
+  Future<TaskStatus> statusRunning;
+  Future<TaskStatus> statusFinished;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillOnce(FutureArg<1>(&statusFinished));
+
+  driver.launchTasks(offer.id(), {task});
+
+  AWAIT_READY_FOR(statusRunning, Seconds(60));
+  EXPECT_EQ(task.task_id(), statusRunning->task_id());
+  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+  AWAIT_READY(statusFinished);
+  EXPECT_EQ(task.task_id(), statusFinished->task_id());
+  EXPECT_EQ(TASK_FINISHED, statusFinished->state());
+
+  driver.stop();
+  driver.join();
+
+  Shutdown();
+}
+
+
+// This test verifies that docker image default entrypoint is executed
+// correctly using registry puller. This corresponds to the case in runtime
+// isolator logic table: sh=0, value=0, argv=1, entrypoint=1, cmd=0.
+TEST_F(DockerRuntimeIsolatorTest,
+       ROOT_CURL_INTERNET_DockerDefaultEntryptRegistryPuller)
+{
+  Try<PID<Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.isolation = "docker/runtime,filesystem/linux";
+  flags.image_providers = "docker";
+  flags.docker_registry = "https://registry-1.docker.io";
+  flags.docker_store_dir = path::join(flags.work_dir, "docker");
+
+  Try<PID<Slave>> slave = StartSlave(flags);
+  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->size());
+
+  const Offer& offer = offers.get()[0];
+
+  TaskInfo task;
+  task.set_name("test-task");
+  task.mutable_task_id()->set_value(UUID::random().toString());
+  task.mutable_slave_id()->CopyFrom(offer.slave_id());
+  task.mutable_resources()->CopyFrom(Resources::parse("cpus:1;mem:128").get());
+  task.mutable_command()->set_shell(false);
+  task.mutable_command()->add_arguments("hello world");
+
+  Image image;
+  image.set_type(Image::DOCKER);
+
+  // 'mesosphere/inky' image is used in docker containerizer test, which
+  // contains entrypoint as 'echo' and cmd as null.
+  image.mutable_docker()->set_name("mesosphere/inky");
+
+  ContainerInfo* container = task.mutable_container();
+  container->set_type(ContainerInfo::MESOS);
+  container->mutable_mesos()->mutable_image()->CopyFrom(image);
+
+  Future<TaskStatus> statusRunning;
+  Future<TaskStatus> statusFinished;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusRunning))
+    .WillOnce(FutureArg<1>(&statusFinished));
+
+  driver.launchTasks(offer.id(), {task});
+
+  AWAIT_READY_FOR(statusRunning, Seconds(60));
+  EXPECT_EQ(task.task_id(), statusRunning->task_id());
+  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
+
+  AWAIT_READY(statusFinished);
+  EXPECT_EQ(task.task_id(), statusFinished->task_id());
+  EXPECT_EQ(TASK_FINISHED, statusFinished->state());
+
+  driver.stop();
+  driver.join();
+
+  Shutdown();
+}
+
+
 #endif // __linux__
 
 } // namespace tests {