Repository: mesos
Updated Branches:
  refs/heads/master eebced480 -> 914b99018


Checking "kind" before creating a module instance.

Introduced a new kind<T>() function that returns the string
representation of the module "kind". This function is specialized for
each module "kind". Also introduced a templatized
contains<T>(moduleName) that returns true only if a module of name
"moduleName" and kind "T" is available.

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


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

Branch: refs/heads/master
Commit: 914b9901845a57e6fce2c63284934de7dfabc703
Parents: eebced4
Author: Kapil Arya <[email protected]>
Authored: Wed Oct 22 10:41:30 2014 -0700
Committer: Niklas Q. Nielsen <[email protected]>
Committed: Wed Oct 22 10:41:30 2014 -0700

----------------------------------------------------------------------
 include/mesos/module.hpp     |  6 +++++-
 src/examples/test_module.hpp |  9 ++++++++-
 src/module/manager.hpp       | 31 ++++++++++++++++++++++++-------
 src/tests/module_tests.cpp   | 10 ++++++++++
 4 files changed, 47 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/914b9901/include/mesos/module.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/module.hpp b/include/mesos/module.hpp
index 477acfd..5bafb40 100644
--- a/include/mesos/module.hpp
+++ b/include/mesos/module.hpp
@@ -94,10 +94,14 @@ struct ModuleBase
 };
 
 
-// This declaration is neeed only for later specializations.
+// These declarations are neeed only for later specializations.
+
 template <typename T>
 struct Module;
 
+template <typename T>
+const char* kind();
+
 } // namespace modules {
 } // namespace mesos {
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/914b9901/src/examples/test_module.hpp
----------------------------------------------------------------------
diff --git a/src/examples/test_module.hpp b/src/examples/test_module.hpp
index 7e22fb7..820df23 100644
--- a/src/examples/test_module.hpp
+++ b/src/examples/test_module.hpp
@@ -45,6 +45,13 @@ public:
 namespace mesos {
 namespace modules {
 
+template<>
+inline const char* kind<TestModule>()
+{
+  return "TestModule";
+}
+
+
 template <>
 struct Module<TestModule> : ModuleBase
 {
@@ -59,7 +66,7 @@ struct Module<TestModule> : ModuleBase
     : ModuleBase(
         _moduleApiVersion,
         _mesosVersion,
-        "TestModule",
+        mesos::modules::kind<TestModule>(),
         _authorName,
         _authorEmail,
         _description,

http://git-wip-us.apache.org/repos/asf/mesos/blob/914b9901/src/module/manager.hpp
----------------------------------------------------------------------
diff --git a/src/module/manager.hpp b/src/module/manager.hpp
index 65d54f1..dc78921 100644
--- a/src/module/manager.hpp
+++ b/src/module/manager.hpp
@@ -66,8 +66,8 @@ public:
   static Try<Nothing> load(const mesos::internal::Modules& modules);
 
   // create() should be called only after load().
-  template <typename Kind>
-  static Try<Kind*> create(const std::string& moduleName)
+  template <typename T>
+  static Try<T*> create(const std::string& moduleName)
   {
     mesos::internal::Lock lock(&mutex);
     if (!moduleBases.contains(moduleName)) {
@@ -75,17 +75,34 @@ public:
           "Module '" + moduleName + "' unknown");
     }
 
-    Module<Kind>* module = (Module<Kind>*) moduleBases[moduleName];
+    Module<T>* module = (Module<T>*) moduleBases[moduleName];
     if (module->create == NULL) {
       return Error(
-          "Error creating Module instance for '" + moduleName + "': "
+          "Error creating module instance for '" + moduleName + "': "
           "create() method not found");
     }
-    Kind* kind = module->create();
-    if (kind == NULL) {
+
+    std::string expectedKind = kind<T>();
+    if (expectedKind != module->kind) {
+      return Error(
+          "Error creating module instance for '" + moduleName + "': "
+          "module is of kind '" + module->kind + "', but the requested "
+          "kind is '" + expectedKind + "'");
+    }
+
+    T* instance = module->create();
+    if (instance == NULL) {
       return Error("Error creating Module instance for '" + moduleName + "'");
     }
-    return kind;
+    return instance;
+  }
+
+  template <typename T>
+  static bool contains(const std::string& moduleName)
+  {
+    mesos::internal::Lock lock(&mutex);
+    return (moduleBases.contains(moduleName) &&
+            moduleBases[moduleName]->kind == stringify(kind<T>()));
   }
 
   // Exposed just for testing so that we can unload a given

http://git-wip-us.apache.org/repos/asf/mesos/blob/914b9901/src/tests/module_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/module_tests.cpp b/src/tests/module_tests.cpp
index 532ff50..c695bf7 100644
--- a/src/tests/module_tests.cpp
+++ b/src/tests/module_tests.cpp
@@ -102,6 +102,7 @@ protected:
 
     // Reset module API version and Mesos version in case the test
     // changed them.
+    moduleBase->kind = "TestModule";
     moduleBase->moduleApiVersion = MESOS_MODULE_API_VERSION;
     moduleBase->mesosVersion = MESOS_VERSION;
 
@@ -142,6 +143,7 @@ TEST_F(ModuleTest, ExampleModuleLoadTest)
 {
   EXPECT_SOME(ModuleManager::load(defaultModules));
 
+  EXPECT_TRUE(ModuleManager::contains<TestModule>(DEFAULT_MODULE_NAME));
   module = ModuleManager::create<TestModule>(DEFAULT_MODULE_NAME);
   EXPECT_SOME(module);
 
@@ -173,6 +175,14 @@ TEST_F(ModuleTest, ExampleModuleUnloadTest)
 }
 
 
+// Verify that loading a module of an invalid kind fails.
+TEST_F(ModuleTest, InvalidModuleKind)
+{
+  moduleBase->kind = "NotTestModule";
+  EXPECT_ERROR(ModuleManager::load(defaultModules));
+}
+
+
 // Test for correct author name, author email and library description.
 TEST_F(ModuleTest, AuthorInfoTest)
 {

Reply via email to