diff options
author | Adam Moss <moss@lindenlab.com> | 2009-10-12 14:13:57 +0000 |
---|---|---|
committer | Adam Moss <moss@lindenlab.com> | 2009-10-12 14:13:57 +0000 |
commit | b73e71ebdf4366b11d3fd43ac80e2a3dc7f30cb2 (patch) | |
tree | f447575edf2aded5a7c0f8ffdd7cba870b11ac3d /indra | |
parent | 276e80ce367dd89d7f3b2882ff669d6b59b78c0c (diff) |
DEV-41174 more automated testing love
* turn llnamevalue_tut into a llmessage unit test
* turn llsdserialize_tut into a llcommon integration test
* re-enable the (quite slow) llsdserialize test on win32 now that it doesn't have to run on every recompile
* re-enable all llmessage unit tests on linux viewer builds
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 5 | ||||
-rw-r--r-- | indra/llcommon/tests/llsdserialize_test.cpp | 1432 | ||||
-rw-r--r-- | indra/llmessage/CMakeLists.txt | 60 | ||||
-rw-r--r-- | indra/llmessage/tests/llnamevalue_test.cpp | 412 | ||||
-rw-r--r-- | indra/test/CMakeLists.txt | 2 |
5 files changed, 1875 insertions, 36 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 371786c44d..0861783df1 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -241,9 +241,10 @@ LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}") #set(TEST_DEBUG on) set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) -LL_ADD_INTEGRATION_TEST(lllazy lllazy.cpp "${test_libs}") -LL_ADD_INTEGRATION_TEST(llstring "llstring.cpp" "${test_libs}") +LL_ADD_INTEGRATION_TEST(lllazy "lllazy.cpp" "${test_libs}") LL_ADD_INTEGRATION_TEST(llrand "llrand.cpp" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llsdserialize "llsdserialize.cpp" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llstring "llstring.cpp" "${test_libs}") # *TODO - reenable these once tcmalloc libs no longer break the build. #ADD_BUILD_TEST(llallocator llcommon) diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp new file mode 100644 index 0000000000..662b599c55 --- /dev/null +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -0,0 +1,1432 @@ +/** + * @file llsdserialize_tut.cpp + * @date 2006-04 + * @brief LLSDSerialize unit tests + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if !LL_WINDOWS +#include <netinet/in.h> +#endif + +#include "linden_common.h" +#include "../llsd.h" +#include "../llsdserialize.h" +#include "../llformat.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +#include <winsock2.h> +typedef U32 uint32_t; +#endif + +namespace tut +{ + struct sd_xml_data + { + sd_xml_data() + { + mFormatter = new LLSDXMLFormatter; + } + LLSD mSD; + LLPointer<LLSDXMLFormatter> mFormatter; + void xml_test(const char* name, const std::string& expected) + { + std::ostringstream ostr; + mFormatter->format(mSD, ostr); + ensure_equals(name, ostr.str(), expected); + } + }; + + typedef test_group<sd_xml_data> sd_xml_test; + typedef sd_xml_test::object sd_xml_object; + tut::sd_xml_test sd_xml_stream("sd_xml_serialization"); + + template<> template<> + void sd_xml_object::test<1>() + { + // random atomic tests + std::string expected; + + expected = "<llsd><undef /></llsd>\n"; + xml_test("undef", expected); + + mSD = 3463; + expected = "<llsd><integer>3463</integer></llsd>\n"; + xml_test("integer", expected); + + mSD = ""; + expected = "<llsd><string /></llsd>\n"; + xml_test("empty string", expected); + + mSD = "foobar"; + expected = "<llsd><string>foobar</string></llsd>\n"; + xml_test("string", expected); + + mSD = LLUUID::null; + expected = "<llsd><uuid /></llsd>\n"; + xml_test("null uuid", expected); + + mSD = LLUUID("c96f9b1e-f589-4100-9774-d98643ce0bed"); + expected = "<llsd><uuid>c96f9b1e-f589-4100-9774-d98643ce0bed</uuid></llsd>\n"; + xml_test("uuid", expected); + + mSD = LLURI("https://secondlife.com/login"); + expected = "<llsd><uri>https://secondlife.com/login</uri></llsd>\n"; + xml_test("uri", expected); + + mSD = LLDate("2006-04-24T16:11:33Z"); + expected = "<llsd><date>2006-04-24T16:11:33Z</date></llsd>\n"; + xml_test("date", expected); + + // *FIX: test binary + } + + template<> template<> + void sd_xml_object::test<2>() + { + // tests with boolean values. + std::string expected; + + mFormatter->boolalpha(true); + mSD = true; + expected = "<llsd><boolean>true</boolean></llsd>\n"; + xml_test("bool alpha true", expected); + mSD = false; + expected = "<llsd><boolean>false</boolean></llsd>\n"; + xml_test("bool alpha false", expected); + + mFormatter->boolalpha(false); + mSD = true; + expected = "<llsd><boolean>1</boolean></llsd>\n"; + xml_test("bool true", expected); + mSD = false; + expected = "<llsd><boolean>0</boolean></llsd>\n"; + xml_test("bool false", expected); + } + + + template<> template<> + void sd_xml_object::test<3>() + { + // tests with real values. + std::string expected; + + mFormatter->realFormat("%.2f"); + mSD = 1.0; + expected = "<llsd><real>1.00</real></llsd>\n"; + xml_test("real 1", expected); + + mSD = -34379.0438; + expected = "<llsd><real>-34379.04</real></llsd>\n"; + xml_test("real reduced precision", expected); + mFormatter->realFormat("%.4f"); + expected = "<llsd><real>-34379.0438</real></llsd>\n"; + xml_test("higher precision", expected); + + mFormatter->realFormat("%.0f"); + mSD = 0.0; + expected = "<llsd><real>0</real></llsd>\n"; + xml_test("no decimal 0", expected); + mSD = 3287.4387; + expected = "<llsd><real>3287</real></llsd>\n"; + xml_test("no decimal real number", expected); + } + + template<> template<> + void sd_xml_object::test<4>() + { + // tests with arrays + std::string expected; + + mSD = LLSD::emptyArray(); + expected = "<llsd><array /></llsd>\n"; + xml_test("empty array", expected); + + mSD.append(LLSD()); + expected = "<llsd><array><undef /></array></llsd>\n"; + xml_test("1 element array", expected); + + mSD.append(1); + expected = "<llsd><array><undef /><integer>1</integer></array></llsd>\n"; + xml_test("2 element array", expected); + } + + template<> template<> + void sd_xml_object::test<5>() + { + // tests with arrays + std::string expected; + + mSD = LLSD::emptyMap(); + expected = "<llsd><map /></llsd>\n"; + xml_test("empty map", expected); + + mSD["foo"] = "bar"; + expected = "<llsd><map><key>foo</key><string>bar</string></map></llsd>\n"; + xml_test("1 element map", expected); + + mSD["baz"] = LLSD(); + expected = "<llsd><map><key>baz</key><undef /><key>foo</key><string>bar</string></map></llsd>\n"; + xml_test("2 element map", expected); + } + + + class TestLLSDSerializeData + { + public: + TestLLSDSerializeData(); + ~TestLLSDSerializeData(); + + void doRoundTripTests(const std::string&); + void checkRoundTrip(const std::string&, const LLSD& v); + + LLPointer<LLSDFormatter> mFormatter; + LLPointer<LLSDParser> mParser; + }; + + TestLLSDSerializeData::TestLLSDSerializeData() + { + } + + TestLLSDSerializeData::~TestLLSDSerializeData() + { + } + + void TestLLSDSerializeData::checkRoundTrip(const std::string& msg, const LLSD& v) + { + std::stringstream stream; + mFormatter->format(v, stream); + //llinfos << "checkRoundTrip: length " << stream.str().length() << llendl; + LLSD w; + mParser->reset(); // reset() call is needed since test code re-uses mParser + mParser->parse(stream, w, stream.str().size()); + + try + { + ensure_equals(msg.c_str(), w, v); + } + catch (...) + { + std::cerr << "the serialized string was:" << std::endl; + std::cerr << stream.str() << std::endl; + throw; + } + } + + static void fillmap(LLSD& root, U32 width, U32 depth) + { + if(depth == 0) + { + root["foo"] = "bar"; + return; + } + + for(U32 i = 0; i < width; ++i) + { + std::string key = llformat("child %d", i); + root[key] = LLSD::emptyMap(); + fillmap(root[key], width, depth - 1); + } + } + + void TestLLSDSerializeData::doRoundTripTests(const std::string& msg) + { + LLSD v; + checkRoundTrip(msg + " undefined", v); + + v = true; + checkRoundTrip(msg + " true bool", v); + + v = false; + checkRoundTrip(msg + " false bool", v); + + v = 1; + checkRoundTrip(msg + " positive int", v); + + v = 0; + checkRoundTrip(msg + " zero int", v); + + v = -1; + checkRoundTrip(msg + " negative int", v); + + v = 1234.5f; + checkRoundTrip(msg + " positive float", v); + + v = 0.0f; + checkRoundTrip(msg + " zero float", v); + + v = -1234.5f; + checkRoundTrip(msg + " negative float", v); + + // FIXME: need a NaN test + + v = LLUUID::null; + checkRoundTrip(msg + " null uuid", v); + + LLUUID newUUID; + newUUID.generate(); + v = newUUID; + checkRoundTrip(msg + " new uuid", v); + + v = ""; + checkRoundTrip(msg + " empty string", v); + + v = "some string"; + checkRoundTrip(msg + " non-empty string", v); + + v = +"Second Life is a 3-D virtual world entirely built and owned by its residents. " +"Since opening to the public in 2003, it has grown explosively and today is " +"inhabited by nearly 100,000 people from around the globe.\n" +"\n" +"From the moment you enter the World you'll discover a vast digital continent, " +"teeming with people, entertainment, experiences and opportunity. Once you've " +"explored a bit, perhaps you'll find a perfect parcel of land to build your " +"house or business.\n" +"\n" +"You'll also be surrounded by the Creations of your fellow residents. Because " +"residents retain the rights to their digital creations, they can buy, sell " +"and trade with other residents.\n" +"\n" +"The Marketplace currently supports millions of US dollars in monthly " +"transactions. This commerce is handled with the in-world currency, the Linden " +"dollar, which can be converted to US dollars at several thriving online " +"currency exchanges.\n" +"\n" +"Welcome to Second Life. We look forward to seeing you in-world!\n" + ; + checkRoundTrip(msg + " long string", v); + + static const U32 block_size = 0x000020; + for (U32 block = 0x000000; block <= 0x10ffff; block += block_size) + { + std::ostringstream out; + + for (U32 c = block; c < block + block_size; ++c) + { + if (c <= 0x000001f + && c != 0x000009 + && c != 0x00000a) + { + // see XML standard, sections 2.2 and 4.1 + continue; + } + if (0x00d800 <= c && c <= 0x00dfff) { continue; } + if (0x00fdd0 <= c && c <= 0x00fdef) { continue; } + if ((c & 0x00fffe) == 0x00fffe) { continue; } + // see Unicode standard, section 15.8 + + if (c <= 0x00007f) + { + out << (char)(c & 0x7f); + } + else if (c <= 0x0007ff) + { + out << (char)(0xc0 | ((c >> 6) & 0x1f)); + out << (char)(0x80 | ((c >> 0) & 0x3f)); + } + else if (c <= 0x00ffff) + { + out << (char)(0xe0 | ((c >> 12) & 0x0f)); + out << (char)(0x80 | ((c >> 6) & 0x3f)); + out << (char)(0x80 | ((c >> 0) & 0x3f)); + } + else + { + out << (char)(0xf0 | ((c >> 18) & 0x07)); + out << (char)(0x80 | ((c >> 12) & 0x3f)); + out << (char)(0x80 | ((c >> 6) & 0x3f)); + out << (char)(0x80 | ((c >> 0) & 0x3f)); + } + } + + v = out.str(); + + std::ostringstream blockmsg; + blockmsg << msg << " unicode string block 0x" << std::hex << block; + checkRoundTrip(blockmsg.str(), v); + } + + LLDate epoch; + v = epoch; + checkRoundTrip(msg + " epoch date", v); + + LLDate aDay("2002-12-07T05:07:15.00Z"); + v = aDay; + checkRoundTrip(msg + " date", v); + + LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); + v = path; + checkRoundTrip(msg + " url", v); + + const char source[] = "it must be a blue moon again"; + std::vector<U8> data; + copy(&source[0], &source[sizeof(source)], back_inserter(data)); + + v = data; + checkRoundTrip(msg + " binary", v); + + v = LLSD::emptyMap(); + checkRoundTrip(msg + " empty map", v); + + v = LLSD::emptyMap(); + v["name"] = "luke"; //v.insert("name", "luke"); + v["age"] = 3; //v.insert("age", 3); + checkRoundTrip(msg + " map", v); + + v.clear(); + v["a"]["1"] = true; + v["b"]["0"] = false; + checkRoundTrip(msg + " nested maps", v); + + v = LLSD::emptyArray(); + checkRoundTrip(msg + " empty array", v); + + v = LLSD::emptyArray(); + v.append("ali"); + v.append(28); + checkRoundTrip(msg + " array", v); + + v.clear(); + v[0][0] = true; + v[1][0] = false; + checkRoundTrip(msg + " nested arrays", v); + + v = LLSD::emptyMap(); + fillmap(v, 10, 6); // 10^6 maps + checkRoundTrip(msg + " many nested maps", v); + } + + typedef tut::test_group<TestLLSDSerializeData> TestLLSDSerialzeGroup; + typedef TestLLSDSerialzeGroup::object TestLLSDSerializeObject; + TestLLSDSerialzeGroup gTestLLSDSerializeGroup("llsd serialization"); + + template<> template<> + void TestLLSDSerializeObject::test<1>() + { + mFormatter = new LLSDNotationFormatter(); + mParser = new LLSDNotationParser(); + doRoundTripTests("notation serialization"); + } + + template<> template<> + void TestLLSDSerializeObject::test<2>() + { + mFormatter = new LLSDXMLFormatter(); + mParser = new LLSDXMLParser(); + doRoundTripTests("xml serialization"); + } + + template<> template<> + void TestLLSDSerializeObject::test<3>() + { + mFormatter = new LLSDBinaryFormatter(); + mParser = new LLSDBinaryParser(); + doRoundTripTests("binary serialization"); + } + + + /** + * @class TestLLSDParsing + * @brief Base class for of a parse tester. + */ + template <class parser_t> + class TestLLSDParsing + { + public: + TestLLSDParsing() + { + mParser = new parser_t; + } + + void ensureParse( + const std::string& msg, + const std::string& in, + const LLSD& expected_value, + S32 expected_count) + { + std::stringstream input; + input.str(in); + + LLSD parsed_result; + mParser->reset(); // reset() call is needed since test code re-uses mParser + S32 parsed_count = mParser->parse(input, parsed_result, in.size()); + ensure_equals(msg.c_str(), parsed_result, expected_value); + + // This count check is really only useful for expected + // parse failures, since the ensures equal will already + // require eqality. + std::string count_msg(msg); + count_msg += " (count)"; + ensure_equals(count_msg, parsed_count, expected_count); + } + + LLPointer<parser_t> mParser; + }; + + + /** + * @class TestLLSDXMLParsing + * @brief Concrete instance of a parse tester. + */ + class TestLLSDXMLParsing : public TestLLSDParsing<LLSDXMLParser> + { + public: + TestLLSDXMLParsing() {} + }; + + typedef tut::test_group<TestLLSDXMLParsing> TestLLSDXMLParsingGroup; + typedef TestLLSDXMLParsingGroup::object TestLLSDXMLParsingObject; + TestLLSDXMLParsingGroup gTestLLSDXMLParsingGroup("llsd XML parsing"); + + template<> template<> + void TestLLSDXMLParsingObject::test<1>() + { + // test handling of xml not recognized as llsd results in an + // LLSD Undefined + ensureParse( + "malformed xml", + "<llsd><string>ha ha</string>", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "not llsd", + "<html><body><p>ha ha</p></body></html>", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "value without llsd", + "<string>ha ha</string>", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "key without llsd", + "<key>ha ha</key>", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + + template<> template<> + void TestLLSDXMLParsingObject::test<2>() + { + // test handling of unrecognized or unparseable llsd values + LLSD v; + v["amy"] = 23; + v["bob"] = LLSD(); + v["cam"] = 1.23; + + ensureParse( + "unknown data type", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<key>bob</key><bigint>99999999999999999</bigint>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + } + + template<> template<> + void TestLLSDXMLParsingObject::test<3>() + { + // test handling of nested bad data + + LLSD v; + v["amy"] = 23; + v["cam"] = 1.23; + + ensureParse( + "map with html", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<html><body>ha ha</body></html>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + + v.clear(); + v["amy"] = 23; + v["cam"] = 1.23; + ensureParse( + "map with value for key", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<string>ha ha</string>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + + v.clear(); + v["amy"] = 23; + v["bob"] = LLSD::emptyMap(); + v["cam"] = 1.23; + ensureParse( + "map with map of html", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<key>bob</key>" + "<map>" + "<html><body>ha ha</body></html>" + "</map>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + + v.clear(); + v[0] = 23; + v[1] = LLSD(); + v[2] = 1.23; + + ensureParse( + "array value of html", + "<llsd><array>" + "<integer>23</integer>" + "<html><body>ha ha</body></html>" + "<real>1.23</real>" + "</array></llsd>", + v, + v.size() + 1); + + v.clear(); + v[0] = 23; + v[1] = LLSD::emptyMap(); + v[2] = 1.23; + ensureParse( + "array with map of html", + "<llsd><array>" + "<integer>23</integer>" + "<map>" + "<html><body>ha ha</body></html>" + "</map>" + "<real>1.23</real>" + "</array></llsd>", + v, + v.size() + 1); + } + + /* + TODO: + test XML parsing + binary with unrecognized encoding + nested LLSD tags + multiple values inside an LLSD + */ + + + /** + * @class TestLLSDNotationParsing + * @brief Concrete instance of a parse tester. + */ + class TestLLSDNotationParsing : public TestLLSDParsing<LLSDNotationParser> + { + public: + TestLLSDNotationParsing() {} + }; + + typedef tut::test_group<TestLLSDNotationParsing> TestLLSDNotationParsingGroup; + typedef TestLLSDNotationParsingGroup::object TestLLSDNotationParsingObject; + TestLLSDNotationParsingGroup gTestLLSDNotationParsingGroup( + "llsd notation parsing"); + + template<> template<> + void TestLLSDNotationParsingObject::test<1>() + { + // test handling of xml not recognized as llsd results in an + // LLSD Undefined + ensureParse( + "malformed notation map", + "{'ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed notation array", + "['ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed notation string", + "'ha ha", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "bad notation noise", + "g48ejlnfr", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<2>() + { + ensureParse("valid undef", "!", LLSD(), 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<3>() + { + LLSD val = false; + ensureParse("valid boolean false 0", "false", val, 1); + ensureParse("valid boolean false 1", "f", val, 1); + ensureParse("valid boolean false 2", "0", val, 1); + ensureParse("valid boolean false 3", "F", val, 1); + ensureParse("valid boolean false 4", "FALSE", val, 1); + val = true; + ensureParse("valid boolean true 0", "true", val, 1); + ensureParse("valid boolean true 1", "t", val, 1); + ensureParse("valid boolean true 2", "1", val, 1); + ensureParse("valid boolean true 3", "T", val, 1); + ensureParse("valid boolean true 4", "TRUE", val, 1); + + val.clear(); + ensureParse("invalid true", "TR", val, LLSDParser::PARSE_FAILURE); + ensureParse("invalid false", "FAL", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<4>() + { + LLSD val = 123; + ensureParse("valid integer", "i123", val, 1); + val.clear(); + ensureParse("invalid integer", "421", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<5>() + { + LLSD val = 456.7; + ensureParse("valid real", "r456.7", val, 1); + val.clear(); + ensureParse("invalid real", "456.7", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<6>() + { + LLUUID id; + LLSD val = id; + ensureParse( + "unparseable uuid", + "u123", + LLSD(), + LLSDParser::PARSE_FAILURE); + id.generate(); + val = id; + std::string uuid_str("u"); + uuid_str += id.asString(); + ensureParse("valid uuid", uuid_str.c_str(), val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<7>() + { + LLSD val = std::string("foolish"); + ensureParse("valid string 1", "\"foolish\"", val, 1); + val = std::string("g'day"); + ensureParse("valid string 2", "\"g'day\"", val, 1); + val = std::string("have a \"nice\" day"); + ensureParse("valid string 3", "'have a \"nice\" day'", val, 1); + val = std::string("whatever"); + ensureParse("valid string 4", "s(8)\"whatever\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<8>() + { + ensureParse( + "invalid string 1", + "s(7)\"whatever\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "invalid string 2", + "s(9)\"whatever\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<9>() + { + LLSD val = LLURI("http://www.google.com"); + ensureParse("valid uri", "l\"http://www.google.com\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<10>() + { + LLSD val = LLDate("2007-12-28T09:22:53.10Z"); + ensureParse("valid date", "d\"2007-12-28T09:22:53.10Z\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<11>() + { + std::vector<U8> vec; + vec.push_back((U8)'a'); vec.push_back((U8)'b'); vec.push_back((U8)'c'); + vec.push_back((U8)'3'); vec.push_back((U8)'2'); vec.push_back((U8)'1'); + LLSD val = vec; + ensureParse("valid binary b64", "b64\"YWJjMzIx\"", val, 1); + ensureParse("valid bainry b16", "b16\"616263333231\"", val, 1); + ensureParse("valid bainry raw", "b(6)\"abc321\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<12>() + { + ensureParse( + "invalid -- binary length specified too long", + "b(7)\"abc321\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "invalid -- binary length specified way too long", + "b(1000000)\"abc321\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<13>() + { + LLSD val; + val["amy"] = 23; + val["bob"] = LLSD(); + val["cam"] = 1.23; + ensureParse("simple map", "{'amy':i23,'bob':!,'cam':r1.23}", val, 4); + + val["bob"] = LLSD::emptyMap(); + val["bob"]["vehicle"] = std::string("bicycle"); + ensureParse( + "nested map", + "{'amy':i23,'bob':{'vehicle':'bicycle'},'cam':r1.23}", + val, + 5); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<14>() + { + LLSD val; + val.append(23); + val.append(LLSD()); + val.append(1.23); + ensureParse("simple array", "[i23,!,r1.23]", val, 4); + val[1] = LLSD::emptyArray(); + val[1].append("bicycle"); + ensureParse("nested array", "[i23,['bicycle'],r1.23]", val, 5); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<15>() + { + LLSD val; + val["amy"] = 23; + val["bob"]["dogs"] = LLSD::emptyArray(); + val["bob"]["dogs"].append(LLSD::emptyMap()); + val["bob"]["dogs"][0]["name"] = std::string("groove"); + val["bob"]["dogs"][0]["breed"] = std::string("samoyed"); + val["bob"]["dogs"].append(LLSD::emptyMap()); + val["bob"]["dogs"][1]["name"] = std::string("greyley"); + val["bob"]["dogs"][1]["breed"] = std::string("chow/husky"); + val["cam"] = 1.23; + ensureParse( + "nested notation", + "{'amy':i23," + " 'bob':{'dogs':[" + "{'name':'groove', 'breed':'samoyed'}," + "{'name':'greyley', 'breed':'chow/husky'}]}," + " 'cam':r1.23}", + val, + 11); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<16>() + { + // text to make sure that incorrect sizes bail because + std::string bad_str("s(5)\"hi\""); + ensureParse( + "size longer than bytes left", + bad_str, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<17>() + { + // text to make sure that incorrect sizes bail because + std::string bad_bin("b(5)\"hi\""); + ensureParse( + "size longer than bytes left", + bad_bin, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + /** + * @class TestLLSDBinaryParsing + * @brief Concrete instance of a parse tester. + */ + class TestLLSDBinaryParsing : public TestLLSDParsing<LLSDBinaryParser> + { + public: + TestLLSDBinaryParsing() {} + }; + + typedef tut::test_group<TestLLSDBinaryParsing> TestLLSDBinaryParsingGroup; + typedef TestLLSDBinaryParsingGroup::object TestLLSDBinaryParsingObject; + TestLLSDBinaryParsingGroup gTestLLSDBinaryParsingGroup( + "llsd binary parsing"); + + template<> template<> + void TestLLSDBinaryParsingObject::test<1>() + { + std::vector<U8> vec; + vec.resize(6); + vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c'; + vec[3] = '3'; vec[4] = '2'; vec[5] = '1'; + std::string string_expected((char*)&vec[0], vec.size()); + LLSD value = string_expected; + + vec.resize(11); + vec[0] = 's'; // for string + vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c'; + vec[8] = '3'; vec[9] = '2'; vec[10] = '1'; + + uint32_t size = htonl(6); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse("correct string parse", str_good, value, 1); + + size = htonl(7); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size string parse", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + size = htonl(100000); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size string parse", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<2>() + { + std::vector<U8> vec; + vec.resize(6); + vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c'; + vec[3] = '3'; vec[4] = '2'; vec[5] = '1'; + LLSD value = vec; + + vec.resize(11); + vec[0] = 'b'; // for binary + vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c'; + vec[8] = '3'; vec[9] = '2'; vec[10] = '1'; + + uint32_t size = htonl(6); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse("correct binary parse", str_good, value, 1); + + size = htonl(7); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size binary parse 1", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + size = htonl(100000); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size binary parse 2", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<3>() + { + // test handling of xml not recognized as llsd results in an + // LLSD Undefined + ensureParse( + "malformed binary map", + "{'ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed binary array", + "['ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed binary string", + "'ha ha", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "bad noise", + "g48ejlnfr", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + template<> template<> + void TestLLSDBinaryParsingObject::test<4>() + { + ensureParse("valid undef", "!", LLSD(), 1); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<5>() + { + LLSD val = false; + ensureParse("valid boolean false 2", "0", val, 1); + val = true; + ensureParse("valid boolean true 2", "1", val, 1); + + val.clear(); + ensureParse("invalid true", "t", val, LLSDParser::PARSE_FAILURE); + ensureParse("invalid false", "f", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<6>() + { + std::vector<U8> vec; + vec.push_back('{'); + vec.resize(vec.size() + 4); + uint32_t size = htonl(1); + memcpy(&vec[1], &size, sizeof(uint32_t)); + vec.push_back('k'); + int key_size_loc = vec.size(); + size = htonl(1); // 1 too short + vec.resize(vec.size() + 4); + memcpy(&vec[key_size_loc], &size, sizeof(uint32_t)); + vec.push_back('a'); vec.push_back('m'); vec.push_back('y'); + vec.push_back('i'); + int integer_loc = vec.size(); + vec.resize(vec.size() + 4); + uint32_t val_int = htonl(23); + memcpy(&vec[integer_loc], &val_int, sizeof(uint32_t)); + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "invalid key size", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check with correct size, but unterminated map (missing '}') + size = htonl(3); // correct size + memcpy(&vec[key_size_loc], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "valid key size, unterminated map", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check w/ correct size and correct map termination + LLSD val; + val["amy"] = 23; + vec.push_back('}'); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse( + "valid map", + str_good, + val, + 2); + + // check w/ incorrect sizes and correct map termination + size = htonl(0); // 1 too few (for the map entry) + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_3((char*)&vec[0], vec.size()); + ensureParse( + "invalid map too long", + str_bad_3, + LLSD(), + LLSDParser::PARSE_FAILURE); + + size = htonl(2); // 1 too many + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_4((char*)&vec[0], vec.size()); + ensureParse( + "invalid map too short", + str_bad_4, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<7>() + { + std::vector<U8> vec; + vec.push_back('['); + vec.resize(vec.size() + 4); + uint32_t size = htonl(1); // 1 too short + memcpy(&vec[1], &size, sizeof(uint32_t)); + vec.push_back('"'); vec.push_back('a'); vec.push_back('m'); + vec.push_back('y'); vec.push_back('"'); vec.push_back('i'); + int integer_loc = vec.size(); + vec.resize(vec.size() + 4); + uint32_t val_int = htonl(23); + memcpy(&vec[integer_loc], &val_int, sizeof(uint32_t)); + + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "invalid array size", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check with correct size, but unterminated map (missing ']') + size = htonl(2); // correct size + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "unterminated array", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check w/ correct size and correct map termination + LLSD val; + val.append("amy"); + val.append(23); + vec.push_back(']'); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse( + "valid array", + str_good, + val, + 3); + + // check with too many elements + size = htonl(3); // 1 too long + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_3((char*)&vec[0], vec.size()); + ensureParse( + "array too short", + str_bad_3, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<8>() + { + std::vector<U8> vec; + vec.push_back('{'); + vec.resize(vec.size() + 4); + memset(&vec[1], 0, 4); + vec.push_back('}'); + std::string str_good((char*)&vec[0], vec.size()); + LLSD val = LLSD::emptyMap(); + ensureParse( + "empty map", + str_good, + val, + 1); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<9>() + { + std::vector<U8> vec; + vec.push_back('['); + vec.resize(vec.size() + 4); + memset(&vec[1], 0, 4); + vec.push_back(']'); + std::string str_good((char*)&vec[0], vec.size()); + LLSD val = LLSD::emptyArray(); + ensureParse( + "empty array", + str_good, + val, + 1); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<10>() + { + std::vector<U8> vec; + vec.push_back('l'); + vec.resize(vec.size() + 4); + uint32_t size = htonl(14); // 1 too long + memcpy(&vec[1], &size, sizeof(uint32_t)); + vec.push_back('h'); vec.push_back('t'); vec.push_back('t'); + vec.push_back('p'); vec.push_back(':'); vec.push_back('/'); + vec.push_back('/'); vec.push_back('s'); vec.push_back('l'); + vec.push_back('.'); vec.push_back('c'); vec.push_back('o'); + vec.push_back('m'); + std::string str_bad((char*)&vec[0], vec.size()); + ensureParse( + "invalid uri length size", + str_bad, + LLSD(), + LLSDParser::PARSE_FAILURE); + + LLSD val; + val = LLURI("http://sl.com"); + size = htonl(13); // correct length + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse( + "valid key size", + str_good, + val, + 1); + } + +/* + template<> template<> + void TestLLSDBinaryParsingObject::test<11>() + { + } +*/ + + /** + * @class TestLLSDCrossCompatible + * @brief Miscellaneous serialization and parsing tests + */ + class TestLLSDCrossCompatible + { + public: + TestLLSDCrossCompatible() {} + + void ensureBinaryAndNotation( + const std::string& msg, + const LLSD& input) + { + // to binary, and back again + std::stringstream str1; + S32 count1 = LLSDSerialize::toBinary(input, str1); + LLSD actual_value_bin; + S32 count2 = LLSDSerialize::fromBinary( + actual_value_bin, + str1, + LLSDSerialize::SIZE_UNLIMITED); + ensure_equals( + "ensureBinaryAndNotation binary count", + count2, + count1); + + // to notation and back again + std::stringstream str2; + S32 count3 = LLSDSerialize::toNotation(actual_value_bin, str2); + ensure_equals( + "ensureBinaryAndNotation notation count1", + count3, + count2); + LLSD actual_value_notation; + S32 count4 = LLSDSerialize::fromNotation( + actual_value_notation, + str2, + LLSDSerialize::SIZE_UNLIMITED); + ensure_equals( + "ensureBinaryAndNotation notation count2", + count4, + count3); + ensure_equals( + (msg + " (binaryandnotation)").c_str(), + actual_value_notation, + input); + } + + void ensureBinaryAndXML( + const std::string& msg, + const LLSD& input) + { + // to binary, and back again + std::stringstream str1; + S32 count1 = LLSDSerialize::toBinary(input, str1); + LLSD actual_value_bin; + S32 count2 = LLSDSerialize::fromBinary( + actual_value_bin, + str1, + LLSDSerialize::SIZE_UNLIMITED); + ensure_equals( + "ensureBinaryAndXML binary count", + count2, + count1); + + // to xml and back again + std::stringstream str2; + S32 count3 = LLSDSerialize::toXML(actual_value_bin, str2); + ensure_equals( + "ensureBinaryAndXML xml count1", + count3, + count2); + LLSD actual_value_xml; + S32 count4 = LLSDSerialize::fromXML(actual_value_xml, str2); + ensure_equals( + "ensureBinaryAndXML xml count2", + count4, + count3); + ensure_equals((msg + " (binaryandxml)").c_str(), actual_value_xml, input); + } + }; + + typedef tut::test_group<TestLLSDCrossCompatible> TestLLSDCompatibleGroup; + typedef TestLLSDCompatibleGroup::object TestLLSDCompatibleObject; + TestLLSDCompatibleGroup gTestLLSDCompatibleGroup( + "llsd serialize compatible"); + + template<> template<> + void TestLLSDCompatibleObject::test<1>() + { + LLSD test; + ensureBinaryAndNotation("undef", test); + ensureBinaryAndXML("undef", test); + test = true; + ensureBinaryAndNotation("boolean true", test); + ensureBinaryAndXML("boolean true", test); + test = false; + ensureBinaryAndNotation("boolean false", test); + ensureBinaryAndXML("boolean false", test); + test = 0; + ensureBinaryAndNotation("integer zero", test); + ensureBinaryAndXML("integer zero", test); + test = 1; + ensureBinaryAndNotation("integer positive", test); + ensureBinaryAndXML("integer positive", test); + test = -234567; + ensureBinaryAndNotation("integer negative", test); + ensureBinaryAndXML("integer negative", test); + test = 0.0; + ensureBinaryAndNotation("real zero", test); + ensureBinaryAndXML("real zero", test); + test = 1.0; + ensureBinaryAndNotation("real positive", test); + ensureBinaryAndXML("real positive", test); + test = -1.0; + ensureBinaryAndNotation("real negative", test); + ensureBinaryAndXML("real negative", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<2>() + { + LLSD test; + test = "foobar"; + ensureBinaryAndNotation("string", test); + ensureBinaryAndXML("string", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<3>() + { + LLSD test; + LLUUID id; + id.generate(); + test = id; + ensureBinaryAndNotation("uuid", test); + ensureBinaryAndXML("uuid", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<4>() + { + LLSD test; + test = LLDate(12345.0); + ensureBinaryAndNotation("date", test); + ensureBinaryAndXML("date", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<5>() + { + LLSD test; + test = LLURI("http://www.secondlife.com/"); + ensureBinaryAndNotation("uri", test); + ensureBinaryAndXML("uri", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<6>() + { + LLSD test; + typedef std::vector<U8> buf_t; + buf_t val; + for(int ii = 0; ii < 100; ++ii) + { + srand(ii); /* Flawfinder: ignore */ + S32 size = rand() % 100 + 10; + std::generate_n( + std::back_insert_iterator<buf_t>(val), + size, + rand); + } + test = val; + ensureBinaryAndNotation("binary", test); + ensureBinaryAndXML("binary", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<7>() + { + LLSD test; + test = LLSD::emptyArray(); + test.append(1); + test.append("hello"); + ensureBinaryAndNotation("array", test); + ensureBinaryAndXML("array", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<8>() + { + LLSD test; + test = LLSD::emptyArray(); + test["foo"] = "bar"; + test["baz"] = 100; + ensureBinaryAndNotation("map", test); + ensureBinaryAndXML("map", test); + } +} + diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 1e8b5517e4..31ea747f52 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -205,39 +205,35 @@ list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) add_library (llmessage ${llmessage_SOURCE_FILES}) target_link_libraries( - llmessage - ${CURL_LIBRARIES} - ${CARES_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${XMLRPCEPI_LIBRARIES} - ) + llmessage + ${CURL_LIBRARIES} + ${CARES_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${XMLRPCEPI_LIBRARIES} + ) -IF (NOT LINUX AND VIEWER) - # When building the viewer the tests links against the shared objects. - # These can not be found when we try to run the tests, so we had to disable them, for the viewer build. - # TODO: Can someone with viewer knowledge figure out how to make these find the correct so. - SET(llmessage_TEST_SOURCE_FILES - # llhttpclientadapter.cpp - lltrustedmessageservice.cpp - lltemplatemessagedispatcher.cpp - ) +SET(llmessage_TEST_SOURCE_FILES + # llhttpclientadapter.cpp + llnamevalue.cpp + lltrustedmessageservice.cpp + lltemplatemessagedispatcher.cpp + ) # set(TEST_DEBUG on) - set(test_libs - ${LLMESSAGE_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ) +set(test_libs + ${LLMESSAGE_LIBRARIES} + ${WINDOWS_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ) - LL_ADD_INTEGRATION_TEST( - llsdmessage - "llsdmessage.cpp" - "${test_libs}" - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py" - ) +LL_ADD_INTEGRATION_TEST( + llsdmessage + "llsdmessage.cpp" + "${test_libs}" + ${PYTHON_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py" + ) - LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") -ENDIF (NOT LINUX AND VIEWER) +LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") diff --git a/indra/llmessage/tests/llnamevalue_test.cpp b/indra/llmessage/tests/llnamevalue_test.cpp new file mode 100644 index 0000000000..3146e7f979 --- /dev/null +++ b/indra/llmessage/tests/llnamevalue_test.cpp @@ -0,0 +1,412 @@ +/** + * @file llnamevalue_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief LLNameValue unit test + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsdserialize.h" + +#include "../llnamevalue.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +// disable unreachable code warnings +#pragma warning(disable: 4702) +#endif + +namespace tut +{ + struct namevalue_test + { + namevalue_test() + { + } + }; + typedef test_group<namevalue_test> namevalue_t; + typedef namevalue_t::object namevalue_object_t; + tut::namevalue_t tut_namevalue("namevalue_test"); + + + template<> template<> + void namevalue_object_t::test<1>() + { + // LLNameValue() + LLNameValue nValue; + ensure("mName should have been NULL", nValue.mName == NULL); + ensure("getTypeEnum failed",nValue.getTypeEnum() == NVT_NULL); + ensure("getClassEnum failed",nValue.getClassEnum() == NVC_NULL); + ensure("getSendtoEnum failed",nValue.getSendtoEnum() == NVS_NULL); + + LLNameValue nValue1(" SecondLife ASSET RW SIM 232324343"); + + } + + // LLNameValue(const char* data); + // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, const char* nvsendto, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<2>() + { + LLNameValue nValue(" SecondLife ASSET RW S 232324343"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + ensure("sendToData or sendToViewer failed", !nValue.sendToData() && !nValue.sendToViewer()); + + LLNameValue nValue1("\n\r SecondLife_1 STRING READ_WRITE SIM 232324343"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife_1"))); + ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); + ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); + ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + ensure("1. sendToData or sendToViewer failed", !nValue1.sendToData() && !nValue1.sendToViewer()); + + LLNameValue nValue2("SecondLife", "23.5", "F32", "R", "DS"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_DATA_SIM); + ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + ensure("2. sendToData or sendToViewer failed", nValue2.sendToData() && !nValue2.sendToViewer()); + + LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY", "SIM_SPACE"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_DATA_SIM); + ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); + + LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV"); + LLVector3 llvec4(1.0, 2.0, 3.0); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); + ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); + + LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER"); + LLVector3 llvec5(-1.0f, 2.4f, 3); + ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); + ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); + ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); + ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); + + LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); + + LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER"); + U64 u64_7 = U64L(89764323323232); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); + } + + // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<3>() + { + LLNameValue nValue("SecondLife", "232324343", "ASSET", "READ_WRITE"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + + LLNameValue nValue1("SecondLife", "232324343", "STRING", "READ_WRITE"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); + ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); + ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); + ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + + LLNameValue nValue2("SecondLife", "23.5", "F32", "R"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + + LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + + LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW"); + LLVector3 llvec4(1.0, 2.0, 3.0); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + + LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW"); + LLVector3 llvec5(-1.0f, 2.4f, 3); + ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); + ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); + ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); + ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + + LLNameValue nValue6("SecondLife", "89764323", "U32", "RW"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + + LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW"); + U64 u64_7 = U64L(89764323323232); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + } + + // LLNameValue(const char* name, const char* type, const char* nvclass, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<4>() + { + LLNameValue nValue("SecondLife", "STRING", "READ_WRITE"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_STRING); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue1("SecondLife", "ASSET", "READ_WRITE"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); + ensure("1. getTypeEnum for RW failed", nValue1.getTypeEnum() == NVT_ASSET); + ensure("1. getClassEnum for RW failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum for RW failed", nValue1.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue2("SecondLife", "F32", "READ_ONLY"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue3("SecondLife", "S32", "READ_ONLY"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE"); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue6("SecondLife", "U32", "READ_WRITE"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue7("SecondLife", "U64", "READ_WRITE"); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + } + + template<> template<> + void namevalue_object_t::test<5>() + { + LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM"); + + ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); + } + + template<> template<> + void namevalue_object_t::test<6>() + { + LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S"); + ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + } + + template<> template<> + void namevalue_object_t::test<7>() + { + LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM"); + + ensure("getF32 failed",*nValue.getF32() == 555555.f); + } + + template<> template<> + void namevalue_object_t::test<8>() + { + LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM"); + + ensure("getS32 failed", *nValue.getS32() == -5555); + + S32 sVal = 0x7FFFFFFF; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + + sVal = -0x7FFFFFFF; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + + sVal = 0; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + } + + template<> template<> + void namevalue_object_t::test<9>() + { + LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM"); + LLVector3 vecExpected(-3, 2, 1); + LLVector3 vec; + nValue.getVec3(vec); + ensure("getVec3 failed", vec == vecExpected); + } + + template<> template<> + void namevalue_object_t::test<10>() + { + LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM"); + + ensure("getU32 failed",*nValue.getU32() == 12345678); + + U32 val = 0xFFFFFFFF; + nValue.setU32(val); + ensure("U32 max", *nValue.getU32() == val); + + val = 0; + nValue.setU32(val); + ensure("U32 min", *nValue.getU32() == val); + } + + template<> template<> + void namevalue_object_t::test<11>() + { + //skip_fail("incomplete support for U64."); + LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM"); + + ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); + + // there is no LLNameValue::setU64() + } + + + template<> template<> + void namevalue_object_t::test<12>() + { + //skip_fail("incomplete support for U64."); + LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); + std::string ret_str = nValue.printNameValue(); + + ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); + + LLNameValue nValue1(ret_str.c_str()); + ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64()); + } + + template<> template<> + void namevalue_object_t::test<13>() + { + LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); + std::string ret_str = nValue.printData(); + ensure_equals("1:printData failed",ret_str,"44444444444"); + + LLNameValue nValue1("SecondLife S32 RW DSV 44444"); + ret_str = nValue1.printData(); + ensure_equals("2:printData failed",ret_str,"44444"); + } + + template<> template<> + void namevalue_object_t::test<14>() + { + LLNameValue nValue("SecodLife STRING RW SIM 22222"); + std::ostringstream stream1,stream2,stream3, stream4, stream5; + stream1 << nValue; + ensure_equals("STRING << failed",stream1.str(),"22222"); + + LLNameValue nValue1("SecodLife F32 RW SIM 22222"); + stream2 << nValue1; + ensure_equals("F32 << failed",stream2.str(),"22222"); + + LLNameValue nValue2("SecodLife S32 RW SIM 22222"); + stream3<< nValue2; + ensure_equals("S32 << failed",stream3.str(),"22222"); + + LLNameValue nValue3("SecodLife U32 RW SIM 122222"); + stream4<< nValue3; + ensure_equals("U32 << failed",stream4.str(),"122222"); + + // I don't think we use U64 name value pairs. JC + //skip_fail("incomplete support for U64."); + //LLNameValue nValue4("SecodLife U64 RW SIM 22222"); + //stream5<< nValue4; + //ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); + } + + template<> template<> + void namevalue_object_t::test<15>() + { + LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S"); + + ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + // this should not have updated as it is read only. + nValue.setAsset("New Value should not be updated"); + ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + + LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S"); + // this should not have updated as it is read only. + nValue1.setU32(4567); + ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); + + LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S"); + // this should not have updated as it is read only. + nValue2.setS32(4567); + ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); + + LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S"); + // this should not have updated as it is read only. + nValue3.setF32(4567); + ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); + + LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S"); + // this should not have updated as it is read only. + LLVector3 vec(4,5,6); + nValue3.setVec3(vec); + LLVector3 vec1(1,2,3); + ensure("setVec3 on ReadOnly failed", *nValue4.getVec3() == vec1); + + // cant test for U64 as no set64 exists nor any operators support U64 type + } +} diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index a842548980..bb33f0956d 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -49,7 +49,6 @@ set(test_SOURCE_FILES llmime_tut.cpp llmessageconfig_tut.cpp llmodularmath_tut.cpp - llnamevalue_tut.cpp llpermissions_tut.cpp llpipeutil.cpp llsaleinfo_tut.cpp @@ -57,7 +56,6 @@ set(test_SOURCE_FILES llsdmessagebuilder_tut.cpp llsdmessagereader_tut.cpp llsd_new_tut.cpp - llsdserialize_tut.cpp llsdutil_tut.cpp llservicebuilder_tut.cpp llstreamtools_tut.cpp |