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 <chhs...@mesosphere.io> Authored: Mon Mar 19 15:43:31 2018 -0700 Committer: Chun-Hung Hsiao <chhs...@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);