Darryl L. Pierce
2010-May-27 20:36 UTC
[Ovirt-devel] [PATCH matahari] Introduces a multiplexer for taking requests and mapping them to APIs.
The Multiplexer lets Matahari register APIs and then call them by that registered name. APIs are function pointers in the form of: const char* function(const char *); where the API takes as input a descriptor containing any arguments, and returns an array containing the response or result. Also adds a testing directory and unit tests to validate the Multiplexer. The new directory, src/tests, has its own standalone makefile that builds the tests. Signed-off-by: Darryl L. Pierce <dpierce at redhat.com> --- configure.ac | 3 +- src/Makefile.am | 6 ++- src/tests/.gitignore | 1 + src/tests/Makefile.am | 13 +++++ src/tests/testmultiplexer.cpp | 109 +++++++++++++++++++++++++++++++++++++++++ src/tests/testmultiplexer.h | 46 +++++++++++++++++ src/virtio/multiplexer.cpp | 62 +++++++++++++++++++++++ src/virtio/multiplexer.h | 48 ++++++++++++++++++ 8 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 src/tests/.gitignore create mode 100644 src/tests/Makefile.am create mode 100644 src/tests/testmultiplexer.cpp create mode 100644 src/tests/testmultiplexer.h create mode 100644 src/virtio/multiplexer.cpp create mode 100644 src/virtio/multiplexer.h diff --git a/configure.ac b/configure.ac index 42d319b..3481c09 100644 --- a/configure.ac +++ b/configure.ac @@ -21,6 +21,7 @@ AC_HEADER_STDBOOL AC_TYPE_UINT32_T # Checks for libraries. +PKG_CHECK_MODULES(CPPUNIT, cppunit >= 1.12.1) PKG_CHECK_MODULES(LIBVIRT, libvirt >= 0.6.2) PKG_CHECK_MODULES(PCRE, libpcre >= 7.8) PKG_CHECK_MODULES(UDEV, libudev >= 145) @@ -28,4 +29,4 @@ PKG_CHECK_MODULES(UDEV, libudev >= 145) # Checks for library functions. AC_CHECK_FUNCS([gethostname inet_ntoa socket]) -AC_OUTPUT(Makefile src/Makefile) +AC_OUTPUT(Makefile src/Makefile src/tests/Makefile) diff --git a/src/Makefile.am b/src/Makefile.am index 498ee72..7b5245a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,7 +32,9 @@ matahari_SOURCES = \ qmf/hostagent.cpp \ qmf/hostagent.h \ qmf/processorsagent.cpp \ - qmf/processorsagent.h + qmf/processorsagent.h \ + virtio/multiplexer.cpp \ + virtio/multiplexer.h $(generated_file_list): $(generated_file_list) @@ -44,6 +46,6 @@ CLEANFILES = $(generated_file_list) $(first) matahari_CPPFLAGS = -fno-strict-aliasing matahari_LDFLAGS = -L/usr/local/lib -matahari_LDADD = -lqmf $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS) +matahari_LDADD = -lqmf -lqpidclient -lqpidcommon $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS) dist_pkgdata_DATA = schema.xml diff --git a/src/tests/.gitignore b/src/tests/.gitignore new file mode 100644 index 0000000..06042ff --- /dev/null +++ b/src/tests/.gitignore @@ -0,0 +1 @@ +testmultiplexer diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am new file mode 100644 index 0000000..8573ac3 --- /dev/null +++ b/src/tests/Makefile.am @@ -0,0 +1,13 @@ + +bin_PROGRAMS = testmultiplexer + +INCLUDES = \ + -I$(top_srcdir)/src + +testmultiplexer_SOURCES = \ + $(top_srcdir)/src/virtio/multiplexer.cpp \ + $(top_srcdir)/src/virtio/multiplexer.h \ + testmultiplexer.cpp \ + testmultiplexer.h + +testmultiplexer_LDADD = -lcppunit \ No newline at end of file diff --git a/src/tests/testmultiplexer.cpp b/src/tests/testmultiplexer.cpp new file mode 100644 index 0000000..8ed77fd --- /dev/null +++ b/src/tests/testmultiplexer.cpp @@ -0,0 +1,109 @@ +/* testmultiplexer.cpp - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce <dpierce at redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. A copy of the GNU General Public License is + * also available at http://www.gnu.org/copyleft/gpl.html. + */ + +#include "testmultiplexer.h" + +#include "virtio/multiplexer.h" + +#include <cppunit/TestAssert.h> +#include <cppunit/TestCaller.h> +#include <cppunit/TestResult.h> +#include <cppunit/TestSuite.h> +#include <cppunit/ui/text/TestRunner.h> + +const string APINAME("testapifunction"); + +const char* +test_callback_function(const char* input) +{ + return input; +} + +TestMultiplexer::TestMultiplexer() + :TestCase("TestMultiplexer") +{} + +TestSuite* +TestMultiplexer::suite() +{ + CppUnit::TestSuite *result = new CppUnit::TestSuite("TestMultiplexer"); + + result->addTest(new CppUnit::TestCaller<TestMultiplexer> + ("testBadAPINameGetsNull", + &TestMultiplexer::testUnregisteredAPIIsNull)); + result->addTest(new CppUnit::TestCaller<TestMultiplexer> + ("testRegisterAPIMethod", + &TestMultiplexer::testRegisterAPIMethod)); + result->addTest(new CppUnit::TestCaller<TestMultiplexer> + ("testEnsureCallingAnUnregisteredAPIFails", + &TestMultiplexer::testEnsureCallingAnUnregisteredAPIFails)); + result->addTest(new CppUnit::TestCaller<TestMultiplexer> + ("testEnsureAPIIsCalled", + &TestMultiplexer::testEnsureAPIIsCalled)); + + return result; +} + +void +TestMultiplexer::setUp() +{ + Multiplexer::instance()->registerAPI(APINAME, test_callback_function); +} + +void +TestMultiplexer::testUnregisteredAPIIsNull() +{ + CPPUNIT_ASSERT(NULL == Multiplexer::instance()->getAPI(APINAME + "!")); +} + +void +TestMultiplexer::testRegisterAPIMethod() +{ + t_apifunction apifunction = test_callback_function; + + CPPUNIT_ASSERT(apifunction == Multiplexer::instance()->getAPI(APINAME)); +} + +void +TestMultiplexer::testEnsureCallingAnUnregisteredAPIFails() +{ + string input = string("This is some input"); + string result = Multiplexer::instance()->invokeAPI(APINAME + "!", input); + + CPPUNIT_ASSERT(string("") == result); +} + +void TestMultiplexer::testEnsureAPIIsCalled() +{ + string expected = "This is what I expected"; + string result = Multiplexer::instance()->invokeAPI(APINAME, expected); + + CPPUNIT_ASSERT(expected == result); +} + +int +main(int argc, char** argv) +{ + CppUnit::TextUi::TestRunner runner; + + runner.addTest(TestMultiplexer::suite()); + runner.run(); + + return 0; +} diff --git a/src/tests/testmultiplexer.h b/src/tests/testmultiplexer.h new file mode 100644 index 0000000..04cb9e5 --- /dev/null +++ b/src/tests/testmultiplexer.h @@ -0,0 +1,46 @@ +#ifndef __TESTMULTIPLEXER_H +#define __TESTMULTIPLEXER_H + +/* testmultiplexer.h - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce <dpierce at redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. A copy of the GNU General Public License is + * also available at http://www.gnu.org/copyleft/gpl.html. + */ + +#include "virtio/multiplexer.h" + +#include <cppunit/TestCase.h> +#include <cppunit/TestSuite.h> + +using namespace CppUnit; +using namespace std; + +class TestMultiplexer : public CppUnit::TestCase +{ + public: + TestMultiplexer(); + + static TestSuite* suite(); + + void setUp(); + + void testUnregisteredAPIIsNull(); + void testRegisterAPIMethod(); + void testEnsureCallingAnUnregisteredAPIFails(); + void testEnsureAPIIsCalled(); +}; + +#endif diff --git a/src/virtio/multiplexer.cpp b/src/virtio/multiplexer.cpp new file mode 100644 index 0000000..79f8b35 --- /dev/null +++ b/src/virtio/multiplexer.cpp @@ -0,0 +1,62 @@ +#include "multiplexer.h" + +/* multiplexer.cpp - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce <dpierce at redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. A copy of the GNU General Public License is + * also available at http://www.gnu.org/copyleft/gpl.html. + */ + +#include "multiplexer.h" + +// the singleton +Multiplexer* Multiplexer::_instance = new Multiplexer(); + +typedef map<string, t_apifunction> APIMAP; + +Multiplexer::Multiplexer() +{} + +Multiplexer* +Multiplexer::instance() +{ + return _instance; +} + +void +Multiplexer::registerAPI(string name, t_apifunction apifunction) +{ + _apis.insert(APIMAP::value_type(string(name), apifunction)); +} + +t_apifunction +Multiplexer::getAPI(string name) +{ + return (*_apis.find(name)).second; +} + +string +Multiplexer::invokeAPI(string name, string input) +{ + string result = string(""); + t_apifunction funcptr = (*_apis.find(name)).second; + + if(funcptr) + { + result = funcptr(input.c_str()); + } + + return result; +} diff --git a/src/virtio/multiplexer.h b/src/virtio/multiplexer.h new file mode 100644 index 0000000..26a288c --- /dev/null +++ b/src/virtio/multiplexer.h @@ -0,0 +1,48 @@ +#ifndef __MULTIPLEXER_H +#define __MULTIPLEXER_H + +/* multiplexer.h - Copyright (C) 2010 Red Hat, Inc. + * Written by Darryl L. Pierce <dpierce at redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. A copy of the GNU General Public License is + * also available at http://www.gnu.org/copyleft/gpl.html. + */ + +#include <map> +#include <string> + +using namespace std; + +typedef const char*(*t_apifunction)(const char*); + +// Multiplexer processes the content received from a remote system. +class Multiplexer +{ + private: + Multiplexer(); + + static Multiplexer* _instance; + + map<string, t_apifunction> _apis; + + public: + static Multiplexer* instance(); + + void registerAPI(string apiname, t_apifunction apifunction); + t_apifunction getAPI(string apiname); + string invokeAPI(string apiname, string input); +}; + +#endif -- 1.7.0.1
Darryl L. Pierce
2010-May-28 15:41 UTC
[Ovirt-devel] [Matahari] [PATCH matahari] Introduces a multiplexer for taking requests and mapping them to APIs.
On Fri, May 28, 2010 at 11:24:46AM +0200, Andrew Beekhof wrote:> > const char* function(const char *); > > Not sure about this method signature. > It would mean each function has to do its own packing and unpacking which might lead to excessive duplication. > It would also cause problems for API calls like "get the paste buffer" which could easily contain images (and thus zero'd bytes which would confuse strlen()).Yeah, I was trying to keep things simple. Perhaps better would be to pass around just a void * and let each API know for itself what to extract. My main goal there was just to avoid having the Multiplexer dig into the XML and try to map values and types to specific method arguments.> Since the input is xml, perhaps xmlNodePtr is a better I/O vector. > > Other than that, the patch is fine. > I'd go ahead and commit it and we can continue discussing the method signature.Agreed. This is pushed now. -- Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc. Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: <http://listman.redhat.com/archives/ovirt-devel/attachments/20100528/251f6615/attachment.sig>