You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ch...@apache.org on 2018/03/21 20:31:23 UTC

[09/11] mesos git commit: Changed names related to `DiskProfileAdaptor` for consistency.

Changed names related to `DiskProfileAdaptor` for consistency.

This patch makes name changes to make the code base consistent with the
finalized module name `DiskProfileAdaptor`. It also moves
`mesos::internal::storage::Flags` into the `UriDiskProfileAdaptor` class
since the flags are specific to this module.

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


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

Branch: refs/heads/master
Commit: 1231e8fe79baeda1a69f18831c883e17aebece67
Parents: edea176
Author: Chun-Hung Hsiao <ch...@mesosphere.io>
Authored: Mon Mar 19 15:43:31 2018 -0700
Committer: Chun-Hung Hsiao <ch...@mesosphere.io>
Committed: Wed Mar 21 13:22:51 2018 -0700

----------------------------------------------------------------------
 src/Makefile.am                                 |   2 +-
 .../storage/uri_disk_profile_adaptor.cpp        |   6 +-
 .../storage/uri_disk_profile_adaptor.hpp        | 243 +++----
 src/tests/disk_profile_adaptor_tests.cpp        | 685 +++++++++++++++++++
 src/tests/disk_profile_tests.cpp                | 683 ------------------
 .../storage_local_resource_provider_tests.cpp   |  56 +-
 6 files changed, 839 insertions(+), 836 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/1231e8fe/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index d2c2416..56ce554 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2471,7 +2471,7 @@ mesos_tests_SOURCES =						\
   tests/cram_md5_authentication_tests.cpp			\
   tests/credentials_tests.cpp					\
   tests/default_executor_tests.cpp				\
-  tests/disk_profile_tests.cpp					\
+  tests/disk_profile_adaptor_tests.cpp				\
   tests/disk_quota_tests.cpp					\
   tests/dynamic_weights_tests.cpp				\
   tests/environment.cpp						\

http://git-wip-us.apache.org/repos/asf/mesos/blob/1231e8fe/src/resource_provider/storage/uri_disk_profile_adaptor.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/uri_disk_profile_adaptor.cpp b/src/resource_provider/storage/uri_disk_profile_adaptor.cpp
index 75b3d1d..300ea12 100644
--- a/src/resource_provider/storage/uri_disk_profile_adaptor.cpp
+++ b/src/resource_provider/storage/uri_disk_profile_adaptor.cpp
@@ -120,8 +120,8 @@ Future<hashset<string>> UriDiskProfileAdaptor::watch(
 
 
 UriDiskProfileAdaptorProcess::UriDiskProfileAdaptorProcess(
-    const Flags& _flags)
-  : ProcessBase(ID::generate("uri-volume-profile")),
+    const UriDiskProfileAdaptor::Flags& _flags)
+  : ProcessBase(ID::generate("uri-disk-profile-adaptor")),
     flags(_flags),
     watchPromise(new Promise<Nothing>()) {}
 
@@ -324,7 +324,7 @@ org_apache_mesos_UriDiskProfileAdaptor(
       }
 
       // Load and validate flags from the map.
-      mesos::internal::storage::Flags flags;
+      mesos::internal::storage::UriDiskProfileAdaptor::Flags flags;
       Try<flags::Warnings> load = flags.load(values);
 
       if (load.isError()) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/1231e8fe/src/resource_provider/storage/uri_disk_profile_adaptor.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/uri_disk_profile_adaptor.hpp b/src/resource_provider/storage/uri_disk_profile_adaptor.hpp
index 5bdea89..0484933 100644
--- a/src/resource_provider/storage/uri_disk_profile_adaptor.hpp
+++ b/src/resource_provider/storage/uri_disk_profile_adaptor.hpp
@@ -47,124 +47,6 @@ namespace storage {
 // Forward declaration.
 class UriDiskProfileAdaptorProcess;
 
-struct Flags : public virtual flags::FlagsBase
-{
-  Flags()
-  {
-    add(&Flags::uri,
-        "uri",
-        None(),
-        "URI to a JSON object containing the disk profile mapping.\n"
-        "This module supports both HTTP(s) and file URIs\n."
-        "\n"
-        "The JSON object should consist of some top-level string keys\n"
-        "corresponding to the disk profile name. Each value should contain\n"
-        "a `ResourceProviderSelector` under 'resource_provider_selector' or\n"
-        "a `CSIPluginTypeSelector` under 'csi_plugin_type_selector' to\n"
-        "specify the set of resource providers this profile applies to,\n"
-        "followed by a `VolumeCapability` under 'volume_capabilities'\n"
-        "and a free-form string-string mapping under 'create_parameters'.\n"
-        "\n"
-        "The JSON is modeled after a protobuf found in\n"
-        "`src/resource_provider/storage/disk_profile.proto`.\n"
-        "\n"
-        "For example:\n"
-        "{\n"
-        "  \"profile_matrix\" : {\n"
-        "    \"my-profile\" : {\n"
-        "      \"csi_plugin_type_selector\": {\n"
-        "        \"plugin_type\" : \"org.apache.mesos.csi.test\"\n"
-        "      \"},\n"
-        "      \"volume_capabilities\" : {\n"
-        "        \"block\" : {},\n"
-        "        \"access_mode\" : { \"mode\" : \"SINGLE_NODE_WRITER\" }\n"
-        "      },\n"
-        "      \"create_parameters\" : {\n"
-        "        \"mesos-does-not\" : \"interpret-these\",\n"
-        "        \"type\" : \"raid5\",\n"
-        "        \"stripes\" : \"3\",\n"
-        "        \"stripesize\" : \"64\"\n"
-        "      }\n"
-        "    }\n"
-        "  }\n"
-        "}",
-        static_cast<const Path*>(nullptr),
-        [](const Path& value) -> Option<Error> {
-          // For now, just check if the URI has a supported scheme.
-          //
-          // TODO(josephw): Once we have a proper URI class and parser,
-          // consider validating this URI more thoroughly.
-          if (strings::startsWith(value.string(), "http://")
-#ifdef USE_SSL_SOCKET
-              || (process::network::openssl::flags().enabled &&
-                  strings::startsWith(value.string(), "https://"))
-#endif // USE_SSL_SOCKET
-          ) {
-            Try<process::http::URL> url =
-              process::http::URL::parse(value.string());
-
-            if (url.isError()) {
-              return Error("Failed to parse URI: " + url.error());
-            }
-
-            return None();
-          }
-
-          // NOTE: The `Path` class will strip off the 'file://' prefix.
-          if (strings::contains(value.string(), "://")) {
-            return Error("--uri must use a supported scheme (file or http(s))");
-          }
-
-          // We only allow absolute paths for file paths.
-          if (!value.absolute()) {
-            return Error("--uri to a file must be an absolute path");
-          }
-
-          return None();
-        });
-
-    add(&Flags::poll_interval,
-        "poll_interval",
-        "How long to wait between polling the specified `--uri`.\n"
-        "The time is checked each time the `translate` method is called.\n"
-        "If the given time has elapsed, then the URI is re-fetched."
-        "If not specified, the URI is only fetched once.",
-        [](const Option<Duration>& value) -> Option<Error> {
-          if (value.isSome() && value.get() <= Seconds(0)) {
-            return Error("--poll_interval must be non-negative");
-          }
-
-          return None();
-        });
-
-    add(&Flags::max_random_wait,
-        "max_random_wait",
-        "How long at most to wait between discovering a new set of profiles\n"
-        "and notifying the callers of `watch`. The actual wait time is a\n"
-        "uniform random value between 0 and this value. If the `--uri` points\n"
-        "to a centralized location, it may be good to scale this number\n"
-        "according to the number of resource providers in the cluster.",
-        Seconds(0),
-        [](const Duration& value) -> Option<Error> {
-          if (value < Seconds(0)) {
-            return Error("--max_random_wait must be zero or greater");
-          }
-
-          return None();
-        });
-  }
-
-  // NOTE: We use the `Path` type here so that the stout flags parser
-  // does not attempt to read a file if given a `file://` prefixed value.
-  //
-  // TODO(josephw): Replace with a URI type when stout gets one.
-  Path uri;
-
-  Option<Duration> poll_interval;
-  Duration max_random_wait;
-};
-
-
 // The `UriDiskProfileAdaptor` is an example DiskProfileAdaptor module
 // that takes a URI as a module parameter and fetches that URI
 // periodically. The fetched data is parsed into the required CSI
@@ -177,10 +59,129 @@ struct Flags : public virtual flags::FlagsBase
 // `CSIPluginInfo::type` and assumes that all fetched profiles are meant
 // for all resource providers.
 //
-// See `Flags` above for more information.
+// See `UriDiskProfileAdaptor::Flags` below for more information.
 class UriDiskProfileAdaptor : public DiskProfileAdaptor
 {
 public:
+  struct Flags : public virtual flags::FlagsBase
+  {
+    Flags()
+    {
+      add(&Flags::uri,
+          "uri",
+          None(),
+          "URI to a JSON object containing the disk profile mapping.\n"
+          "This module supports both HTTP(s) and file URIs\n."
+          "\n"
+          "The JSON object should consist of some top-level string keys\n"
+          "corresponding to the disk profile name. Each value should contain\n"
+          "a `ResourceProviderSelector` under 'resource_provider_selector' or\n"
+          "a `CSIPluginTypeSelector` under 'csi_plugin_type_selector' to\n"
+          "specify the set of resource providers this profile applies to,\n"
+          "followed by a `VolumeCapability` under 'volume_capabilities'\n"
+          "and a free-form string-string mapping under 'create_parameters'.\n"
+          "\n"
+          "The JSON is modeled after a protobuf found in\n"
+          "`src/resource_provider/storage/disk_profile.proto`.\n"
+          "\n"
+          "For example:\n"
+          "{\n"
+          "  \"profile_matrix\" : {\n"
+          "    \"my-profile\" : {\n"
+          "      \"csi_plugin_type_selector\": {\n"
+          "        \"plugin_type\" : \"org.apache.mesos.csi.test\"\n"
+          "      \"},\n"
+          "      \"volume_capabilities\" : {\n"
+          "        \"block\" : {},\n"
+          "        \"access_mode\" : { \"mode\" : \"SINGLE_NODE_WRITER\" }\n"
+          "      },\n"
+          "      \"create_parameters\" : {\n"
+          "        \"mesos-does-not\" : \"interpret-these\",\n"
+          "        \"type\" : \"raid5\",\n"
+          "        \"stripes\" : \"3\",\n"
+          "        \"stripesize\" : \"64\"\n"
+          "      }\n"
+          "    }\n"
+          "  }\n"
+          "}",
+          static_cast<const Path*>(nullptr),
+          [](const Path& value) -> Option<Error> {
+            // For now, just check if the URI has a supported scheme.
+            //
+            // TODO(josephw): Once we have a proper URI class and parser,
+            // consider validating this URI more thoroughly.
+            if (strings::startsWith(value.string(), "http://")
+#ifdef USE_SSL_SOCKET
+                || (process::network::openssl::flags().enabled &&
+                    strings::startsWith(value.string(), "https://"))
+#endif // USE_SSL_SOCKET
+            ) {
+              Try<process::http::URL> url =
+                process::http::URL::parse(value.string());
+
+              if (url.isError()) {
+                return Error("Failed to parse URI: " + url.error());
+              }
+
+              return None();
+            }
+
+            // NOTE: The `Path` class will strip off the 'file://' prefix.
+            if (strings::contains(value.string(), "://")) {
+              return Error(
+                  "--uri must use a supported scheme (file or http(s))");
+            }
+
+            // We only allow absolute paths for file paths.
+            if (!value.absolute()) {
+              return Error("--uri to a file must be an absolute path");
+            }
+
+            return None();
+          });
+
+      add(&Flags::poll_interval,
+          "poll_interval",
+          "How long to wait between polling the specified `--uri`.\n"
+          "The time is checked each time the `translate` method is called.\n"
+          "If the given time has elapsed, then the URI is re-fetched.\n"
+          "If not specified, the URI is only fetched once.",
+          [](const Option<Duration>& value) -> Option<Error> {
+            if (value.isSome() && value.get() <= Seconds(0)) {
+              return Error("--poll_interval must be non-negative");
+            }
+
+            return None();
+          });
+
+      add(&Flags::max_random_wait,
+          "max_random_wait",
+          "How long at most to wait between discovering a new set of profiles\n"
+          "and notifying the callers of `watch`. The actual wait time is a\n"
+          "uniform random value between 0 and this value. If `--uri` points\n"
+          "to a centralized location, it may be good to scale this number\n"
+          "according to the number of resource providers in the cluster.",
+          Seconds(0),
+          [](const Duration& value) -> Option<Error> {
+            if (value < Seconds(0)) {
+              return Error("--max_random_wait must be zero or greater");
+            }
+
+            return None();
+          });
+    }
+
+    // NOTE: We use the `Path` type here so that the stout flags parser
+    // does not attempt to read a file if given a `file://` prefixed value.
+    //
+    // TODO(josephw): Replace with a URI type when stout gets one.
+    Path uri;
+
+    Option<Duration> poll_interval;
+    Duration max_random_wait;
+  };
+
+
   UriDiskProfileAdaptor(const Flags& _flags);
 
   virtual ~UriDiskProfileAdaptor();
@@ -203,7 +204,7 @@ class UriDiskProfileAdaptorProcess :
   public process::Process<UriDiskProfileAdaptorProcess>
 {
 public:
-  UriDiskProfileAdaptorProcess(const Flags& _flags);
+  UriDiskProfileAdaptorProcess(const UriDiskProfileAdaptor::Flags& _flags);
 
   virtual void initialize() override;
 
@@ -230,7 +231,7 @@ private:
   void notify(const resource_provider::DiskProfileMapping& parsed);
 
 private:
-  Flags flags;
+  UriDiskProfileAdaptor::Flags flags;
 
   // The last fetched profile mapping.
   // This module assumes that profiles can only be added and never

http://git-wip-us.apache.org/repos/asf/mesos/blob/1231e8fe/src/tests/disk_profile_adaptor_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/disk_profile_adaptor_tests.cpp b/src/tests/disk_profile_adaptor_tests.cpp
new file mode 100644
index 0000000..948f6ef
--- /dev/null
+++ b/src/tests/disk_profile_adaptor_tests.cpp
@@ -0,0 +1,685 @@
+// 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 <map>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include <mesos/module/disk_profile_adaptor.hpp>
+
+#include <mesos/resource_provider/storage/disk_profile_adaptor.hpp>
+
+#include <process/clock.hpp>
+#include <process/future.hpp>
+#include <process/gmock.hpp>
+#include <process/gtest.hpp>
+#include <process/owned.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/gtest.hpp>
+#include <stout/hashset.hpp>
+#include <stout/path.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+#include <stout/os/write.hpp>
+
+#include "module/manager.hpp"
+
+#include "resource_provider/storage/uri_disk_profile_adaptor.hpp"
+#include "resource_provider/storage/disk_profile_utils.hpp"
+
+#include "tests/flags.hpp"
+#include "tests/mesos.hpp"
+#include "tests/utils.hpp"
+
+using namespace process;
+
+using std::map;
+using std::string;
+using std::tuple;
+using std::vector;
+
+using google::protobuf::Map;
+
+using mesos::resource_provider::DiskProfileMapping;
+
+using testing::_;
+using testing::DoAll;
+using testing::Return;
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+constexpr char URI_DISK_PROFILE_ADAPTOR_NAME[] =
+  "org_apache_mesos_UriDiskProfileAdaptor";
+
+
+class UriDiskProfileAdaptorTest : public MesosTest
+{
+public:
+  virtual void SetUp()
+  {
+    MesosTest::SetUp();
+
+    string libraryPath = getModulePath("uri_disk_profile_adaptor");
+
+    Modules::Library* library = modules.add_libraries();
+    library->set_name("uri_disk_profile_adaptor");
+    library->set_file(libraryPath);
+
+    Modules::Library::Module* module = library->add_modules();
+    module->set_name(URI_DISK_PROFILE_ADAPTOR_NAME);
+
+    ASSERT_SOME(modules::ModuleManager::load(modules));
+  }
+
+  virtual void TearDown()
+  {
+    foreach (const Modules::Library& library, modules.libraries()) {
+      foreach (const Modules::Library::Module& module, library.modules()) {
+        if (module.has_name()) {
+          ASSERT_SOME(modules::ModuleManager::unload(module.name()));
+        }
+      }
+    }
+
+    MesosTest::TearDown();
+  }
+
+protected:
+  Modules modules;
+};
+
+
+// Exercises the disk profile map parsing method with the example found
+// in the UriDiskProfileAdaptor module's help string.
+TEST_F(UriDiskProfileAdaptorTest, ParseExample)
+{
+  const string example = R"~(
+    {
+      "profile_matrix" : {
+        "my-profile" : {
+          "csi_plugin_type_selector" : {
+            "plugin_type" : "org.apache.mesos.csi.test"
+          },
+          "volume_capabilities" : {
+            "block" : {},
+            "access_mode" : { "mode" : "SINGLE_NODE_WRITER" }
+          },
+          "create_parameters" : {
+            "mesos-does-not" : "interpret-these",
+            "type" : "raid5",
+            "stripes" : "3",
+            "stripesize" : "64"
+          }
+        }
+      }
+    })~";
+
+  Try<DiskProfileMapping> parsed =
+    mesos::internal::storage::parseDiskProfileMapping(example);
+  ASSERT_SOME(parsed);
+
+  const string key = "my-profile";
+  ASSERT_EQ(1u, parsed->profile_matrix().count(key));
+
+  csi::VolumeCapability capability =
+    parsed->profile_matrix().at(key).volume_capabilities();
+
+  ASSERT_TRUE(capability.has_block());
+  ASSERT_TRUE(capability.has_access_mode());
+  ASSERT_EQ(
+      csi::VolumeCapability::AccessMode::SINGLE_NODE_WRITER,
+      capability.access_mode().mode());
+
+  Map<string, string> parameters =
+    parsed->profile_matrix().at(key).create_parameters();
+
+  ASSERT_EQ(4u, parameters.size());
+  ASSERT_EQ(1u, parameters.count("mesos-does-not"));
+  ASSERT_EQ(1u, parameters.count("type"));
+  ASSERT_EQ(1u, parameters.count("stripes"));
+  ASSERT_EQ(1u, parameters.count("stripesize"));
+
+  ASSERT_EQ("interpret-these", parameters.at("mesos-does-not"));
+  ASSERT_EQ("raid5", parameters.at("type"));
+  ASSERT_EQ("3", parameters.at("stripes"));
+  ASSERT_EQ("64", parameters.at("stripesize"));
+}
+
+
+// Exercises the disk profile map parsing method with some slightly incorrect
+// inputs. Each item in the array of examples should error at a different area
+// of the code (and are ordered corresponding to the code as well).
+TEST_F(UriDiskProfileAdaptorTest, ParseInvalids)
+{
+  const vector<string> examples = {
+    "Not an object, but still JSON",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : "This is not an object"
+        }
+      })~",
+
+    // Missing one of 'resource_provider_selector' or
+    // 'csi_plugin_type_selector'.
+    R"~({
+        "profile_matrix" : {
+          "profile" : {}
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "resource_provider_selector" : "Wrong JSON type"
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "resource_provider_selector" : {
+              "resource_providers" : "Wrong JSON type"
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "resource_provider_selector" : {
+              "resource_providers" : [
+                {
+                  "not-type" : "Missing required key"
+                }
+              ]
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "resource_provider_selector" : {
+              "resource_providers" : [
+                {
+                  "type" : "org.apache.mesos.rp.local.storage",
+                  "not-name" : "Missing required key"
+                }
+              ]
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : "Wrong JSON type"
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "not-plugin_type" : "Missing required key",
+            }
+          }
+        }
+      })~",
+
+    // More than one selector.
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "resource_provider_selector" : {
+              "resource_providers" : [
+                {
+                  "type" : "org.apache.mesos.rp.local.storage",
+                  "name" : "test"
+                }
+              ]
+            },
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "not-volume_capabilities" : "Missing required key"
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : "Wrong JSON type"
+          }
+        }
+      })~",
+
+    // Missing one of 'block' or 'mount'.
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : {}
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : {
+              "mount" : {
+                "fs_type" : [ "This should not be an array" ]
+              }
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : {
+              "block" : {},
+              "access_mode" : { "mode": "No-enum-of-this-name" }
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : {
+              "mount" : {
+                "mount_flags" : [ "a", "b", "c" ]
+              },
+              "access_mode" : { "mode": "SINGLE_NODE_WRITER" }
+            },
+            "create_parameters" : "Wrong JSON type"
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : {
+              "mount" : { "fs_type" : "abc" },
+              "access_mode" : { "mode": "SINGLE_NODE_READER_ONLY" }
+            },
+            "create_parameters" : {
+              "incorrect" : [ "JSON type of parameter" ]
+            }
+          }
+        }
+      })~",
+
+    R"~({
+        "profile_matrix" : {
+          "profile" : {
+            "csi_plugin_type_selector" : {
+              "plugin_type" : "org.apache.mesos.csi.test",
+            },
+            "volume_capabilities" : {
+              "block" : {},
+              "access_mode" : { "mode": "MULTI_NODE_READER_ONLY" }
+            }
+          },
+          "first profile is fine, second profile is broken" : {}
+        }
+      })~",
+    };
+
+  hashset<string> errors;
+  for (size_t i = 0; i < examples.size(); i++) {
+    Try<DiskProfileMapping> parsed =
+      mesos::internal::storage::parseDiskProfileMapping(examples[i]);
+
+    ASSERT_ERROR(parsed) << examples[i];
+    ASSERT_EQ(0u, errors.count(parsed.error())) << parsed.error();
+
+    errors.insert(parsed.error());
+  }
+}
+
+
+// This creates a UriDiskProfileAdaptor module configured to read from a
+// file and tests the basic `watch` -> `translate` workflow which
+// callers of the module are expected to follow.
+//
+// Enable this test once MESOS-8567 is resolved.
+TEST_F(UriDiskProfileAdaptorTest, DISABLED_FetchFromFile)
+{
+  Clock::pause();
+
+  const string contents =R"~(
+    {
+      "profile_matrix" : {
+        "profile" : {
+          "resource_provider_selector" : {
+            "resource_providers" : [
+              {
+                "type" : "resource_provider_type",
+                "name" : "resource_provider_name"
+              }
+            ]
+          },
+          "volume_capabilities" : {
+            "block" : {},
+            "access_mode" : { "mode": "MULTI_NODE_SINGLE_WRITER" }
+          }
+        }
+      }
+    })~";
+
+  const string profileName = "profile";
+  const string profileFile = path::join(sandbox.get(), "profiles.json");
+  const Duration pollInterval = Seconds(10);
+
+  ResourceProviderInfo resourceProviderInfo;
+  resourceProviderInfo.set_type("resource_provider_type");
+  resourceProviderInfo.set_name("resource_provider_name");
+
+  Parameters params;
+
+  Parameter* pollIntervalFlag = params.add_parameter();
+  pollIntervalFlag->set_key("poll_interval");
+  pollIntervalFlag->set_value(stringify(pollInterval));
+
+  // NOTE: We cannot use the `file://` URI to specify the file location,
+  // otherwise the file contents will be prematurely read. Therefore, we
+  // specify the absolute path of the file in the `uri` flag.
+  Parameter* uriFlag = params.add_parameter();
+  uriFlag->set_key("uri");
+  uriFlag->set_value(profileFile);
+
+  // Create the module before we've written anything to the file.
+  // This means the first poll will fail, so the module believes there
+  // are no profiles at the moment.
+  Try<DiskProfileAdaptor*> module =
+    modules::ModuleManager::create<DiskProfileAdaptor>(
+        URI_DISK_PROFILE_ADAPTOR_NAME,
+        params);
+  ASSERT_SOME(module);
+
+  // Start watching for updates.
+  // By the time this returns, we'll know that the first poll has finished
+  // because when the module reads from file, it does so immediately upon
+  // being initialized.
+  Future<hashset<string>> future =
+    module.get()->watch(hashset<string>::EMPTY, resourceProviderInfo);
+
+  // Write the single profile to the file.
+  ASSERT_SOME(os::write(profileFile, contents));
+
+  // Trigger the next poll.
+  Clock::advance(pollInterval);
+
+  AWAIT_ASSERT_READY(future);
+  ASSERT_EQ(1u, future->size());
+  EXPECT_EQ(profileName, *(future->begin()));
+
+  // Translate the profile name into the profile mapping.
+  Future<DiskProfileAdaptor::ProfileInfo> mapping =
+    module.get()->translate(profileName, resourceProviderInfo);
+
+  AWAIT_ASSERT_READY(mapping);
+  ASSERT_TRUE(mapping.get().capability.has_block());
+  ASSERT_EQ(
+      csi::VolumeCapability::AccessMode::MULTI_NODE_SINGLE_WRITER,
+      mapping.get().capability.access_mode().mode());
+
+  Clock::resume();
+}
+
+
+// Basic helper for UriDiskProfileAdaptor modules configured to fetch
+// from HTTP URIs.
+class MockProfileServer : public Process<MockProfileServer>
+{
+public:
+  MOCK_METHOD1(profiles, Future<http::Response>(const http::Request&));
+
+protected:
+  virtual void initialize()
+  {
+    route("/profiles", None(), &MockProfileServer::profiles);
+  }
+};
+
+
+class ServerWrapper
+{
+public:
+  ServerWrapper() : process(new MockProfileServer())
+  {
+    spawn(process.get());
+  }
+
+  ~ServerWrapper()
+  {
+    terminate(process.get());
+    wait(process.get());
+  }
+
+  Owned<MockProfileServer> process;
+};
+
+
+// This creates a UriDiskProfileAdaptor module configured to read from
+// an HTTP URI. The HTTP server will return a different profile mapping
+// between each of the calls. We expect the module to ignore the second
+// call because the module does not allow profiles to be renamed. This
+// is not a fatal error however, as the HTTP server can be "fixed"
+// without restarting the agent.
+TEST_F(UriDiskProfileAdaptorTest, FetchFromHTTP)
+{
+  Clock::pause();
+
+  const string contents1 =R"~(
+    {
+      "profile_matrix" : {
+        "profile" : {
+          "resource_provider_selector" : {
+            "resource_providers" : [
+              {
+                "type" : "resource_provider_type",
+                "name" : "resource_provider_name"
+              }
+            ]
+          },
+          "volume_capabilities" : {
+            "block" : {},
+            "access_mode" : { "mode": "MULTI_NODE_MULTI_WRITER" }
+          }
+        }
+      }
+    })~";
+
+  const string contents2 =R"~(
+    {
+      "profile_matrix" : {
+        "renamed-profile" : {
+          "resource_provider_selector" : {
+            "resource_providers" : [
+              {
+                "type" : "resource_provider_type",
+                "name" : "resource_provider_name"
+              }
+            ]
+          },
+          "volume_capabilities" : {
+            "block" : {},
+            "access_mode" : { "mode": "SINGLE_NODE_WRITER" }
+          }
+        }
+      }
+    })~";
+
+  const string contents3 =R"~(
+    {
+      "profile_matrix" : {
+        "profile" : {
+          "resource_provider_selector" : {
+            "resource_providers" : [
+              {
+                "type" : "resource_provider_type",
+                "name" : "resource_provider_name"
+              }
+            ]
+          },
+          "volume_capabilities" : {
+            "block" : {},
+            "access_mode" : { "mode": "MULTI_NODE_MULTI_WRITER" }
+          }
+        },
+        "another-profile" : {
+          "resource_provider_selector" : {
+            "resource_providers" : [
+              {
+                "type" : "resource_provider_type",
+                "name" : "resource_provider_name"
+              }
+            ]
+          },
+          "volume_capabilities" : {
+            "block" : {},
+            "access_mode" : { "mode": "SINGLE_NODE_WRITER" }
+          }
+        }
+      }
+    })~";
+
+  const Duration pollInterval = Seconds(10);
+
+  ResourceProviderInfo resourceProviderInfo;
+  resourceProviderInfo.set_type("resource_provider_type");
+  resourceProviderInfo.set_name("resource_provider_name");
+
+  ServerWrapper server;
+
+  // Wait for the server to finish initializing so that the routes are ready.
+  AWAIT_READY(dispatch(server.process->self(), []() { return Nothing(); }));
+
+  // We need to intercept this call since the module is expected to
+  // ignore the result of the second call.
+  Future<Nothing> secondCall;
+
+  EXPECT_CALL(*server.process, profiles(_))
+    .WillOnce(Return(http::OK(contents1)))
+    .WillOnce(DoAll(FutureSatisfy(&secondCall), Return(http::OK(contents2))))
+    .WillOnce(Return(http::OK(contents3)));
+
+  Parameters params;
+
+  Parameter* pollIntervalFlag = params.add_parameter();
+  pollIntervalFlag->set_key("poll_interval");
+  pollIntervalFlag->set_value(stringify(pollInterval));
+
+  Parameter* uriFlag = params.add_parameter();
+  uriFlag->set_key("uri");
+  uriFlag->set_value(stringify(process::http::URL(
+      "http",
+      process::address().ip,
+      process::address().port,
+      server.process->self().id + "/profiles")));
+
+  Try<DiskProfileAdaptor*> module =
+    modules::ModuleManager::create<DiskProfileAdaptor>(
+        URI_DISK_PROFILE_ADAPTOR_NAME,
+        params);
+  ASSERT_SOME(module);
+
+  // Wait for the first HTTP poll to complete.
+  Future<hashset<string>> future =
+    module.get()->watch(hashset<string>::EMPTY, resourceProviderInfo);
+
+  AWAIT_ASSERT_READY(future);
+  ASSERT_EQ(1u, future->size());
+  EXPECT_EQ("profile", *(future->begin()));
+
+  // Start watching for an update to the list of profiles.
+  future = module.get()->watch({"profile"}, resourceProviderInfo);
+
+  // Trigger the second HTTP poll.
+  Clock::advance(pollInterval);
+  AWAIT_ASSERT_READY(secondCall);
+
+  // Dispatch a call to the module, which ensures that the polling has actually
+  // completed (not just the HTTP call).
+  AWAIT_ASSERT_READY(module.get()->translate("profile", resourceProviderInfo));
+
+  // We don't expect the module to notify watcher(s) because the server's
+  // response is considered invalid (the module does not allow profiles
+  // to be renamed).
+  ASSERT_TRUE(future.isPending());
+
+  // Trigger the third HTTP poll.
+  Clock::advance(pollInterval);
+
+  // This time, the server's response is correct and also includes a second
+  // profile, which means that the watcher(s) should be notified.
+  AWAIT_ASSERT_READY(future);
+  ASSERT_EQ(2u, future->size());
+  EXPECT_EQ((hashset<string>{"profile", "another-profile"}), future.get());
+
+  Clock::resume();
+}
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/1231e8fe/src/tests/disk_profile_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/disk_profile_tests.cpp b/src/tests/disk_profile_tests.cpp
deleted file mode 100644
index da8d4e8..0000000
--- a/src/tests/disk_profile_tests.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-// 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 <map>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include <mesos/module/disk_profile_adaptor.hpp>
-
-#include <mesos/resource_provider/storage/disk_profile_adaptor.hpp>
-
-#include <process/clock.hpp>
-#include <process/future.hpp>
-#include <process/gmock.hpp>
-#include <process/gtest.hpp>
-#include <process/owned.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/gtest.hpp>
-#include <stout/hashset.hpp>
-#include <stout/path.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-
-#include <stout/os/write.hpp>
-
-#include "module/manager.hpp"
-
-#include "resource_provider/storage/uri_disk_profile_adaptor.hpp"
-#include "resource_provider/storage/disk_profile_utils.hpp"
-
-#include "tests/flags.hpp"
-#include "tests/mesos.hpp"
-#include "tests/utils.hpp"
-
-using namespace process;
-
-using std::map;
-using std::string;
-using std::tuple;
-using std::vector;
-
-using google::protobuf::Map;
-
-using mesos::resource_provider::DiskProfileMapping;
-
-using testing::_;
-using testing::DoAll;
-using testing::Return;
-
-namespace mesos {
-namespace internal {
-namespace tests {
-
-constexpr char URI_DISK_PROFILE_ADAPTOR_NAME[] =
-  "org_apache_mesos_UriDiskProfileAdaptor";
-
-
-class UriDiskProfileTest : public MesosTest
-{
-public:
-  virtual void SetUp()
-  {
-    MesosTest::SetUp();
-
-    string libraryPath = getModulePath("uri_disk_profile_adaptor");
-
-    Modules::Library* library = modules.add_libraries();
-    library->set_name("uri_disk_profile_adaptor");
-    library->set_file(libraryPath);
-
-    Modules::Library::Module* module = library->add_modules();
-    module->set_name(URI_DISK_PROFILE_ADAPTOR_NAME);
-
-    ASSERT_SOME(modules::ModuleManager::load(modules));
-  }
-
-  virtual void TearDown()
-  {
-    foreach (const Modules::Library& library, modules.libraries()) {
-      foreach (const Modules::Library::Module& module, library.modules()) {
-        if (module.has_name()) {
-          ASSERT_SOME(modules::ModuleManager::unload(module.name()));
-        }
-      }
-    }
-
-    MesosTest::TearDown();
-  }
-
-protected:
-  Modules modules;
-};
-
-
-// Exercises the disk profile map parsing method with the example found
-// in the UriDiskProfile module's help string.
-TEST_F(UriDiskProfileTest, ParseExample)
-{
-  const string example = R"~(
-    {
-      "profile_matrix" : {
-        "my-profile" : {
-          "csi_plugin_type_selector" : {
-            "plugin_type" : "org.apache.mesos.csi.test"
-          },
-          "volume_capabilities" : {
-            "block" : {},
-            "access_mode" : { "mode" : "SINGLE_NODE_WRITER" }
-          },
-          "create_parameters" : {
-            "mesos-does-not" : "interpret-these",
-            "type" : "raid5",
-            "stripes" : "3",
-            "stripesize" : "64"
-          }
-        }
-      }
-    })~";
-
-  Try<DiskProfileMapping> parsed =
-    mesos::internal::storage::parseDiskProfileMapping(example);
-  ASSERT_SOME(parsed);
-
-  const string key = "my-profile";
-  ASSERT_EQ(1u, parsed->profile_matrix().count(key));
-
-  csi::VolumeCapability capability =
-    parsed->profile_matrix().at(key).volume_capabilities();
-
-  ASSERT_TRUE(capability.has_block());
-  ASSERT_TRUE(capability.has_access_mode());
-  ASSERT_EQ(
-      csi::VolumeCapability::AccessMode::SINGLE_NODE_WRITER,
-      capability.access_mode().mode());
-
-  Map<string, string> parameters =
-    parsed->profile_matrix().at(key).create_parameters();
-
-  ASSERT_EQ(4u, parameters.size());
-  ASSERT_EQ(1u, parameters.count("mesos-does-not"));
-  ASSERT_EQ(1u, parameters.count("type"));
-  ASSERT_EQ(1u, parameters.count("stripes"));
-  ASSERT_EQ(1u, parameters.count("stripesize"));
-
-  ASSERT_EQ("interpret-these", parameters.at("mesos-does-not"));
-  ASSERT_EQ("raid5", parameters.at("type"));
-  ASSERT_EQ("3", parameters.at("stripes"));
-  ASSERT_EQ("64", parameters.at("stripesize"));
-}
-
-
-// Exercises the disk profile map parsing method with some slightly incorrect
-// inputs. Each item in the array of examples should error at a different area
-// of the code (and are ordered corresponding to the code as well).
-TEST_F(UriDiskProfileTest, ParseInvalids)
-{
-  const vector<string> examples = {
-    "Not an object, but still JSON",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : "This is not an object"
-        }
-      })~",
-
-    // Missing one of 'resource_provider_selector' or
-    // 'csi_plugin_type_selector'.
-    R"~({
-        "profile_matrix" : {
-          "profile" : {}
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "resource_provider_selector" : "Wrong JSON type"
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "resource_provider_selector" : {
-              "resource_providers" : "Wrong JSON type"
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "resource_provider_selector" : {
-              "resource_providers" : [
-                {
-                  "not-type" : "Missing required key"
-                }
-              ]
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "resource_provider_selector" : {
-              "resource_providers" : [
-                {
-                  "type" : "org.apache.mesos.rp.local.storage",
-                  "not-name" : "Missing required key"
-                }
-              ]
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : "Wrong JSON type"
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "not-plugin_type" : "Missing required key",
-            }
-          }
-        }
-      })~",
-
-    // More than one selector.
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "resource_provider_selector" : {
-              "resource_providers" : [
-                {
-                  "type" : "org.apache.mesos.rp.local.storage",
-                  "name" : "test"
-                }
-              ]
-            },
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "not-volume_capabilities" : "Missing required key"
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : "Wrong JSON type"
-          }
-        }
-      })~",
-
-    // Missing one of 'block' or 'mount'.
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : {}
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : {
-              "mount" : {
-                "fs_type" : [ "This should not be an array" ]
-              }
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : {
-              "block" : {},
-              "access_mode" : { "mode": "No-enum-of-this-name" }
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : {
-              "mount" : {
-                "mount_flags" : [ "a", "b", "c" ]
-              },
-              "access_mode" : { "mode": "SINGLE_NODE_WRITER" }
-            },
-            "create_parameters" : "Wrong JSON type"
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : {
-              "mount" : { "fs_type" : "abc" },
-              "access_mode" : { "mode": "SINGLE_NODE_READER_ONLY" }
-            },
-            "create_parameters" : {
-              "incorrect" : [ "JSON type of parameter" ]
-            }
-          }
-        }
-      })~",
-
-    R"~({
-        "profile_matrix" : {
-          "profile" : {
-            "csi_plugin_type_selector" : {
-              "plugin_type" : "org.apache.mesos.csi.test",
-            },
-            "volume_capabilities" : {
-              "block" : {},
-              "access_mode" : { "mode": "MULTI_NODE_READER_ONLY" }
-            }
-          },
-          "first profile is fine, second profile is broken" : {}
-        }
-      })~",
-    };
-
-  hashset<string> errors;
-  for (size_t i = 0; i < examples.size(); i++) {
-    Try<DiskProfileMapping> parsed =
-      mesos::internal::storage::parseDiskProfileMapping(examples[i]);
-
-    ASSERT_ERROR(parsed) << examples[i];
-    ASSERT_EQ(0u, errors.count(parsed.error())) << parsed.error();
-
-    errors.insert(parsed.error());
-  }
-}
-
-
-// This creates a UriDiskProfile module configured to read from a file
-// and tests the basic `watch` -> `translate` workflow which callers of
-// the module are expected to follow.
-//
-// Enable this test once MESOS-8567 is resolved.
-TEST_F(UriDiskProfileTest, DISABLED_FetchFromFile)
-{
-  Clock::pause();
-
-  const string contents =R"~(
-    {
-      "profile_matrix" : {
-        "profile" : {
-          "resource_provider_selector" : {
-            "resource_providers" : [
-              {
-                "type" : "resource_provider_type",
-                "name" : "resource_provider_name"
-              }
-            ]
-          },
-          "volume_capabilities" : {
-            "block" : {},
-            "access_mode" : { "mode": "MULTI_NODE_SINGLE_WRITER" }
-          }
-        }
-      }
-    })~";
-
-  const string profileName = "profile";
-  const string profileFile = path::join(sandbox.get(), "profiles.json");
-  const Duration pollInterval = Seconds(10);
-
-  ResourceProviderInfo resourceProviderInfo;
-  resourceProviderInfo.set_type("resource_provider_type");
-  resourceProviderInfo.set_name("resource_provider_name");
-
-  Parameters params;
-
-  Parameter* pollIntervalFlag = params.add_parameter();
-  pollIntervalFlag->set_key("poll_interval");
-  pollIntervalFlag->set_value(stringify(pollInterval));
-
-  // NOTE: We cannot use the `file://` URI to specify the file location,
-  // otherwise the file contents will be prematurely read. Therefore, we
-  // specify the absolute path of the file in the `uri` flag.
-  Parameter* uriFlag = params.add_parameter();
-  uriFlag->set_key("uri");
-  uriFlag->set_value(profileFile);
-
-  // Create the module before we've written anything to the file.
-  // This means the first poll will fail, so the module believes there
-  // are no profiles at the moment.
-  Try<DiskProfileAdaptor*> module =
-    modules::ModuleManager::create<DiskProfileAdaptor>(
-        URI_DISK_PROFILE_ADAPTOR_NAME,
-        params);
-  ASSERT_SOME(module);
-
-  // Start watching for updates.
-  // By the time this returns, we'll know that the first poll has finished
-  // because when the module reads from file, it does so immediately upon
-  // being initialized.
-  Future<hashset<string>> future =
-    module.get()->watch(hashset<string>::EMPTY, resourceProviderInfo);
-
-  // Write the single profile to the file.
-  ASSERT_SOME(os::write(profileFile, contents));
-
-  // Trigger the next poll.
-  Clock::advance(pollInterval);
-
-  AWAIT_ASSERT_READY(future);
-  ASSERT_EQ(1u, future->size());
-  EXPECT_EQ(profileName, *(future->begin()));
-
-  // Translate the profile name into the profile mapping.
-  Future<DiskProfileAdaptor::ProfileInfo> mapping =
-    module.get()->translate(profileName, resourceProviderInfo);
-
-  AWAIT_ASSERT_READY(mapping);
-  ASSERT_TRUE(mapping.get().capability.has_block());
-  ASSERT_EQ(
-      csi::VolumeCapability::AccessMode::MULTI_NODE_SINGLE_WRITER,
-      mapping.get().capability.access_mode().mode());
-
-  Clock::resume();
-}
-
-
-// Basic helper for UriDiskProfile modules configured to fetch from HTTP URIs.
-class MockProfileServer : public Process<MockProfileServer>
-{
-public:
-  MOCK_METHOD1(profiles, Future<http::Response>(const http::Request&));
-
-protected:
-  virtual void initialize()
-  {
-    route("/profiles", None(), &MockProfileServer::profiles);
-  }
-};
-
-
-class ServerWrapper
-{
-public:
-  ServerWrapper() : process(new MockProfileServer())
-  {
-    spawn(process.get());
-  }
-
-  ~ServerWrapper()
-  {
-    terminate(process.get());
-    wait(process.get());
-  }
-
-  Owned<MockProfileServer> process;
-};
-
-
-// This creates a UriDiskProfile module configured to read from an HTTP URI.
-// The HTTP server will return a different profile mapping between each of the
-// calls. We expect the module to ignore the second call because the module
-// does not allow profiles to be renamed. This is not a fatal error however,
-// as the HTTP server can be "fixed" without restarting the agent.
-TEST_F(UriDiskProfileTest, FetchFromHTTP)
-{
-  Clock::pause();
-
-  const string contents1 =R"~(
-    {
-      "profile_matrix" : {
-        "profile" : {
-          "resource_provider_selector" : {
-            "resource_providers" : [
-              {
-                "type" : "resource_provider_type",
-                "name" : "resource_provider_name"
-              }
-            ]
-          },
-          "volume_capabilities" : {
-            "block" : {},
-            "access_mode" : { "mode": "MULTI_NODE_MULTI_WRITER" }
-          }
-        }
-      }
-    })~";
-
-  const string contents2 =R"~(
-    {
-      "profile_matrix" : {
-        "renamed-profile" : {
-          "resource_provider_selector" : {
-            "resource_providers" : [
-              {
-                "type" : "resource_provider_type",
-                "name" : "resource_provider_name"
-              }
-            ]
-          },
-          "volume_capabilities" : {
-            "block" : {},
-            "access_mode" : { "mode": "SINGLE_NODE_WRITER" }
-          }
-        }
-      }
-    })~";
-
-  const string contents3 =R"~(
-    {
-      "profile_matrix" : {
-        "profile" : {
-          "resource_provider_selector" : {
-            "resource_providers" : [
-              {
-                "type" : "resource_provider_type",
-                "name" : "resource_provider_name"
-              }
-            ]
-          },
-          "volume_capabilities" : {
-            "block" : {},
-            "access_mode" : { "mode": "MULTI_NODE_MULTI_WRITER" }
-          }
-        },
-        "another-profile" : {
-          "resource_provider_selector" : {
-            "resource_providers" : [
-              {
-                "type" : "resource_provider_type",
-                "name" : "resource_provider_name"
-              }
-            ]
-          },
-          "volume_capabilities" : {
-            "block" : {},
-            "access_mode" : { "mode": "SINGLE_NODE_WRITER" }
-          }
-        }
-      }
-    })~";
-
-  const Duration pollInterval = Seconds(10);
-
-  ResourceProviderInfo resourceProviderInfo;
-  resourceProviderInfo.set_type("resource_provider_type");
-  resourceProviderInfo.set_name("resource_provider_name");
-
-  ServerWrapper server;
-
-  // Wait for the server to finish initializing so that the routes are ready.
-  AWAIT_READY(dispatch(server.process->self(), []() { return Nothing(); }));
-
-  // We need to intercept this call since the module is expected to
-  // ignore the result of the second call.
-  Future<Nothing> secondCall;
-
-  EXPECT_CALL(*server.process, profiles(_))
-    .WillOnce(Return(http::OK(contents1)))
-    .WillOnce(DoAll(FutureSatisfy(&secondCall), Return(http::OK(contents2))))
-    .WillOnce(Return(http::OK(contents3)));
-
-  Parameters params;
-
-  Parameter* pollIntervalFlag = params.add_parameter();
-  pollIntervalFlag->set_key("poll_interval");
-  pollIntervalFlag->set_value(stringify(pollInterval));
-
-  Parameter* uriFlag = params.add_parameter();
-  uriFlag->set_key("uri");
-  uriFlag->set_value(stringify(process::http::URL(
-      "http",
-      process::address().ip,
-      process::address().port,
-      server.process->self().id + "/profiles")));
-
-  Try<DiskProfileAdaptor*> module =
-    modules::ModuleManager::create<DiskProfileAdaptor>(
-        URI_DISK_PROFILE_ADAPTOR_NAME,
-        params);
-  ASSERT_SOME(module);
-
-  // Wait for the first HTTP poll to complete.
-  Future<hashset<string>> future =
-    module.get()->watch(hashset<string>::EMPTY, resourceProviderInfo);
-
-  AWAIT_ASSERT_READY(future);
-  ASSERT_EQ(1u, future->size());
-  EXPECT_EQ("profile", *(future->begin()));
-
-  // Start watching for an update to the list of profiles.
-  future = module.get()->watch({"profile"}, resourceProviderInfo);
-
-  // Trigger the second HTTP poll.
-  Clock::advance(pollInterval);
-  AWAIT_ASSERT_READY(secondCall);
-
-  // Dispatch a call to the module, which ensures that the polling has actually
-  // completed (not just the HTTP call).
-  AWAIT_ASSERT_READY(module.get()->translate("profile", resourceProviderInfo));
-
-  // We don't expect the module to notify watcher(s) because the server's
-  // response is considered invalid (the module does not allow profiles
-  // to be renamed).
-  ASSERT_TRUE(future.isPending());
-
-  // Trigger the third HTTP poll.
-  Clock::advance(pollInterval);
-
-  // This time, the server's response is correct and also includes a second
-  // profile, which means that the watcher(s) should be notified.
-  AWAIT_ASSERT_READY(future);
-  ASSERT_EQ(2u, future->size());
-  EXPECT_EQ((hashset<string>{"profile", "another-profile"}), future.get());
-
-  Clock::resume();
-}
-
-} // namespace tests {
-} // namespace internal {
-} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/1231e8fe/src/tests/storage_local_resource_provider_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/storage_local_resource_provider_tests.cpp b/src/tests/storage_local_resource_provider_tests.cpp
index 47631ab..0ad2d24 100644
--- a/src/tests/storage_local_resource_provider_tests.cpp
+++ b/src/tests/storage_local_resource_provider_tests.cpp
@@ -83,7 +83,7 @@ public:
       path::join(sandbox.get(), "resource_provider_configs");
     ASSERT_SOME(os::mkdir(resourceProviderConfigDir));
 
-    uriDiskProfileConfigPath =
+    uriDiskProfileMappingPath =
       path::join(sandbox.get(), "disk_profiles.json");
   }
 
@@ -140,7 +140,7 @@ public:
     return flags;
   }
 
-  void loadUriDiskProfileModule()
+  void loadUriDiskProfileAdaptorModule()
   {
     const string libraryPath = getModulePath("uri_disk_profile_adaptor");
 
@@ -153,7 +153,7 @@ public:
 
     Parameter* uri = module->add_parameters();
     uri->set_key("uri");
-    uri->set_value(uriDiskProfileConfigPath);
+    uri->set_value(uriDiskProfileMappingPath);
     Parameter* pollInterval = module->add_parameters();
     pollInterval->set_key("poll_interval");
     pollInterval->set_value("1secs");
@@ -227,10 +227,10 @@ public:
         resourceProviderConfig.get()));
   }
 
-  void setupDiskProfileConfig()
+  void setupDiskProfileMapping()
   {
     Try<Nothing> write = os::write(
-        uriDiskProfileConfigPath,
+        uriDiskProfileMappingPath,
         R"~(
         {
           "profile_matrix": {
@@ -267,7 +267,7 @@ protected:
   Modules modules;
   vector<string> slaveWorkDirs;
   string resourceProviderConfigDir;
-  string uriDiskProfileConfigPath;
+  string uriDiskProfileMappingPath;
 };
 
 
@@ -441,10 +441,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_ZeroSizedDisk)
 // handle disks less than 1MB correctly.
 TEST_F(StorageLocalResourceProviderTest, ROOT_SmallDisk)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Kilobytes(512), "volume0:512KB");
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
 
@@ -565,7 +565,7 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_NewProfile)
 {
   Clock::pause();
 
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
 
@@ -627,7 +627,7 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_NewProfile)
     FUTURE_PROTOBUF(UpdateSlaveMessage(), _, _);
 
   // Add new profiles.
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   // A new storage pool for profile "volume-default" should be reported
   // by the resource provider. Still expect no storage pool for
@@ -672,10 +672,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_NewProfile)
 // create then destroy a new volume from a storage pool.
 TEST_F(StorageLocalResourceProviderTest, ROOT_CreateDestroyVolume)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -861,10 +861,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_CreateDestroyVolume)
 // destroy a volume created from a storage pool after recovery.
 TEST_F(StorageLocalResourceProviderTest, ROOT_CreateDestroyVolumeRecovery)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -1070,10 +1070,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_CreateDestroyVolumeRecovery)
 // created volume becomes a pre-existing volume.
 TEST_F(StorageLocalResourceProviderTest, ROOT_AgentRegisteredWithNewId)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -1282,10 +1282,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_AgentRegisteredWithNewId)
 // volume after the task finishes.
 TEST_F(StorageLocalResourceProviderTest, ROOT_PublishResources)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -1508,10 +1508,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_PublishResources)
 // destroy a published volume after recovery.
 TEST_F(StorageLocalResourceProviderTest, ROOT_PublishResourcesRecovery)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -1791,10 +1791,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_PublishResourcesRecovery)
 // destroy a published volume after agent reboot.
 TEST_F(StorageLocalResourceProviderTest, ROOT_PublishResourcesReboot)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -2115,10 +2115,10 @@ TEST_F(
     StorageLocalResourceProviderTest,
     ROOT_PublishUnpublishResourcesPluginKilled)
 {
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.allocation_interval = Milliseconds(50);
@@ -2622,10 +2622,10 @@ TEST_F(StorageLocalResourceProviderTest, ROOT_RetryOperationStatusUpdate)
 {
   Clock::pause();
 
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
@@ -2785,10 +2785,10 @@ TEST_F(
 {
   Clock::pause();
 
-  loadUriDiskProfileModule();
+  loadUriDiskProfileAdaptorModule();
 
   setupResourceProviderConfig(Gigabytes(4));
-  setupDiskProfileConfig();
+  setupDiskProfileMapping();
 
   master::Flags masterFlags = CreateMasterFlags();
   Try<Owned<cluster::Master>> master = StartMaster(masterFlags);