// multiple recorders void ErrorTestObject::test<11>() { TestRecorder altRecorder; LLError::addRecorder(&altRecorder); llinfos << "boo" << llendl; ensure_message_contains(0, "boo"); ensure_equals("alt recorder count", altRecorder.countMessages(), 1); ensure_contains("alt recorder message 0", altRecorder.message(0), "boo"); LLError::setTimeFunction(roswell); TestRecorder anotherRecorder; anotherRecorder.setWantsTime(true); LLError::addRecorder(&anotherRecorder); llinfos << "baz" << llendl; std::string when = roswell(); ensure_message_does_not_contain(1, when); ensure_equals("alt recorder count", altRecorder.countMessages(), 2); ensure_does_not_contain("alt recorder message 1", altRecorder.message(1), when); ensure_equals("another recorder count", anotherRecorder.countMessages(), 1); ensure_contains("another recorder message 0", anotherRecorder.message(0), when); }
void object::test<5>() { set_test_name("bad type"); LLSD request; request["uri"] = uri; request["method"] = "getdict"; request["reply"] = "reply"; (void)request["params"]; // Set up a timeout filter so we don't spin forever waiting. LLEventTimeout watchdog; // Connect the timeout filter to the reply pump. LLTempBoundListener temp( pumps.obtain("reply"). listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1))); // Now connect our target listener to the timeout filter. watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1)); // Kick off the request... reply.clear(); pumps.obtain("LLXMLRPCTransaction").post(request); // Set the timer F32 timeout(10); watchdog.eventAfter(timeout, LLSD().insert("timeout", 0)); // and pump "mainloop" until we get something, whether from // LLXMLRPCListener or from the watchdog filter. LLTimer timer; F32 start = timer.getElapsedTimeF32(); LLEventPump& mainloop(pumps.obtain("mainloop")); while (reply.isUndefined()) { mainloop.post(LLSD()); } ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1)); ensure_equals(reply["status"].asString(), "BadType"); ensure_contains("bad type", reply["responses"]["nested_dict"].asString(), "bad XMLRPC type"); }
void ensure_message_contains(int n, const std::string& expectedText) { std::ostringstream test_name; test_name << "testing message " << n; ensure_contains(test_name.str(), mRecorder.message(n), expectedText); }
void HTTPServiceTestObject::test<1>() { std::string result = httpGET("web/hello"); ensure_starts_with("web/hello status", result, "HTTP/1.0 200 OK\r\n"); ensure_contains("web/hello content type", result, "Content-Type: application/llsd+xml\r\n"); ensure_contains("web/hello content length", result, "Content-Length: 36\r\n"); ensure_contains("web/hello content", result, "\r\n" "<llsd><string>hello</string></llsd>" ); }
void HTTPServiceTestObject::test<4>() { // test calling things based on pipes std::string result; result = httpGET("wire/hello"); ensure_contains("wire/hello", result, "yo!"); }
void object::test<1>() { set_test_name("request validation"); WrapLL_ERRS capture; LLSD request; request["uri"] = uri; std::string threw; try { pumps.obtain("LLXMLRPCTransaction").post(request); } catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } ensure_contains("threw exception", threw, "missing params"); ensure_contains("identified missing", threw, "method"); ensure_contains("identified missing", threw, "reply"); }
void HTTPClientTestObject::test<5>() { LLSD sd; sd["status"] = 543; sd["reason"] = "error for testing"; setupTheServer(); LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult()); runThePump(); ensureStatusError(); ensure_contains("reason", mReason, sd["reason"]); }
void HTTPServiceTestObject::test<8>() { // test the OPTIONS http method -- the default implementation // should return the X-Documentation-URL std::ostringstream http_request; http_request << "OPTIONS / HTTP/1.0\r\nHost: localhost\r\n\r\n"; bool timeout = false; std::string result = makeRequest("/", http_request.str(), timeout); ensure_starts_with("OPTIONS verb ok", result, "HTTP/1.0 200 OK\r\n"); ensure_contains( "Doc url header exists", result, "X-Documentation-URL: http://localhost"); }
void llcapears_object::test<5>() { TestMapper testMapper; std::string threw; try { TestMapper testMapper2; } catch (const std::runtime_error& e) { threw = e.what(); } ensure_contains("no dup cap mapper", threw, "DupCapMapper"); }
void lllazy_object::test<2>() { TestNeedsTesting tnt; std::string threw; try { tnt.toolate(); } catch (const LLLazyCommon::InstanceChange& e) { threw = e.what(); } ensure_contains("InstanceChange exception", threw, "replace LLLazy instance"); }
void HTTPServiceTestObject::test<3>() { // test POST & content-length handling std::string result; result = httpPOST("web/echo", "<llsd><integer>42</integer></llsd>"); ensure_starts_with("web/echo status", result, "HTTP/1.0 200 OK\r\n"); ensure_contains("web/echo content type", result, "Content-Type: application/llsd+xml\r\n"); ensure_contains("web/echo content length", result, "Content-Length: 35\r\n"); ensure_contains("web/hello content", result, "\r\n" "<llsd><integer>42</integer></llsd>" ); /* TO DO: this test doesn't pass!! result = httpPOST("web/echo", "<llsd><string>evil</string></llsd>", "really! evil!!!"); ensure_equals("web/echo evil result", result, "HTTP/1.0 200 OK\r\n" "Content-Length: 34\r\n" "\r\n" "<llsd><string>evil</string></llsd>" ); */ }
void HTTPServiceTestObject::test<6>() { // test delayed service std::string result; result = httpPOST("delayed/echo", "<llsd><string>agent99</string></llsd>"); ensure_starts_with("delayed/echo status", result, "HTTP/1.0 200 OK\r\n"); ensure_contains("delayed/echo content", result, "\r\n" "<llsd><string>agent99</string></llsd>" ); }
void filter_object::test<4>() { set_test_name("LLEventTimeout::errorAfter()"); WrapLLErrs capture; LLEventPump& driver(pumps.obtain("driver")); TestEventTimeout filter(driver); listener0.reset(0); LLTempBoundListener temp1( listener0.listenTo(filter)); filter.errorAfter(20, "timeout"); // Okay, (fake) timer is ticking. 'filter' can only sense the timer // when we pump mainloop. Do that right now to take the logic path // before either the anticipated event arrives or the timer expires. mainloop.post(17); check_listener("no timeout 1", listener0, LLSD(0)); // Expected event arrives... driver.post(1); check_listener("event passed thru", listener0, LLSD(1)); // Should have canceled the timer. Verify that by asserting that the // time has expired, then pumping mainloop again. filter.forceTimeout(); mainloop.post(17); check_listener("no timeout 2", listener0, LLSD(1)); // Set timer again. filter.errorAfter(20, "timeout"); // Now let the timer expire. filter.forceTimeout(); // Notice the timeout. std::string threw; try { mainloop.post(17); } catch (const WrapLLErrs::FatalException& e) { threw = e.what(); } ensure_contains("errorAfter() timeout exception", threw, "timeout"); // Timing out cancels the timer. Verify that. listener0.reset(0); filter.forceTimeout(); mainloop.post(17); check_listener("no timeout 3", listener0, LLSD(0)); }
void llcapears_object::test<1>() { LLSD request, body; body["data"] = "yes"; request["payload"] = body; request["reply"] = replyPump.getName(); request["error"] = errorPump.getName(); std::string threw; try { WrapLL_ERRS capture; regionPump.post(request); } catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } ensure_contains("missing capability name", threw, "without 'message' key"); }
void llcapears_object::test<4>() { TestMapper testMapper("WantReply"); LLSD request, body; body["data"] = "yes"; request["message"] = "test"; request["payload"] = body; request["reply"] = replyPump.getName(); request["error"] = errorPump.getName(); std::string threw; try { WrapLL_ERRS capture; regionPump.post(request); } catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } ensure_contains("capability mapper wants reply", threw, "unimplemented support for reply message"); }
void object::test<2>() { set_test_name("param types validation"); WrapLL_ERRS capture; LLSD request; request["uri"] = uri; request["method"] = "hello"; request["reply"] = "reply"; LLSD& params(request["params"]); params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params std::string threw; try { pumps.obtain("LLXMLRPCTransaction").post(request); } catch (const WrapLL_ERRS::FatalException& e) { threw = e.what(); } ensure_contains("threw exception", threw, "unknown type"); }
void llsdutil_object::test<9>() { set_test_name("llsd_matches"); // for this test, construct a map of all possible LLSD types LLSD map; map.insert("empty", LLSD()); map.insert("Boolean", LLSD::Boolean()); map.insert("Integer", LLSD::Integer(0)); map.insert("Real", LLSD::Real(0.0)); map.insert("String", LLSD::String("bah")); map.insert("NumString", LLSD::String("1")); map.insert("UUID", LLSD::UUID()); map.insert("Date", LLSD::Date()); map.insert("URI", LLSD::URI()); map.insert("Binary", LLSD::Binary()); map.insert("Map", LLSD().with("foo", LLSD())); // Only an empty array can be constructed on the fly LLSD array; array.append(LLSD()); map.insert("Array", array); // These iterators are declared outside our various for loops to avoid // fatal MSVC warning: "I used to be broken, but I'm all better now!" LLSD::map_const_iterator mi, mend(map.endMap()); /*-------------------------- llsd_matches --------------------------*/ // empty prototype matches anything for (mi = map.beginMap(); mi != mend; ++mi) { ensure_equals(std::string("empty matches ") + mi->first, llsd_matches(LLSD(), mi->second), ""); } LLSD proto_array, data_array; for (int i = 0; i < 3; ++i) { proto_array.append(LLSD()); data_array.append(LLSD()); } // prototype array matches only array for (mi = map.beginMap(); mi != mend; ++mi) { ensure(std::string("array doesn't match ") + mi->first, ! llsd_matches(proto_array, mi->second).empty()); } // data array must be at least as long as prototype array proto_array.append(LLSD()); ensure_equals("data array too short", llsd_matches(proto_array, data_array), "Array size 4 required instead of Array size 3"); data_array.append(LLSD()); ensure_equals("data array just right", llsd_matches(proto_array, data_array), ""); data_array.append(LLSD()); ensure_equals("data array longer", llsd_matches(proto_array, data_array), ""); // array element matching data_array[0] = LLSD::String(); ensure_equals("undefined prototype array entry", llsd_matches(proto_array, data_array), ""); proto_array[0] = LLSD::Binary(); ensure_equals("scalar prototype array entry", llsd_matches(proto_array, data_array), "[0]: Binary required instead of String"); data_array[0] = LLSD::Binary(); ensure_equals("matching prototype array entry", llsd_matches(proto_array, data_array), ""); // build a coupla maps LLSD proto_map, data_map; data_map["got"] = LLSD(); data_map["found"] = LLSD(); for (LLSD::map_const_iterator dmi(data_map.beginMap()), dmend(data_map.endMap()); dmi != dmend; ++dmi) { proto_map[dmi->first] = dmi->second; } proto_map["foo"] = LLSD(); proto_map["bar"] = LLSD(); // prototype map matches only map for (mi = map.beginMap(); mi != mend; ++mi) { ensure(std::string("map doesn't match ") + mi->first, ! llsd_matches(proto_map, mi->second).empty()); } // data map must contain all keys in prototype map std::string error(llsd_matches(proto_map, data_map)); ensure_contains("missing keys", error, "missing keys"); ensure_contains("missing foo", error, "foo"); ensure_contains("missing bar", error, "bar"); ensure_does_not_contain("found found", error, "found"); ensure_does_not_contain("got got", error, "got"); data_map["bar"] = LLSD(); error = llsd_matches(proto_map, data_map); ensure_contains("missing foo", error, "foo"); ensure_does_not_contain("got bar", error, "bar"); data_map["foo"] = LLSD(); ensure_equals("data map just right", llsd_matches(proto_map, data_map), ""); data_map["extra"] = LLSD(); ensure_equals("data map with extra", llsd_matches(proto_map, data_map), ""); // map element matching data_map["foo"] = LLSD::String(); ensure_equals("undefined prototype map entry", llsd_matches(proto_map, data_map), ""); proto_map["foo"] = LLSD::Binary(); ensure_equals("scalar prototype map entry", llsd_matches(proto_map, data_map), "['foo']: Binary required instead of String"); data_map["foo"] = LLSD::Binary(); ensure_equals("matching prototype map entry", llsd_matches(proto_map, data_map), ""); // String { static const char* matches[] = { "String", "NumString", "Boolean", "Integer", "Real", "UUID", "Date", "URI" }; test_matches("String", map, boost::begin(matches), boost::end(matches)); } // Boolean, Integer, Real static const char* numerics[] = { "Boolean", "Integer", "Real" }; for (const char **ni = boost::begin(numerics), **nend = boost::end(numerics); ni != nend; ++ni) { static const char* matches[] = { "Boolean", "Integer", "Real", "String", "NumString" }; test_matches(*ni, map, boost::begin(matches), boost::end(matches)); } // UUID { static const char* matches[] = { "UUID", "String", "NumString" }; test_matches("UUID", map, boost::begin(matches), boost::end(matches)); } // Date { static const char* matches[] = { "Date", "String", "NumString" }; test_matches("Date", map, boost::begin(matches), boost::end(matches)); } // URI { static const char* matches[] = { "URI", "String", "NumString" }; test_matches("URI", map, boost::begin(matches), boost::end(matches)); } // Binary { static const char* matches[] = { "Binary" }; test_matches("Binary", map, boost::begin(matches), boost::end(matches)); } /*-------------------------- llsd_equals ---------------------------*/ // Cross-product of each LLSD type with every other for (LLSD::map_const_iterator lmi(map.beginMap()), lmend(map.endMap()); lmi != lmend; ++lmi) { for (LLSD::map_const_iterator rmi(map.beginMap()), rmend(map.endMap()); rmi != rmend; ++rmi) { // Name this test based on the map keys naming the types of // interest, e.g "String::Integer". // We expect the values (xmi->second) to be equal if and only // if the type names (xmi->first) are equal. ensure(STRINGIZE(lmi->first << "::" << rmi->first), bool(lmi->first == rmi->first) == bool(llsd_equals(lmi->second, rmi->second))); } } // Array cases LLSD rarray; rarray.append(1.0); rarray.append(2); rarray.append("3"); LLSD larray(rarray); ensure("llsd_equals(equal arrays)", llsd_equals(larray, rarray)); rarray[2] = "4"; ensure("llsd_equals(different [2])", ! llsd_equals(larray, rarray)); rarray = larray; rarray.append(LLSD::Date()); ensure("llsd_equals(longer right array)", ! llsd_equals(larray, rarray)); rarray = larray; rarray.erase(2); ensure("llsd_equals(shorter right array)", ! llsd_equals(larray, rarray)); // Map cases LLSD rmap; rmap["San Francisco"] = 65; rmap["Phoenix"] = 92; rmap["Boston"] = 77; LLSD lmap(rmap); ensure("llsd_equals(equal maps)", llsd_equals(lmap, rmap)); rmap["Boston"] = 80; ensure("llsd_equals(different [\"Boston\"])", ! llsd_equals(lmap, rmap)); rmap = lmap; rmap["Atlanta"] = 95; ensure("llsd_equals(superset right map)", ! llsd_equals(lmap, rmap)); rmap = lmap; lmap["Seattle"] = 72; ensure("llsd_equals(superset left map)", ! llsd_equals(lmap, rmap)); }