1 /*=============================================================================
3 ===============================================================================
4 Test the Abyss server C++ facilities of XML-RPC for C/C++.
6 =============================================================================*/
7 #include <sys/unistd.h>
8 #include <sys/socket.h>
19 #include "xmlrpc-c/girerr.hpp"
22 #include "xmlrpc-c/base.hpp"
23 #include "xmlrpc-c/registry.hpp"
24 #include "xmlrpc-c/server_abyss.hpp"
27 #include "server_abyss.hpp"
29 using namespace xmlrpc_c;
37 boundSocket(short const portNumber) {
38 this->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
41 throwf("socket() failed. errno=%d (%s)",
42 errno, strerror(errno));
44 struct sockaddr_in sockAddr;
47 sockAddr.sin_family = AF_INET;
48 sockAddr.sin_port = htons(portNumber);
49 sockAddr.sin_addr.s_addr = 0;
51 rc = bind(this->fd, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
55 throwf("Couldn't bind. bind() failed with errno=%d (%s)",
56 errno, strerror(errno));
69 class sampleAddMethod : public method {
72 this->_signature = "i:ii";
73 this->_help = "This method adds two integers together";
76 execute(xmlrpc_c::paramList const& paramList,
77 value * const retvalP) {
79 int const addend(paramList.getInt(0));
80 int const adder(paramList.getInt(1));
82 paramList.verifyEnd(2);
84 *retvalP = value_int(addend + adder);
90 class addHandlerTestSuite : public testSuite {
93 virtual string suiteName() {
94 return "addHandlerTestSuite";
96 virtual void runtests(unsigned int) {
99 ServerCreate(&abyssServer, "testserver", 8080, NULL, NULL);
103 myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod));
105 registryPtr myRegistryP(new registry);
107 myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod));
109 server_abyss_set_handlers(&abyssServer, myRegistry);
111 server_abyss_set_handlers(&abyssServer, &myRegistry);
113 server_abyss_set_handlers(&abyssServer, myRegistryP);
115 server_abyss_set_handlers(&abyssServer, myRegistry, "/RPC3");
117 server_abyss_set_handlers(&abyssServer, &myRegistry, "/RPC3");
119 server_abyss_set_handlers(&abyssServer, myRegistryP, "/RPC3");
121 ServerFree(&abyssServer);
128 serverAbyssTestSuite::suiteName() {
129 return "serverAbyssTestSuite";
134 serverAbyssTestSuite::runtests(unsigned int const indentation) {
136 addHandlerTestSuite().run(indentation+1);
140 myRegistry.addMethod("sample.add", methodPtr(new sampleAddMethod));
142 registryPtr myRegistryP(new registry);
144 myRegistryP->addMethod("sample.add", methodPtr(new sampleAddMethod));
146 EXPECT_ERROR( // No registry
147 serverAbyss::constrOpt opt;
148 serverAbyss abyssServer(opt);
150 EXPECT_ERROR( // Both portNumber and socketFd
151 serverAbyss abyssServer(serverAbyss::constrOpt()
156 // Due to the vagaries of Abyss, construction of the following
157 // objects may exit the program if it detects an error, such as
158 // port number already in use. We need to fix Abyss some day.
161 serverAbyss abyssServer(serverAbyss::constrOpt()
162 .registryP(&myRegistry)
167 serverAbyss abyssServer(serverAbyss::constrOpt()
168 .registryPtr(myRegistryP)
172 EXPECT_ERROR( // Both registryP and registryPtr
173 serverAbyss abyssServer(serverAbyss::constrOpt()
174 .registryPtr(myRegistryP)
175 .registryP(&myRegistry)
181 boundSocket socket(12345);
183 serverAbyss abyssServer(serverAbyss::constrOpt()
184 .registryP(&myRegistry)
189 serverAbyss abyssServer(serverAbyss::constrOpt()
190 .registryP(&myRegistry)
195 // Test all the options
196 serverAbyss abyssServer(serverAbyss::constrOpt()
197 .registryPtr(myRegistryP)
199 .logFileName("/tmp/logfile")
209 serverAbyss abyssServer(
211 12345, // TCP port on which to listen
212 "/tmp/xmlrpc_log" // Log file