PageRenderTime 79ms CodeModel.GetById 26ms app.highlight 48ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/newview/tests/llxmlrpclistener_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 250 lines | 171 code | 11 blank | 68 comment | 3 complexity | 22d96e1f1e268f11857de5b23553d90e MD5 | raw file
  1/*
  2 * @file   llxmlrpclistener_test.cpp
  3 * @author Nat Goodspeed
  4 * @date   2009-03-20
  5 * @brief  Test for llxmlrpclistener.
  6 * 
  7 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  8 * Second Life Viewer Source Code
  9 * Copyright (C) 2010, Linden Research, Inc.
 10 * 
 11 * This library is free software; you can redistribute it and/or
 12 * modify it under the terms of the GNU Lesser General Public
 13 * License as published by the Free Software Foundation;
 14 * version 2.1 of the License only.
 15 * 
 16 * This library is distributed in the hope that it will be useful,
 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 19 * Lesser General Public License for more details.
 20 * 
 21 * You should have received a copy of the GNU Lesser General Public
 22 * License along with this library; if not, write to the Free Software
 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 24 * 
 25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 26 * $/LicenseInfo$
 27 */
 28
 29// Precompiled header
 30#include "../llviewerprecompiledheaders.h"
 31// associated header
 32#include "../llxmlrpclistener.h"
 33// STL headers
 34#include <iomanip>
 35// std headers
 36// external library headers
 37// other Linden headers
 38#include "../test/lltut.h"
 39#include "../llxmlrpctransaction.h"
 40#include "llevents.h"
 41#include "lleventfilter.h"
 42#include "llsd.h"
 43#include "llhost.h"
 44#include "llcontrol.h"
 45#include "tests/wrapllerrs.h"
 46#include "tests/commtest.h"
 47
 48LLControlGroup gSavedSettings("Global");
 49
 50/*****************************************************************************
 51*   TUT
 52*****************************************************************************/
 53namespace tut
 54{
 55    struct data
 56    {
 57        data():
 58            pumps(LLEventPumps::instance()),
 59            uri(std::string("http://") +
 60                LLHost("127.0.0.1", commtest_data::getport("PORT")).getString())
 61        {
 62            // These variables are required by machinery used by
 63            // LLXMLRPCTransaction. The values reflect reality for this test
 64            // executable; hopefully these values are correct.
 65            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist
 66            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist
 67        }
 68
 69        // LLEventPump listener signature
 70        bool captureReply(const LLSD& r)
 71        {
 72            reply = r;
 73            return false;
 74        }
 75
 76        LLSD reply;
 77        LLEventPumps& pumps;
 78        std::string uri;
 79    };
 80    typedef test_group<data> llxmlrpclistener_group;
 81    typedef llxmlrpclistener_group::object object;
 82    llxmlrpclistener_group llxmlrpclistenergrp("llxmlrpclistener");
 83
 84    template<> template<>
 85    void object::test<1>()
 86    {
 87        set_test_name("request validation");
 88        WrapLL_ERRS capture;
 89        LLSD request;
 90        request["uri"] = uri;
 91        std::string threw;
 92        try
 93        {
 94            pumps.obtain("LLXMLRPCTransaction").post(request);
 95        }
 96        catch (const WrapLL_ERRS::FatalException& e)
 97        {
 98            threw = e.what();
 99        }
100        ensure_contains("threw exception", threw, "missing params");
101        ensure_contains("identified missing", threw, "method");
102        ensure_contains("identified missing", threw, "reply");
103    }
104
105    template<> template<>
106    void object::test<2>()
107    {
108        set_test_name("param types validation");
109        WrapLL_ERRS capture;
110        LLSD request;
111        request["uri"] = uri;
112        request["method"] = "hello";
113        request["reply"] = "reply";
114        LLSD& params(request["params"]);
115        params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params
116        std::string threw;
117        try
118        {
119            pumps.obtain("LLXMLRPCTransaction").post(request);
120        }
121        catch (const WrapLL_ERRS::FatalException& e)
122        {
123            threw = e.what();
124        }
125        ensure_contains("threw exception", threw, "unknown type");
126    }
127
128    template<> template<>
129    void object::test<3>()
130    {
131        set_test_name("success case");
132        LLSD request;
133        request["uri"] = uri;
134        request["method"] = "hello";
135        request["reply"] = "reply";
136        LLSD& params(request["params"]);
137        params["who"] = "world";
138        // Set up a timeout filter so we don't spin forever waiting.
139        LLEventTimeout watchdog;
140        // Connect the timeout filter to the reply pump.
141        LLTempBoundListener temp(
142            pumps.obtain("reply").
143            listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
144        // Now connect our target listener to the timeout filter.
145        watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
146        // Kick off the request...
147        reply.clear();
148        pumps.obtain("LLXMLRPCTransaction").post(request);
149        // Set the timer
150        F32 timeout(10);
151        watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
152        // and pump "mainloop" until we get something, whether from
153        // LLXMLRPCListener or from the watchdog filter.
154        LLTimer timer;
155        F32 start = timer.getElapsedTimeF32();
156        LLEventPump& mainloop(pumps.obtain("mainloop"));
157        while (reply.isUndefined())
158        {
159            mainloop.post(LLSD());
160        }
161        ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
162        ensure_equals(reply["responses"]["hi_there"].asString(), "Hello, world!");
163    }
164
165    template<> template<>
166    void object::test<4>()
167    {
168        set_test_name("bogus method");
169        LLSD request;
170        request["uri"] = uri;
171        request["method"] = "goodbye";
172        request["reply"] = "reply";
173        LLSD& params(request["params"]);
174        params["who"] = "world";
175        // Set up a timeout filter so we don't spin forever waiting.
176        LLEventTimeout watchdog;
177        // Connect the timeout filter to the reply pump.
178        LLTempBoundListener temp(
179            pumps.obtain("reply").
180            listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
181        // Now connect our target listener to the timeout filter.
182        watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
183        // Kick off the request...
184        reply.clear();
185        pumps.obtain("LLXMLRPCTransaction").post(request);
186        // Set the timer
187        F32 timeout(10);
188        watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
189        // and pump "mainloop" until we get something, whether from
190        // LLXMLRPCListener or from the watchdog filter.
191        LLTimer timer;
192        F32 start = timer.getElapsedTimeF32();
193        LLEventPump& mainloop(pumps.obtain("mainloop"));
194        while (reply.isUndefined())
195        {
196            mainloop.post(LLSD());
197        }
198        ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
199        ensure_equals("XMLRPC error", reply["status"].asString(), "XMLRPCError");
200    }
201
202    template<> template<>
203    void object::test<5>()
204    {
205        set_test_name("bad type");
206        LLSD request;
207        request["uri"] = uri;
208        request["method"] = "getdict";
209        request["reply"] = "reply";
210        (void)request["params"];
211        // Set up a timeout filter so we don't spin forever waiting.
212        LLEventTimeout watchdog;
213        // Connect the timeout filter to the reply pump.
214        LLTempBoundListener temp(
215            pumps.obtain("reply").
216            listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
217        // Now connect our target listener to the timeout filter.
218        watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
219        // Kick off the request...
220        reply.clear();
221        pumps.obtain("LLXMLRPCTransaction").post(request);
222        // Set the timer
223        F32 timeout(10);
224        watchdog.eventAfter(timeout, LLSD().with("timeout", 0));
225        // and pump "mainloop" until we get something, whether from
226        // LLXMLRPCListener or from the watchdog filter.
227        LLTimer timer;
228        F32 start = timer.getElapsedTimeF32();
229        LLEventPump& mainloop(pumps.obtain("mainloop"));
230        while (reply.isUndefined())
231        {
232            mainloop.post(LLSD());
233        }
234        ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
235        ensure_equals(reply["status"].asString(), "BadType");
236        ensure_contains("bad type", reply["responses"]["nested_dict"].asString(), "bad XMLRPC type");
237    }
238} // namespace tut
239
240/*****************************************************************************
241*   Resolve link errors: use real machinery here, since we intend to exchange
242*   actual XML with a peer process.
243*****************************************************************************/
244// Including llxmlrpctransaction.cpp drags in the static LLXMLRPCListener
245// instantiated there. That's why it works to post requests to the LLEventPump
246// named "LLXMLRPCTransaction".
247#include "../llxmlrpctransaction.cpp"
248#include "llcontrol.cpp"
249#include "llxmltree.cpp"
250#include "llxmlparser.cpp"