summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Dachary <loic@dachary.org>2013-09-19 09:28:14 +0200
committerLoic Dachary <loic@dachary.org>2013-09-19 09:47:53 +0200
commit4c9497f9be0560e0aed4b97d5969001c27a58203 (patch)
tree2858201dbd58581467d944d2a2bdaffe72de0c3e
parent7324931d5ec8e57ff9d5ae4e5700a1a479f5a6bb (diff)
downloadceph-4c9497f9be0560e0aed4b97d5969001c27a58203.tar.gz
ErasureCode: complete plugin loader unit tests
* 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>
-rw-r--r--src/test/Makefile.am23
-rw-r--r--src/test/osd/ErasureCodePluginFailToInitialize.cc23
-rw-r--r--src/test/osd/ErasureCodePluginFailToRegister.cc22
-rw-r--r--src/test/osd/ErasureCodePluginMissingEntryPoint.cc1
-rw-r--r--src/test/osd/TestErasureCodePlugin.cc114
-rw-r--r--src/test/osd/TestErasureCodePluginExample.cc51
6 files changed, 182 insertions, 52 deletions
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 80ec69425ca..278243b5beb 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -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
index 00000000000..cded6eef556
--- /dev/null
+++ b/src/test/osd/ErasureCodePluginFailToInitialize.cc
@@ -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
index 00000000000..ea980b722ae
--- /dev/null
+++ b/src/test/osd/ErasureCodePluginFailToRegister.cc
@@ -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
index 00000000000..fc60f866086
--- /dev/null
+++ b/src/test/osd/ErasureCodePluginMissingEntryPoint.cc
@@ -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
index 00000000000..ba7d13fbd2d
--- /dev/null
+++ b/src/test/osd/TestErasureCodePlugin.cc
@@ -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
index 67b41f2011a..00000000000
--- a/src/test/osd/TestErasureCodePluginExample.cc
+++ /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: