]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ErasureCode: complete plugin loader unit tests 605/head
authorLoic Dachary <loic@dachary.org>
Thu, 19 Sep 2013 07:28:14 +0000 (09:28 +0200)
committerLoic Dachary <loic@dachary.org>
Thu, 19 Sep 2013 07:47:53 +0000 (09:47 +0200)
* TestErasureCodePluginExample.cc is renamed to TestErasureCodePlugin.cc
  because it's not limited to the example which is really used to
  support tests rather than being tested.

* Bugous plugins are added to exhibit failures and enable the unit tests
  to check they are handled as expected

  ErasureCodePluginFailToInitialize : the entry point returns != 0
  ErasureCodePluginFailToRegister : the plugin registry is not updated
  ErasureCodePluginMissingEntryPoint : the shared library has no entry
  point

* It would be difficult to prove that the mutex protecting against
  multiple loads actually does what it is expected to because of the
  lack of thread introspection functions such as : tell me if this
  thread is waiting on this mutex. A simpler approach is chosen : create
  a thread that blocks forever when loading ( that's what the delay in
  the example plugin is for ) and then check that the lock has indeed
  been acquired. Since this mutex is merely about making sure that only
  one thread at a time runs this sequence of code, it's probably enough.

Signed-off-by: Loic Dachary <loic@dachary.org>
src/test/Makefile.am
src/test/osd/ErasureCodePluginFailToInitialize.cc [new file with mode: 0644]
src/test/osd/ErasureCodePluginFailToRegister.cc [new file with mode: 0644]
src/test/osd/ErasureCodePluginMissingEntryPoint.cc [new file with mode: 0644]
src/test/osd/TestErasureCodePlugin.cc [new file with mode: 0644]
src/test/osd/TestErasureCodePluginExample.cc [deleted file]

index 80ec69425ca09ba39f7e1f8129ddfcbfd95fcaaa..278243b5beb4dab4c1c35ea26fd09f7bdbf45912 100644 (file)
@@ -307,7 +307,28 @@ libec_example_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS)
 libec_example_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*'
 erasure_codelib_LTLIBRARIES += libec_example.la
 
-unittest_erasure_code_plugin_SOURCES = test/osd/TestErasureCodePluginExample.cc 
+libec_missing_entry_point_la_SOURCES = test/osd/ErasureCodePluginMissingEntryPoint.cc
+libec_missing_entry_point_la_CFLAGS = ${AM_CFLAGS}
+libec_missing_entry_point_la_CXXFLAGS= ${AM_CXXFLAGS}
+libec_missing_entry_point_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS)
+libec_missing_entry_point_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*'
+erasure_codelib_LTLIBRARIES += libec_missing_entry_point.la
+
+libec_fail_to_initialize_la_SOURCES = test/osd/ErasureCodePluginFailToInitialize.cc
+libec_fail_to_initialize_la_CFLAGS = ${AM_CFLAGS}
+libec_fail_to_initialize_la_CXXFLAGS= ${AM_CXXFLAGS}
+libec_fail_to_initialize_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS)
+libec_fail_to_initialize_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*'
+erasure_codelib_LTLIBRARIES += libec_fail_to_initialize.la
+
+libec_fail_to_register_la_SOURCES = test/osd/ErasureCodePluginFailToRegister.cc
+libec_fail_to_register_la_CFLAGS = ${AM_CFLAGS}
+libec_fail_to_register_la_CXXFLAGS= ${AM_CXXFLAGS}
+libec_fail_to_register_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS)
+libec_fail_to_register_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*'
+erasure_codelib_LTLIBRARIES += libec_fail_to_register.la
+
+unittest_erasure_code_plugin_SOURCES = test/osd/TestErasureCodePlugin.cc 
 unittest_erasure_code_plugin_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 unittest_erasure_code_plugin_LDADD = $(LIBOSD) $(LIBCOMMON) $(UNITTEST_LDADD) $(CEPH_GLOBAL)
 if LINUX
diff --git a/src/test/osd/ErasureCodePluginFailToInitialize.cc b/src/test/osd/ErasureCodePluginFailToInitialize.cc
new file mode 100644 (file)
index 0000000..cded6ee
--- /dev/null
@@ -0,0 +1,23 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
+ *
+ * Author: Loic Dachary <loic@dachary.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+#include <errno.h>
+#include "osd/ErasureCodePlugin.h"
+
+int __erasure_code_init(char *plugin_name)
+{
+  return -ESRCH;
+}
diff --git a/src/test/osd/ErasureCodePluginFailToRegister.cc b/src/test/osd/ErasureCodePluginFailToRegister.cc
new file mode 100644 (file)
index 0000000..ea980b7
--- /dev/null
@@ -0,0 +1,22 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
+ *
+ * Author: Loic Dachary <loic@dachary.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+#include "osd/ErasureCodePlugin.h"
+
+int __erasure_code_init(char *plugin_name)
+{
+  return 0;
+}
diff --git a/src/test/osd/ErasureCodePluginMissingEntryPoint.cc b/src/test/osd/ErasureCodePluginMissingEntryPoint.cc
new file mode 100644 (file)
index 0000000..fc60f86
--- /dev/null
@@ -0,0 +1 @@
+// missing int __erasure_code_init(char *plugin_name) {}
diff --git a/src/test/osd/TestErasureCodePlugin.cc b/src/test/osd/TestErasureCodePlugin.cc
new file mode 100644 (file)
index 0000000..ba7d13f
--- /dev/null
@@ -0,0 +1,114 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
+ *
+ * Author: Loic Dachary <loic@dachary.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include "common/Thread.h"
+#include "global/global_init.h"
+#include "osd/ErasureCodePlugin.h"
+#include "common/ceph_argparse.h"
+#include "global/global_context.h"
+#include "gtest/gtest.h"
+
+class ErasureCodePluginRegistryTest : public ::testing::Test {
+protected:
+
+  class Thread_factory : public Thread {
+  public:
+    useconds_t delay;
+
+    Thread_factory(useconds_t _delay) :
+      delay(_delay)
+    {}
+
+    virtual void *entry() {
+      map<std::string,std::string> parameters;
+      parameters["erasure-code-directory"] = ".libs";
+      parameters["usleep"] = delay;
+      ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
+      ErasureCodeInterfaceRef erasure_code;
+      instance.factory("example", parameters, &erasure_code);
+      return NULL;
+    }
+  };
+
+};
+
+TEST_F(ErasureCodePluginRegistryTest, factory_mutex) {
+  ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
+
+  EXPECT_TRUE(instance.lock.TryLock());
+  instance.lock.Unlock();
+
+  // 
+  // Test that the loading of a plugin is protected by a mutex.
+  //
+  useconds_t delay = 0;
+  const useconds_t DELAY_MAX = 20 * 1000 * 1000;
+  Thread_factory sleep_forever(1024 * 1024 * 1024);
+  sleep_forever.create();
+  do {
+    cout << "Trying (1) with delay " << delay << "us\n";
+    if (delay > 0)
+      usleep(delay);
+    if (!instance.loading)
+      delay = ( delay + 1 ) * 2;
+  } while(!instance.loading && delay < DELAY_MAX);
+  ASSERT_TRUE(delay < DELAY_MAX);
+
+  EXPECT_FALSE(instance.lock.TryLock());
+
+  EXPECT_EQ(0, sleep_forever.detach());
+}
+
+TEST_F(ErasureCodePluginRegistryTest, all)
+{
+  map<std::string,std::string> parameters;
+  parameters["erasure-code-directory"] = ".libs";
+  ErasureCodeInterfaceRef erasure_code;
+  ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
+  EXPECT_FALSE(erasure_code);
+  EXPECT_EQ(-EIO, instance.factory("invalid", parameters, &erasure_code));
+  EXPECT_FALSE(erasure_code);
+  EXPECT_EQ(-ENOENT, instance.factory("missing_entry_point", parameters,
+                                     &erasure_code));
+  EXPECT_FALSE(erasure_code);
+  EXPECT_EQ(-ESRCH, instance.factory("fail_to_initialize", parameters,
+                                    &erasure_code));
+  EXPECT_FALSE(erasure_code);
+  EXPECT_EQ(-EBADF, instance.factory("fail_to_register", parameters,
+                                    &erasure_code));
+  EXPECT_FALSE(erasure_code);
+  EXPECT_EQ(0, instance.factory("example", parameters, &erasure_code));
+  EXPECT_TRUE(erasure_code);
+  ErasureCodePlugin *plugin = 0;
+  EXPECT_EQ(-EEXIST, instance.load("example", parameters, &plugin));
+}
+
+int main(int argc, char **argv) {
+  vector<const char*> args;
+  argv_to_vec(argc, (const char **)argv, args);
+
+  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+
+// Local Variables:
+// compile-command: "cd ../.. ; make -j4 && make unittest_erasure_code_plugin && valgrind  --leak-check=full --tool=memcheck ./unittest_erasure_code_plugin --gtest_filter=*.* --log-to-stderr=true --debug-osd=20"
+// End:
diff --git a/src/test/osd/TestErasureCodePluginExample.cc b/src/test/osd/TestErasureCodePluginExample.cc
deleted file mode 100644 (file)
index 67b41f2..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
- *
- * Author: Loic Dachary <loic@dachary.org>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- * 
- */
-
-#include <errno.h>
-#include "common/Thread.h"
-#include "global/global_init.h"
-#include "osd/ErasureCodePlugin.h"
-#include "common/ceph_argparse.h"
-#include "global/global_context.h"
-#include "gtest/gtest.h"
-
-TEST(ErasureCodePluginRegistry, factory)
-{
-  map<std::string,std::string> parameters;
-  parameters["erasure-code-directory"] = ".libs";
-  ErasureCodeInterfaceRef erasure_code;
-  ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
-  EXPECT_FALSE(erasure_code);
-  EXPECT_EQ(0, instance.factory("example", parameters, &erasure_code));
-  EXPECT_TRUE(erasure_code);
-  ErasureCodePlugin *plugin = 0;
-  EXPECT_EQ(-EEXIST, instance.load("example", parameters, &plugin));
-}
-
-int main(int argc, char **argv) {
-  vector<const char*> args;
-  argv_to_vec(argc, (const char **)argv, args);
-
-  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
-  common_init_finish(g_ceph_context);
-
-  ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
-
-// Local Variables:
-// compile-command: "cd ../.. ; make -j4 && make unittest_erasure_code_plugin && ./unittest_erasure_code_plugin --gtest_filter=*.* --log-to-stderr=true --debug-osd=20"
-// End: