diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 20:51:58 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-22 20:51:58 +0300 |
commit | 6cc7dd09d5e69cf57e6de7fb568a0ad2693f9c9a (patch) | |
tree | fab23811a5cedc1ebf01479c852ee92ff62b636c /indra/test | |
parent | ef8f4819822288e044ea719feb6af7a1f4df4c4e (diff) | |
parent | 7bb5afc11ee5a6af78302a8d76a9a619e2baaab2 (diff) |
Merge pull request #1545 from Ansariel/DRTVWR-600-maint-A
Merge main into DRTVWR-600-maint-a
Diffstat (limited to 'indra/test')
46 files changed, 10786 insertions, 10786 deletions
diff --git a/indra/test/catch_and_store_what_in.h b/indra/test/catch_and_store_what_in.h index 5beba06024..d3dada2acf 100644 --- a/indra/test/catch_and_store_what_in.h +++ b/indra/test/catch_and_store_what_in.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2012-02-15 * @brief catch_what() template function, CATCH_AND_STORE_WHAT_IN() macro - * + * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Copyright (c) 2012, Linden Research, Inc. * $/LicenseInfo$ @@ -64,45 +64,45 @@ std::string catch_what(FUNC func) * ensure("some_call_that_should_throw_Foo() didn't throw", ! threw.empty()); * @endcode */ -#define CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \ -catch (const EXCEPTION& ex) \ -{ \ - (THREW) = ex.what(); \ -} \ +#define CATCH_AND_STORE_WHAT_IN(THREW, EXCEPTION) \ +catch (const EXCEPTION& ex) \ +{ \ + (THREW) = ex.what(); \ +} \ CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) #ifndef LL_LINUX -#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \ - /* only needed on Linux */ +#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \ + /* only needed on Linux */ #else // LL_LINUX -#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \ -catch (const std::runtime_error& ex) \ -{ \ - /* This clause is needed on Linux, on the viewer side, because */ \ - /* the exception isn't caught by catch (const EXCEPTION&). */ \ - /* But if the expected exception was thrown, allow the test to */ \ - /* succeed anyway. Not sure how else to handle this odd case. */ \ - if (std::string(typeid(ex).name()) == typeid(EXCEPTION).name()) \ - { \ - /* std::cerr << "Caught " << typeid(ex).name() */ \ - /* << " with Linux workaround" << std::endl; */ \ - (THREW) = ex.what(); \ - /*std::cout << ex.what() << std::endl;*/ \ - } \ - else \ - { \ - /* We don't even recognize this exception. Let it propagate */ \ - /* out to TUT to fail the test. */ \ - throw; \ - } \ -} \ -catch (...) \ -{ \ - std::cerr << "Failed to catch expected exception " \ - << #EXCEPTION << "!" << std::endl; \ - /* This indicates a problem in the test that should be addressed. */ \ - throw; \ +#define CATCH_MISSED_LINUX_EXCEPTION(THREW, EXCEPTION) \ +catch (const std::runtime_error& ex) \ +{ \ + /* This clause is needed on Linux, on the viewer side, because */ \ + /* the exception isn't caught by catch (const EXCEPTION&). */ \ + /* But if the expected exception was thrown, allow the test to */ \ + /* succeed anyway. Not sure how else to handle this odd case. */ \ + if (std::string(typeid(ex).name()) == typeid(EXCEPTION).name()) \ + { \ + /* std::cerr << "Caught " << typeid(ex).name() */ \ + /* << " with Linux workaround" << std::endl; */ \ + (THREW) = ex.what(); \ + /*std::cout << ex.what() << std::endl;*/ \ + } \ + else \ + { \ + /* We don't even recognize this exception. Let it propagate */ \ + /* out to TUT to fail the test. */ \ + throw; \ + } \ +} \ +catch (...) \ +{ \ + std::cerr << "Failed to catch expected exception " \ + << #EXCEPTION << "!" << std::endl; \ + /* This indicates a problem in the test that should be addressed. */ \ + throw; \ } #endif // LL_LINUX diff --git a/indra/test/chained_callback.h b/indra/test/chained_callback.h index 05929e33ad..984e2f1dbc 100644 --- a/indra/test/chained_callback.h +++ b/indra/test/chained_callback.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2020-01-03 * @brief Subclass of tut::callback used for chaining callbacks. - * + * * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Copyright (c) 2020, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/debug.h b/indra/test/debug.h index 76dbb973b2..1579bb9c86 100644 --- a/indra/test/debug.h +++ b/indra/test/debug.h @@ -3,25 +3,25 @@ * @author Nat Goodspeed * @date 2009-05-28 * @brief Debug output for unit test code - * + * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/test/hexdump.h b/indra/test/hexdump.h index dd7cbaaa3c..95f1e297c3 100644 --- a/indra/test/hexdump.h +++ b/indra/test/hexdump.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2023-09-08 * @brief Provide hexdump() and hexmix() ostream formatters - * + * * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Copyright (c) 2023, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/io.cpp b/indra/test/io.cpp index 99b49c8b29..412f9ca1d2 100644 --- a/indra/test/io.cpp +++ b/indra/test/io.cpp @@ -1,4 +1,4 @@ -/** +/** * @file io.cpp * @author Phoenix * @date 2005-10-02 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,1132 +48,1132 @@ namespace tut { - struct heap_buffer_data - { - heap_buffer_data() : mBuffer(NULL) {} - ~heap_buffer_data() { if(mBuffer) delete mBuffer; } - LLHeapBuffer* mBuffer; - }; - typedef test_group<heap_buffer_data> heap_buffer_test; - typedef heap_buffer_test::object heap_buffer_object; - tut::heap_buffer_test thb("heap_buffer"); - - template<> template<> - void heap_buffer_object::test<1>() - { - const S32 BUF_SIZE = 100; - mBuffer = new LLHeapBuffer(BUF_SIZE); - ensure_equals("empty buffer capacity", mBuffer->capacity(), BUF_SIZE); - const S32 SEGMENT_SIZE = 50; - LLSegment segment; - mBuffer->createSegment(0, SEGMENT_SIZE, segment); - ensure_equals("used buffer capacity", mBuffer->capacity(), BUF_SIZE); - } - - template<> template<> - void heap_buffer_object::test<2>() - { - const S32 BUF_SIZE = 10; - mBuffer = new LLHeapBuffer(BUF_SIZE); - LLSegment segment; - mBuffer->createSegment(0, BUF_SIZE, segment); - ensure("segment is in buffer", mBuffer->containsSegment(segment)); - ensure_equals("buffer consumed", mBuffer->bytesLeft(), 0); - bool created; - created = mBuffer->createSegment(0, 0, segment); - ensure("Create zero size segment fails", !created); - created = mBuffer->createSegment(0, BUF_SIZE, segment); - ensure("Create segment fails", !created); - } - - template<> template<> - void heap_buffer_object::test<3>() - { - const S32 BUF_SIZE = 10; - mBuffer = new LLHeapBuffer(BUF_SIZE); - LLSegment segment; - mBuffer->createSegment(0, BUF_SIZE, segment); - ensure("segment is in buffer", mBuffer->containsSegment(segment)); - ensure_equals("buffer consumed", mBuffer->bytesLeft(), 0); - bool reclaimed = mBuffer->reclaimSegment(segment); - ensure("buffer reclaimed.", reclaimed); - ensure_equals("buffer available", mBuffer->bytesLeft(), BUF_SIZE); - bool created; - created = mBuffer->createSegment(0, 0, segment); - ensure("Create zero size segment fails", !created); - created = mBuffer->createSegment(0, BUF_SIZE, segment); - ensure("Create another segment succeeds", created); - } - - template<> template<> - void heap_buffer_object::test<4>() - { - const S32 BUF_SIZE = 10; - const S32 SEGMENT_SIZE = 4; - mBuffer = new LLHeapBuffer(BUF_SIZE); - LLSegment seg1; - mBuffer->createSegment(0, SEGMENT_SIZE, seg1); - ensure("segment is in buffer", mBuffer->containsSegment(seg1)); - LLSegment seg2; - mBuffer->createSegment(0, SEGMENT_SIZE, seg2); - ensure("segment is in buffer", mBuffer->containsSegment(seg2)); - LLSegment seg3; - mBuffer->createSegment(0, SEGMENT_SIZE, seg3); - ensure("segment is in buffer", mBuffer->containsSegment(seg3)); - ensure_equals("segment is truncated", seg3.size(), 2); - LLSegment seg4; - bool created; - created = mBuffer->createSegment(0, SEGMENT_SIZE, seg4); - ensure("Create segment fails", !created); - bool reclaimed; - reclaimed = mBuffer->reclaimSegment(seg1); - ensure("buffer reclaim succeed.", reclaimed); - ensure_equals("no buffer available", mBuffer->bytesLeft(), 0); - reclaimed = mBuffer->reclaimSegment(seg2); - ensure("buffer reclaim succeed.", reclaimed); - ensure_equals("buffer reclaimed", mBuffer->bytesLeft(), 0); - reclaimed = mBuffer->reclaimSegment(seg3); - ensure("buffer reclaim succeed.", reclaimed); - ensure_equals("buffer reclaimed", mBuffer->bytesLeft(), BUF_SIZE); - created = mBuffer->createSegment(0, SEGMENT_SIZE, seg1); - ensure("segment is in buffer", mBuffer->containsSegment(seg1)); - ensure("Create segment succeds", created); - } + struct heap_buffer_data + { + heap_buffer_data() : mBuffer(NULL) {} + ~heap_buffer_data() { if(mBuffer) delete mBuffer; } + LLHeapBuffer* mBuffer; + }; + typedef test_group<heap_buffer_data> heap_buffer_test; + typedef heap_buffer_test::object heap_buffer_object; + tut::heap_buffer_test thb("heap_buffer"); + + template<> template<> + void heap_buffer_object::test<1>() + { + const S32 BUF_SIZE = 100; + mBuffer = new LLHeapBuffer(BUF_SIZE); + ensure_equals("empty buffer capacity", mBuffer->capacity(), BUF_SIZE); + const S32 SEGMENT_SIZE = 50; + LLSegment segment; + mBuffer->createSegment(0, SEGMENT_SIZE, segment); + ensure_equals("used buffer capacity", mBuffer->capacity(), BUF_SIZE); + } + + template<> template<> + void heap_buffer_object::test<2>() + { + const S32 BUF_SIZE = 10; + mBuffer = new LLHeapBuffer(BUF_SIZE); + LLSegment segment; + mBuffer->createSegment(0, BUF_SIZE, segment); + ensure("segment is in buffer", mBuffer->containsSegment(segment)); + ensure_equals("buffer consumed", mBuffer->bytesLeft(), 0); + bool created; + created = mBuffer->createSegment(0, 0, segment); + ensure("Create zero size segment fails", !created); + created = mBuffer->createSegment(0, BUF_SIZE, segment); + ensure("Create segment fails", !created); + } + + template<> template<> + void heap_buffer_object::test<3>() + { + const S32 BUF_SIZE = 10; + mBuffer = new LLHeapBuffer(BUF_SIZE); + LLSegment segment; + mBuffer->createSegment(0, BUF_SIZE, segment); + ensure("segment is in buffer", mBuffer->containsSegment(segment)); + ensure_equals("buffer consumed", mBuffer->bytesLeft(), 0); + bool reclaimed = mBuffer->reclaimSegment(segment); + ensure("buffer reclaimed.", reclaimed); + ensure_equals("buffer available", mBuffer->bytesLeft(), BUF_SIZE); + bool created; + created = mBuffer->createSegment(0, 0, segment); + ensure("Create zero size segment fails", !created); + created = mBuffer->createSegment(0, BUF_SIZE, segment); + ensure("Create another segment succeeds", created); + } + + template<> template<> + void heap_buffer_object::test<4>() + { + const S32 BUF_SIZE = 10; + const S32 SEGMENT_SIZE = 4; + mBuffer = new LLHeapBuffer(BUF_SIZE); + LLSegment seg1; + mBuffer->createSegment(0, SEGMENT_SIZE, seg1); + ensure("segment is in buffer", mBuffer->containsSegment(seg1)); + LLSegment seg2; + mBuffer->createSegment(0, SEGMENT_SIZE, seg2); + ensure("segment is in buffer", mBuffer->containsSegment(seg2)); + LLSegment seg3; + mBuffer->createSegment(0, SEGMENT_SIZE, seg3); + ensure("segment is in buffer", mBuffer->containsSegment(seg3)); + ensure_equals("segment is truncated", seg3.size(), 2); + LLSegment seg4; + bool created; + created = mBuffer->createSegment(0, SEGMENT_SIZE, seg4); + ensure("Create segment fails", !created); + bool reclaimed; + reclaimed = mBuffer->reclaimSegment(seg1); + ensure("buffer reclaim succeed.", reclaimed); + ensure_equals("no buffer available", mBuffer->bytesLeft(), 0); + reclaimed = mBuffer->reclaimSegment(seg2); + ensure("buffer reclaim succeed.", reclaimed); + ensure_equals("buffer reclaimed", mBuffer->bytesLeft(), 0); + reclaimed = mBuffer->reclaimSegment(seg3); + ensure("buffer reclaim succeed.", reclaimed); + ensure_equals("buffer reclaimed", mBuffer->bytesLeft(), BUF_SIZE); + created = mBuffer->createSegment(0, SEGMENT_SIZE, seg1); + ensure("segment is in buffer", mBuffer->containsSegment(seg1)); + ensure("Create segment succeds", created); + } } namespace tut { - struct buffer_data - { - LLBufferArray mBuffer; - }; - typedef test_group<buffer_data> buffer_test; - typedef buffer_test::object buffer_object; - tut::buffer_test tba("buffer_array"); - - template<> template<> - void buffer_object::test<1>() - { - const char HELLO_WORLD[] = "hello world"; - const S32 str_len = strlen(HELLO_WORLD); - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); - S32 count = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("total append size", count, str_len); - LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); - U8* first = (*it).data(); - count = mBuffer.countAfter(ch.in(), first); - ensure_equals("offset append size", count, str_len - 1); - } - - template<> template<> - void buffer_object::test<2>() - { - const char HELLO_WORLD[] = "hello world"; - const S32 str_len = strlen(HELLO_WORLD); /* Flawfinder: ignore */ - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); - mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); - S32 count = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("total append size", count, 2 * str_len); - LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); - U8* first = (*it).data(); - count = mBuffer.countAfter(ch.in(), first); - ensure_equals("offset append size", count, (2 * str_len) - 1); - } - - template<> template<> - void buffer_object::test<3>() - { - const char ONE[] = "one"; - const char TWO[] = "two"; - std::string expected(ONE); - expected.append(TWO); - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)ONE, 3); - mBuffer.append(ch.in(), (U8*)TWO, 3); - char buffer[255]; /* Flawfinder: ignore */ - S32 len = 6; - mBuffer.readAfter(ch.in(), NULL, (U8*)buffer, len); - ensure_equals(len, 6); - buffer[len] = '\0'; - std::string actual(buffer); - ensure_equals("read", actual, expected); - } - - template<> template<> - void buffer_object::test<4>() - { - const char ONE[] = "one"; - const char TWO[] = "two"; - std::string expected(ONE); - expected.append(TWO); - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)TWO, 3); - mBuffer.prepend(ch.in(), (U8*)ONE, 3); - char buffer[255]; /* Flawfinder: ignore */ - S32 len = 6; - mBuffer.readAfter(ch.in(), NULL, (U8*)buffer, len); - ensure_equals(len, 6); - buffer[len] = '\0'; - std::string actual(buffer); - ensure_equals("read", actual, expected); - } - - template<> template<> - void buffer_object::test<5>() - { - const char ONE[] = "one"; - const char TWO[] = "two"; - std::string expected("netwo"); - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)TWO, 3); - mBuffer.prepend(ch.in(), (U8*)ONE, 3); - char buffer[255]; /* Flawfinder: ignore */ - S32 len = 5; - LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); - U8* addr = (*it).data(); - mBuffer.readAfter(ch.in(), addr, (U8*)buffer, len); - ensure_equals(len, 5); - buffer[len] = '\0'; - std::string actual(buffer); - ensure_equals("read", actual, expected); - } - - template<> template<> - void buffer_object::test<6>() - { - std::string request("The early bird catches the worm."); - std::string response("If you're a worm, sleep late."); - std::ostringstream expected; - expected << "ContentLength: " << response.length() << "\r\n\r\n" - << response; - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)request.c_str(), request.length()); - mBuffer.append(ch.out(), (U8*)response.c_str(), response.length()); - S32 count = mBuffer.countAfter(ch.out(), NULL); - std::ostringstream header; - header << "ContentLength: " << count << "\r\n\r\n"; - std::string head(header.str()); - mBuffer.prepend(ch.out(), (U8*)head.c_str(), head.length()); - char buffer[1024]; /* Flawfinder: ignore */ - S32 len = response.size() + head.length(); - ensure_equals("same length", len, (S32)expected.str().length()); - mBuffer.readAfter(ch.out(), NULL, (U8*)buffer, len); - buffer[len] = '\0'; - std::string actual(buffer); - ensure_equals("threaded writes", actual, expected.str()); - } - - template<> template<> - void buffer_object::test<7>() - { - const S32 LINE_COUNT = 3; - std::string lines[LINE_COUNT] = - { - std::string("GET /index.htm HTTP/1.0\r\n"), - std::string("User-Agent: Wget/1.9.1\r\n"), - std::string("Host: localhost:8008\r\n") - }; - std::string text; - S32 i; - for(i = 0; i < LINE_COUNT; ++i) - { - text.append(lines[i]); - } - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)text.c_str(), text.length()); - const S32 BUFFER_LEN = 1024; - char buf[BUFFER_LEN]; - S32 len; - U8* last = NULL; - std::string last_line; - for(i = 0; i < LINE_COUNT; ++i) - { - len = BUFFER_LEN; - last = mBuffer.readAfter(ch.in(), last, (U8*)buf, len); - char* newline = strchr((char*)buf, '\n'); - S32 offset = -((len - 1) - (newline - buf)); - ++newline; - *newline = '\0'; - last_line.assign(buf); - std::ostringstream message; - message << "line reads in line[" << i << "]"; - ensure_equals(message.str().c_str(), last_line, lines[i]); - last = mBuffer.seek(ch.in(), last, offset); - } - } - - template<> template<> - void buffer_object::test<8>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)"1", 1); - LLBufferArray buffer; - buffer.append(ch.in(), (U8*)"2", 1); - mBuffer.takeContents(buffer); - mBuffer.append(ch.in(), (U8*)"3", 1); - S32 count = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("buffer size", count, 3); - U8* temp = new U8[count]; - mBuffer.readAfter(ch.in(), NULL, temp, count); - ensure("buffer content", (0 == memcmp(temp, (void*)"123", 3))); - delete[] temp; - } - - template<> template<> - void buffer_object::test<9>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.in(), (U8*)"1", 1); - S32 capacity = mBuffer.capacity(); - ensure("has capacity", capacity > 0); - U8* temp = new U8[capacity - 1]; - mBuffer.append(ch.in(), temp, capacity - 1); - capacity = mBuffer.capacity(); - ensure("has capacity when full", capacity > 0); - S32 used = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("used equals capacity", used, capacity); - - LLBufferArray::segment_iterator_t iter = mBuffer.beginSegment(); - while(iter != mBuffer.endSegment()) - { - mBuffer.eraseSegment(iter++); - } - - used = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("used is zero", used, 0); - S32 capacity2 = mBuffer.capacity(); - ensure_equals("capacity the same after erase", capacity2, capacity); - mBuffer.append(ch.in(), temp, capacity - 1); - capacity2 = mBuffer.capacity(); - ensure_equals("capacity the same after append", capacity2, capacity); - - delete[] temp; - } + struct buffer_data + { + LLBufferArray mBuffer; + }; + typedef test_group<buffer_data> buffer_test; + typedef buffer_test::object buffer_object; + tut::buffer_test tba("buffer_array"); + + template<> template<> + void buffer_object::test<1>() + { + const char HELLO_WORLD[] = "hello world"; + const S32 str_len = strlen(HELLO_WORLD); + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); + S32 count = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("total append size", count, str_len); + LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); + U8* first = (*it).data(); + count = mBuffer.countAfter(ch.in(), first); + ensure_equals("offset append size", count, str_len - 1); + } + + template<> template<> + void buffer_object::test<2>() + { + const char HELLO_WORLD[] = "hello world"; + const S32 str_len = strlen(HELLO_WORLD); /* Flawfinder: ignore */ + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); + mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); + S32 count = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("total append size", count, 2 * str_len); + LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); + U8* first = (*it).data(); + count = mBuffer.countAfter(ch.in(), first); + ensure_equals("offset append size", count, (2 * str_len) - 1); + } + + template<> template<> + void buffer_object::test<3>() + { + const char ONE[] = "one"; + const char TWO[] = "two"; + std::string expected(ONE); + expected.append(TWO); + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)ONE, 3); + mBuffer.append(ch.in(), (U8*)TWO, 3); + char buffer[255]; /* Flawfinder: ignore */ + S32 len = 6; + mBuffer.readAfter(ch.in(), NULL, (U8*)buffer, len); + ensure_equals(len, 6); + buffer[len] = '\0'; + std::string actual(buffer); + ensure_equals("read", actual, expected); + } + + template<> template<> + void buffer_object::test<4>() + { + const char ONE[] = "one"; + const char TWO[] = "two"; + std::string expected(ONE); + expected.append(TWO); + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)TWO, 3); + mBuffer.prepend(ch.in(), (U8*)ONE, 3); + char buffer[255]; /* Flawfinder: ignore */ + S32 len = 6; + mBuffer.readAfter(ch.in(), NULL, (U8*)buffer, len); + ensure_equals(len, 6); + buffer[len] = '\0'; + std::string actual(buffer); + ensure_equals("read", actual, expected); + } + + template<> template<> + void buffer_object::test<5>() + { + const char ONE[] = "one"; + const char TWO[] = "two"; + std::string expected("netwo"); + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)TWO, 3); + mBuffer.prepend(ch.in(), (U8*)ONE, 3); + char buffer[255]; /* Flawfinder: ignore */ + S32 len = 5; + LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); + U8* addr = (*it).data(); + mBuffer.readAfter(ch.in(), addr, (U8*)buffer, len); + ensure_equals(len, 5); + buffer[len] = '\0'; + std::string actual(buffer); + ensure_equals("read", actual, expected); + } + + template<> template<> + void buffer_object::test<6>() + { + std::string request("The early bird catches the worm."); + std::string response("If you're a worm, sleep late."); + std::ostringstream expected; + expected << "ContentLength: " << response.length() << "\r\n\r\n" + << response; + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)request.c_str(), request.length()); + mBuffer.append(ch.out(), (U8*)response.c_str(), response.length()); + S32 count = mBuffer.countAfter(ch.out(), NULL); + std::ostringstream header; + header << "ContentLength: " << count << "\r\n\r\n"; + std::string head(header.str()); + mBuffer.prepend(ch.out(), (U8*)head.c_str(), head.length()); + char buffer[1024]; /* Flawfinder: ignore */ + S32 len = response.size() + head.length(); + ensure_equals("same length", len, (S32)expected.str().length()); + mBuffer.readAfter(ch.out(), NULL, (U8*)buffer, len); + buffer[len] = '\0'; + std::string actual(buffer); + ensure_equals("threaded writes", actual, expected.str()); + } + + template<> template<> + void buffer_object::test<7>() + { + const S32 LINE_COUNT = 3; + std::string lines[LINE_COUNT] = + { + std::string("GET /index.htm HTTP/1.0\r\n"), + std::string("User-Agent: Wget/1.9.1\r\n"), + std::string("Host: localhost:8008\r\n") + }; + std::string text; + S32 i; + for(i = 0; i < LINE_COUNT; ++i) + { + text.append(lines[i]); + } + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)text.c_str(), text.length()); + const S32 BUFFER_LEN = 1024; + char buf[BUFFER_LEN]; + S32 len; + U8* last = NULL; + std::string last_line; + for(i = 0; i < LINE_COUNT; ++i) + { + len = BUFFER_LEN; + last = mBuffer.readAfter(ch.in(), last, (U8*)buf, len); + char* newline = strchr((char*)buf, '\n'); + S32 offset = -((len - 1) - (newline - buf)); + ++newline; + *newline = '\0'; + last_line.assign(buf); + std::ostringstream message; + message << "line reads in line[" << i << "]"; + ensure_equals(message.str().c_str(), last_line, lines[i]); + last = mBuffer.seek(ch.in(), last, offset); + } + } + + template<> template<> + void buffer_object::test<8>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)"1", 1); + LLBufferArray buffer; + buffer.append(ch.in(), (U8*)"2", 1); + mBuffer.takeContents(buffer); + mBuffer.append(ch.in(), (U8*)"3", 1); + S32 count = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("buffer size", count, 3); + U8* temp = new U8[count]; + mBuffer.readAfter(ch.in(), NULL, temp, count); + ensure("buffer content", (0 == memcmp(temp, (void*)"123", 3))); + delete[] temp; + } + + template<> template<> + void buffer_object::test<9>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.in(), (U8*)"1", 1); + S32 capacity = mBuffer.capacity(); + ensure("has capacity", capacity > 0); + U8* temp = new U8[capacity - 1]; + mBuffer.append(ch.in(), temp, capacity - 1); + capacity = mBuffer.capacity(); + ensure("has capacity when full", capacity > 0); + S32 used = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("used equals capacity", used, capacity); + + LLBufferArray::segment_iterator_t iter = mBuffer.beginSegment(); + while(iter != mBuffer.endSegment()) + { + mBuffer.eraseSegment(iter++); + } + + used = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("used is zero", used, 0); + S32 capacity2 = mBuffer.capacity(); + ensure_equals("capacity the same after erase", capacity2, capacity); + mBuffer.append(ch.in(), temp, capacity - 1); + capacity2 = mBuffer.capacity(); + ensure_equals("capacity the same after append", capacity2, capacity); + + delete[] temp; + } #if 0 - template<> template<> - void buffer_object::test<9>() - { - char buffer[1024]; /* Flawfinder: ignore */ - S32 size = sprintf(buffer, - "%d|%d|%s|%s|%s|%s|%s|%x|%x|%x|%x|%x|%s|%s|%d|%d|%x", - 7, - 7, - "Hang Glider INFO", - "18e84d1e-04a4-4c0d-8cb6-6c73477f0a9a", - "0e346d8b-4433-4d66-a6b0-fd37083abc4c", - "0e346d8b-4433-4d66-a6b0-fd37083abc4c", - "00000000-0000-0000-0000-000000000000", - 0x7fffffff, - 0x7fffffff, - 0, - 0, - 0x7fffffff, - "69e0d357-2e7c-8990-a2bc-7f61c868e5a3", - "2004-06-04 16:09:17 note card", - 0, - 10, - 0) + 1; - - //const char* expected = "7|7|Hang Glider INFO|18e84d1e-04a4-4c0d-8cb6-6c73477f0a9a|0e346d8b-4433-4d66-a6b0-fd37083abc4c|0e346d8b-4433-4d66-a6b0-fd37083abc4c|00000000-0000-0000-0000-000000000000|7fffffff|7fffffff|0|0|7fffffff|69e0d357-2e7c-8990-a2bc-7f61c868e5a3|2004-06-04 16:09:17 note card|0|10|0\0"; - - LLSD* bin_bucket = LLIMInfo::buildSDfrombuffer((U8*)buffer,size); - - char post_buffer[1024]; - U32 post_size; - LLIMInfo::getBinaryBucket(bin_bucket,(U8*)post_buffer,post_size); - ensure_equals("Buffer sizes",size,(S32)post_size); - ensure("Buffer content",!strcmp(buffer,post_buffer)); - } + template<> template<> + void buffer_object::test<9>() + { + char buffer[1024]; /* Flawfinder: ignore */ + S32 size = sprintf(buffer, + "%d|%d|%s|%s|%s|%s|%s|%x|%x|%x|%x|%x|%s|%s|%d|%d|%x", + 7, + 7, + "Hang Glider INFO", + "18e84d1e-04a4-4c0d-8cb6-6c73477f0a9a", + "0e346d8b-4433-4d66-a6b0-fd37083abc4c", + "0e346d8b-4433-4d66-a6b0-fd37083abc4c", + "00000000-0000-0000-0000-000000000000", + 0x7fffffff, + 0x7fffffff, + 0, + 0, + 0x7fffffff, + "69e0d357-2e7c-8990-a2bc-7f61c868e5a3", + "2004-06-04 16:09:17 note card", + 0, + 10, + 0) + 1; + + //const char* expected = "7|7|Hang Glider INFO|18e84d1e-04a4-4c0d-8cb6-6c73477f0a9a|0e346d8b-4433-4d66-a6b0-fd37083abc4c|0e346d8b-4433-4d66-a6b0-fd37083abc4c|00000000-0000-0000-0000-000000000000|7fffffff|7fffffff|0|0|7fffffff|69e0d357-2e7c-8990-a2bc-7f61c868e5a3|2004-06-04 16:09:17 note card|0|10|0\0"; + + LLSD* bin_bucket = LLIMInfo::buildSDfrombuffer((U8*)buffer,size); + + char post_buffer[1024]; + U32 post_size; + LLIMInfo::getBinaryBucket(bin_bucket,(U8*)post_buffer,post_size); + ensure_equals("Buffer sizes",size,(S32)post_size); + ensure("Buffer content",!strcmp(buffer,post_buffer)); + } #endif - /* - template<> template<> - void buffer_object::test<>() - { - } - */ + /* + template<> template<> + void buffer_object::test<>() + { + } + */ } namespace tut { - struct buffer_and_stream_data - { - LLBufferArray mBuffer; - }; - typedef test_group<buffer_and_stream_data> bas_test; - typedef bas_test::object bas_object; - tut::bas_test tbs("buffer_stream"); - - template<> template<> - void bas_object::test<1>() - { - const char HELLO_WORLD[] = "hello world"; - const S32 str_len = strlen(HELLO_WORLD); /* Flawfinder: ignore */ - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream str(ch, &mBuffer); - mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); - std::string hello; - std::string world; - str >> hello >> world; - ensure_equals("first word", hello, std::string("hello")); - ensure_equals("second word", world, std::string("world")); - } - - template<> template<> - void bas_object::test<2>() - { - std::string part1("Eat my shor"); - std::string part2("ts ho"); - std::string part3("mer"); - std::string ignore("ignore me"); - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream str(ch, &mBuffer); - mBuffer.append(ch.in(), (U8*)part1.c_str(), part1.length()); - mBuffer.append(ch.in(), (U8*)part2.c_str(), part2.length()); - mBuffer.append(ch.out(), (U8*)ignore.c_str(), ignore.length()); - mBuffer.append(ch.in(), (U8*)part3.c_str(), part3.length()); - std::string eat; - std::string my; - std::string shorts; - std::string homer; - str >> eat >> my >> shorts >> homer; - ensure_equals("word1", eat, std::string("Eat")); - ensure_equals("word2", my, std::string("my")); - ensure_equals("word3", shorts, std::string("shorts")); - ensure_equals("word4", homer, std::string("homer")); - } - - template<> template<> - void bas_object::test<3>() - { - std::string part1("junk in "); - std::string part2("the trunk"); - const S32 CHANNEL = 0; - mBuffer.append(CHANNEL, (U8*)part1.c_str(), part1.length()); - mBuffer.append(CHANNEL, (U8*)part2.c_str(), part2.length()); - U8* last = 0; - const S32 BUF_LEN = 128; - char buf[BUF_LEN]; - S32 len = 11; - last = mBuffer.readAfter(CHANNEL, last, (U8*)buf, len); - buf[len] = '\0'; - std::string actual(buf); - ensure_equals("first read", actual, std::string("junk in the")); - last = mBuffer.seek(CHANNEL, last, -6); - len = 12; - last = mBuffer.readAfter(CHANNEL, last, (U8*)buf, len); - buf[len] = '\0'; - actual.assign(buf); - ensure_equals("seek and read", actual, std::string("in the trunk")); - } - - template<> template<> - void bas_object::test<4>() - { - std::string phrase("zippity do da!"); - const S32 CHANNEL = 0; - mBuffer.append(CHANNEL, (U8*)phrase.c_str(), phrase.length()); - const S32 BUF_LEN = 128; - char buf[BUF_LEN]; - S32 len = 7; - U8* last = mBuffer.readAfter(CHANNEL, NULL, (U8*)buf, len); - mBuffer.splitAfter(last); - LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); - LLBufferArray::segment_iterator_t end = mBuffer.endSegment(); - std::string first((char*)((*it).data()), (*it).size()); - ensure_equals("first part", first, std::string("zippity")); - ++it; - std::string second((char*)((*it).data()), (*it).size()); - ensure_equals("second part", second, std::string(" do da!")); - ++it; - ensure("iterators equal", (it == end)); - } - - template<> template<> - void bas_object::test<5>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream str(ch, &mBuffer); - std::string h1("hello"); - std::string h2(", how are you doing?"); - std::string expected(h1); - expected.append(h2); - str << h1 << h2; - str.flush(); - const S32 BUF_LEN = 128; - char buf[BUF_LEN]; - S32 actual_len = BUF_LEN; - S32 expected_len = h1.size() + h2.size(); - (void) mBuffer.readAfter(ch.out(), NULL, (U8*)buf, actual_len); - ensure_equals("streamed size", actual_len, expected_len); - buf[actual_len] = '\0'; - std::string actual(buf); - ensure_equals("streamed to buf", actual, expected); - } - - template<> template<> - void bas_object::test<6>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream bstr(ch, &mBuffer); - std::ostringstream ostr; - std::vector<LLUUID> ids; - LLUUID id; - for(int i = 0; i < 5; ++i) - { - id.generate(); - ids.push_back(id); - } - bstr << "SELECT concat(u.username, ' ', l.name) " - << "FROM user u, user_last_name l " - << "WHERE u.last_name_id = l.last_name_id" - << " AND u.agent_id IN ('"; - ostr << "SELECT concat(u.username, ' ', l.name) " - << "FROM user u, user_last_name l " - << "WHERE u.last_name_id = l.last_name_id" - << " AND u.agent_id IN ('"; - std::copy( - ids.begin(), - ids.end(), - std::ostream_iterator<LLUUID>(bstr, "','")); - std::copy( - ids.begin(), - ids.end(), - std::ostream_iterator<LLUUID>(ostr, "','")); - bstr.seekp(-2, std::ios::cur); - ostr.seekp(-2, std::ios::cur); - bstr << ") "; - ostr << ") "; - bstr.flush(); - const S32 BUF_LEN = 512; - char buf[BUF_LEN]; /* Flawfinder: ignore */ - S32 actual_len = BUF_LEN; - (void) mBuffer.readAfter(ch.out(), NULL, (U8*)buf, actual_len); - buf[actual_len] = '\0'; - std::string actual(buf); - std::string expected(ostr.str()); - ensure_equals("size of string in seek",actual.size(),expected.size()); - ensure_equals("seek in ostream", actual, expected); - } - - template<> template<> - void bas_object::test<7>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream bstr(ch, &mBuffer); - bstr << "1"; - bstr.flush(); - S32 count = mBuffer.countAfter(ch.out(), NULL); - ensure_equals("buffer size 1", count, 1); - LLBufferArray buffer; - buffer.append(ch.out(), (U8*)"2", 1); - mBuffer.takeContents(buffer); - count = mBuffer.countAfter(ch.out(), NULL); - ensure_equals("buffer size 2", count, 2); - bstr << "3"; - bstr.flush(); - count = mBuffer.countAfter(ch.out(), NULL); - ensure_equals("buffer size 3", count, 3); - U8* temp = new U8[count]; - mBuffer.readAfter(ch.out(), NULL, temp, count); - ensure("buffer content", (0 == memcmp(temp, (void*)"123", 3))); - delete[] temp; - } - - template<> template<> - void bas_object::test<8>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream ostr(ch, &mBuffer); - typedef std::vector<U8> buf_t; - typedef std::vector<buf_t> actual_t; - actual_t actual; - buf_t source; - bool need_comma = false; - ostr << "["; - S32 total_size = 1; - for(S32 i = 2000; i < 2003; ++i) - { - if(need_comma) - { - ostr << ","; - ++total_size; - } - need_comma = true; - srand(69 + i); /* Flawfinder: ignore */ - S32 size = rand() % 1000 + 1000; - std::generate_n( - std::back_insert_iterator<buf_t>(source), - size, - rand); - actual.push_back(source); - ostr << "b(" << size << ")\""; - total_size += 8; - ostr.write((const char*)(&source[0]), size); - total_size += size; - source.clear(); - ostr << "\""; - ++total_size; - } - ostr << "]"; - ++total_size; - ostr.flush(); - - // now that we have a bunch of data on a stream, parse it all. - ch = mBuffer.nextChannel(); - S32 count = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("size of buffer", count, total_size); - LLBufferStream istr(ch, &mBuffer); - LLSD data; - count = LLSDSerialize::fromNotation(data, istr, total_size); - ensure("sd parsed", data.isDefined()); - - for(S32 j = 0; j < 3; ++j) - { - std::ostringstream name; - LLSD child(data[j]); - name << "found buffer " << j; - ensure(name.str(), child.isDefined()); - source = child.asBinary(); - name.str(""); - name << "buffer " << j << " size"; - ensure_equals(name.str().c_str(), source.size(), actual[j].size()); - name.str(""); - name << "buffer " << j << " contents"; - ensure( - name.str(), - (0 == memcmp(&source[0], &actual[j][0], source.size()))); - } - } - - template<> template<> - void bas_object::test<9>() - { - LLChannelDescriptors ch = mBuffer.nextChannel(); - LLBufferStream ostr(ch, &mBuffer); - typedef std::vector<U8> buf_t; - buf_t source; - bool need_comma = false; - ostr << "{"; - S32 total_size = 1; - for(S32 i = 1000; i < 3000; ++i) - { - if(need_comma) - { - ostr << ","; - ++total_size; - } - need_comma = true; - ostr << "'" << i << "':"; - total_size += 7; - srand(69 + i); /* Flawfinder: ignore */ - S32 size = rand() % 1000 + 1000; - std::generate_n( - std::back_insert_iterator<buf_t>(source), - size, - rand); - ostr << "b(" << size << ")\""; - total_size += 8; - ostr.write((const char*)(&source[0]), size); - total_size += size; - source.clear(); - ostr << "\""; - ++total_size; - } - ostr << "}"; - ++total_size; - ostr.flush(); - - // now that we have a bunch of data on a stream, parse it all. - ch = mBuffer.nextChannel(); - S32 count = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("size of buffer", count, total_size); - LLBufferStream istr(ch, &mBuffer); - LLSD data; - count = LLSDSerialize::fromNotation(data, istr, total_size); - ensure("sd parsed", data.isDefined()); - } - - template<> template<> - void bas_object::test<10>() - { + struct buffer_and_stream_data + { + LLBufferArray mBuffer; + }; + typedef test_group<buffer_and_stream_data> bas_test; + typedef bas_test::object bas_object; + tut::bas_test tbs("buffer_stream"); + + template<> template<> + void bas_object::test<1>() + { + const char HELLO_WORLD[] = "hello world"; + const S32 str_len = strlen(HELLO_WORLD); /* Flawfinder: ignore */ + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream str(ch, &mBuffer); + mBuffer.append(ch.in(), (U8*)HELLO_WORLD, str_len); + std::string hello; + std::string world; + str >> hello >> world; + ensure_equals("first word", hello, std::string("hello")); + ensure_equals("second word", world, std::string("world")); + } + + template<> template<> + void bas_object::test<2>() + { + std::string part1("Eat my shor"); + std::string part2("ts ho"); + std::string part3("mer"); + std::string ignore("ignore me"); + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream str(ch, &mBuffer); + mBuffer.append(ch.in(), (U8*)part1.c_str(), part1.length()); + mBuffer.append(ch.in(), (U8*)part2.c_str(), part2.length()); + mBuffer.append(ch.out(), (U8*)ignore.c_str(), ignore.length()); + mBuffer.append(ch.in(), (U8*)part3.c_str(), part3.length()); + std::string eat; + std::string my; + std::string shorts; + std::string homer; + str >> eat >> my >> shorts >> homer; + ensure_equals("word1", eat, std::string("Eat")); + ensure_equals("word2", my, std::string("my")); + ensure_equals("word3", shorts, std::string("shorts")); + ensure_equals("word4", homer, std::string("homer")); + } + + template<> template<> + void bas_object::test<3>() + { + std::string part1("junk in "); + std::string part2("the trunk"); + const S32 CHANNEL = 0; + mBuffer.append(CHANNEL, (U8*)part1.c_str(), part1.length()); + mBuffer.append(CHANNEL, (U8*)part2.c_str(), part2.length()); + U8* last = 0; + const S32 BUF_LEN = 128; + char buf[BUF_LEN]; + S32 len = 11; + last = mBuffer.readAfter(CHANNEL, last, (U8*)buf, len); + buf[len] = '\0'; + std::string actual(buf); + ensure_equals("first read", actual, std::string("junk in the")); + last = mBuffer.seek(CHANNEL, last, -6); + len = 12; + last = mBuffer.readAfter(CHANNEL, last, (U8*)buf, len); + buf[len] = '\0'; + actual.assign(buf); + ensure_equals("seek and read", actual, std::string("in the trunk")); + } + + template<> template<> + void bas_object::test<4>() + { + std::string phrase("zippity do da!"); + const S32 CHANNEL = 0; + mBuffer.append(CHANNEL, (U8*)phrase.c_str(), phrase.length()); + const S32 BUF_LEN = 128; + char buf[BUF_LEN]; + S32 len = 7; + U8* last = mBuffer.readAfter(CHANNEL, NULL, (U8*)buf, len); + mBuffer.splitAfter(last); + LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); + LLBufferArray::segment_iterator_t end = mBuffer.endSegment(); + std::string first((char*)((*it).data()), (*it).size()); + ensure_equals("first part", first, std::string("zippity")); + ++it; + std::string second((char*)((*it).data()), (*it).size()); + ensure_equals("second part", second, std::string(" do da!")); + ++it; + ensure("iterators equal", (it == end)); + } + + template<> template<> + void bas_object::test<5>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream str(ch, &mBuffer); + std::string h1("hello"); + std::string h2(", how are you doing?"); + std::string expected(h1); + expected.append(h2); + str << h1 << h2; + str.flush(); + const S32 BUF_LEN = 128; + char buf[BUF_LEN]; + S32 actual_len = BUF_LEN; + S32 expected_len = h1.size() + h2.size(); + (void) mBuffer.readAfter(ch.out(), NULL, (U8*)buf, actual_len); + ensure_equals("streamed size", actual_len, expected_len); + buf[actual_len] = '\0'; + std::string actual(buf); + ensure_equals("streamed to buf", actual, expected); + } + + template<> template<> + void bas_object::test<6>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream bstr(ch, &mBuffer); + std::ostringstream ostr; + std::vector<LLUUID> ids; + LLUUID id; + for(int i = 0; i < 5; ++i) + { + id.generate(); + ids.push_back(id); + } + bstr << "SELECT concat(u.username, ' ', l.name) " + << "FROM user u, user_last_name l " + << "WHERE u.last_name_id = l.last_name_id" + << " AND u.agent_id IN ('"; + ostr << "SELECT concat(u.username, ' ', l.name) " + << "FROM user u, user_last_name l " + << "WHERE u.last_name_id = l.last_name_id" + << " AND u.agent_id IN ('"; + std::copy( + ids.begin(), + ids.end(), + std::ostream_iterator<LLUUID>(bstr, "','")); + std::copy( + ids.begin(), + ids.end(), + std::ostream_iterator<LLUUID>(ostr, "','")); + bstr.seekp(-2, std::ios::cur); + ostr.seekp(-2, std::ios::cur); + bstr << ") "; + ostr << ") "; + bstr.flush(); + const S32 BUF_LEN = 512; + char buf[BUF_LEN]; /* Flawfinder: ignore */ + S32 actual_len = BUF_LEN; + (void) mBuffer.readAfter(ch.out(), NULL, (U8*)buf, actual_len); + buf[actual_len] = '\0'; + std::string actual(buf); + std::string expected(ostr.str()); + ensure_equals("size of string in seek",actual.size(),expected.size()); + ensure_equals("seek in ostream", actual, expected); + } + + template<> template<> + void bas_object::test<7>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream bstr(ch, &mBuffer); + bstr << "1"; + bstr.flush(); + S32 count = mBuffer.countAfter(ch.out(), NULL); + ensure_equals("buffer size 1", count, 1); + LLBufferArray buffer; + buffer.append(ch.out(), (U8*)"2", 1); + mBuffer.takeContents(buffer); + count = mBuffer.countAfter(ch.out(), NULL); + ensure_equals("buffer size 2", count, 2); + bstr << "3"; + bstr.flush(); + count = mBuffer.countAfter(ch.out(), NULL); + ensure_equals("buffer size 3", count, 3); + U8* temp = new U8[count]; + mBuffer.readAfter(ch.out(), NULL, temp, count); + ensure("buffer content", (0 == memcmp(temp, (void*)"123", 3))); + delete[] temp; + } + + template<> template<> + void bas_object::test<8>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream ostr(ch, &mBuffer); + typedef std::vector<U8> buf_t; + typedef std::vector<buf_t> actual_t; + actual_t actual; + buf_t source; + bool need_comma = false; + ostr << "["; + S32 total_size = 1; + for(S32 i = 2000; i < 2003; ++i) + { + if(need_comma) + { + ostr << ","; + ++total_size; + } + need_comma = true; + srand(69 + i); /* Flawfinder: ignore */ + S32 size = rand() % 1000 + 1000; + std::generate_n( + std::back_insert_iterator<buf_t>(source), + size, + rand); + actual.push_back(source); + ostr << "b(" << size << ")\""; + total_size += 8; + ostr.write((const char*)(&source[0]), size); + total_size += size; + source.clear(); + ostr << "\""; + ++total_size; + } + ostr << "]"; + ++total_size; + ostr.flush(); + + // now that we have a bunch of data on a stream, parse it all. + ch = mBuffer.nextChannel(); + S32 count = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("size of buffer", count, total_size); + LLBufferStream istr(ch, &mBuffer); + LLSD data; + count = LLSDSerialize::fromNotation(data, istr, total_size); + ensure("sd parsed", data.isDefined()); + + for(S32 j = 0; j < 3; ++j) + { + std::ostringstream name; + LLSD child(data[j]); + name << "found buffer " << j; + ensure(name.str(), child.isDefined()); + source = child.asBinary(); + name.str(""); + name << "buffer " << j << " size"; + ensure_equals(name.str().c_str(), source.size(), actual[j].size()); + name.str(""); + name << "buffer " << j << " contents"; + ensure( + name.str(), + (0 == memcmp(&source[0], &actual[j][0], source.size()))); + } + } + + template<> template<> + void bas_object::test<9>() + { + LLChannelDescriptors ch = mBuffer.nextChannel(); + LLBufferStream ostr(ch, &mBuffer); + typedef std::vector<U8> buf_t; + buf_t source; + bool need_comma = false; + ostr << "{"; + S32 total_size = 1; + for(S32 i = 1000; i < 3000; ++i) + { + if(need_comma) + { + ostr << ","; + ++total_size; + } + need_comma = true; + ostr << "'" << i << "':"; + total_size += 7; + srand(69 + i); /* Flawfinder: ignore */ + S32 size = rand() % 1000 + 1000; + std::generate_n( + std::back_insert_iterator<buf_t>(source), + size, + rand); + ostr << "b(" << size << ")\""; + total_size += 8; + ostr.write((const char*)(&source[0]), size); + total_size += size; + source.clear(); + ostr << "\""; + ++total_size; + } + ostr << "}"; + ++total_size; + ostr.flush(); + + // now that we have a bunch of data on a stream, parse it all. + ch = mBuffer.nextChannel(); + S32 count = mBuffer.countAfter(ch.in(), NULL); + ensure_equals("size of buffer", count, total_size); + LLBufferStream istr(ch, &mBuffer); + LLSD data; + count = LLSDSerialize::fromNotation(data, istr, total_size); + ensure("sd parsed", data.isDefined()); + } + + template<> template<> + void bas_object::test<10>() + { //#if LL_WINDOWS && _MSC_VER >= 1400 // skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); //#endif - const char LOGIN_STREAM[] = "{'method':'login', 'parameter': [ {" - "'uri': 'sl-am:kellys.region.siva.lindenlab.com/location?start=url&px=128&py=128&pz=128&lx=0&ly=0&lz=0'}, " - "{'version': i1}, {'texture_data': [ '61d724fb-ad79-f637-2186-5cf457560daa', '6e38b9be-b7cc-e77a-8aec-029a42b0b416', " - "'a9073524-e89b-2924-ca6e-a81944109a1a', '658f18b5-5f1e-e593-f5d5-36c3abc7249a', '0cc799f4-8c99-6b91-bd75-b179b12429e2', " - "'59fd9b64-8300-a425-aad8-2ffcbe9a49d2', '59fd9b64-8300-a425-aad8-2ffcbe9a49d2', '5748decc-f629-461c-9a36-a35a221fe21f', " - "'b8fc9be2-26a6-6b47-690b-0e902e983484', 'a13ca0fe-3802-dc97-e79a-70d12171c724', 'dd9643cf-fd5d-0376-ed4a-b1cc646a97d5', " - "'4ad13ae9-a112-af09-210a-cf9353a7a9e7', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', " - "'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', " - "'5748decc-f629-461c-9a36-a35a221fe21f', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97']," - "'session_id': '324cfa9f-fe5d-4d1c-a317-35f20a86a4d1','position': [ i128, i128, i128],'last_name': 'Linden','group_title': '-> !BLING! <-','group_name': 'test!','agent_access': 'M'," - "'attachment_data': [ {'asset_id': 'aaede2b1-9955-09d4-5c93-2b557c778cf3','attachment_point': i6,'item_id': 'f3694abc-5122-db33-73d9-e0f4288dc2bf'}]," - "'buddy_ids': [ '101358d5-469d-4b24-9b85-4dc3c05e635d', '1b00fec7-6265-4875-acac-80d9cfe9295c', '203ad6df-b522-491d-ba48-4e24eb57aeff', " - "'22d4dcdb-aebb-47fa-b925-a871cc75ee48','27da3df5-1339-4463-80aa-40504ee3b3e5', '299d1720-b61f-4268-8c29-9614aa2d44c2', " - "'2b048a24-2737-4994-9fa5-becc8e466253', '2cd5dc14-a853-49a4-be3c-a5a7178e37bc', '3de548e1-57be-cfea-2b78-83ae3ad95998', " - "'3dee98e4-a6a3-4543-91c3-bbd528447ba7', '3e2d81a3-6263-6ffe-ad5c-8ce04bee07e9', '40e70b98-fed7-47f3-9700-1bce93f9350b', " - "'50a9b68e-b5aa-4d35-9137-3cfebda0a15c', '54295571-9357-43ff-ae74-a83b5138160f', '6191e2d7-5f96-4856-bdab-af0f79f47ae4', " - "'63e577d8-cd34-4235-a0a3-de0500133364', '79cfb666-4fd0-4af7-95df-fb7d96b4e24d', '8121c2f3-4a88-4c33-9899-8fc1273f47ee', " - "'909da964-ef23-4f2a-ba13-f2a8cfd454b6','a2e76fcd-9360-4f6d-a924-000000000001', 'aaa6d664-527e-4d83-9cbb-7ef79ccc7cc8', " - "'b79bfb6c-23be-49eb-b35b-30ff2f501b37', 'ba0d9c79-148c-4a79-8e3c-0665eebe2427', 'bc9bda98-57cd-498f-b993-4ff1ac9dec93', " - "'c62d16f6-81cb-419d-9cac-e46dc394084d', 'd48f8fa7-2512-4fe5-80c8-c0a923412e07', 'd77e3e24-7e6c-4c3f-96d0-a1746337f8fb', " - "'da615c63-a84b-4592-a3d6-a90dd3e92e6e', 'df47190a-7eb7-4aff-985f-2d1d3ad6c6e9', 'e3380196-72cd-499c-a2ba-caa180bd5fe4', " - "'e937863f-f134-4207-803b-d6e686651d6c', 'efcdf98b-5269-45ef-ac7a-0671f09ea9d9']," - "'circuit_code': i124,'group_id': '8615c885-9cf0-bf0a-6e40-0c11462aa652','limited_to_estate': i1,'look_at': [ i0, i0, i0]," - "'agent_id': '0e346d8b-4433-4d66-a6b0-fd37083abc4c','first_name': 'Kelly','start': 'url'}]}"; - LLChannelDescriptors ch = mBuffer.nextChannel(); - mBuffer.append(ch.out(), (U8*)LOGIN_STREAM, strlen(LOGIN_STREAM)); /* Flawfinder: ignore */ - ch = mBuffer.nextChannel(); - LLBufferStream istr(ch, &mBuffer); - LLSD data; - S32 count = LLSDSerialize::fromNotation( - data, - istr, - mBuffer.count(ch.in())); - ensure("parsed something", (count > 0)); - ensure("sd parsed", data.isDefined()); - ensure_equals("sd type", data.type(), LLSD::TypeMap); - ensure("has method", data.has("method")); - ensure("has parameter", data.has("parameter")); - LLSD parameter = data["parameter"]; - ensure_equals("parameter is array", parameter.type(), LLSD::TypeArray); - LLSD agent_params = parameter[2]; - std::string s_value; - s_value = agent_params["last_name"].asString(); - ensure_equals("last name", s_value, std::string("Linden")); - s_value = agent_params["first_name"].asString(); - ensure_equals("first name", s_value, std::string("Kelly")); - s_value = agent_params["agent_access"].asString(); - ensure_equals("agent access", s_value, std::string("M")); - s_value = agent_params["group_name"].asString(); - ensure_equals("group name", s_value, std::string("test!")); - s_value = agent_params["group_title"].asString(); - ensure_equals("group title", s_value, std::string("-> !BLING! <-")); - - LLUUID agent_id("0e346d8b-4433-4d66-a6b0-fd37083abc4c"); - LLUUID id = agent_params["agent_id"]; - ensure_equals("agent id", id, agent_id); - LLUUID session_id("324cfa9f-fe5d-4d1c-a317-35f20a86a4d1"); - id = agent_params["session_id"]; - ensure_equals("session id", id, session_id); - LLUUID group_id ("8615c885-9cf0-bf0a-6e40-0c11462aa652"); - id = agent_params["group_id"]; - ensure_equals("group id", id, group_id); - - S32 i_val = agent_params["limited_to_estate"]; - ensure_equals("limited to estate", i_val, 1); - i_val = agent_params["circuit_code"]; - ensure_equals("circuit code", i_val, 124); - } - - - template<> template<> - void bas_object::test<11>() - { - std::string val = "{!'foo'@:#'bar'}"; - std::istringstream istr; - istr.str(val); - LLSD sd; - S32 count = LLSDSerialize::fromNotation(sd, istr, val.size()); - ensure_equals("parser error return value", count, -1); - ensure("data undefined", sd.isUndefined()); - } - - template<> template<> - void bas_object::test<12>() - { + const char LOGIN_STREAM[] = "{'method':'login', 'parameter': [ {" + "'uri': 'sl-am:kellys.region.siva.lindenlab.com/location?start=url&px=128&py=128&pz=128&lx=0&ly=0&lz=0'}, " + "{'version': i1}, {'texture_data': [ '61d724fb-ad79-f637-2186-5cf457560daa', '6e38b9be-b7cc-e77a-8aec-029a42b0b416', " + "'a9073524-e89b-2924-ca6e-a81944109a1a', '658f18b5-5f1e-e593-f5d5-36c3abc7249a', '0cc799f4-8c99-6b91-bd75-b179b12429e2', " + "'59fd9b64-8300-a425-aad8-2ffcbe9a49d2', '59fd9b64-8300-a425-aad8-2ffcbe9a49d2', '5748decc-f629-461c-9a36-a35a221fe21f', " + "'b8fc9be2-26a6-6b47-690b-0e902e983484', 'a13ca0fe-3802-dc97-e79a-70d12171c724', 'dd9643cf-fd5d-0376-ed4a-b1cc646a97d5', " + "'4ad13ae9-a112-af09-210a-cf9353a7a9e7', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', " + "'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', " + "'5748decc-f629-461c-9a36-a35a221fe21f', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97', 'c228d1cf-4b5d-4ba8-84f4-899a0796aa97']," + "'session_id': '324cfa9f-fe5d-4d1c-a317-35f20a86a4d1','position': [ i128, i128, i128],'last_name': 'Linden','group_title': '-> !BLING! <-','group_name': 'test!','agent_access': 'M'," + "'attachment_data': [ {'asset_id': 'aaede2b1-9955-09d4-5c93-2b557c778cf3','attachment_point': i6,'item_id': 'f3694abc-5122-db33-73d9-e0f4288dc2bf'}]," + "'buddy_ids': [ '101358d5-469d-4b24-9b85-4dc3c05e635d', '1b00fec7-6265-4875-acac-80d9cfe9295c', '203ad6df-b522-491d-ba48-4e24eb57aeff', " + "'22d4dcdb-aebb-47fa-b925-a871cc75ee48','27da3df5-1339-4463-80aa-40504ee3b3e5', '299d1720-b61f-4268-8c29-9614aa2d44c2', " + "'2b048a24-2737-4994-9fa5-becc8e466253', '2cd5dc14-a853-49a4-be3c-a5a7178e37bc', '3de548e1-57be-cfea-2b78-83ae3ad95998', " + "'3dee98e4-a6a3-4543-91c3-bbd528447ba7', '3e2d81a3-6263-6ffe-ad5c-8ce04bee07e9', '40e70b98-fed7-47f3-9700-1bce93f9350b', " + "'50a9b68e-b5aa-4d35-9137-3cfebda0a15c', '54295571-9357-43ff-ae74-a83b5138160f', '6191e2d7-5f96-4856-bdab-af0f79f47ae4', " + "'63e577d8-cd34-4235-a0a3-de0500133364', '79cfb666-4fd0-4af7-95df-fb7d96b4e24d', '8121c2f3-4a88-4c33-9899-8fc1273f47ee', " + "'909da964-ef23-4f2a-ba13-f2a8cfd454b6','a2e76fcd-9360-4f6d-a924-000000000001', 'aaa6d664-527e-4d83-9cbb-7ef79ccc7cc8', " + "'b79bfb6c-23be-49eb-b35b-30ff2f501b37', 'ba0d9c79-148c-4a79-8e3c-0665eebe2427', 'bc9bda98-57cd-498f-b993-4ff1ac9dec93', " + "'c62d16f6-81cb-419d-9cac-e46dc394084d', 'd48f8fa7-2512-4fe5-80c8-c0a923412e07', 'd77e3e24-7e6c-4c3f-96d0-a1746337f8fb', " + "'da615c63-a84b-4592-a3d6-a90dd3e92e6e', 'df47190a-7eb7-4aff-985f-2d1d3ad6c6e9', 'e3380196-72cd-499c-a2ba-caa180bd5fe4', " + "'e937863f-f134-4207-803b-d6e686651d6c', 'efcdf98b-5269-45ef-ac7a-0671f09ea9d9']," + "'circuit_code': i124,'group_id': '8615c885-9cf0-bf0a-6e40-0c11462aa652','limited_to_estate': i1,'look_at': [ i0, i0, i0]," + "'agent_id': '0e346d8b-4433-4d66-a6b0-fd37083abc4c','first_name': 'Kelly','start': 'url'}]}"; + LLChannelDescriptors ch = mBuffer.nextChannel(); + mBuffer.append(ch.out(), (U8*)LOGIN_STREAM, strlen(LOGIN_STREAM)); /* Flawfinder: ignore */ + ch = mBuffer.nextChannel(); + LLBufferStream istr(ch, &mBuffer); + LLSD data; + S32 count = LLSDSerialize::fromNotation( + data, + istr, + mBuffer.count(ch.in())); + ensure("parsed something", (count > 0)); + ensure("sd parsed", data.isDefined()); + ensure_equals("sd type", data.type(), LLSD::TypeMap); + ensure("has method", data.has("method")); + ensure("has parameter", data.has("parameter")); + LLSD parameter = data["parameter"]; + ensure_equals("parameter is array", parameter.type(), LLSD::TypeArray); + LLSD agent_params = parameter[2]; + std::string s_value; + s_value = agent_params["last_name"].asString(); + ensure_equals("last name", s_value, std::string("Linden")); + s_value = agent_params["first_name"].asString(); + ensure_equals("first name", s_value, std::string("Kelly")); + s_value = agent_params["agent_access"].asString(); + ensure_equals("agent access", s_value, std::string("M")); + s_value = agent_params["group_name"].asString(); + ensure_equals("group name", s_value, std::string("test!")); + s_value = agent_params["group_title"].asString(); + ensure_equals("group title", s_value, std::string("-> !BLING! <-")); + + LLUUID agent_id("0e346d8b-4433-4d66-a6b0-fd37083abc4c"); + LLUUID id = agent_params["agent_id"]; + ensure_equals("agent id", id, agent_id); + LLUUID session_id("324cfa9f-fe5d-4d1c-a317-35f20a86a4d1"); + id = agent_params["session_id"]; + ensure_equals("session id", id, session_id); + LLUUID group_id ("8615c885-9cf0-bf0a-6e40-0c11462aa652"); + id = agent_params["group_id"]; + ensure_equals("group id", id, group_id); + + S32 i_val = agent_params["limited_to_estate"]; + ensure_equals("limited to estate", i_val, 1); + i_val = agent_params["circuit_code"]; + ensure_equals("circuit code", i_val, 124); + } + + + template<> template<> + void bas_object::test<11>() + { + std::string val = "{!'foo'@:#'bar'}"; + std::istringstream istr; + istr.str(val); + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, istr, val.size()); + ensure_equals("parser error return value", count, -1); + ensure("data undefined", sd.isUndefined()); + } + + template<> template<> + void bas_object::test<12>() + { //#if LL_WINDOWS && _MSC_VER >= 1400 // skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); //#endif - std::string val = "{!'foo':[i1,'hi',{@'bar'#:[$i2%,^'baz'&]*}+]=}"; - std::istringstream istr; - istr.str(val); - LLSD sd; - S32 count = LLSDSerialize::fromNotation(sd, istr, val.size()); - ensure_equals("parser error return value", count, -1); - ensure("data undefined", sd.isUndefined()); - } + std::string val = "{!'foo':[i1,'hi',{@'bar'#:[$i2%,^'baz'&]*}+]=}"; + std::istringstream istr; + istr.str(val); + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, istr, val.size()); + ensure_equals("parser error return value", count, -1); + ensure("data undefined", sd.isUndefined()); + } /* - template<> template<> - void bas_object::test<13>() - { - } - template<> template<> - void bas_object::test<14>() - { - } - template<> template<> - void bas_object::test<15>() - { - } + template<> template<> + void bas_object::test<13>() + { + } + template<> template<> + void bas_object::test<14>() + { + } + template<> template<> + void bas_object::test<15>() + { + } */ } namespace tut { - class PumpAndChainTestData - { - protected: - apr_pool_t* mPool; - LLPumpIO* mPump; - LLPumpIO::chain_t mChain; - - public: - PumpAndChainTestData() - { - apr_pool_create(&mPool, NULL); - mPump = new LLPumpIO(mPool); - } - - ~PumpAndChainTestData() - { - mChain.clear(); - delete mPump; - apr_pool_destroy(mPool); - } - }; - typedef test_group<PumpAndChainTestData> PumpAndChainTestGroup; - typedef PumpAndChainTestGroup::object PumpAndChainTestObject; - PumpAndChainTestGroup pumpAndChainTestGroup("pump_and_chain"); - - template<> template<> - void PumpAndChainTestObject::test<1>() - { - LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); - - mChain.push_back(LLIOPipe::ptr_t(new LLIOFlush)); - mChain.push_back(LLIOPipe::ptr_t(extractor)); - - LLTimer timer; - timer.setTimerExpirySec(100.0f); - - mPump->addChain(mChain, DEFAULT_CHAIN_EXPIRY_SECS); - while(!extractor->done() && !timer.hasExpired()) - { - mPump->pump(); - mPump->callback(); - } - - ensure("reading string finished", extractor->done()); - ensure_equals("string was empty", extractor->string(), ""); - } + class PumpAndChainTestData + { + protected: + apr_pool_t* mPool; + LLPumpIO* mPump; + LLPumpIO::chain_t mChain; + + public: + PumpAndChainTestData() + { + apr_pool_create(&mPool, NULL); + mPump = new LLPumpIO(mPool); + } + + ~PumpAndChainTestData() + { + mChain.clear(); + delete mPump; + apr_pool_destroy(mPool); + } + }; + typedef test_group<PumpAndChainTestData> PumpAndChainTestGroup; + typedef PumpAndChainTestGroup::object PumpAndChainTestObject; + PumpAndChainTestGroup pumpAndChainTestGroup("pump_and_chain"); + + template<> template<> + void PumpAndChainTestObject::test<1>() + { + LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); + + mChain.push_back(LLIOPipe::ptr_t(new LLIOFlush)); + mChain.push_back(LLIOPipe::ptr_t(extractor)); + + LLTimer timer; + timer.setTimerExpirySec(100.0f); + + mPump->addChain(mChain, DEFAULT_CHAIN_EXPIRY_SECS); + while(!extractor->done() && !timer.hasExpired()) + { + mPump->pump(); + mPump->callback(); + } + + ensure("reading string finished", extractor->done()); + ensure_equals("string was empty", extractor->string(), ""); + } } /* namespace tut { - struct double_construct - { - public: - double_construct() - { - LL_INFOS() << "constructed" << LL_ENDL; - } - ~double_construct() - { - LL_INFOS() << "destroyed" << LL_ENDL; - } - }; - typedef test_group<double_construct> double_construct_test_group; - typedef double_construct_test_group::object dc_test_object; - double_construct_test_group dctest("double construct"); - template<> template<> - void dc_test_object::test<1>() - { - ensure("test 1", true); - } + struct double_construct + { + public: + double_construct() + { + LL_INFOS() << "constructed" << LL_ENDL; + } + ~double_construct() + { + LL_INFOS() << "destroyed" << LL_ENDL; + } + }; + typedef test_group<double_construct> double_construct_test_group; + typedef double_construct_test_group::object dc_test_object; + double_construct_test_group dctest("double construct"); + template<> template<> + void dc_test_object::test<1>() + { + ensure("test 1", true); + } } */ namespace tut { - /** - * @brief we want to test the pipes & pumps under bad conditions. - */ - struct pipe_and_pump_fitness - { - public: - enum - { - SERVER_LISTEN_PORT = 13050 - }; - - pipe_and_pump_fitness() - { - LLFrameTimer::updateFrameTime(); - apr_pool_create(&mPool, NULL); - mPump = new LLPumpIO(mPool); - mSocket = LLSocket::create( - mPool, - LLSocket::STREAM_TCP, - SERVER_LISTEN_PORT, - "127.0.0.1"); - } - - ~pipe_and_pump_fitness() - { - mSocket.reset(); - delete mPump; - apr_pool_destroy(mPool); - } - - protected: - apr_pool_t* mPool; - LLPumpIO* mPump; - LLSocket::ptr_t mSocket; - }; - typedef test_group<pipe_and_pump_fitness> fitness_test_group; - typedef fitness_test_group::object fitness_test_object; - fitness_test_group fitness("pipe and pump fitness"); - - template<> template<> - void fitness_test_object::test<1>() - { - LL_DEBUGS() << "fitness_test_object::test<1>()" << LL_ENDL; - - // Set up the server - //LL_DEBUGS() << "fitness_test_object::test<1> - setting up server." - // << LL_ENDL; - LLPumpIO::chain_t chain; - typedef LLCloneIOFactory<LLPipeStringInjector> emitter_t; - emitter_t* emitter = new emitter_t( - new LLPipeStringInjector("suckers never play me")); - std::shared_ptr<LLChainIOFactory> factory(emitter); - LLIOServerSocket* server = new LLIOServerSocket( - mPool, - mSocket, - factory); - server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS); - chain.push_back(LLIOPipe::ptr_t(server)); - mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - - // We need to tickle the pump a little to set up the listen() - //LL_DEBUGS() << "fitness_test_object::test<1> - initializing server." - // << LL_ENDL; - pump_loop(mPump, 0.1f); - - // Set up the client - //LL_DEBUGS() << "fitness_test_object::test<1> - connecting client." - // << LL_ENDL; - LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); - LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); - bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); - LL_DEBUGS() << "connected" << LL_ENDL; - - // We have connected, since the socket reader does not block, - // the first call to read data will return EAGAIN, so we need - // to write something. - chain.clear(); - chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); - chain.push_back(LLIOPipe::ptr_t(new LLIONull)); - mPump->addChain(chain, 1.0f); - - // Now, the server should immediately send the data, but we'll - // never read it. pump for a bit - F32 elapsed = pump_loop(mPump, 2.0f); - ensure("Did not take too long", (elapsed < 3.0f)); - } - - template<> template<> - void fitness_test_object::test<2>() - { - LL_DEBUGS() << "fitness_test_object::test<2>()" << LL_ENDL; - - // Set up the server - LLPumpIO::chain_t chain; - typedef LLCloneIOFactory<LLIOFuzz> emitter_t; - emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); - std::shared_ptr<LLChainIOFactory> factory(emitter); - LLIOServerSocket* server = new LLIOServerSocket( - mPool, - mSocket, - factory); - server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS); - chain.push_back(LLIOPipe::ptr_t(server)); - mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - - // We need to tickle the pump a little to set up the listen() - pump_loop(mPump, 0.1f); - - // Set up the client - LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); - LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); - bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); - LL_DEBUGS() << "connected" << LL_ENDL; - - // We have connected, since the socket reader does not block, - // the first call to read data will return EAGAIN, so we need - // to write something. - chain.clear(); - chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); - chain.push_back(LLIOPipe::ptr_t(new LLIONull)); - mPump->addChain(chain, SHORT_CHAIN_EXPIRY_SECS / 2.0f); - - // Now, the server should immediately send the data, but we'll - // never read it. pump for a bit - F32 elapsed = pump_loop(mPump, SHORT_CHAIN_EXPIRY_SECS * 2.0f); - ensure("Did not take too long", (elapsed < 3.0f)); - } - - template<> template<> - void fitness_test_object::test<3>() - { - LL_DEBUGS() << "fitness_test_object::test<3>()" << LL_ENDL; - - // Set up the server - LLPumpIO::chain_t chain; - typedef LLCloneIOFactory<LLIOFuzz> emitter_t; - emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); - std::shared_ptr<LLChainIOFactory> factory(emitter); - LLIOServerSocket* server = new LLIOServerSocket( - mPool, - mSocket, - factory); - server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS); - chain.push_back(LLIOPipe::ptr_t(server)); - mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - - // We need to tickle the pump a little to set up the listen() - pump_loop(mPump, 0.1f); - - // Set up the client - LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); - LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); - bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); - LL_DEBUGS() << "connected" << LL_ENDL; - - // We have connected, since the socket reader does not block, - // the first call to read data will return EAGAIN, so we need - // to write something. - chain.clear(); - chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); - chain.push_back(LLIOPipe::ptr_t(new LLIONull)); - mPump->addChain(chain, SHORT_CHAIN_EXPIRY_SECS * 2.0f); - - // Now, the server should immediately send the data, but we'll - // never read it. pump for a bit - F32 elapsed = pump_loop(mPump, SHORT_CHAIN_EXPIRY_SECS * 2.0f + 1.0f); - ensure("Did not take too long", (elapsed < 4.0f)); - } - - template<> template<> - void fitness_test_object::test<4>() - { - LL_DEBUGS() << "fitness_test_object::test<4>()" << LL_ENDL; - - // Set up the server - LLPumpIO::chain_t chain; - typedef LLCloneIOFactory<LLIOFuzz> emitter_t; - emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); - std::shared_ptr<LLChainIOFactory> factory(emitter); - LLIOServerSocket* server = new LLIOServerSocket( - mPool, - mSocket, - factory); - server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS + 1.80f); - chain.push_back(LLIOPipe::ptr_t(server)); - mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - - // We need to tickle the pump a little to set up the listen() - pump_loop(mPump, 0.1f); - - // Set up the client - LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); - LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); - bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); - LL_DEBUGS() << "connected" << LL_ENDL; - - // We have connected, since the socket reader does not block, - // the first call to read data will return EAGAIN, so we need - // to write something. - chain.clear(); - chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); - chain.push_back(LLIOPipe::ptr_t(new LLIONull)); - mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - - // Now, the server should immediately send the data, but we'll - // never read it. pump for a bit - F32 elapsed = pump_loop(mPump, SHORT_CHAIN_EXPIRY_SECS + 3.0f); - ensure("Did not take too long", (elapsed < DEFAULT_CHAIN_EXPIRY_SECS)); - } - - template<> template<> - void fitness_test_object::test<5>() - { - // Set up the server - LLPumpIO::chain_t chain; - typedef LLCloneIOFactory<LLIOSleeper> sleeper_t; - sleeper_t* sleeper = new sleeper_t(new LLIOSleeper); - std::shared_ptr<LLChainIOFactory> factory(sleeper); - LLIOServerSocket* server = new LLIOServerSocket( - mPool, - mSocket, - factory); - server->setResponseTimeout(1.0); - chain.push_back(LLIOPipe::ptr_t(server)); - mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); - // We need to tickle the pump a little to set up the listen() - pump_loop(mPump, 0.1f); - U32 count = mPump->runningChains(); - ensure_equals("server chain onboard", count, 1); - LL_DEBUGS() << "** Server is up." << LL_ENDL; - - // Set up the client - LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); - LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); - bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); - LL_DEBUGS() << "connected" << LL_ENDL; - pump_loop(mPump,0.1f); - count = mPump->runningChains(); - ensure_equals("server chain onboard", count, 2); - LL_DEBUGS() << "** Client is connected." << LL_ENDL; - - // We have connected, since the socket reader does not block, - // the first call to read data will return EAGAIN, so we need - // to write something. - chain.clear(); - chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); - chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); - chain.push_back(LLIOPipe::ptr_t(new LLIONull)); - mPump->addChain(chain, 0.2f); - chain.clear(); - - // pump for a bit and make sure all 3 chains are running - pump_loop(mPump,0.1f); - count = mPump->runningChains(); - // ensure_equals("client chain onboard", count, 3); commented out because it fails frequently - appears to be timing sensitive - LL_DEBUGS() << "** request should have been sent." << LL_ENDL; - - // pump for long enough the the client socket closes, and the - // server socket should not be closed yet. - pump_loop(mPump,0.2f); - count = mPump->runningChains(); - ensure_equals("client chain timed out ", count, 2); - LL_DEBUGS() << "** client chain should be closed." << LL_ENDL; - - // At this point, the socket should be closed by the timeout - pump_loop(mPump,1.0f); - count = mPump->runningChains(); - ensure_equals("accepted socked close", count, 1); - LL_DEBUGS() << "** Sleeper should have timed out.." << LL_ENDL; - } + /** + * @brief we want to test the pipes & pumps under bad conditions. + */ + struct pipe_and_pump_fitness + { + public: + enum + { + SERVER_LISTEN_PORT = 13050 + }; + + pipe_and_pump_fitness() + { + LLFrameTimer::updateFrameTime(); + apr_pool_create(&mPool, NULL); + mPump = new LLPumpIO(mPool); + mSocket = LLSocket::create( + mPool, + LLSocket::STREAM_TCP, + SERVER_LISTEN_PORT, + "127.0.0.1"); + } + + ~pipe_and_pump_fitness() + { + mSocket.reset(); + delete mPump; + apr_pool_destroy(mPool); + } + + protected: + apr_pool_t* mPool; + LLPumpIO* mPump; + LLSocket::ptr_t mSocket; + }; + typedef test_group<pipe_and_pump_fitness> fitness_test_group; + typedef fitness_test_group::object fitness_test_object; + fitness_test_group fitness("pipe and pump fitness"); + + template<> template<> + void fitness_test_object::test<1>() + { + LL_DEBUGS() << "fitness_test_object::test<1>()" << LL_ENDL; + + // Set up the server + //LL_DEBUGS() << "fitness_test_object::test<1> - setting up server." + // << LL_ENDL; + LLPumpIO::chain_t chain; + typedef LLCloneIOFactory<LLPipeStringInjector> emitter_t; + emitter_t* emitter = new emitter_t( + new LLPipeStringInjector("suckers never play me")); + std::shared_ptr<LLChainIOFactory> factory(emitter); + LLIOServerSocket* server = new LLIOServerSocket( + mPool, + mSocket, + factory); + server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS); + chain.push_back(LLIOPipe::ptr_t(server)); + mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); + + // We need to tickle the pump a little to set up the listen() + //LL_DEBUGS() << "fitness_test_object::test<1> - initializing server." + // << LL_ENDL; + pump_loop(mPump, 0.1f); + + // Set up the client + //LL_DEBUGS() << "fitness_test_object::test<1> - connecting client." + // << LL_ENDL; + LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); + LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); + bool connected = client->blockingConnect(server_host); + ensure("Connected to server", connected); + LL_DEBUGS() << "connected" << LL_ENDL; + + // We have connected, since the socket reader does not block, + // the first call to read data will return EAGAIN, so we need + // to write something. + chain.clear(); + chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); + chain.push_back(LLIOPipe::ptr_t(new LLIONull)); + mPump->addChain(chain, 1.0f); + + // Now, the server should immediately send the data, but we'll + // never read it. pump for a bit + F32 elapsed = pump_loop(mPump, 2.0f); + ensure("Did not take too long", (elapsed < 3.0f)); + } + + template<> template<> + void fitness_test_object::test<2>() + { + LL_DEBUGS() << "fitness_test_object::test<2>()" << LL_ENDL; + + // Set up the server + LLPumpIO::chain_t chain; + typedef LLCloneIOFactory<LLIOFuzz> emitter_t; + emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); + std::shared_ptr<LLChainIOFactory> factory(emitter); + LLIOServerSocket* server = new LLIOServerSocket( + mPool, + mSocket, + factory); + server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS); + chain.push_back(LLIOPipe::ptr_t(server)); + mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); + + // We need to tickle the pump a little to set up the listen() + pump_loop(mPump, 0.1f); + + // Set up the client + LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); + LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); + bool connected = client->blockingConnect(server_host); + ensure("Connected to server", connected); + LL_DEBUGS() << "connected" << LL_ENDL; + + // We have connected, since the socket reader does not block, + // the first call to read data will return EAGAIN, so we need + // to write something. + chain.clear(); + chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); + chain.push_back(LLIOPipe::ptr_t(new LLIONull)); + mPump->addChain(chain, SHORT_CHAIN_EXPIRY_SECS / 2.0f); + + // Now, the server should immediately send the data, but we'll + // never read it. pump for a bit + F32 elapsed = pump_loop(mPump, SHORT_CHAIN_EXPIRY_SECS * 2.0f); + ensure("Did not take too long", (elapsed < 3.0f)); + } + + template<> template<> + void fitness_test_object::test<3>() + { + LL_DEBUGS() << "fitness_test_object::test<3>()" << LL_ENDL; + + // Set up the server + LLPumpIO::chain_t chain; + typedef LLCloneIOFactory<LLIOFuzz> emitter_t; + emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); + std::shared_ptr<LLChainIOFactory> factory(emitter); + LLIOServerSocket* server = new LLIOServerSocket( + mPool, + mSocket, + factory); + server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS); + chain.push_back(LLIOPipe::ptr_t(server)); + mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); + + // We need to tickle the pump a little to set up the listen() + pump_loop(mPump, 0.1f); + + // Set up the client + LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); + LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); + bool connected = client->blockingConnect(server_host); + ensure("Connected to server", connected); + LL_DEBUGS() << "connected" << LL_ENDL; + + // We have connected, since the socket reader does not block, + // the first call to read data will return EAGAIN, so we need + // to write something. + chain.clear(); + chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); + chain.push_back(LLIOPipe::ptr_t(new LLIONull)); + mPump->addChain(chain, SHORT_CHAIN_EXPIRY_SECS * 2.0f); + + // Now, the server should immediately send the data, but we'll + // never read it. pump for a bit + F32 elapsed = pump_loop(mPump, SHORT_CHAIN_EXPIRY_SECS * 2.0f + 1.0f); + ensure("Did not take too long", (elapsed < 4.0f)); + } + + template<> template<> + void fitness_test_object::test<4>() + { + LL_DEBUGS() << "fitness_test_object::test<4>()" << LL_ENDL; + + // Set up the server + LLPumpIO::chain_t chain; + typedef LLCloneIOFactory<LLIOFuzz> emitter_t; + emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); + std::shared_ptr<LLChainIOFactory> factory(emitter); + LLIOServerSocket* server = new LLIOServerSocket( + mPool, + mSocket, + factory); + server->setResponseTimeout(SHORT_CHAIN_EXPIRY_SECS + 1.80f); + chain.push_back(LLIOPipe::ptr_t(server)); + mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); + + // We need to tickle the pump a little to set up the listen() + pump_loop(mPump, 0.1f); + + // Set up the client + LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); + LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); + bool connected = client->blockingConnect(server_host); + ensure("Connected to server", connected); + LL_DEBUGS() << "connected" << LL_ENDL; + + // We have connected, since the socket reader does not block, + // the first call to read data will return EAGAIN, so we need + // to write something. + chain.clear(); + chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); + chain.push_back(LLIOPipe::ptr_t(new LLIONull)); + mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); + + // Now, the server should immediately send the data, but we'll + // never read it. pump for a bit + F32 elapsed = pump_loop(mPump, SHORT_CHAIN_EXPIRY_SECS + 3.0f); + ensure("Did not take too long", (elapsed < DEFAULT_CHAIN_EXPIRY_SECS)); + } + + template<> template<> + void fitness_test_object::test<5>() + { + // Set up the server + LLPumpIO::chain_t chain; + typedef LLCloneIOFactory<LLIOSleeper> sleeper_t; + sleeper_t* sleeper = new sleeper_t(new LLIOSleeper); + std::shared_ptr<LLChainIOFactory> factory(sleeper); + LLIOServerSocket* server = new LLIOServerSocket( + mPool, + mSocket, + factory); + server->setResponseTimeout(1.0); + chain.push_back(LLIOPipe::ptr_t(server)); + mPump->addChain(chain, NEVER_CHAIN_EXPIRY_SECS); + // We need to tickle the pump a little to set up the listen() + pump_loop(mPump, 0.1f); + U32 count = mPump->runningChains(); + ensure_equals("server chain onboard", count, 1); + LL_DEBUGS() << "** Server is up." << LL_ENDL; + + // Set up the client + LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); + LLHost server_host("127.0.0.1", SERVER_LISTEN_PORT); + bool connected = client->blockingConnect(server_host); + ensure("Connected to server", connected); + LL_DEBUGS() << "connected" << LL_ENDL; + pump_loop(mPump,0.1f); + count = mPump->runningChains(); + ensure_equals("server chain onboard", count, 2); + LL_DEBUGS() << "** Client is connected." << LL_ENDL; + + // We have connected, since the socket reader does not block, + // the first call to read data will return EAGAIN, so we need + // to write something. + chain.clear(); + chain.push_back(LLIOPipe::ptr_t(new LLPipeStringInjector("hi"))); + chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(client))); + chain.push_back(LLIOPipe::ptr_t(new LLIONull)); + mPump->addChain(chain, 0.2f); + chain.clear(); + + // pump for a bit and make sure all 3 chains are running + pump_loop(mPump,0.1f); + count = mPump->runningChains(); + // ensure_equals("client chain onboard", count, 3); commented out because it fails frequently - appears to be timing sensitive + LL_DEBUGS() << "** request should have been sent." << LL_ENDL; + + // pump for long enough the the client socket closes, and the + // server socket should not be closed yet. + pump_loop(mPump,0.2f); + count = mPump->runningChains(); + ensure_equals("client chain timed out ", count, 2); + LL_DEBUGS() << "** client chain should be closed." << LL_ENDL; + + // At this point, the socket should be closed by the timeout + pump_loop(mPump,1.0f); + count = mPump->runningChains(); + ensure_equals("accepted socked close", count, 1); + LL_DEBUGS() << "** Sleeper should have timed out.." << LL_ENDL; + } } /* diff --git a/indra/test/llapp_tut.cpp b/indra/test/llapp_tut.cpp index 98e714a497..114af6edbf 100644 --- a/indra/test/llapp_tut.cpp +++ b/indra/test/llapp_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llapp_tut.cpp * @author Phoenix * @date 2006-09-12 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2006-2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,129 +34,129 @@ namespace tut { - struct application - { - class LLTestApp : public LLApp - { - public: - virtual bool init() { return true; } - virtual bool cleanup() { return true; } - virtual bool frame() { return true; } - }; - LLTestApp* mApp; - application() - { - mApp = new LLTestApp; - } - ~application() - { - delete mApp; - } - }; + struct application + { + class LLTestApp : public LLApp + { + public: + virtual bool init() { return true; } + virtual bool cleanup() { return true; } + virtual bool frame() { return true; } + }; + LLTestApp* mApp; + application() + { + mApp = new LLTestApp; + } + ~application() + { + delete mApp; + } + }; - typedef test_group<application> application_t; - typedef application_t::object application_object_t; - tut::application_t tut_application("application"); + typedef test_group<application> application_t; + typedef application_t::object application_object_t; + tut::application_t tut_application("application"); - template<> template<> - void application_object_t::test<1>() - { - LLSD defaults; - defaults["template"] = "../../../scripts/messages/message_template.msg"; - defaults["configdir"] = "."; - defaults["datadir"] = "data"; - mApp->setOptionData(LLApp::PRIORITY_DEFAULT, defaults); + template<> template<> + void application_object_t::test<1>() + { + LLSD defaults; + defaults["template"] = "../../../scripts/messages/message_template.msg"; + defaults["configdir"] = "."; + defaults["datadir"] = "data"; + mApp->setOptionData(LLApp::PRIORITY_DEFAULT, defaults); - LLSD datadir_sd = mApp->getOption("datadir"); - ensure_equals("data type", datadir_sd.type(), LLSD::TypeString); - ensure_equals( - "data value", datadir_sd.asString(), std::string("data")); - } + LLSD datadir_sd = mApp->getOption("datadir"); + ensure_equals("data type", datadir_sd.type(), LLSD::TypeString); + ensure_equals( + "data value", datadir_sd.asString(), std::string("data")); + } - template<> template<> - void application_object_t::test<2>() - { - const int ARGC = 13; - const char* ARGV[ARGC] = - { - "", // argv[0] is usually the application name - "-crashcount", - "2", - "-space", - "spaceserver.grid.lindenlab.com", - "-db_host", - "localhost", - "--allowlslhttprequests", - "-asset-uri", - "http://test.lindenlab.com/assets", - "-data", - "127.0.0.1", - "--smtp" - }; - bool ok = mApp->parseCommandOptions(ARGC, const_cast<char**>(ARGV)); - ensure("command line parsed", ok); - ensure_equals( - "crashcount", mApp->getOption("crashcount").asInteger(), 2); - ensure_equals( - "space", - mApp->getOption("space").asString(), - std::string("spaceserver.grid.lindenlab.com")); - ensure_equals( - "db_host", - mApp->getOption("db_host").asString(), - std::string("localhost")); - ensure("allowlshlttprequests", mApp->getOption("smtp")); - ensure_equals( - "asset-uri", - mApp->getOption("asset-uri").asString(), - std::string("http://test.lindenlab.com/assets")); - ensure_equals( - "data", - mApp->getOption("data").asString(), - std::string("127.0.0.1")); - ensure("smtp", mApp->getOption("smtp")); - } + template<> template<> + void application_object_t::test<2>() + { + const int ARGC = 13; + const char* ARGV[ARGC] = + { + "", // argv[0] is usually the application name + "-crashcount", + "2", + "-space", + "spaceserver.grid.lindenlab.com", + "-db_host", + "localhost", + "--allowlslhttprequests", + "-asset-uri", + "http://test.lindenlab.com/assets", + "-data", + "127.0.0.1", + "--smtp" + }; + bool ok = mApp->parseCommandOptions(ARGC, const_cast<char**>(ARGV)); + ensure("command line parsed", ok); + ensure_equals( + "crashcount", mApp->getOption("crashcount").asInteger(), 2); + ensure_equals( + "space", + mApp->getOption("space").asString(), + std::string("spaceserver.grid.lindenlab.com")); + ensure_equals( + "db_host", + mApp->getOption("db_host").asString(), + std::string("localhost")); + ensure("allowlshlttprequests", mApp->getOption("smtp")); + ensure_equals( + "asset-uri", + mApp->getOption("asset-uri").asString(), + std::string("http://test.lindenlab.com/assets")); + ensure_equals( + "data", + mApp->getOption("data").asString(), + std::string("127.0.0.1")); + ensure("smtp", mApp->getOption("smtp")); + } - template<> template<> - void application_object_t::test<3>() - { - const int ARGC = 4; - const char* ARGV[ARGC] = - { - "", // argv[0] is usually the application name - "crashcount", - "2", - "--space" - }; - bool ok = mApp->parseCommandOptions(ARGC, const_cast<char**>(ARGV)); - ensure("command line parse failure", !ok); - } + template<> template<> + void application_object_t::test<3>() + { + const int ARGC = 4; + const char* ARGV[ARGC] = + { + "", // argv[0] is usually the application name + "crashcount", + "2", + "--space" + }; + bool ok = mApp->parseCommandOptions(ARGC, const_cast<char**>(ARGV)); + ensure("command line parse failure", !ok); + } - template<> template<> - void application_object_t::test<4>() - { - const int ARGC = 4; - const char* ARGV[ARGC] = - { - "", // argv[0] is usually the application name - "--crashcount", - "2", - "space" - }; - bool ok = mApp->parseCommandOptions(ARGC, const_cast<char**>(ARGV)); - ensure("command line parse failure", !ok); - } + template<> template<> + void application_object_t::test<4>() + { + const int ARGC = 4; + const char* ARGV[ARGC] = + { + "", // argv[0] is usually the application name + "--crashcount", + "2", + "space" + }; + bool ok = mApp->parseCommandOptions(ARGC, const_cast<char**>(ARGV)); + ensure("command line parse failure", !ok); + } - template<> template<> - void application_object_t::test<5>() - { - LLSD options; - options["boolean-test"] = true; - mApp->setOptionData(LLApp::PRIORITY_GENERAL_CONFIGURATION, options); - ensure("bool set", mApp->getOption("boolean-test").asBoolean()); - options["boolean-test"] = false; - mApp->setOptionData(LLApp::PRIORITY_RUNTIME_OVERRIDE, options); - ensure("bool unset", !mApp->getOption("boolean-test").asBoolean()); - } + template<> template<> + void application_object_t::test<5>() + { + LLSD options; + options["boolean-test"] = true; + mApp->setOptionData(LLApp::PRIORITY_GENERAL_CONFIGURATION, options); + ensure("bool set", mApp->getOption("boolean-test").asBoolean()); + options["boolean-test"] = false; + mApp->setOptionData(LLApp::PRIORITY_RUNTIME_OVERRIDE, options); + ensure("bool unset", !mApp->getOption("boolean-test").asBoolean()); + } } diff --git a/indra/test/llassetuploadqueue_tut.cpp b/indra/test/llassetuploadqueue_tut.cpp index 25efe63d3f..be5f9e4288 100644 --- a/indra/test/llassetuploadqueue_tut.cpp +++ b/indra/test/llassetuploadqueue_tut.cpp @@ -1,25 +1,25 @@ -/** +/** * @file asset_upload_queue_tut.cpp * @brief Tests for newview/llassetuploadqueue.cpp * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,8 +32,8 @@ // Mock implementation. LLAssetUploadResponder::LLAssetUploadResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type) + const LLUUID& vfile_id, + LLAssetType::EType asset_type) { } @@ -66,22 +66,22 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content) } LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type) : - LLAssetUploadResponder(post_data, vfile_id, asset_type) + const LLUUID& vfile_id, + LLAssetType::EType asset_type) : + LLAssetUploadResponder(post_data, vfile_id, asset_type) { } LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, - const std::string& file_name) : - LLAssetUploadResponder(post_data, file_name) + const std::string& file_name) : + LLAssetUploadResponder(post_data, file_name) { } LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, - const std::string& file_name, - const LLUUID& queue_id) : - LLAssetUploadResponder(post_data, file_name) + const std::string& file_name, + const LLUUID& queue_id) : + LLAssetUploadResponder(post_data, file_name) { } @@ -91,105 +91,105 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) namespace tut { - class asset_upload_queue_test_data : public MockHttpClient {}; - typedef test_group<asset_upload_queue_test_data> asset_upload_queue_test; - typedef asset_upload_queue_test::object asset_upload_queue_object; - tut::asset_upload_queue_test asset_upload_queue("asset_upload_queue"); - - void queue(LLAssetUploadQueue& q, const std::string& filename) - { - LLUUID task_id; - LLUUID item_id; - BOOL is_running = FALSE; - BOOL is_target_mono = TRUE; - LLUUID queue_id; - q.queue(filename, task_id, item_id, is_running, is_target_mono, queue_id); - } - - class LLTestSupplier : public LLAssetUploadQueueSupplier - { - public: - - void set(LLAssetUploadQueue* queue) {mQueue = queue;} - - virtual LLAssetUploadQueue* get() const - { - return mQueue; - } - - private: - LLAssetUploadQueue* mQueue; - }; - - template<> template<> - void asset_upload_queue_object::test<1>() - { - setupTheServer(); - reset(); - LLTestSupplier* supplier = new LLTestSupplier(); - LLAssetUploadQueue q("http://localhost:8888/test/success", supplier); - supplier->set(&q); - queue(q, "foo.bar"); - ensure("upload queue not empty before request", q.isEmpty()); - runThePump(10); - ensure("upload queue not empty after request", q.isEmpty()); - } - - template<> template<> - void asset_upload_queue_object::test<2>() - { - reset(); - LLTestSupplier* supplier = new LLTestSupplier(); - LLAssetUploadQueue q("http://localhost:8888/test/error", supplier); - supplier->set(&q); - queue(q, "foo.bar"); - ensure("upload queue not empty before request", q.isEmpty()); - runThePump(10); - ensure("upload queue not empty after request", q.isEmpty()); - } - - template<> template<> - void asset_upload_queue_object::test<3>() - { - reset(); - LLTestSupplier* supplier = new LLTestSupplier(); - LLAssetUploadQueue q("http://localhost:8888/test/timeout", supplier); - supplier->set(&q); - queue(q, "foo.bar"); - ensure("upload queue not empty before request", q.isEmpty()); - runThePump(10); - ensure("upload queue not empty after request", q.isEmpty()); - } - - template<> template<> - void asset_upload_queue_object::test<4>() - { - reset(); - LLTestSupplier* supplier = new LLTestSupplier(); - LLAssetUploadQueue q("http://localhost:8888/test/success", supplier); - supplier->set(&q); - queue(q, "foo.bar"); - queue(q, "baz.bar"); - ensure("upload queue empty before request", !q.isEmpty()); - runThePump(10); - ensure("upload queue not empty before request", q.isEmpty()); - runThePump(10); - ensure("upload queue not empty after request", q.isEmpty()); - } - - template<> template<> - void asset_upload_queue_object::test<5>() - { - reset(); - LLTestSupplier* supplier = new LLTestSupplier(); - LLAssetUploadQueue q("http://localhost:8888/test/success", supplier); - supplier->set(&q); - queue(q, "foo.bar"); - runThePump(10); - ensure("upload queue not empty before request", q.isEmpty()); - queue(q, "baz.bar"); - ensure("upload queue not empty after request", q.isEmpty()); - runThePump(10); - killServer(); - } + class asset_upload_queue_test_data : public MockHttpClient {}; + typedef test_group<asset_upload_queue_test_data> asset_upload_queue_test; + typedef asset_upload_queue_test::object asset_upload_queue_object; + tut::asset_upload_queue_test asset_upload_queue("asset_upload_queue"); + + void queue(LLAssetUploadQueue& q, const std::string& filename) + { + LLUUID task_id; + LLUUID item_id; + BOOL is_running = FALSE; + BOOL is_target_mono = TRUE; + LLUUID queue_id; + q.queue(filename, task_id, item_id, is_running, is_target_mono, queue_id); + } + + class LLTestSupplier : public LLAssetUploadQueueSupplier + { + public: + + void set(LLAssetUploadQueue* queue) {mQueue = queue;} + + virtual LLAssetUploadQueue* get() const + { + return mQueue; + } + + private: + LLAssetUploadQueue* mQueue; + }; + + template<> template<> + void asset_upload_queue_object::test<1>() + { + setupTheServer(); + reset(); + LLTestSupplier* supplier = new LLTestSupplier(); + LLAssetUploadQueue q("http://localhost:8888/test/success", supplier); + supplier->set(&q); + queue(q, "foo.bar"); + ensure("upload queue not empty before request", q.isEmpty()); + runThePump(10); + ensure("upload queue not empty after request", q.isEmpty()); + } + + template<> template<> + void asset_upload_queue_object::test<2>() + { + reset(); + LLTestSupplier* supplier = new LLTestSupplier(); + LLAssetUploadQueue q("http://localhost:8888/test/error", supplier); + supplier->set(&q); + queue(q, "foo.bar"); + ensure("upload queue not empty before request", q.isEmpty()); + runThePump(10); + ensure("upload queue not empty after request", q.isEmpty()); + } + + template<> template<> + void asset_upload_queue_object::test<3>() + { + reset(); + LLTestSupplier* supplier = new LLTestSupplier(); + LLAssetUploadQueue q("http://localhost:8888/test/timeout", supplier); + supplier->set(&q); + queue(q, "foo.bar"); + ensure("upload queue not empty before request", q.isEmpty()); + runThePump(10); + ensure("upload queue not empty after request", q.isEmpty()); + } + + template<> template<> + void asset_upload_queue_object::test<4>() + { + reset(); + LLTestSupplier* supplier = new LLTestSupplier(); + LLAssetUploadQueue q("http://localhost:8888/test/success", supplier); + supplier->set(&q); + queue(q, "foo.bar"); + queue(q, "baz.bar"); + ensure("upload queue empty before request", !q.isEmpty()); + runThePump(10); + ensure("upload queue not empty before request", q.isEmpty()); + runThePump(10); + ensure("upload queue not empty after request", q.isEmpty()); + } + + template<> template<> + void asset_upload_queue_object::test<5>() + { + reset(); + LLTestSupplier* supplier = new LLTestSupplier(); + LLAssetUploadQueue q("http://localhost:8888/test/success", supplier); + supplier->set(&q); + queue(q, "foo.bar"); + runThePump(10); + ensure("upload queue not empty before request", q.isEmpty()); + queue(q, "baz.bar"); + ensure("upload queue not empty after request", q.isEmpty()); + runThePump(10); + killServer(); + } } diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp index 18eb01363f..a8690ccb33 100644 --- a/indra/test/llblowfish_tut.cpp +++ b/indra/test/llblowfish_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llblowfish_tut.cpp * @author James Cook, james@lindenlab.com * @date 2007-02-04 @@ -10,21 +10,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,104 +38,104 @@ namespace tut { - class LLData - { - public: - unsigned char* mInput; - int mInputSize; - - LLData() - { - // \n to make it easier to create text files - // for testing with command line openssl - mInput = (unsigned char*)"01234567890123456789012345678901234\n"; - mInputSize = 36; - } - - bool matchFile(const std::string& filename, - const std::string& data) - { - LLFILE* fp = LLFile::fopen(filename, "rb"); - if (!fp) - { - // sometimes test is run inside the indra directory - std::string path = "test/"; - path += filename; - fp = LLFile::fopen(path, "rb"); - } - if (!fp) - { - LL_WARNS() << "unable to open " << filename << LL_ENDL; - return false; - } - - std::string good; - good.resize(256); - size_t got = fread(&good[0], 1, 256, fp); - LL_DEBUGS() << "matchFile read " << got << LL_ENDL; - fclose(fp); - good.resize(got); - - return (good == data); - } - }; - typedef test_group<LLData> blowfish_test; - typedef blowfish_test::object blowfish_object; - // Create test with name that can be selected on - // command line of test app. - tut::blowfish_test blowfish("blowfish"); - - template<> template<> - void blowfish_object::test<1>() - { - LLUUID blank; - LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); - - U32 dst_len = cipher.requiredEncryptionSpace(36); - ensure("encryption space 36", - (dst_len == 40) ); - - // Blowfish adds an additional 8-byte block if your - // input is an exact multiple of 8 - dst_len = cipher.requiredEncryptionSpace(8); - ensure("encryption space 8", - (dst_len == 16) ); - } - - template<> template<> - void blowfish_object::test<2>() - { - LLUUID blank; - LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); - - std::string result; - result.resize(256); - U32 count = cipher.encrypt(mInput, mInputSize, - (U8*) &result[0], 256); - - ensure("encrypt output count", - (count == 40) ); - result.resize(count); - - ensure("encrypt null key", matchFile("blowfish.1.bin", result)); - } - - template<> template<> - void blowfish_object::test<3>() - { + class LLData + { + public: + unsigned char* mInput; + int mInputSize; + + LLData() + { + // \n to make it easier to create text files + // for testing with command line openssl + mInput = (unsigned char*)"01234567890123456789012345678901234\n"; + mInputSize = 36; + } + + bool matchFile(const std::string& filename, + const std::string& data) + { + LLFILE* fp = LLFile::fopen(filename, "rb"); + if (!fp) + { + // sometimes test is run inside the indra directory + std::string path = "test/"; + path += filename; + fp = LLFile::fopen(path, "rb"); + } + if (!fp) + { + LL_WARNS() << "unable to open " << filename << LL_ENDL; + return false; + } + + std::string good; + good.resize(256); + size_t got = fread(&good[0], 1, 256, fp); + LL_DEBUGS() << "matchFile read " << got << LL_ENDL; + fclose(fp); + good.resize(got); + + return (good == data); + } + }; + typedef test_group<LLData> blowfish_test; + typedef blowfish_test::object blowfish_object; + // Create test with name that can be selected on + // command line of test app. + tut::blowfish_test blowfish("blowfish"); + + template<> template<> + void blowfish_object::test<1>() + { + LLUUID blank; + LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); + + U32 dst_len = cipher.requiredEncryptionSpace(36); + ensure("encryption space 36", + (dst_len == 40) ); + + // Blowfish adds an additional 8-byte block if your + // input is an exact multiple of 8 + dst_len = cipher.requiredEncryptionSpace(8); + ensure("encryption space 8", + (dst_len == 16) ); + } + + template<> template<> + void blowfish_object::test<2>() + { + LLUUID blank; + LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); + + std::string result; + result.resize(256); + U32 count = cipher.encrypt(mInput, mInputSize, + (U8*) &result[0], 256); + + ensure("encrypt output count", + (count == 40) ); + result.resize(count); + + ensure("encrypt null key", matchFile("blowfish.1.bin", result)); + } + + template<> template<> + void blowfish_object::test<3>() + { // same as base64 test id - LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e"); - LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES); + LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e"); + LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES); - std::string result; - result.resize(256); - U32 count = cipher.encrypt(mInput, mInputSize, - (U8*) &result[0], 256); + std::string result; + result.resize(256); + U32 count = cipher.encrypt(mInput, mInputSize, + (U8*) &result[0], 256); - ensure("encrypt output count", - (count == 40) ); - result.resize(count); + ensure("encrypt output count", + (count == 40) ); + result.resize(count); - ensure("encrypt real key", matchFile("blowfish.2.bin", result)); - } + ensure("encrypt real key", matchFile("blowfish.2.bin", result)); + } } diff --git a/indra/test/llbuffer_tut.cpp b/indra/test/llbuffer_tut.cpp index 52dc909a2c..0100a3e225 100644 --- a/indra/test/llbuffer_tut.cpp +++ b/indra/test/llbuffer_tut.cpp @@ -1,271 +1,271 @@ -/** - * @file llbuffer_tut.cpp - * @author Adroit - * @date 2007-03 - * @brief llbuffer test cases. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> - -#include "linden_common.h" -#include "lltut.h" -#include "llbuffer.h" -#include "llerror.h" - - -namespace tut -{ - struct buffer - { - }; - - typedef test_group<buffer> buffer_t; - typedef buffer_t::object buffer_object_t; - tut::buffer_t tut_buffer("buffer"); - - template<> template<> - void buffer_object_t::test<1>() - { - LLChannelDescriptors channelDescriptors; - ensure("in() and out() functions Failed", (0 == channelDescriptors.in() && 1 == channelDescriptors.out())); - - S32 val = 50; - LLChannelDescriptors channelDescriptors1(val); - ensure("LLChannelDescriptors in() and out() functions Failed", (50 == channelDescriptors1.in() && 51 == channelDescriptors1.out())); - } - - template<> template<> - void buffer_object_t::test<2>() - { - LLSegment segment; - ensure("LLSegment get functions failed", (0 == segment.getChannel() && NULL == segment.data() && 0 == segment.size())); - segment.setChannel(50); - ensure_equals("LLSegment setChannel() function failed", segment.getChannel(), 50); - ensure("LLSegment isOnChannel() function failed", (true == segment.isOnChannel(50))); - } - - template<> template<> - void buffer_object_t::test<3>() - { - S32 channel = 30; - const char str[] = "SecondLife"; - S32 len = sizeof(str); - LLSegment segment(channel, (U8*)str, len); - ensure("LLSegment get functions failed", (30 == segment.getChannel() && len == segment.size() && (U8*)str == segment.data())); - ensure_memory_matches("LLSegment::data() failed", segment.data(), segment.size(), (U8*)str, len); - ensure("LLSegment isOnChannel() function failed", (true == segment.isOnChannel(channel))); - } - - template<> template<> - void buffer_object_t::test<4>() - { - S32 channel = 50; - S32 bigSize = 16384*2; - char str[] = "SecondLife"; - S32 smallSize = sizeof(str); - - LLSegment segment; - LLHeapBuffer buf; // use default size of DEFAULT_HEAP_BUFFER_SIZE = 16384 - - S32 requestSize; - - requestSize = 16384-1; - ensure("1. LLHeapBuffer createSegment failed", (true == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize); - // second request for remainign 1 byte - - requestSize = 1; - ensure("2. LLHeapBuffer createSegment failed", (true == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize); - - // it should fail now. - requestSize = 1; - ensure("3. LLHeapBuffer createSegment failed", (false == buf.createSegment(channel, requestSize, segment))); - - LLHeapBuffer buf1(bigSize); - - // requst for more than default size but less than total sizeit should fail now. - requestSize = 16384 + 1; - ensure("4. LLHeapBuffer createSegment failed", (true == buf1.createSegment(channel, requestSize, segment)) && segment.size() == requestSize); - - LLHeapBuffer buf2((U8*) str, smallSize); - requestSize = smallSize; - ensure("5. LLHeapBuffer createSegment failed", (true == buf2.createSegment(channel, requestSize, segment)) && segment.size() == requestSize && memcmp(segment.data(), (U8*) str, requestSize) == 0); - requestSize = smallSize+1; - ensure("6. LLHeapBuffer createSegment failed", (false == buf2.createSegment(channel, requestSize, segment))); - } - - //makeChannelConsumer() - template<> template<> - void buffer_object_t::test<5>() - { - LLChannelDescriptors inchannelDescriptors(20); - LLChannelDescriptors outchannelDescriptors = LLBufferArray::makeChannelConsumer(inchannelDescriptors); - ensure("LLBufferArray::makeChannelConsumer() function Failed", (21 == outchannelDescriptors.in())); - } - - template<> template<> - void buffer_object_t::test<6>() - { - LLBufferArray bufferArray; - const char array[] = "SecondLife"; - S32 len = strlen(array); - LLChannelDescriptors channelDescriptors = bufferArray.nextChannel(); - bufferArray.append(channelDescriptors.in(), (U8*)array, len); - S32 count = bufferArray.countAfter(channelDescriptors.in(), NULL); - ensure_equals("Appended size is:", count, len); - } - - //append() and prepend() - template<> template<> - void buffer_object_t::test<7>() - { - LLBufferArray bufferArray; - const char array[] = "SecondLife"; - S32 len = strlen(array); - const char array1[] = "LindenLabs"; - S32 len1 = strlen(array1); - - std::string str(array1); - str.append(array); - - LLChannelDescriptors channelDescriptors = bufferArray.nextChannel(); - bufferArray.append(channelDescriptors.in(), (U8*)array, len); - bufferArray.prepend(channelDescriptors.in(), (U8*)array1, len1); - char buf[100]; - S32 len2 = 20; - bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2); - ensure_equals("readAfter length failed", len2, 20); - - buf[len2] = '\0'; - ensure_equals("readAfter/prepend/append failed", buf, str); - } - - //append() - template<> template<> - void buffer_object_t::test<8>() - { - LLBufferArray bufferArray; - const char array[] = "SecondLife"; - S32 len = strlen(array); - const char array1[] = "LindenLabs"; - S32 len1 = strlen(array1); - - std::string str(array); - str.append(array1); - - LLChannelDescriptors channelDescriptors = bufferArray.nextChannel(); - bufferArray.append(channelDescriptors.in(), (U8*)array, len); - bufferArray.append(channelDescriptors.in(), (U8*)array1, len1); - char buf[100]; - S32 len2 = 20; - bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2); - ensure_equals("readAfter length failed", len2, 20); - - buf[len2] = '\0'; - ensure_equals("readAfter/append/append failed", buf, str); - } - - template<> template<> - void buffer_object_t::test<9>() - { - LLBufferArray bufferArray; - const char array[] = "SecondLife"; - S32 len = strlen(array) + 1; - std::string str(array); - LLChannelDescriptors channelDescriptors = bufferArray.nextChannel(); - bufferArray.append(channelDescriptors.in(), (U8*)array, len); - LLBufferArray bufferArray1; - ensure("Contents are not copied and the source buffer is not empty", (1 == bufferArray1.takeContents(bufferArray))); - - char buf[100]; - S32 len2 = len; - bufferArray1.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2); - ensure_equals("takeContents failed to copy", buf, str); - } - - //seek() - template<> template<> - void buffer_object_t::test<10>() - { - const char array[] = "SecondLife is a Virtual World"; - S32 len = strlen(array); - LLBufferArray bufferArray; - bufferArray.append(0, (U8*)array, len); - - char buf[255]; - S32 len1 = 16; - U8* last = bufferArray.readAfter(0, 0, (U8*)buf, len1); - buf[len1] = '\0'; - last = bufferArray.seek(0, last, -2); - - len1 = 15; - last = bufferArray.readAfter(0, last, (U8*)buf, len1); - buf[len1] = '\0'; - std::string str(buf); - ensure_equals("Seek does'nt worked", str, std::string("a Virtual World")); - } - - template<> template<> - void buffer_object_t::test<11>() - { - const char array[] = "SecondLife is a Virtual World"; - S32 len = strlen(array); - LLBufferArray bufferArray; - bufferArray.append(0, (U8*)array, len); - - char buf[255]; - S32 len1 = 10; - U8* last = bufferArray.readAfter(0, 0, (U8*)buf, len1); - bufferArray.splitAfter(last); - LLBufferArray::segment_iterator_t iterator = bufferArray.beginSegment(); - ++iterator; - std::string str(((char*)(*iterator).data()), (*iterator).size()); - ensure_equals("Strings are not equal;splitAfter() operation failed", str, std::string(" is a Virtual World")); - } - - //makeSegment()->eraseSegment() - template<> template<> - void buffer_object_t::test<12>() - { - LLBufferArray bufferArray; - LLChannelDescriptors channelDescriptors; - LLBufferArray::segment_iterator_t it; - S32 length = 1000; - it = bufferArray.makeSegment(channelDescriptors.out(), length); - ensure("makeSegment() function failed", (it != bufferArray.endSegment())); - ensure("eraseSegment() function failed", bufferArray.eraseSegment(it)); - ensure("eraseSegment() begin/end should now be same", bufferArray.beginSegment() == bufferArray.endSegment()); - } - - // constructSegmentAfter() - template<> template<> - void buffer_object_t::test<13>() - { - LLBufferArray bufferArray; - LLBufferArray::segment_iterator_t it; - LLSegment segment; - LLBufferArray::segment_iterator_t end = bufferArray.endSegment(); - it = bufferArray.constructSegmentAfter(NULL, segment); - ensure("constructSegmentAfter() function failed", (it == end)); - } -} +/**
+ * @file llbuffer_tut.cpp
+ * @author Adroit
+ * @date 2007-03
+ * @brief llbuffer test cases.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+
+#include "linden_common.h"
+#include "lltut.h"
+#include "llbuffer.h"
+#include "llerror.h"
+
+
+namespace tut
+{
+ struct buffer
+ {
+ };
+
+ typedef test_group<buffer> buffer_t;
+ typedef buffer_t::object buffer_object_t;
+ tut::buffer_t tut_buffer("buffer");
+
+ template<> template<>
+ void buffer_object_t::test<1>()
+ {
+ LLChannelDescriptors channelDescriptors;
+ ensure("in() and out() functions Failed", (0 == channelDescriptors.in() && 1 == channelDescriptors.out()));
+
+ S32 val = 50;
+ LLChannelDescriptors channelDescriptors1(val);
+ ensure("LLChannelDescriptors in() and out() functions Failed", (50 == channelDescriptors1.in() && 51 == channelDescriptors1.out()));
+ }
+
+ template<> template<>
+ void buffer_object_t::test<2>()
+ {
+ LLSegment segment;
+ ensure("LLSegment get functions failed", (0 == segment.getChannel() && NULL == segment.data() && 0 == segment.size()));
+ segment.setChannel(50);
+ ensure_equals("LLSegment setChannel() function failed", segment.getChannel(), 50);
+ ensure("LLSegment isOnChannel() function failed", (true == segment.isOnChannel(50)));
+ }
+
+ template<> template<>
+ void buffer_object_t::test<3>()
+ {
+ S32 channel = 30;
+ const char str[] = "SecondLife";
+ S32 len = sizeof(str);
+ LLSegment segment(channel, (U8*)str, len);
+ ensure("LLSegment get functions failed", (30 == segment.getChannel() && len == segment.size() && (U8*)str == segment.data()));
+ ensure_memory_matches("LLSegment::data() failed", segment.data(), segment.size(), (U8*)str, len);
+ ensure("LLSegment isOnChannel() function failed", (true == segment.isOnChannel(channel)));
+ }
+
+ template<> template<>
+ void buffer_object_t::test<4>()
+ {
+ S32 channel = 50;
+ S32 bigSize = 16384*2;
+ char str[] = "SecondLife";
+ S32 smallSize = sizeof(str);
+
+ LLSegment segment;
+ LLHeapBuffer buf; // use default size of DEFAULT_HEAP_BUFFER_SIZE = 16384
+
+ S32 requestSize;
+
+ requestSize = 16384-1;
+ ensure("1. LLHeapBuffer createSegment failed", (true == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize);
+ // second request for remainign 1 byte
+
+ requestSize = 1;
+ ensure("2. LLHeapBuffer createSegment failed", (true == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize);
+
+ // it should fail now.
+ requestSize = 1;
+ ensure("3. LLHeapBuffer createSegment failed", (false == buf.createSegment(channel, requestSize, segment)));
+
+ LLHeapBuffer buf1(bigSize);
+
+ // requst for more than default size but less than total sizeit should fail now.
+ requestSize = 16384 + 1;
+ ensure("4. LLHeapBuffer createSegment failed", (true == buf1.createSegment(channel, requestSize, segment)) && segment.size() == requestSize);
+
+ LLHeapBuffer buf2((U8*) str, smallSize);
+ requestSize = smallSize;
+ ensure("5. LLHeapBuffer createSegment failed", (true == buf2.createSegment(channel, requestSize, segment)) && segment.size() == requestSize && memcmp(segment.data(), (U8*) str, requestSize) == 0);
+ requestSize = smallSize+1;
+ ensure("6. LLHeapBuffer createSegment failed", (false == buf2.createSegment(channel, requestSize, segment)));
+ }
+
+ //makeChannelConsumer()
+ template<> template<>
+ void buffer_object_t::test<5>()
+ {
+ LLChannelDescriptors inchannelDescriptors(20);
+ LLChannelDescriptors outchannelDescriptors = LLBufferArray::makeChannelConsumer(inchannelDescriptors);
+ ensure("LLBufferArray::makeChannelConsumer() function Failed", (21 == outchannelDescriptors.in()));
+ }
+
+ template<> template<>
+ void buffer_object_t::test<6>()
+ {
+ LLBufferArray bufferArray;
+ const char array[] = "SecondLife";
+ S32 len = strlen(array);
+ LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
+ bufferArray.append(channelDescriptors.in(), (U8*)array, len);
+ S32 count = bufferArray.countAfter(channelDescriptors.in(), NULL);
+ ensure_equals("Appended size is:", count, len);
+ }
+
+ //append() and prepend()
+ template<> template<>
+ void buffer_object_t::test<7>()
+ {
+ LLBufferArray bufferArray;
+ const char array[] = "SecondLife";
+ S32 len = strlen(array);
+ const char array1[] = "LindenLabs";
+ S32 len1 = strlen(array1);
+
+ std::string str(array1);
+ str.append(array);
+
+ LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
+ bufferArray.append(channelDescriptors.in(), (U8*)array, len);
+ bufferArray.prepend(channelDescriptors.in(), (U8*)array1, len1);
+ char buf[100];
+ S32 len2 = 20;
+ bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2);
+ ensure_equals("readAfter length failed", len2, 20);
+
+ buf[len2] = '\0';
+ ensure_equals("readAfter/prepend/append failed", buf, str);
+ }
+
+ //append()
+ template<> template<>
+ void buffer_object_t::test<8>()
+ {
+ LLBufferArray bufferArray;
+ const char array[] = "SecondLife";
+ S32 len = strlen(array);
+ const char array1[] = "LindenLabs";
+ S32 len1 = strlen(array1);
+
+ std::string str(array);
+ str.append(array1);
+
+ LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
+ bufferArray.append(channelDescriptors.in(), (U8*)array, len);
+ bufferArray.append(channelDescriptors.in(), (U8*)array1, len1);
+ char buf[100];
+ S32 len2 = 20;
+ bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2);
+ ensure_equals("readAfter length failed", len2, 20);
+
+ buf[len2] = '\0';
+ ensure_equals("readAfter/append/append failed", buf, str);
+ }
+
+ template<> template<>
+ void buffer_object_t::test<9>()
+ {
+ LLBufferArray bufferArray;
+ const char array[] = "SecondLife";
+ S32 len = strlen(array) + 1;
+ std::string str(array);
+ LLChannelDescriptors channelDescriptors = bufferArray.nextChannel();
+ bufferArray.append(channelDescriptors.in(), (U8*)array, len);
+ LLBufferArray bufferArray1;
+ ensure("Contents are not copied and the source buffer is not empty", (1 == bufferArray1.takeContents(bufferArray)));
+
+ char buf[100];
+ S32 len2 = len;
+ bufferArray1.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2);
+ ensure_equals("takeContents failed to copy", buf, str);
+ }
+
+ //seek()
+ template<> template<>
+ void buffer_object_t::test<10>()
+ {
+ const char array[] = "SecondLife is a Virtual World";
+ S32 len = strlen(array);
+ LLBufferArray bufferArray;
+ bufferArray.append(0, (U8*)array, len);
+
+ char buf[255];
+ S32 len1 = 16;
+ U8* last = bufferArray.readAfter(0, 0, (U8*)buf, len1);
+ buf[len1] = '\0';
+ last = bufferArray.seek(0, last, -2);
+
+ len1 = 15;
+ last = bufferArray.readAfter(0, last, (U8*)buf, len1);
+ buf[len1] = '\0';
+ std::string str(buf);
+ ensure_equals("Seek does'nt worked", str, std::string("a Virtual World"));
+ }
+
+ template<> template<>
+ void buffer_object_t::test<11>()
+ {
+ const char array[] = "SecondLife is a Virtual World";
+ S32 len = strlen(array);
+ LLBufferArray bufferArray;
+ bufferArray.append(0, (U8*)array, len);
+
+ char buf[255];
+ S32 len1 = 10;
+ U8* last = bufferArray.readAfter(0, 0, (U8*)buf, len1);
+ bufferArray.splitAfter(last);
+ LLBufferArray::segment_iterator_t iterator = bufferArray.beginSegment();
+ ++iterator;
+ std::string str(((char*)(*iterator).data()), (*iterator).size());
+ ensure_equals("Strings are not equal;splitAfter() operation failed", str, std::string(" is a Virtual World"));
+ }
+
+ //makeSegment()->eraseSegment()
+ template<> template<>
+ void buffer_object_t::test<12>()
+ {
+ LLBufferArray bufferArray;
+ LLChannelDescriptors channelDescriptors;
+ LLBufferArray::segment_iterator_t it;
+ S32 length = 1000;
+ it = bufferArray.makeSegment(channelDescriptors.out(), length);
+ ensure("makeSegment() function failed", (it != bufferArray.endSegment()));
+ ensure("eraseSegment() function failed", bufferArray.eraseSegment(it));
+ ensure("eraseSegment() begin/end should now be same", bufferArray.beginSegment() == bufferArray.endSegment());
+ }
+
+ // constructSegmentAfter()
+ template<> template<>
+ void buffer_object_t::test<13>()
+ {
+ LLBufferArray bufferArray;
+ LLBufferArray::segment_iterator_t it;
+ LLSegment segment;
+ LLBufferArray::segment_iterator_t end = bufferArray.endSegment();
+ it = bufferArray.constructSegmentAfter(NULL, segment);
+ ensure("constructSegmentAfter() function failed", (it == end));
+ }
+}
diff --git a/indra/test/lldatapacker_tut.cpp b/indra/test/lldatapacker_tut.cpp index b403660c13..2e975ee637 100644 --- a/indra/test/lldatapacker_tut.cpp +++ b/indra/test/lldatapacker_tut.cpp @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,534 +37,534 @@ #include "v4math.h" #include "llsdserialize.h" -#define TEST_FILE_NAME "datapacker_test.txt" +#define TEST_FILE_NAME "datapacker_test.txt" namespace tut { - struct datapacker_test - { - }; - typedef test_group<datapacker_test> datapacker_test_t; - typedef datapacker_test_t::object datapacker_test_object_t; - tut::datapacker_test_t tut_datapacker_test("datapacker_test"); - - //*********LLDataPackerBinaryBuffer - template<> template<> - void datapacker_test_object_t::test<1>() - { - U8 packbuf[128]; - F32 f_val1 = 44.44f, f_unpkval1; - F32 f_val2 = 12344.443232f, f_unpkval2; - F32 f_val3 = 44.4456789f, f_unpkval3; - LLDataPackerBinaryBuffer lldp(packbuf,128); - lldp.packFixed( f_val1, "linden_lab", FALSE, 8, 8); - lldp.packFixed( f_val2, "linden_lab", FALSE, 14, 16); - lldp.packFixed( f_val3, "linden_lab", FALSE, 8, 23); - - LLDataPackerBinaryBuffer lldp1(packbuf, lldp.getCurrentSize()); - lldp1.unpackFixed(f_unpkval1, "linden_lab", FALSE, 8, 8); - lldp1.unpackFixed(f_unpkval2, "linden_lab", FALSE, 14, 16); - lldp1.unpackFixed(f_unpkval3, "linden_lab", FALSE, 8, 23); - ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 8 failed", f_val1, f_unpkval1, 8); - ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 16 failed", f_val2, f_unpkval2, 16); - ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 23 failed", f_val3, f_unpkval3, 31); - } - - template<> template<> - void datapacker_test_object_t::test<2>() - { - U8 packbuf[1024]; - - char str[] = "SecondLife is virtual World\0"; - char strBinary[] = "SecondLife is virtual World"; - char strBinaryFixed[] = "Fixed Data"; - S32 sizeBinaryFixed = sizeof(strBinaryFixed); - U8 valU8 = 'C'; - U16 valU16 = 0xFFFF; - U32 valU32 = 0xFFFFFFFF; - S32 valS32 = -94967295; - F32 valF32 = 4354355.44f ; - LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); - LLColor4U llcol4u(3, 128, 24, 33); - LLVector2 llvec2(333.33f, 444.44f); - LLVector3 llvec3(333.33f, 444.44f, 555.55f); - LLVector4 llvec4(333.33f, 444.44f, 555.55f, 666.66f); - LLUUID uuid; - - std::string unpkstr; - char unpkstrBinary[256]; - char unpkstrBinaryFixed[256]; - S32 unpksizeBinary; - U8 unpkvalU8; - U16 unpkvalU16; - U32 unpkvalU32; - S32 unpkvalS32; - F32 unpkvalF32; - LLColor4 unpkllcol4; - LLColor4U unpkllcol4u; - LLVector2 unpkllvec2; - LLVector3 unpkllvec3; - LLVector4 unpkllvec4; - LLUUID unpkuuid; - - LLDataPackerBinaryBuffer lldp(packbuf,1024); - lldp.packString(str , "linden_lab_str"); - lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); - lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp.packU8(valU8,"linden_lab_u8"); - lldp.packU16(valU16,"linden_lab_u16"); - lldp.packU32(valU32, "linden_lab_u32"); - lldp.packS32(valS32, "linden_lab_s32"); - lldp.packF32(valF32, "linden_lab_f32"); - lldp.packColor4(llcol4, "linden_lab_col4"); - lldp.packColor4U(llcol4u, "linden_lab_col4u"); - lldp.packVector2(llvec2, "linden_lab_vec2"); - lldp.packVector3(llvec3, "linden_lab_vec3"); - lldp.packVector4(llvec4, "linden_lab_vec4"); - uuid.generate(); - lldp.packUUID(uuid, "linden_lab_uuid"); - - S32 cur_size = lldp.getCurrentSize(); - - LLDataPackerBinaryBuffer lldp1(packbuf, cur_size); - lldp1.unpackString(unpkstr , "linden_lab_str"); - lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); - lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); - lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); - lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); - lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); - lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); - lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); - lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); - lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); - lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); - lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); - lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); - - ensure("LLDataPackerBinaryBuffer::packString failed", strcmp(str, unpkstr.c_str()) == 0); - ensure("LLDataPackerBinaryBuffer::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0); - ensure("LLDataPackerBinaryBuffer::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); - ensure_equals("LLDataPackerBinaryBuffer::packU8 failed", valU8, unpkvalU8); - ensure_equals("LLDataPackerBinaryBuffer::packU16 failed", valU16, unpkvalU16); - ensure_equals("LLDataPackerBinaryBuffer::packU32 failed", valU32, unpkvalU32); - ensure_equals("LLDataPackerBinaryBuffer::packS32 failed", valS32, unpkvalS32); - ensure("LLDataPackerBinaryBuffer::packF32 failed", is_approx_equal(valF32, unpkvalF32)); - ensure_equals("LLDataPackerBinaryBuffer::packColor4 failed", llcol4, unpkllcol4); - ensure_equals("LLDataPackerBinaryBuffer::packColor4U failed", llcol4u, unpkllcol4u); - ensure_equals("LLDataPackerBinaryBuffer::packVector2 failed", llvec2, unpkllvec2); - ensure_equals("LLDataPackerBinaryBuffer::packVector3 failed", llvec3, unpkllvec3); - ensure_equals("LLDataPackerBinaryBuffer::packVector4 failed", llvec4, unpkllvec4); - ensure_equals("LLDataPackerBinaryBuffer::packUUID failed", uuid, unpkuuid); - } - - template<> template<> - void datapacker_test_object_t::test<3>() - { - U8 packbuf[128]; - char str[] = "SecondLife is virtual World"; - S32 strSize = sizeof(str); // include '\0' - LLDataPackerBinaryBuffer lldp(packbuf, 128); - lldp.packString(str , "linden_lab"); - - ensure("LLDataPackerBinaryBuffer: current size is wrong", strSize == lldp.getCurrentSize()); - ensure("LLDataPackerBinaryBuffer: buffer size is wrong", 128 == lldp.getBufferSize()); - - lldp.reset(); - ensure("LLDataPackerBinaryBuffer::reset failed",0 == lldp.getCurrentSize()); - } - - template<> template<> - void datapacker_test_object_t::test<4>() - { - U8* packbuf = new U8[128]; - char str[] = "SecondLife is virtual World"; - LLDataPackerBinaryBuffer lldp(packbuf, 128); - lldp.packString(str , "linden_lab"); - lldp.freeBuffer(); - ensure("LLDataPackerBinaryBuffer.freeBuffer failed" , 0 == lldp.getBufferSize()); - - } - - template<> template<> - void datapacker_test_object_t::test<5>() - { - U8 buf[] = "SecondLife is virtual World"; - S32 size = sizeof(buf); - LLDataPackerBinaryBuffer lldp(buf, size); - U8 new_buf[] = "Its Amazing"; - size = sizeof(new_buf); - lldp.assignBuffer(new_buf, size); - ensure("LLDataPackerBinaryBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (0 == lldp.getCurrentSize()))) ; - } - - template<> template<> - void datapacker_test_object_t::test<6>() - { - U8 packbuf[128]; - char str[] = "SecondLife is virtual World"; - LLDataPackerBinaryBuffer lldp(packbuf, 128); - lldp.packString(str , "linden_lab"); - U8 new_buffer[128]; - std::string unpkbuf; - LLDataPackerBinaryBuffer lldp1(new_buffer,128); - lldp1 = lldp; - lldp1.unpackString(unpkbuf, "linden_lab"); - ensure("1. LLDataPackerBinaryBuffer::operator= failed" , lldp1.getBufferSize() == lldp.getBufferSize()); - ensure_equals("2.LLDataPackerBinaryBuffer::operator= failed", str,unpkbuf); - } - - //*********LLDataPackerAsciiBuffer - - template<> template<> - void datapacker_test_object_t::test<7>() - { - char packbuf[128]; - F32 f_val = 44.44f, f_unpkval; - LLDataPackerAsciiBuffer lldp(packbuf,128); - lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8); - - LLDataPackerAsciiBuffer lldp1(packbuf, lldp.getCurrentSize()); - lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8); - ensure_approximately_equals("LLDataPackerAsciiBuffer::packFixed failed", f_val, f_unpkval, 8); - } - - template<> template<> - void datapacker_test_object_t::test<8>() - { - char packbuf[1024]; - - char str[] = "SecondLife is virtual World\0"; - char strBinary[] = "SecondLife is virtual World"; - char strBinaryFixed[] = "Fixed Data"; - S32 sizeBinaryFixed = sizeof(strBinaryFixed); - U8 valU8 = 'C'; - U16 valU16 = 0xFFFF; - U32 valU32 = 0xFFFFFFFF; - S32 valS32 = -94967295; - F32 valF32 = 4354355.44f ; - LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); - LLColor4U llcol4u(3, 128, 24, 33); - LLVector2 llvec2(333.33f, 444.44f); - LLVector3 llvec3(333.33f, 444.44f, 555.55f); - LLVector4 llvec4(4354355.44f, 444.44f, 555.55f, 666.66f); - LLUUID uuid; - - std::string unpkstr; - char unpkstrBinary[256]; - char unpkstrBinaryFixed[256]; - S32 unpksizeBinary; - U8 unpkvalU8; - U16 unpkvalU16; - U32 unpkvalU32; - S32 unpkvalS32; - F32 unpkvalF32; - LLColor4 unpkllcol4; - LLColor4U unpkllcol4u; - LLVector2 unpkllvec2; - LLVector3 unpkllvec3; - LLVector4 unpkllvec4; - LLUUID unpkuuid; - - LLDataPackerAsciiBuffer lldp(packbuf,1024); - lldp.packString(str , "linden_lab_str"); - lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); - lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp.packU8(valU8,"linden_lab_u8"); - lldp.packU16(valU16,"linden_lab_u16"); - lldp.packU32(valU32, "linden_lab_u32"); - lldp.packS32(valS32, "linden_lab_s32"); - lldp.packF32(valF32, "linden_lab_f32"); - lldp.packColor4(llcol4, "linden_lab_col4"); - lldp.packColor4U(llcol4u, "linden_lab_col4u"); - lldp.packVector2(llvec2, "linden_lab_vec2"); - lldp.packVector3(llvec3, "linden_lab_vec3"); - lldp.packVector4(llvec4, "linden_lab_vec4"); - uuid.generate(); - lldp.packUUID(uuid, "linden_lab_uuid"); - - S32 cur_size = lldp.getCurrentSize(); - - LLDataPackerAsciiBuffer lldp1(packbuf, cur_size); - lldp1.unpackString(unpkstr , "linden_lab_str"); - lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); - lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); - lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); - lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); - lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); - lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); - lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); - lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); - lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); - lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); - lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); - lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); - - ensure("LLDataPackerAsciiBuffer::packString failed", strcmp(str, unpkstr.c_str()) == 0); - ensure("LLDataPackerAsciiBuffer::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0); - ensure("LLDataPackerAsciiBuffer::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); - ensure_equals("LLDataPackerAsciiBuffer::packU8 failed", valU8, unpkvalU8); - ensure_equals("LLDataPackerAsciiBuffer::packU16 failed", valU16, unpkvalU16); - ensure_equals("LLDataPackerAsciiBuffer::packU32 failed", valU32, unpkvalU32); - ensure_equals("LLDataPackerAsciiBuffer::packS32 failed", valS32, unpkvalS32); - ensure("LLDataPackerAsciiBuffer::packF32 failed", is_approx_equal(valF32, unpkvalF32)); - ensure_equals("LLDataPackerAsciiBuffer::packColor4 failed", llcol4, unpkllcol4); - ensure_equals("LLDataPackerAsciiBuffer::packColor4U failed", llcol4u, unpkllcol4u); - ensure_equals("LLDataPackerAsciiBuffer::packVector2 failed", llvec2, unpkllvec2); - ensure_equals("LLDataPackerAsciiBuffer::packVector3 failed", llvec3, unpkllvec3); - ensure_equals("LLDataPackerAsciiBuffer::packVector4 failed", llvec4, unpkllvec4); - ensure_equals("LLDataPackerAsciiBuffer::packUUID failed", uuid, unpkuuid); - } - - template<> template<> - void datapacker_test_object_t::test<9>() - { - char* packbuf = new char[128]; - char str[] = "SecondLife is virtual World"; - LLDataPackerAsciiBuffer lldp(packbuf, 128); - lldp.packString(str , "linden_lab"); - lldp.freeBuffer(); - ensure("LLDataPackerAsciiBuffer::freeBuffer failed" , 0 == lldp.getBufferSize()); - } - - template<> template<> - void datapacker_test_object_t::test<10>() - { - char buf[] = "SecondLife is virtual World"; - S32 size = sizeof(buf); - LLDataPackerAsciiBuffer lldp(buf, size); - char new_buf[] = "Its Amazing"; - size = sizeof(new_buf); - lldp.assignBuffer(new_buf, size); - ensure("LLDataPackerAsciiBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (1 == lldp.getCurrentSize()))) ; - } - - //*********LLDataPackerAsciiFile - - template<> template<> - void datapacker_test_object_t::test<11>() - { - F32 f_val = 44.44f, f_unpkval; - - LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, "w+"); - if(!fp) - { - LL_ERRS() << "File couldnt be open" << LL_ENDL; - return; - } - - LLDataPackerAsciiFile lldp(fp,2); - lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8); - - fflush(fp); - fseek(fp,0,SEEK_SET); - LLDataPackerAsciiFile lldp1(fp,2); - - lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8); - fclose(fp); - - ensure_approximately_equals("LLDataPackerAsciiFile::packFixed failed", f_val, f_unpkval, 8); - } - - template<> template<> - void datapacker_test_object_t::test<12>() - { - char str[] = "SecondLife is virtual World\0"; - char strBinary[] = "SecondLife is virtual World"; - char strBinaryFixed[] = "Fixed Data"; - S32 sizeBinaryFixed = sizeof(strBinaryFixed); - U8 valU8 = 'C'; - U16 valU16 = 0xFFFF; - U32 valU32 = 0xFFFFFFFF; - S32 valS32 = -94967295; - F32 valF32 = 4354355.44f ; - LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); - LLColor4U llcol4u(3, 128, 24, 33); - LLVector2 llvec2(333.33f, 444.44f); - LLVector3 llvec3(333.33f, 444.44f, 555.55f); - LLVector4 llvec4(333.33f, 444.44f, 555.55f, 666.66f); - LLUUID uuid; - - std::string unpkstr; - char unpkstrBinary[256]; - char unpkstrBinaryFixed[256]; - S32 unpksizeBinary; - U8 unpkvalU8; - U16 unpkvalU16; - U32 unpkvalU32; - S32 unpkvalS32; - F32 unpkvalF32; - LLColor4 unpkllcol4; - LLColor4U unpkllcol4u; - LLVector2 unpkllvec2; - LLVector3 unpkllvec3; - LLVector4 unpkllvec4; - LLUUID unpkuuid; - - LLFILE* fp = LLFile::fopen(TEST_FILE_NAME,"w+"); - if(!fp) - { - LL_ERRS() << "File couldnt be open" << LL_ENDL; - return; - } - - LLDataPackerAsciiFile lldp(fp,2); - - lldp.packString(str , "linden_lab_str"); - lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); - lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp.packU8(valU8,"linden_lab_u8"); - lldp.packU16(valU16,"linden_lab_u16"); - lldp.packU32(valU32, "linden_lab_u32"); - lldp.packS32(valS32, "linden_lab_s32"); - lldp.packF32(valF32, "linden_lab_f32"); - lldp.packColor4(llcol4, "linden_lab_col4"); - lldp.packColor4U(llcol4u, "linden_lab_col4u"); - lldp.packVector2(llvec2, "linden_lab_vec2"); - lldp.packVector3(llvec3, "linden_lab_vec3"); - lldp.packVector4(llvec4, "linden_lab_vec4"); - uuid.generate(); - lldp.packUUID(uuid, "linden_lab_uuid"); - - fflush(fp); - fseek(fp,0,SEEK_SET); - LLDataPackerAsciiFile lldp1(fp,2); - - lldp1.unpackString(unpkstr , "linden_lab_str"); - lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); - lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); - lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); - lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); - lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); - lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); - lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); - lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); - lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); - lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); - lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); - lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); - - fclose(fp); - - ensure("LLDataPackerAsciiFile::packString failed", strcmp(str, unpkstr.c_str()) == 0); - ensure("LLDataPackerAsciiFile::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0); - ensure("LLDataPackerAsciiFile::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); - ensure_equals("LLDataPackerAsciiFile::packU8 failed", valU8, unpkvalU8); - ensure_equals("LLDataPackerAsciiFile::packU16 failed", valU16, unpkvalU16); - ensure_equals("LLDataPackerAsciiFile::packU32 failed", valU32, unpkvalU32); - ensure_equals("LLDataPackerAsciiFile::packS32 failed", valS32, unpkvalS32); - ensure("LLDataPackerAsciiFile::packF32 failed", is_approx_equal(valF32, unpkvalF32)); - ensure_equals("LLDataPackerAsciiFile::packColor4 failed", llcol4, unpkllcol4); - ensure_equals("LLDataPackerAsciiFile::packColor4U failed", llcol4u, unpkllcol4u); - ensure_equals("LLDataPackerAsciiFile::packVector2 failed", llvec2, unpkllvec2); - ensure_equals("LLDataPackerAsciiFile::packVector3 failed", llvec3, unpkllvec3); - ensure_equals("LLDataPackerAsciiFile::packVector4 failed", llvec4, unpkllvec4); - ensure_equals("LLDataPackerAsciiFile::packUUID failed", uuid, unpkuuid); - } - - template<> template<> - void datapacker_test_object_t::test<13>() - { - F32 f_val = 44.44f, f_unpkval; - - std::ostringstream ostr; - LLDataPackerAsciiFile lldp(ostr,2); - lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8); - - std::istringstream istr(ostr.str()); - LLDataPackerAsciiFile lldp1(istr,2); - - lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8); - - ensure_approximately_equals("LLDataPackerAsciiFile::packFixed (iostring) failed", f_val, f_unpkval, 8); - } - - template<> template<> - void datapacker_test_object_t::test<14>() - { - char str[] = "SecondLife is virtual World\0"; - char strBinary[] = "SecondLife is virtual World"; - char strBinaryFixed[] = "Fixed Data"; - S32 sizeBinaryFixed = sizeof(strBinaryFixed); - U8 valU8 = 'C'; - U16 valU16 = 0xFFFF; - U32 valU32 = 0xFFFFFFFF; - S32 valS32 = -94967295; - F32 valF32 = 4354355.44f ; - LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); - LLColor4U llcol4u(3, 128, 24, 33); - LLVector2 llvec2(3333333.33f, 444.333344f); - LLVector3 llvec3(3323233.33f, 444.4324f, 555.553232f); - LLVector4 llvec4(333.33233f, 444.4323234f, 55323225.55f, 6323236.66f); - LLUUID uuid; - - std::string unpkstr; - char unpkstrBinary[256]; - char unpkstrBinaryFixed[256]; - S32 unpksizeBinary; - U8 unpkvalU8; - U16 unpkvalU16; - U32 unpkvalU32; - S32 unpkvalS32; - F32 unpkvalF32; - LLColor4 unpkllcol4; - LLColor4U unpkllcol4u; - LLVector2 unpkllvec2; - LLVector3 unpkllvec3; - LLVector4 unpkllvec4; - LLUUID unpkuuid; - - std::ostringstream ostr; - LLDataPackerAsciiFile lldp(ostr,2); - - lldp.packString(str , "linden_lab_str"); - lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); - lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp.packU8(valU8,"linden_lab_u8"); - lldp.packU16(valU16,"linden_lab_u16"); - lldp.packU32(valU32, "linden_lab_u32"); - lldp.packS32(valS32, "linden_lab_s32"); - lldp.packF32(valF32, "linden_lab_f32"); - lldp.packColor4(llcol4, "linden_lab_col4"); - lldp.packColor4U(llcol4u, "linden_lab_col4u"); - lldp.packVector2(llvec2, "linden_lab_vec2"); - lldp.packVector3(llvec3, "linden_lab_vec3"); - lldp.packVector4(llvec4, "linden_lab_vec4"); - uuid.generate(); - lldp.packUUID(uuid, "linden_lab_uuid"); - - std::istringstream istr(ostr.str()); - LLDataPackerAsciiFile lldp1(istr,2); - - lldp1.unpackString(unpkstr , "linden_lab_str"); - lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); - lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); - lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); - lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); - lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); - lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); - lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); - lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); - lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); - lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); - lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); - lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); - lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); - - ensure("LLDataPackerAsciiFile::packString (iostring) failed", strcmp(str, unpkstr.c_str()) == 0); - ensure("LLDataPackerAsciiFile::packBinaryData (iostring) failed", strcmp(strBinary, unpkstrBinary) == 0); - ensure("LLDataPackerAsciiFile::packBinaryDataFixed (iostring) failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); - ensure_equals("LLDataPackerAsciiFile::packU8 (iostring) failed", valU8, unpkvalU8); - ensure_equals("LLDataPackerAsciiFile::packU16 (iostring) failed", valU16, unpkvalU16); - ensure_equals("LLDataPackerAsciiFile::packU32 (iostring) failed", valU32, unpkvalU32); - ensure_equals("LLDataPackerAsciiFile::packS32 (iostring) failed", valS32, unpkvalS32); - ensure("LLDataPackerAsciiFile::packF32 (iostring) failed", is_approx_equal(valF32, unpkvalF32)); - ensure_equals("LLDataPackerAsciiFile::packColor4 (iostring) failed", llcol4, unpkllcol4); - ensure_equals("LLDataPackerAsciiFile::packColor4U (iostring) failed", llcol4u, unpkllcol4u); - ensure_equals("LLDataPackerAsciiFile::packVector2 (iostring) failed", llvec2, unpkllvec2); - ensure_equals("LLDataPackerAsciiFile::packVector3 (iostring) failed", llvec3, unpkllvec3); - ensure_equals("LLDataPackerAsciiFile::packVector4 (iostring) failed", llvec4, unpkllvec4); - ensure_equals("LLDataPackerAsciiFile::packUUID (iostring) failed", uuid, unpkuuid); - } + struct datapacker_test + { + }; + typedef test_group<datapacker_test> datapacker_test_t; + typedef datapacker_test_t::object datapacker_test_object_t; + tut::datapacker_test_t tut_datapacker_test("datapacker_test"); + + //*********LLDataPackerBinaryBuffer + template<> template<> + void datapacker_test_object_t::test<1>() + { + U8 packbuf[128]; + F32 f_val1 = 44.44f, f_unpkval1; + F32 f_val2 = 12344.443232f, f_unpkval2; + F32 f_val3 = 44.4456789f, f_unpkval3; + LLDataPackerBinaryBuffer lldp(packbuf,128); + lldp.packFixed( f_val1, "linden_lab", FALSE, 8, 8); + lldp.packFixed( f_val2, "linden_lab", FALSE, 14, 16); + lldp.packFixed( f_val3, "linden_lab", FALSE, 8, 23); + + LLDataPackerBinaryBuffer lldp1(packbuf, lldp.getCurrentSize()); + lldp1.unpackFixed(f_unpkval1, "linden_lab", FALSE, 8, 8); + lldp1.unpackFixed(f_unpkval2, "linden_lab", FALSE, 14, 16); + lldp1.unpackFixed(f_unpkval3, "linden_lab", FALSE, 8, 23); + ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 8 failed", f_val1, f_unpkval1, 8); + ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 16 failed", f_val2, f_unpkval2, 16); + ensure_approximately_equals("LLDataPackerBinaryBuffer::packFixed 23 failed", f_val3, f_unpkval3, 31); + } + + template<> template<> + void datapacker_test_object_t::test<2>() + { + U8 packbuf[1024]; + + char str[] = "SecondLife is virtual World\0"; + char strBinary[] = "SecondLife is virtual World"; + char strBinaryFixed[] = "Fixed Data"; + S32 sizeBinaryFixed = sizeof(strBinaryFixed); + U8 valU8 = 'C'; + U16 valU16 = 0xFFFF; + U32 valU32 = 0xFFFFFFFF; + S32 valS32 = -94967295; + F32 valF32 = 4354355.44f ; + LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); + LLColor4U llcol4u(3, 128, 24, 33); + LLVector2 llvec2(333.33f, 444.44f); + LLVector3 llvec3(333.33f, 444.44f, 555.55f); + LLVector4 llvec4(333.33f, 444.44f, 555.55f, 666.66f); + LLUUID uuid; + + std::string unpkstr; + char unpkstrBinary[256]; + char unpkstrBinaryFixed[256]; + S32 unpksizeBinary; + U8 unpkvalU8; + U16 unpkvalU16; + U32 unpkvalU32; + S32 unpkvalS32; + F32 unpkvalF32; + LLColor4 unpkllcol4; + LLColor4U unpkllcol4u; + LLVector2 unpkllvec2; + LLVector3 unpkllvec3; + LLVector4 unpkllvec4; + LLUUID unpkuuid; + + LLDataPackerBinaryBuffer lldp(packbuf,1024); + lldp.packString(str , "linden_lab_str"); + lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); + lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp.packU8(valU8,"linden_lab_u8"); + lldp.packU16(valU16,"linden_lab_u16"); + lldp.packU32(valU32, "linden_lab_u32"); + lldp.packS32(valS32, "linden_lab_s32"); + lldp.packF32(valF32, "linden_lab_f32"); + lldp.packColor4(llcol4, "linden_lab_col4"); + lldp.packColor4U(llcol4u, "linden_lab_col4u"); + lldp.packVector2(llvec2, "linden_lab_vec2"); + lldp.packVector3(llvec3, "linden_lab_vec3"); + lldp.packVector4(llvec4, "linden_lab_vec4"); + uuid.generate(); + lldp.packUUID(uuid, "linden_lab_uuid"); + + S32 cur_size = lldp.getCurrentSize(); + + LLDataPackerBinaryBuffer lldp1(packbuf, cur_size); + lldp1.unpackString(unpkstr , "linden_lab_str"); + lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); + lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); + lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); + lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); + lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); + lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); + lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); + lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); + lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); + lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); + lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); + lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); + + ensure("LLDataPackerBinaryBuffer::packString failed", strcmp(str, unpkstr.c_str()) == 0); + ensure("LLDataPackerBinaryBuffer::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0); + ensure("LLDataPackerBinaryBuffer::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); + ensure_equals("LLDataPackerBinaryBuffer::packU8 failed", valU8, unpkvalU8); + ensure_equals("LLDataPackerBinaryBuffer::packU16 failed", valU16, unpkvalU16); + ensure_equals("LLDataPackerBinaryBuffer::packU32 failed", valU32, unpkvalU32); + ensure_equals("LLDataPackerBinaryBuffer::packS32 failed", valS32, unpkvalS32); + ensure("LLDataPackerBinaryBuffer::packF32 failed", is_approx_equal(valF32, unpkvalF32)); + ensure_equals("LLDataPackerBinaryBuffer::packColor4 failed", llcol4, unpkllcol4); + ensure_equals("LLDataPackerBinaryBuffer::packColor4U failed", llcol4u, unpkllcol4u); + ensure_equals("LLDataPackerBinaryBuffer::packVector2 failed", llvec2, unpkllvec2); + ensure_equals("LLDataPackerBinaryBuffer::packVector3 failed", llvec3, unpkllvec3); + ensure_equals("LLDataPackerBinaryBuffer::packVector4 failed", llvec4, unpkllvec4); + ensure_equals("LLDataPackerBinaryBuffer::packUUID failed", uuid, unpkuuid); + } + + template<> template<> + void datapacker_test_object_t::test<3>() + { + U8 packbuf[128]; + char str[] = "SecondLife is virtual World"; + S32 strSize = sizeof(str); // include '\0' + LLDataPackerBinaryBuffer lldp(packbuf, 128); + lldp.packString(str , "linden_lab"); + + ensure("LLDataPackerBinaryBuffer: current size is wrong", strSize == lldp.getCurrentSize()); + ensure("LLDataPackerBinaryBuffer: buffer size is wrong", 128 == lldp.getBufferSize()); + + lldp.reset(); + ensure("LLDataPackerBinaryBuffer::reset failed",0 == lldp.getCurrentSize()); + } + + template<> template<> + void datapacker_test_object_t::test<4>() + { + U8* packbuf = new U8[128]; + char str[] = "SecondLife is virtual World"; + LLDataPackerBinaryBuffer lldp(packbuf, 128); + lldp.packString(str , "linden_lab"); + lldp.freeBuffer(); + ensure("LLDataPackerBinaryBuffer.freeBuffer failed" , 0 == lldp.getBufferSize()); + + } + + template<> template<> + void datapacker_test_object_t::test<5>() + { + U8 buf[] = "SecondLife is virtual World"; + S32 size = sizeof(buf); + LLDataPackerBinaryBuffer lldp(buf, size); + U8 new_buf[] = "Its Amazing"; + size = sizeof(new_buf); + lldp.assignBuffer(new_buf, size); + ensure("LLDataPackerBinaryBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (0 == lldp.getCurrentSize()))) ; + } + + template<> template<> + void datapacker_test_object_t::test<6>() + { + U8 packbuf[128]; + char str[] = "SecondLife is virtual World"; + LLDataPackerBinaryBuffer lldp(packbuf, 128); + lldp.packString(str , "linden_lab"); + U8 new_buffer[128]; + std::string unpkbuf; + LLDataPackerBinaryBuffer lldp1(new_buffer,128); + lldp1 = lldp; + lldp1.unpackString(unpkbuf, "linden_lab"); + ensure("1. LLDataPackerBinaryBuffer::operator= failed" , lldp1.getBufferSize() == lldp.getBufferSize()); + ensure_equals("2.LLDataPackerBinaryBuffer::operator= failed", str,unpkbuf); + } + + //*********LLDataPackerAsciiBuffer + + template<> template<> + void datapacker_test_object_t::test<7>() + { + char packbuf[128]; + F32 f_val = 44.44f, f_unpkval; + LLDataPackerAsciiBuffer lldp(packbuf,128); + lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8); + + LLDataPackerAsciiBuffer lldp1(packbuf, lldp.getCurrentSize()); + lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8); + ensure_approximately_equals("LLDataPackerAsciiBuffer::packFixed failed", f_val, f_unpkval, 8); + } + + template<> template<> + void datapacker_test_object_t::test<8>() + { + char packbuf[1024]; + + char str[] = "SecondLife is virtual World\0"; + char strBinary[] = "SecondLife is virtual World"; + char strBinaryFixed[] = "Fixed Data"; + S32 sizeBinaryFixed = sizeof(strBinaryFixed); + U8 valU8 = 'C'; + U16 valU16 = 0xFFFF; + U32 valU32 = 0xFFFFFFFF; + S32 valS32 = -94967295; + F32 valF32 = 4354355.44f ; + LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); + LLColor4U llcol4u(3, 128, 24, 33); + LLVector2 llvec2(333.33f, 444.44f); + LLVector3 llvec3(333.33f, 444.44f, 555.55f); + LLVector4 llvec4(4354355.44f, 444.44f, 555.55f, 666.66f); + LLUUID uuid; + + std::string unpkstr; + char unpkstrBinary[256]; + char unpkstrBinaryFixed[256]; + S32 unpksizeBinary; + U8 unpkvalU8; + U16 unpkvalU16; + U32 unpkvalU32; + S32 unpkvalS32; + F32 unpkvalF32; + LLColor4 unpkllcol4; + LLColor4U unpkllcol4u; + LLVector2 unpkllvec2; + LLVector3 unpkllvec3; + LLVector4 unpkllvec4; + LLUUID unpkuuid; + + LLDataPackerAsciiBuffer lldp(packbuf,1024); + lldp.packString(str , "linden_lab_str"); + lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); + lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp.packU8(valU8,"linden_lab_u8"); + lldp.packU16(valU16,"linden_lab_u16"); + lldp.packU32(valU32, "linden_lab_u32"); + lldp.packS32(valS32, "linden_lab_s32"); + lldp.packF32(valF32, "linden_lab_f32"); + lldp.packColor4(llcol4, "linden_lab_col4"); + lldp.packColor4U(llcol4u, "linden_lab_col4u"); + lldp.packVector2(llvec2, "linden_lab_vec2"); + lldp.packVector3(llvec3, "linden_lab_vec3"); + lldp.packVector4(llvec4, "linden_lab_vec4"); + uuid.generate(); + lldp.packUUID(uuid, "linden_lab_uuid"); + + S32 cur_size = lldp.getCurrentSize(); + + LLDataPackerAsciiBuffer lldp1(packbuf, cur_size); + lldp1.unpackString(unpkstr , "linden_lab_str"); + lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); + lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); + lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); + lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); + lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); + lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); + lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); + lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); + lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); + lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); + lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); + lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); + + ensure("LLDataPackerAsciiBuffer::packString failed", strcmp(str, unpkstr.c_str()) == 0); + ensure("LLDataPackerAsciiBuffer::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0); + ensure("LLDataPackerAsciiBuffer::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); + ensure_equals("LLDataPackerAsciiBuffer::packU8 failed", valU8, unpkvalU8); + ensure_equals("LLDataPackerAsciiBuffer::packU16 failed", valU16, unpkvalU16); + ensure_equals("LLDataPackerAsciiBuffer::packU32 failed", valU32, unpkvalU32); + ensure_equals("LLDataPackerAsciiBuffer::packS32 failed", valS32, unpkvalS32); + ensure("LLDataPackerAsciiBuffer::packF32 failed", is_approx_equal(valF32, unpkvalF32)); + ensure_equals("LLDataPackerAsciiBuffer::packColor4 failed", llcol4, unpkllcol4); + ensure_equals("LLDataPackerAsciiBuffer::packColor4U failed", llcol4u, unpkllcol4u); + ensure_equals("LLDataPackerAsciiBuffer::packVector2 failed", llvec2, unpkllvec2); + ensure_equals("LLDataPackerAsciiBuffer::packVector3 failed", llvec3, unpkllvec3); + ensure_equals("LLDataPackerAsciiBuffer::packVector4 failed", llvec4, unpkllvec4); + ensure_equals("LLDataPackerAsciiBuffer::packUUID failed", uuid, unpkuuid); + } + + template<> template<> + void datapacker_test_object_t::test<9>() + { + char* packbuf = new char[128]; + char str[] = "SecondLife is virtual World"; + LLDataPackerAsciiBuffer lldp(packbuf, 128); + lldp.packString(str , "linden_lab"); + lldp.freeBuffer(); + ensure("LLDataPackerAsciiBuffer::freeBuffer failed" , 0 == lldp.getBufferSize()); + } + + template<> template<> + void datapacker_test_object_t::test<10>() + { + char buf[] = "SecondLife is virtual World"; + S32 size = sizeof(buf); + LLDataPackerAsciiBuffer lldp(buf, size); + char new_buf[] = "Its Amazing"; + size = sizeof(new_buf); + lldp.assignBuffer(new_buf, size); + ensure("LLDataPackerAsciiBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (1 == lldp.getCurrentSize()))) ; + } + + //*********LLDataPackerAsciiFile + + template<> template<> + void datapacker_test_object_t::test<11>() + { + F32 f_val = 44.44f, f_unpkval; + + LLFILE* fp = LLFile::fopen(TEST_FILE_NAME, "w+"); + if(!fp) + { + LL_ERRS() << "File couldnt be open" << LL_ENDL; + return; + } + + LLDataPackerAsciiFile lldp(fp,2); + lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8); + + fflush(fp); + fseek(fp,0,SEEK_SET); + LLDataPackerAsciiFile lldp1(fp,2); + + lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8); + fclose(fp); + + ensure_approximately_equals("LLDataPackerAsciiFile::packFixed failed", f_val, f_unpkval, 8); + } + + template<> template<> + void datapacker_test_object_t::test<12>() + { + char str[] = "SecondLife is virtual World\0"; + char strBinary[] = "SecondLife is virtual World"; + char strBinaryFixed[] = "Fixed Data"; + S32 sizeBinaryFixed = sizeof(strBinaryFixed); + U8 valU8 = 'C'; + U16 valU16 = 0xFFFF; + U32 valU32 = 0xFFFFFFFF; + S32 valS32 = -94967295; + F32 valF32 = 4354355.44f ; + LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); + LLColor4U llcol4u(3, 128, 24, 33); + LLVector2 llvec2(333.33f, 444.44f); + LLVector3 llvec3(333.33f, 444.44f, 555.55f); + LLVector4 llvec4(333.33f, 444.44f, 555.55f, 666.66f); + LLUUID uuid; + + std::string unpkstr; + char unpkstrBinary[256]; + char unpkstrBinaryFixed[256]; + S32 unpksizeBinary; + U8 unpkvalU8; + U16 unpkvalU16; + U32 unpkvalU32; + S32 unpkvalS32; + F32 unpkvalF32; + LLColor4 unpkllcol4; + LLColor4U unpkllcol4u; + LLVector2 unpkllvec2; + LLVector3 unpkllvec3; + LLVector4 unpkllvec4; + LLUUID unpkuuid; + + LLFILE* fp = LLFile::fopen(TEST_FILE_NAME,"w+"); + if(!fp) + { + LL_ERRS() << "File couldnt be open" << LL_ENDL; + return; + } + + LLDataPackerAsciiFile lldp(fp,2); + + lldp.packString(str , "linden_lab_str"); + lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); + lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp.packU8(valU8,"linden_lab_u8"); + lldp.packU16(valU16,"linden_lab_u16"); + lldp.packU32(valU32, "linden_lab_u32"); + lldp.packS32(valS32, "linden_lab_s32"); + lldp.packF32(valF32, "linden_lab_f32"); + lldp.packColor4(llcol4, "linden_lab_col4"); + lldp.packColor4U(llcol4u, "linden_lab_col4u"); + lldp.packVector2(llvec2, "linden_lab_vec2"); + lldp.packVector3(llvec3, "linden_lab_vec3"); + lldp.packVector4(llvec4, "linden_lab_vec4"); + uuid.generate(); + lldp.packUUID(uuid, "linden_lab_uuid"); + + fflush(fp); + fseek(fp,0,SEEK_SET); + LLDataPackerAsciiFile lldp1(fp,2); + + lldp1.unpackString(unpkstr , "linden_lab_str"); + lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); + lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); + lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); + lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); + lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); + lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); + lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); + lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); + lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); + lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); + lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); + lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); + + fclose(fp); + + ensure("LLDataPackerAsciiFile::packString failed", strcmp(str, unpkstr.c_str()) == 0); + ensure("LLDataPackerAsciiFile::packBinaryData failed", strcmp(strBinary, unpkstrBinary) == 0); + ensure("LLDataPackerAsciiFile::packBinaryDataFixed failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); + ensure_equals("LLDataPackerAsciiFile::packU8 failed", valU8, unpkvalU8); + ensure_equals("LLDataPackerAsciiFile::packU16 failed", valU16, unpkvalU16); + ensure_equals("LLDataPackerAsciiFile::packU32 failed", valU32, unpkvalU32); + ensure_equals("LLDataPackerAsciiFile::packS32 failed", valS32, unpkvalS32); + ensure("LLDataPackerAsciiFile::packF32 failed", is_approx_equal(valF32, unpkvalF32)); + ensure_equals("LLDataPackerAsciiFile::packColor4 failed", llcol4, unpkllcol4); + ensure_equals("LLDataPackerAsciiFile::packColor4U failed", llcol4u, unpkllcol4u); + ensure_equals("LLDataPackerAsciiFile::packVector2 failed", llvec2, unpkllvec2); + ensure_equals("LLDataPackerAsciiFile::packVector3 failed", llvec3, unpkllvec3); + ensure_equals("LLDataPackerAsciiFile::packVector4 failed", llvec4, unpkllvec4); + ensure_equals("LLDataPackerAsciiFile::packUUID failed", uuid, unpkuuid); + } + + template<> template<> + void datapacker_test_object_t::test<13>() + { + F32 f_val = 44.44f, f_unpkval; + + std::ostringstream ostr; + LLDataPackerAsciiFile lldp(ostr,2); + lldp.packFixed( f_val, "linden_lab", FALSE, 8, 8); + + std::istringstream istr(ostr.str()); + LLDataPackerAsciiFile lldp1(istr,2); + + lldp1.unpackFixed(f_unpkval, "linden_lab", FALSE, 8, 8); + + ensure_approximately_equals("LLDataPackerAsciiFile::packFixed (iostring) failed", f_val, f_unpkval, 8); + } + + template<> template<> + void datapacker_test_object_t::test<14>() + { + char str[] = "SecondLife is virtual World\0"; + char strBinary[] = "SecondLife is virtual World"; + char strBinaryFixed[] = "Fixed Data"; + S32 sizeBinaryFixed = sizeof(strBinaryFixed); + U8 valU8 = 'C'; + U16 valU16 = 0xFFFF; + U32 valU32 = 0xFFFFFFFF; + S32 valS32 = -94967295; + F32 valF32 = 4354355.44f ; + LLColor4 llcol4(3.3f, 0, 4.4f, 5.5f); + LLColor4U llcol4u(3, 128, 24, 33); + LLVector2 llvec2(3333333.33f, 444.333344f); + LLVector3 llvec3(3323233.33f, 444.4324f, 555.553232f); + LLVector4 llvec4(333.33233f, 444.4323234f, 55323225.55f, 6323236.66f); + LLUUID uuid; + + std::string unpkstr; + char unpkstrBinary[256]; + char unpkstrBinaryFixed[256]; + S32 unpksizeBinary; + U8 unpkvalU8; + U16 unpkvalU16; + U32 unpkvalU32; + S32 unpkvalS32; + F32 unpkvalF32; + LLColor4 unpkllcol4; + LLColor4U unpkllcol4u; + LLVector2 unpkllvec2; + LLVector3 unpkllvec3; + LLVector4 unpkllvec4; + LLUUID unpkuuid; + + std::ostringstream ostr; + LLDataPackerAsciiFile lldp(ostr,2); + + lldp.packString(str , "linden_lab_str"); + lldp.packBinaryData((U8*)strBinary, sizeof(strBinary), "linden_lab_bd"); + lldp.packBinaryDataFixed((U8*)strBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp.packU8(valU8,"linden_lab_u8"); + lldp.packU16(valU16,"linden_lab_u16"); + lldp.packU32(valU32, "linden_lab_u32"); + lldp.packS32(valS32, "linden_lab_s32"); + lldp.packF32(valF32, "linden_lab_f32"); + lldp.packColor4(llcol4, "linden_lab_col4"); + lldp.packColor4U(llcol4u, "linden_lab_col4u"); + lldp.packVector2(llvec2, "linden_lab_vec2"); + lldp.packVector3(llvec3, "linden_lab_vec3"); + lldp.packVector4(llvec4, "linden_lab_vec4"); + uuid.generate(); + lldp.packUUID(uuid, "linden_lab_uuid"); + + std::istringstream istr(ostr.str()); + LLDataPackerAsciiFile lldp1(istr,2); + + lldp1.unpackString(unpkstr , "linden_lab_str"); + lldp1.unpackBinaryData((U8*)unpkstrBinary, unpksizeBinary, "linden_lab_bd"); + lldp1.unpackBinaryDataFixed((U8*)unpkstrBinaryFixed, sizeBinaryFixed, "linden_lab_bdf"); + lldp1.unpackU8(unpkvalU8,"linden_lab_u8"); + lldp1.unpackU16(unpkvalU16,"linden_lab_u16"); + lldp1.unpackU32(unpkvalU32, "linden_lab_u32"); + lldp1.unpackS32(unpkvalS32, "linden_lab_s32"); + lldp1.unpackF32(unpkvalF32, "linden_lab_f32"); + lldp1.unpackColor4(unpkllcol4, "linden_lab_col4"); + lldp1.unpackColor4U(unpkllcol4u, "linden_lab_col4u"); + lldp1.unpackVector2(unpkllvec2, "linden_lab_vec2"); + lldp1.unpackVector3(unpkllvec3, "linden_lab_vec3"); + lldp1.unpackVector4(unpkllvec4, "linden_lab_vec4"); + lldp1.unpackUUID(unpkuuid, "linden_lab_uuid"); + + ensure("LLDataPackerAsciiFile::packString (iostring) failed", strcmp(str, unpkstr.c_str()) == 0); + ensure("LLDataPackerAsciiFile::packBinaryData (iostring) failed", strcmp(strBinary, unpkstrBinary) == 0); + ensure("LLDataPackerAsciiFile::packBinaryDataFixed (iostring) failed", strcmp(strBinaryFixed, unpkstrBinaryFixed) == 0); + ensure_equals("LLDataPackerAsciiFile::packU8 (iostring) failed", valU8, unpkvalU8); + ensure_equals("LLDataPackerAsciiFile::packU16 (iostring) failed", valU16, unpkvalU16); + ensure_equals("LLDataPackerAsciiFile::packU32 (iostring) failed", valU32, unpkvalU32); + ensure_equals("LLDataPackerAsciiFile::packS32 (iostring) failed", valS32, unpkvalS32); + ensure("LLDataPackerAsciiFile::packF32 (iostring) failed", is_approx_equal(valF32, unpkvalF32)); + ensure_equals("LLDataPackerAsciiFile::packColor4 (iostring) failed", llcol4, unpkllcol4); + ensure_equals("LLDataPackerAsciiFile::packColor4U (iostring) failed", llcol4u, unpkllcol4u); + ensure_equals("LLDataPackerAsciiFile::packVector2 (iostring) failed", llvec2, unpkllvec2); + ensure_equals("LLDataPackerAsciiFile::packVector3 (iostring) failed", llvec3, unpkllvec3); + ensure_equals("LLDataPackerAsciiFile::packVector4 (iostring) failed", llvec4, unpkllvec4); + ensure_equals("LLDataPackerAsciiFile::packUUID (iostring) failed", uuid, unpkuuid); + } } diff --git a/indra/test/lldoubledispatch_tut.cpp b/indra/test/lldoubledispatch_tut.cpp index dbf55e666f..79c4edc058 100644 --- a/indra/test/lldoubledispatch_tut.cpp +++ b/indra/test/lldoubledispatch_tut.cpp @@ -10,21 +10,21 @@ * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -190,7 +190,7 @@ namespace tut dispatcher.add(DD::Type<SpaceShip>(), DD::Type<Asteroid>(), shipAsteroid, true); dispatcher.add(DD::Type<SpaceShip>(), DD::Type<SpaceStation>(), shipStation, true); dispatcher.add(DD::Type<Asteroid>(), DD::Type<SpaceStation>(), asteroidStation, true); - + ensure_equals(dispatcher(*patrol, *obstacle), "militaryShipAsteroid"); ensure_equals(dispatcher(*tug, *obstacle), "shipAsteroid"); } diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp index a38de71e48..875ca9ad89 100644 --- a/indra/test/llevents_tut.cpp +++ b/indra/test/llevents_tut.cpp @@ -3,25 +3,25 @@ * @author Nat Goodspeed * @date 2008-09-12 * @brief Test of llevents.h - * + * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -57,7 +57,7 @@ using boost::assign::list_of; template<typename T> T make(const T& value) { - return value; + return value; } /***************************************************************************** @@ -67,21 +67,21 @@ namespace tut { struct events_data { - events_data() : - pumps(LLEventPumps::instance()), - listener0("first"), - listener1("second") - { - } - LLEventPumps& pumps; - Listener listener0; - Listener listener1; + events_data() : + pumps(LLEventPumps::instance()), + listener0("first"), + listener1("second") + { + } + LLEventPumps& pumps; + Listener listener0; + Listener listener1; - void check_listener(const std::string& desc, const Listener& listener, LLSD::Integer got) - { - ensure_equals(STRINGIZE(listener << ' ' << desc), - listener.getLastEvent().asInteger(), got); - } + void check_listener(const std::string& desc, const Listener& listener, LLSD::Integer got) + { + ensure_equals(STRINGIZE(listener << ' ' << desc), + listener.getLastEvent().asInteger(), got); + } }; typedef test_group<events_data> events_group; typedef events_group::object events_object; @@ -90,367 +90,367 @@ tut::events_group evgr("events"); template<> template<> void events_object::test<1>() { - set_test_name("basic operations"); - // Having to modify this to track the statically- - // constructed pumps in other TUT modules in this giant monolithic test - // executable isn't such a hot idea. - // ensure_equals("initial pump", pumps.mPumpMap.size(), 1); - size_t initial_pumps(pumps.mPumpMap.size()); - LLEventPump& per_frame(pumps.obtain("per-frame")); - ensure_equals("first explicit pump", pumps.mPumpMap.size(), initial_pumps + 1); - // Verify that per_frame was instantiated as an LLEventStream. - ensure("LLEventStream leaf class", dynamic_cast<LLEventStream*> (&per_frame)); - ensure("enabled", per_frame.enabled()); - // Trivial test, but posting an event to an EventPump with no - // listeners should not blow up. The test is relevant because defining - // a boost::signal with a non-void return signature, using the default - // combiner, blows up if there are no listeners. This is because the - // default combiner is defined to return the value returned by the - // last listener, which is meaningless if there were no listeners. - per_frame.post(0); - LLBoundListener connection = listener0.listenTo(per_frame); - ensure("connected", connection.connected()); - ensure("not blocked", !connection.blocked()); - per_frame.post(1); - check_listener("received", listener0, 1); - { // block the connection - LLEventPump::Blocker block(connection); - ensure("blocked", connection.blocked()); - per_frame.post(2); - check_listener("not updated", listener0, 1); - } // unblock - ensure("unblocked", !connection.blocked()); - per_frame.post(3); - check_listener("unblocked", listener0, 3); - LLBoundListener sameConnection = per_frame.getListener(listener0.getName()); - ensure("still connected", sameConnection.connected()); - ensure("still not blocked", !sameConnection.blocked()); - { // block it again - LLEventPump::Blocker block(sameConnection); - ensure("re-blocked", sameConnection.blocked()); - per_frame.post(4); - check_listener("re-blocked", listener0, 3); - } // unblock - std::string threw = catch_what<LLEventPump::DupListenerName>( - [&per_frame, this](){ - // NOTE: boost::bind() saves its arguments by VALUE! If you pass - // an object instance rather than a pointer, you'll end up binding - // to an internal copy of that instance! Use boost::ref() to - // capture a reference instead. - per_frame.listen(listener0.getName(), // note bug, dup name - boost::bind(&Listener::call, boost::ref(listener1), _1)); - }); - ensure_equals(threw, - std::string("DupListenerName: " - "Attempt to register duplicate listener name '") + - listener0.getName() + "' on " + typeid(per_frame).name() + - " '" + per_frame.getName() + "'"); - // do it right this time - listener1.listenTo(per_frame); - per_frame.post(5); - check_listener("got", listener0, 5); - check_listener("got", listener1, 5); - per_frame.enable(false); - per_frame.post(6); - check_listener("didn't get", listener0, 5); - check_listener("didn't get", listener1, 5); - per_frame.enable(); - per_frame.post(7); - check_listener("got", listener0, 7); - check_listener("got", listener1, 7); - per_frame.stopListening(listener0.getName()); - ensure("disconnected 0", ! connection.connected()); - ensure("disconnected 1", ! sameConnection.connected()); - per_frame.post(8); - check_listener("disconnected", listener0, 7); - check_listener("still connected", listener1, 8); - per_frame.stopListening(listener1.getName()); - per_frame.post(9); - check_listener("disconnected", listener1, 8); + set_test_name("basic operations"); + // Having to modify this to track the statically- + // constructed pumps in other TUT modules in this giant monolithic test + // executable isn't such a hot idea. + // ensure_equals("initial pump", pumps.mPumpMap.size(), 1); + size_t initial_pumps(pumps.mPumpMap.size()); + LLEventPump& per_frame(pumps.obtain("per-frame")); + ensure_equals("first explicit pump", pumps.mPumpMap.size(), initial_pumps + 1); + // Verify that per_frame was instantiated as an LLEventStream. + ensure("LLEventStream leaf class", dynamic_cast<LLEventStream*> (&per_frame)); + ensure("enabled", per_frame.enabled()); + // Trivial test, but posting an event to an EventPump with no + // listeners should not blow up. The test is relevant because defining + // a boost::signal with a non-void return signature, using the default + // combiner, blows up if there are no listeners. This is because the + // default combiner is defined to return the value returned by the + // last listener, which is meaningless if there were no listeners. + per_frame.post(0); + LLBoundListener connection = listener0.listenTo(per_frame); + ensure("connected", connection.connected()); + ensure("not blocked", !connection.blocked()); + per_frame.post(1); + check_listener("received", listener0, 1); + { // block the connection + LLEventPump::Blocker block(connection); + ensure("blocked", connection.blocked()); + per_frame.post(2); + check_listener("not updated", listener0, 1); + } // unblock + ensure("unblocked", !connection.blocked()); + per_frame.post(3); + check_listener("unblocked", listener0, 3); + LLBoundListener sameConnection = per_frame.getListener(listener0.getName()); + ensure("still connected", sameConnection.connected()); + ensure("still not blocked", !sameConnection.blocked()); + { // block it again + LLEventPump::Blocker block(sameConnection); + ensure("re-blocked", sameConnection.blocked()); + per_frame.post(4); + check_listener("re-blocked", listener0, 3); + } // unblock + std::string threw = catch_what<LLEventPump::DupListenerName>( + [&per_frame, this](){ + // NOTE: boost::bind() saves its arguments by VALUE! If you pass + // an object instance rather than a pointer, you'll end up binding + // to an internal copy of that instance! Use boost::ref() to + // capture a reference instead. + per_frame.listen(listener0.getName(), // note bug, dup name + boost::bind(&Listener::call, boost::ref(listener1), _1)); + }); + ensure_equals(threw, + std::string("DupListenerName: " + "Attempt to register duplicate listener name '") + + listener0.getName() + "' on " + typeid(per_frame).name() + + " '" + per_frame.getName() + "'"); + // do it right this time + listener1.listenTo(per_frame); + per_frame.post(5); + check_listener("got", listener0, 5); + check_listener("got", listener1, 5); + per_frame.enable(false); + per_frame.post(6); + check_listener("didn't get", listener0, 5); + check_listener("didn't get", listener1, 5); + per_frame.enable(); + per_frame.post(7); + check_listener("got", listener0, 7); + check_listener("got", listener1, 7); + per_frame.stopListening(listener0.getName()); + ensure("disconnected 0", ! connection.connected()); + ensure("disconnected 1", ! sameConnection.connected()); + per_frame.post(8); + check_listener("disconnected", listener0, 7); + check_listener("still connected", listener1, 8); + per_frame.stopListening(listener1.getName()); + per_frame.post(9); + check_listener("disconnected", listener1, 8); } template<> template<> void events_object::test<2>() { - set_test_name("callstop() returning true"); - LLEventPump& per_frame(pumps.obtain("per-frame")); - listener0.reset(0); - listener1.reset(0); - LLBoundListener bound0 = listener0.listenTo(per_frame, &Listener::callstop); - LLBoundListener bound1 = listener1.listenTo(per_frame, &Listener::call, - // after listener0 - make<LLEventPump::NameList>(list_of(listener0.getName()))); - ensure("enabled", per_frame.enabled()); - ensure("connected 0", bound0.connected()); - ensure("unblocked 0", !bound0.blocked()); - ensure("connected 1", bound1.connected()); - ensure("unblocked 1", !bound1.blocked()); - per_frame.post(1); - check_listener("got", listener0, 1); - // Because listener0.callstop() returns true, control never reaches listener1.call(). - check_listener("got", listener1, 0); + set_test_name("callstop() returning true"); + LLEventPump& per_frame(pumps.obtain("per-frame")); + listener0.reset(0); + listener1.reset(0); + LLBoundListener bound0 = listener0.listenTo(per_frame, &Listener::callstop); + LLBoundListener bound1 = listener1.listenTo(per_frame, &Listener::call, + // after listener0 + make<LLEventPump::NameList>(list_of(listener0.getName()))); + ensure("enabled", per_frame.enabled()); + ensure("connected 0", bound0.connected()); + ensure("unblocked 0", !bound0.blocked()); + ensure("connected 1", bound1.connected()); + ensure("unblocked 1", !bound1.blocked()); + per_frame.post(1); + check_listener("got", listener0, 1); + // Because listener0.callstop() returns true, control never reaches listener1.call(). + check_listener("got", listener1, 0); } bool chainEvents(Listener& someListener, const LLSD& event) { - // Make this call so we can watch for side effects for test purposes. - someListener.call(event); - // This function represents a recursive event chain -- or some other - // scenario in which an event handler raises additional events. - int value = event.asInteger(); - if (value) - { - LLEventPumps::instance().obtain("login").post(value - 1); - } - return false; + // Make this call so we can watch for side effects for test purposes. + someListener.call(event); + // This function represents a recursive event chain -- or some other + // scenario in which an event handler raises additional events. + int value = event.asInteger(); + if (value) + { + LLEventPumps::instance().obtain("login").post(value - 1); + } + return false; } template<> template<> void events_object::test<3>() { - set_test_name("explicitly-instantiated LLEventStream"); - // Explicitly instantiate an LLEventStream, and verify that it - // self-registers with LLEventPumps - size_t registered = pumps.mPumpMap.size(); - size_t owned = pumps.mOurPumps.size(); - LLEventPump* localInstance; - { - LLEventStream myEventStream("stream"); - localInstance = &myEventStream; - LLEventPump& stream(pumps.obtain("stream")); - ensure("found named LLEventStream instance", &stream == localInstance); - ensure_equals("registered new instance", pumps.mPumpMap.size(), registered + 1); - ensure_equals("explicit instance not owned", pumps.mOurPumps.size(), owned); - } // destroy myEventStream -- should unregister - ensure_equals("destroyed instance unregistered", pumps.mPumpMap.size(), registered); - ensure_equals("destroyed instance not owned", pumps.mOurPumps.size(), owned); - LLEventPump& stream(pumps.obtain("stream")); - ensure("new LLEventStream instance", &stream != localInstance); - ensure_equals("obtain()ed instance registered", pumps.mPumpMap.size(), registered + 1); - ensure_equals("obtain()ed instance owned", pumps.mOurPumps.size(), owned + 1); + set_test_name("explicitly-instantiated LLEventStream"); + // Explicitly instantiate an LLEventStream, and verify that it + // self-registers with LLEventPumps + size_t registered = pumps.mPumpMap.size(); + size_t owned = pumps.mOurPumps.size(); + LLEventPump* localInstance; + { + LLEventStream myEventStream("stream"); + localInstance = &myEventStream; + LLEventPump& stream(pumps.obtain("stream")); + ensure("found named LLEventStream instance", &stream == localInstance); + ensure_equals("registered new instance", pumps.mPumpMap.size(), registered + 1); + ensure_equals("explicit instance not owned", pumps.mOurPumps.size(), owned); + } // destroy myEventStream -- should unregister + ensure_equals("destroyed instance unregistered", pumps.mPumpMap.size(), registered); + ensure_equals("destroyed instance not owned", pumps.mOurPumps.size(), owned); + LLEventPump& stream(pumps.obtain("stream")); + ensure("new LLEventStream instance", &stream != localInstance); + ensure_equals("obtain()ed instance registered", pumps.mPumpMap.size(), registered + 1); + ensure_equals("obtain()ed instance owned", pumps.mOurPumps.size(), owned + 1); } template<> template<> void events_object::test<4>() { - set_test_name("stopListening()"); - LLEventPump& login(pumps.obtain("login")); - listener0.listenTo(login); - login.stopListening(listener0.getName()); - // should not throw because stopListening() should have removed name - listener0.listenTo(login, &Listener::callstop); - LLBoundListener wrong = login.getListener("bogus"); - ensure("bogus connection disconnected", !wrong.connected()); - ensure("bogus connection blocked", wrong.blocked()); + set_test_name("stopListening()"); + LLEventPump& login(pumps.obtain("login")); + listener0.listenTo(login); + login.stopListening(listener0.getName()); + // should not throw because stopListening() should have removed name + listener0.listenTo(login, &Listener::callstop); + LLBoundListener wrong = login.getListener("bogus"); + ensure("bogus connection disconnected", !wrong.connected()); + ensure("bogus connection blocked", wrong.blocked()); } template<> template<> void events_object::test<5>() { - set_test_name("chaining LLEventPump instances"); - LLEventPump& upstream(pumps.obtain("upstream")); - // One potentially-useful construct is to chain LLEventPumps together. - // Among other things, this allows you to turn subsets of listeners on - // and off in groups. - LLEventPump& filter0(pumps.obtain("filter0")); - LLEventPump& filter1(pumps.obtain("filter1")); - upstream.listen(filter0.getName(), boost::bind(&LLEventPump::post, boost::ref(filter0), _1)); - upstream.listen(filter1.getName(), boost::bind(&LLEventPump::post, boost::ref(filter1), _1)); - listener0.listenTo(filter0); - listener1.listenTo(filter1); - listener0.reset(0); - listener1.reset(0); - upstream.post(1); - check_listener("got unfiltered", listener0, 1); - check_listener("got unfiltered", listener1, 1); - filter0.enable(false); - upstream.post(2); - check_listener("didn't get filtered", listener0, 1); - check_listener("got filtered", listener1, 2); + set_test_name("chaining LLEventPump instances"); + LLEventPump& upstream(pumps.obtain("upstream")); + // One potentially-useful construct is to chain LLEventPumps together. + // Among other things, this allows you to turn subsets of listeners on + // and off in groups. + LLEventPump& filter0(pumps.obtain("filter0")); + LLEventPump& filter1(pumps.obtain("filter1")); + upstream.listen(filter0.getName(), boost::bind(&LLEventPump::post, boost::ref(filter0), _1)); + upstream.listen(filter1.getName(), boost::bind(&LLEventPump::post, boost::ref(filter1), _1)); + listener0.listenTo(filter0); + listener1.listenTo(filter1); + listener0.reset(0); + listener1.reset(0); + upstream.post(1); + check_listener("got unfiltered", listener0, 1); + check_listener("got unfiltered", listener1, 1); + filter0.enable(false); + upstream.post(2); + check_listener("didn't get filtered", listener0, 1); + check_listener("got filtered", listener1, 2); } template<> template<> void events_object::test<6>() { - set_test_name("listener dependency order"); - typedef LLEventPump::NameList NameList; - LLEventPump& button(pumps.obtain("button")); - Collect collector; - button.listen("Mary", - boost::bind(&Collect::add, boost::ref(collector), "Mary", _1), - // state that "Mary" must come after "checked" - make<NameList> (list_of("checked"))); - button.listen("checked", - boost::bind(&Collect::add, boost::ref(collector), "checked", _1), - // "checked" must come after "spot" - make<NameList> (list_of("spot"))); - button.listen("spot", - boost::bind(&Collect::add, boost::ref(collector), "spot", _1)); - button.post(1); - ensure_equals(collector.result, make<StringVec>(list_of("spot")("checked")("Mary"))); - collector.clear(); - button.stopListening("Mary"); - button.listen("Mary", - boost::bind(&Collect::add, boost::ref(collector), "Mary", _1), - LLEventPump::empty, // no after dependencies - // now "Mary" must come before "spot" - make<NameList>(list_of("spot"))); - button.post(2); - ensure_equals(collector.result, make<StringVec>(list_of("Mary")("spot")("checked"))); - collector.clear(); - button.stopListening("spot"); - std::string threw = catch_what<LLEventPump::Cycle>( - [&button, &collector](){ - button.listen("spot", - boost::bind(&Collect::add, boost::ref(collector), "spot", _1), - // after "Mary" and "checked" -- whoops! - make<NameList>(list_of("Mary")("checked"))); - }); - // Obviously the specific wording of the exception text can - // change; go ahead and change the test to match. - // Establish that it contains: - // - the name and runtime type of the LLEventPump - ensure_contains("LLEventPump type", threw, typeid(button).name()); - ensure_contains("LLEventPump name", threw, "'button'"); - // - the name of the new listener that caused the problem - ensure_contains("new listener name", threw, "'spot'"); - // - a synopsis of the problematic dependencies. - ensure_contains("cyclic dependencies", threw, - "\"Mary\" -> before (\"spot\")"); - ensure_contains("cyclic dependencies", threw, - "after (\"spot\") -> \"checked\""); - ensure_contains("cyclic dependencies", threw, - "after (\"Mary\", \"checked\") -> \"spot\""); - button.listen("yellow", - boost::bind(&Collect::add, boost::ref(collector), "yellow", _1), - make<NameList>(list_of("checked"))); - button.listen("shoelaces", - boost::bind(&Collect::add, boost::ref(collector), "shoelaces", _1), - make<NameList>(list_of("checked"))); - button.post(3); - ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces"))); - collector.clear(); - threw = catch_what<LLEventPump::OrderChange>( - [&button, &collector](){ - button.listen("of", - boost::bind(&Collect::add, boost::ref(collector), "of", _1), - make<NameList>(list_of("shoelaces")), - make<NameList>(list_of("yellow"))); - }); - // Same remarks about the specific wording of the exception. Just - // ensure that it contains enough information to clarify the - // problem and what must be done to resolve it. - ensure_contains("LLEventPump type", threw, typeid(button).name()); - ensure_contains("LLEventPump name", threw, "'button'"); - ensure_contains("new listener name", threw, "'of'"); - ensure_contains("prev listener name", threw, "'yellow'"); - // std::cout << "Thrown Exception: " << threw << std::endl; - ensure_contains("old order", threw, "was: Mary, checked, yellow, shoelaces"); - ensure_contains("new order", threw, "now: Mary, checked, shoelaces, of, yellow"); - button.post(4); - ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces"))); + set_test_name("listener dependency order"); + typedef LLEventPump::NameList NameList; + LLEventPump& button(pumps.obtain("button")); + Collect collector; + button.listen("Mary", + boost::bind(&Collect::add, boost::ref(collector), "Mary", _1), + // state that "Mary" must come after "checked" + make<NameList> (list_of("checked"))); + button.listen("checked", + boost::bind(&Collect::add, boost::ref(collector), "checked", _1), + // "checked" must come after "spot" + make<NameList> (list_of("spot"))); + button.listen("spot", + boost::bind(&Collect::add, boost::ref(collector), "spot", _1)); + button.post(1); + ensure_equals(collector.result, make<StringVec>(list_of("spot")("checked")("Mary"))); + collector.clear(); + button.stopListening("Mary"); + button.listen("Mary", + boost::bind(&Collect::add, boost::ref(collector), "Mary", _1), + LLEventPump::empty, // no after dependencies + // now "Mary" must come before "spot" + make<NameList>(list_of("spot"))); + button.post(2); + ensure_equals(collector.result, make<StringVec>(list_of("Mary")("spot")("checked"))); + collector.clear(); + button.stopListening("spot"); + std::string threw = catch_what<LLEventPump::Cycle>( + [&button, &collector](){ + button.listen("spot", + boost::bind(&Collect::add, boost::ref(collector), "spot", _1), + // after "Mary" and "checked" -- whoops! + make<NameList>(list_of("Mary")("checked"))); + }); + // Obviously the specific wording of the exception text can + // change; go ahead and change the test to match. + // Establish that it contains: + // - the name and runtime type of the LLEventPump + ensure_contains("LLEventPump type", threw, typeid(button).name()); + ensure_contains("LLEventPump name", threw, "'button'"); + // - the name of the new listener that caused the problem + ensure_contains("new listener name", threw, "'spot'"); + // - a synopsis of the problematic dependencies. + ensure_contains("cyclic dependencies", threw, + "\"Mary\" -> before (\"spot\")"); + ensure_contains("cyclic dependencies", threw, + "after (\"spot\") -> \"checked\""); + ensure_contains("cyclic dependencies", threw, + "after (\"Mary\", \"checked\") -> \"spot\""); + button.listen("yellow", + boost::bind(&Collect::add, boost::ref(collector), "yellow", _1), + make<NameList>(list_of("checked"))); + button.listen("shoelaces", + boost::bind(&Collect::add, boost::ref(collector), "shoelaces", _1), + make<NameList>(list_of("checked"))); + button.post(3); + ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces"))); + collector.clear(); + threw = catch_what<LLEventPump::OrderChange>( + [&button, &collector](){ + button.listen("of", + boost::bind(&Collect::add, boost::ref(collector), "of", _1), + make<NameList>(list_of("shoelaces")), + make<NameList>(list_of("yellow"))); + }); + // Same remarks about the specific wording of the exception. Just + // ensure that it contains enough information to clarify the + // problem and what must be done to resolve it. + ensure_contains("LLEventPump type", threw, typeid(button).name()); + ensure_contains("LLEventPump name", threw, "'button'"); + ensure_contains("new listener name", threw, "'of'"); + ensure_contains("prev listener name", threw, "'yellow'"); + // std::cout << "Thrown Exception: " << threw << std::endl; + ensure_contains("old order", threw, "was: Mary, checked, yellow, shoelaces"); + ensure_contains("new order", threw, "now: Mary, checked, shoelaces, of, yellow"); + button.post(4); + ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces"))); } template<> template<> void events_object::test<7>() { - set_test_name("tweaked and untweaked LLEventPump instance names"); - { // nested scope - // Hand-instantiate an LLEventStream... - LLEventStream bob("bob"); - std::string threw = catch_what<LLEventPump::DupPumpName>( - [](){ - // then another with a duplicate name. - LLEventStream bob2("bob"); - }); - ensure("Caught DupPumpName", !threw.empty()); - } // delete first 'bob' - LLEventStream bob("bob"); // should work, previous one unregistered - LLEventStream bob1("bob", true);// allowed to tweak name - ensure_equals("tweaked LLEventStream name", bob1.getName(), "bob1"); - std::vector<std::shared_ptr<LLEventStream> > streams; - for (int i = 2; i <= 10; ++i) - { - streams.push_back(std::shared_ptr<LLEventStream>(new LLEventStream("bob", true))); - } - ensure_equals("last tweaked LLEventStream name", streams.back()->getName(), "bob10"); + set_test_name("tweaked and untweaked LLEventPump instance names"); + { // nested scope + // Hand-instantiate an LLEventStream... + LLEventStream bob("bob"); + std::string threw = catch_what<LLEventPump::DupPumpName>( + [](){ + // then another with a duplicate name. + LLEventStream bob2("bob"); + }); + ensure("Caught DupPumpName", !threw.empty()); + } // delete first 'bob' + LLEventStream bob("bob"); // should work, previous one unregistered + LLEventStream bob1("bob", true);// allowed to tweak name + ensure_equals("tweaked LLEventStream name", bob1.getName(), "bob1"); + std::vector<std::shared_ptr<LLEventStream> > streams; + for (int i = 2; i <= 10; ++i) + { + streams.push_back(std::shared_ptr<LLEventStream>(new LLEventStream("bob", true))); + } + ensure_equals("last tweaked LLEventStream name", streams.back()->getName(), "bob10"); } // Define a function that accepts an LLListenerOrPumpName void eventSource(const LLListenerOrPumpName& listener) { - // Pretend that some time has elapsed. Call listener immediately. - listener(17); + // Pretend that some time has elapsed. Call listener immediately. + listener(17); } template<> template<> void events_object::test<8>() { - set_test_name("LLListenerOrPumpName"); - // Passing a boost::bind() expression to LLListenerOrPumpName - listener0.reset(0); - eventSource(boost::bind(&Listener::call, boost::ref(listener0), _1)); - check_listener("got by listener", listener0, 17); - // Passing a string LLEventPump name to LLListenerOrPumpName - listener0.reset(0); - LLEventStream random("random"); - listener0.listenTo(random); - eventSource("random"); - check_listener("got by pump name", listener0, 17); - std::string threw = catch_what<LLListenerOrPumpName::Empty>( - [](){ - LLListenerOrPumpName empty; - empty(17); - }); + set_test_name("LLListenerOrPumpName"); + // Passing a boost::bind() expression to LLListenerOrPumpName + listener0.reset(0); + eventSource(boost::bind(&Listener::call, boost::ref(listener0), _1)); + check_listener("got by listener", listener0, 17); + // Passing a string LLEventPump name to LLListenerOrPumpName + listener0.reset(0); + LLEventStream random("random"); + listener0.listenTo(random); + eventSource("random"); + check_listener("got by pump name", listener0, 17); + std::string threw = catch_what<LLListenerOrPumpName::Empty>( + [](){ + LLListenerOrPumpName empty; + empty(17); + }); - ensure("threw Empty", !threw.empty()); + ensure("threw Empty", !threw.empty()); } class TempListener: public Listener { public: - TempListener(const std::string& name, bool& liveFlag) : - Listener(name), mLiveFlag(liveFlag) - { - mLiveFlag = true; - } + TempListener(const std::string& name, bool& liveFlag) : + Listener(name), mLiveFlag(liveFlag) + { + mLiveFlag = true; + } - virtual ~TempListener() - { - mLiveFlag = false; - } + virtual ~TempListener() + { + mLiveFlag = false; + } private: - bool& mLiveFlag; + bool& mLiveFlag; }; template<> template<> void events_object::test<9>() { - set_test_name("listen(boost::bind(...TempListener...))"); - // listen() can't do anything about a plain TempListener instance: - // it's not managed with shared_ptr, nor is it an LLEventTrackable subclass - bool live = false; - LLEventPump& heaptest(pumps.obtain("heaptest")); - LLBoundListener connection; - { - TempListener tempListener("temp", live); - ensure("TempListener constructed", live); - connection = heaptest.listen(tempListener.getName(), - boost::bind(&Listener::call, - boost::ref(tempListener), - _1)); - heaptest.post(1); - check_listener("received", tempListener, 1); - } // presumably this will make newListener go away? - // verify that - ensure("TempListener destroyed", !live); - // This is the case against which we can't defend. Don't even try to - // post to heaptest -- that would engage Undefined Behavior. - // Cautiously inspect connection... - ensure("misleadingly connected", connection.connected()); - // then disconnect by hand. - heaptest.stopListening("temp"); + set_test_name("listen(boost::bind(...TempListener...))"); + // listen() can't do anything about a plain TempListener instance: + // it's not managed with shared_ptr, nor is it an LLEventTrackable subclass + bool live = false; + LLEventPump& heaptest(pumps.obtain("heaptest")); + LLBoundListener connection; + { + TempListener tempListener("temp", live); + ensure("TempListener constructed", live); + connection = heaptest.listen(tempListener.getName(), + boost::bind(&Listener::call, + boost::ref(tempListener), + _1)); + heaptest.post(1); + check_listener("received", tempListener, 1); + } // presumably this will make newListener go away? + // verify that + ensure("TempListener destroyed", !live); + // This is the case against which we can't defend. Don't even try to + // post to heaptest -- that would engage Undefined Behavior. + // Cautiously inspect connection... + ensure("misleadingly connected", connection.connected()); + // then disconnect by hand. + heaptest.stopListening("temp"); } class TempTrackableListener: public TempListener, public LLEventTrackable diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp index ecf734ee90..a47602dec5 100644 --- a/indra/test/llhttpdate_tut.cpp +++ b/indra/test/llhttpdate_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llhttpdate_tut.cpp * @author Kartic Krishnamurthy * @date Wednesday, 18 Jul 2007 17:00:00 GMT :) @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -39,12 +39,12 @@ namespace tut { struct httpdate_data { - httpdate_data() - { - } - ~httpdate_data() - { - } + httpdate_data() + { + } + ~httpdate_data() + { + } LLDate some_date; }; typedef test_group<httpdate_data> httpdate_test; @@ -79,11 +79,11 @@ namespace tut some_date = LLDate((F64) sometime); struct tm *result; char expected[255]; - std::string actual; - + std::string actual; + result = gmtime(&sometime); /* - std::cout << " seconds: "<< result->tm_sec + std::cout << " seconds: "<< result->tm_sec << ", minutes: " << result->tm_min << ", hours: " << result->tm_hour << ", day of the month: " << result->tm_mday @@ -99,69 +99,69 @@ namespace tut ensure("Current time in RFC 1123", (strcmp(expected, actual.c_str()) == 0)); } - void test_date_string(const std::string &locale, struct tm *t, - const std::string &fmt, const std::string &expected) - { - std::string result = LLDate::toHTTPDateString(t, fmt); - LLStringUtil::toLower(result); - std::string label = std::string("toHTTPDateString - ") + locale; - ensure_equals(label.c_str(), result, expected); - } - - template<> template<> - void httpdate_object::test<4>() - { - // test localization of http dates + void test_date_string(const std::string &locale, struct tm *t, + const std::string &fmt, const std::string &expected) + { + std::string result = LLDate::toHTTPDateString(t, fmt); + LLStringUtil::toLower(result); + std::string label = std::string("toHTTPDateString - ") + locale; + ensure_equals(label.c_str(), result, expected); + } + + template<> template<> + void httpdate_object::test<4>() + { + // test localization of http dates #if LL_WINDOWS - const char *en_locale = "english"; - const char *fr_locale = "french"; + const char *en_locale = "english"; + const char *fr_locale = "french"; #else - const char *en_locale = "en_GB.UTF-8"; - const char *fr_locale = "fr_FR.UTF-8"; + const char *en_locale = "en_GB.UTF-8"; + const char *fr_locale = "fr_FR.UTF-8"; #endif - std::string prev_locale = LLStringUtil::getLocale(); - std::string prev_clocale = std::string(setlocale(LC_TIME, NULL)); - time_t test_time = 1252374030; // 8 Sep 2009 01:40:01 - struct tm *t = gmtime(&test_time); - - setlocale(LC_TIME, en_locale); - if (strcmp(setlocale(LC_TIME, NULL), en_locale) != 0) - { - setlocale(LC_TIME, prev_clocale.c_str()); - skip("Cannot set English locale"); - } - - LLStringUtil::setLocale(en_locale); - test_date_string(en_locale, t, "%d %B %Y - %H:%M", "08 september 2009 - 01:40"); - test_date_string(en_locale, t, "%H", "01"); - test_date_string(en_locale, t, "%M", "40"); - test_date_string(en_locale, t, "%I", "01"); - test_date_string(en_locale, t, "%d", "08"); - test_date_string(en_locale, t, "%Y", "2009"); - test_date_string(en_locale, t, "%p", "am"); - test_date_string(en_locale, t, "%A", "tuesday"); - test_date_string(en_locale, t, "%B", "september"); - - setlocale(LC_TIME, fr_locale); - if (strcmp(setlocale(LC_TIME, NULL), fr_locale) != 0) - { - LLStringUtil::setLocale(prev_locale); - setlocale(LC_TIME, prev_clocale.c_str()); - skip("Cannot set French locale"); - } - - LLStringUtil::setLocale(fr_locale); - test_date_string(fr_locale, t, "%d %B %Y - %H:%M", "08 septembre 2009 - 01:40"); - test_date_string(fr_locale, t, "%H", "01"); - test_date_string(fr_locale, t, "%M", "40"); - test_date_string(fr_locale, t, "%I", "01"); - test_date_string(fr_locale, t, "%d", "08"); - test_date_string(fr_locale, t, "%Y", "2009"); - test_date_string(fr_locale, t, "%A", "mardi"); - test_date_string(fr_locale, t, "%B", "septembre"); - - LLStringUtil::setLocale(prev_locale); - setlocale(LC_TIME, prev_clocale.c_str()); - } + std::string prev_locale = LLStringUtil::getLocale(); + std::string prev_clocale = std::string(setlocale(LC_TIME, NULL)); + time_t test_time = 1252374030; // 8 Sep 2009 01:40:01 + struct tm *t = gmtime(&test_time); + + setlocale(LC_TIME, en_locale); + if (strcmp(setlocale(LC_TIME, NULL), en_locale) != 0) + { + setlocale(LC_TIME, prev_clocale.c_str()); + skip("Cannot set English locale"); + } + + LLStringUtil::setLocale(en_locale); + test_date_string(en_locale, t, "%d %B %Y - %H:%M", "08 september 2009 - 01:40"); + test_date_string(en_locale, t, "%H", "01"); + test_date_string(en_locale, t, "%M", "40"); + test_date_string(en_locale, t, "%I", "01"); + test_date_string(en_locale, t, "%d", "08"); + test_date_string(en_locale, t, "%Y", "2009"); + test_date_string(en_locale, t, "%p", "am"); + test_date_string(en_locale, t, "%A", "tuesday"); + test_date_string(en_locale, t, "%B", "september"); + + setlocale(LC_TIME, fr_locale); + if (strcmp(setlocale(LC_TIME, NULL), fr_locale) != 0) + { + LLStringUtil::setLocale(prev_locale); + setlocale(LC_TIME, prev_clocale.c_str()); + skip("Cannot set French locale"); + } + + LLStringUtil::setLocale(fr_locale); + test_date_string(fr_locale, t, "%d %B %Y - %H:%M", "08 septembre 2009 - 01:40"); + test_date_string(fr_locale, t, "%H", "01"); + test_date_string(fr_locale, t, "%M", "40"); + test_date_string(fr_locale, t, "%I", "01"); + test_date_string(fr_locale, t, "%d", "08"); + test_date_string(fr_locale, t, "%Y", "2009"); + test_date_string(fr_locale, t, "%A", "mardi"); + test_date_string(fr_locale, t, "%B", "septembre"); + + LLStringUtil::setLocale(prev_locale); + setlocale(LC_TIME, prev_clocale.c_str()); + } } diff --git a/indra/test/llhttpnode_tut.cpp b/indra/test/llhttpnode_tut.cpp index c528a34129..c38dee120b 100644 --- a/indra/test/llhttpnode_tut.cpp +++ b/indra/test/llhttpnode_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliohttpnode_tut.cpp * @date May 2006 * @brief HTTP server unit tests @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -32,397 +32,397 @@ namespace tut { - struct HTTPNodeTestData - { - LLHTTPNode mRoot; - LLSD mContext; - - const LLSD& context() { return mContext; } - - std::string remainderPath() - { - std::ostringstream pathOutput; - bool addSlash = false; - - LLSD& remainder = mContext[CONTEXT_REQUEST]["remainder"]; - for (LLSD::array_const_iterator i = remainder.beginArray(); - i != remainder.endArray(); - ++i) - { - if (addSlash) { pathOutput << '/'; } - pathOutput << i->asString(); - addSlash = true; - } - - return pathOutput.str(); - } - - void ensureRootTraversal(const std::string& path, - const LLHTTPNode* expectedNode, - const char* expectedRemainder) - { - mContext.clear(); - - const LLHTTPNode* actualNode = mRoot.traverse(path, mContext); - - ensure_equals("traverse " + path + " node", - actualNode, expectedNode); - ensure_equals("traverse " + path + " remainder", - remainderPath(), expectedRemainder); - } - - class Response : public LLHTTPNode::Response - { - public: - static LLPointer<Response> create() {return new Response();} - - LLSD mResult; - - void result(const LLSD& result) { mResult = result; } - void status(S32 code, const std::string& message) { } - void extendedResult(S32 code, const std::string& message, const LLSD& headers) { } - void extendedResult(S32 code, const LLSD& result, const LLSD& headers) { } - - private: - Response() {;} // Must be accessed through LLPointer. - }; - - typedef LLPointer<Response> ResponsePtr; - - LLSD get(const std::string& path) - { - mContext.clear(); - const LLHTTPNode* node = mRoot.traverse(path, mContext); - ensure(path + " found", node != NULL); - - ResponsePtr response = Response::create(); - node->get(LLHTTPNode::ResponsePtr(response), mContext); - return response->mResult; - } - - LLSD post(const std::string& path, const LLSD& input) - { - mContext.clear(); - const LLHTTPNode* node = mRoot.traverse(path, mContext); - ensure(path + " found", node != NULL); - - ResponsePtr response = Response::create(); - node->post(LLHTTPNode::ResponsePtr(response), mContext, input); - return response->mResult; - } - - void ensureMemberString(const std::string& name, - const LLSD& actualMap, const std::string& member, - const std::string& expectedValue) - { - ensure_equals(name + " " + member, - actualMap[member].asString(), expectedValue); - } - - - void ensureInArray(const LLSD& actualArray, - const std::string& expectedValue) - { - LLSD::array_const_iterator i = actualArray.beginArray(); - LLSD::array_const_iterator end = actualArray.endArray(); - - for (; i != end; ++i) - { - std::string path = i->asString(); - - if (path == expectedValue) - { - return; - } - } - - fail("didn't find " + expectedValue); - } - - }; - - typedef test_group<HTTPNodeTestData> HTTPNodeTestGroup; - typedef HTTPNodeTestGroup::object HTTPNodeTestObject; - HTTPNodeTestGroup httpNodeTestGroup("http node"); - - template<> template<> - void HTTPNodeTestObject::test<1>() - { - // traversal of the lone node - - ensureRootTraversal("", &mRoot, ""); - ensureRootTraversal("/", &mRoot, ""); - ensureRootTraversal("foo", NULL, "foo"); - ensureRootTraversal("foo/bar", NULL, "foo/bar"); - - ensure_equals("root of root", mRoot.rootNode(), &mRoot); - } - - template<> template<> - void HTTPNodeTestObject::test<2>() - { - // simple traversal of a single node - - LLHTTPNode* helloNode = new LLHTTPNode; - mRoot.addNode("hello", helloNode); - - ensureRootTraversal("hello", helloNode, ""); - ensureRootTraversal("/hello", helloNode, ""); - ensureRootTraversal("hello/", helloNode, ""); - ensureRootTraversal("/hello/", helloNode, ""); - - ensureRootTraversal("hello/there", NULL, "there"); - - ensure_equals("root of hello", helloNode->rootNode(), &mRoot); - } - - template<> template<> - void HTTPNodeTestObject::test<3>() - { - // traversal of mutli-branched tree - - LLHTTPNode* greekNode = new LLHTTPNode; - LLHTTPNode* alphaNode = new LLHTTPNode; - LLHTTPNode* betaNode = new LLHTTPNode; - LLHTTPNode* gammaNode = new LLHTTPNode; - - greekNode->addNode("alpha", alphaNode); - greekNode->addNode("beta", betaNode); - greekNode->addNode("gamma", gammaNode); - mRoot.addNode("greek", greekNode); - - LLHTTPNode* hebrewNode = new LLHTTPNode; - LLHTTPNode* alephNode = new LLHTTPNode; - - hebrewNode->addNode("aleph", alephNode); - mRoot.addNode("hebrew", hebrewNode); - - ensureRootTraversal("greek/alpha", alphaNode, ""); - ensureRootTraversal("greek/beta", betaNode, ""); - ensureRootTraversal("greek/delta", NULL, "delta"); - ensureRootTraversal("greek/gamma", gammaNode, ""); - ensureRootTraversal("hebrew/aleph", alephNode, ""); - - ensure_equals("root of greek", greekNode->rootNode(), &mRoot); - ensure_equals("root of alpha", alphaNode->rootNode(), &mRoot); - ensure_equals("root of beta", betaNode->rootNode(), &mRoot); - ensure_equals("root of gamma", gammaNode->rootNode(), &mRoot); - ensure_equals("root of hebrew", hebrewNode->rootNode(), &mRoot); - ensure_equals("root of aleph", alephNode->rootNode(), &mRoot); - } - - template<> template<> - void HTTPNodeTestObject::test<4>() - { - // automatic creation of parent nodes and not overriding existing nodes - - LLHTTPNode* alphaNode = new LLHTTPNode; - LLHTTPNode* betaNode = new LLHTTPNode; - LLHTTPNode* gammaNode = new LLHTTPNode; - LLHTTPNode* gamma2Node = new LLHTTPNode; - - mRoot.addNode("greek/alpha", alphaNode); - mRoot.addNode("greek/beta", betaNode); - - mRoot.addNode("greek/gamma", gammaNode); - mRoot.addNode("greek/gamma", gamma2Node); - - LLHTTPNode* alephNode = new LLHTTPNode; - - mRoot.addNode("hebrew/aleph", alephNode); - - ensureRootTraversal("greek/alpha", alphaNode, ""); - ensureRootTraversal("greek/beta", betaNode, ""); - ensureRootTraversal("greek/delta", NULL, "delta"); - ensureRootTraversal("greek/gamma", gammaNode, ""); - ensureRootTraversal("hebrew/aleph", alephNode, ""); - - ensure_equals("root of alpha", alphaNode->rootNode(), &mRoot); - ensure_equals("root of beta", betaNode->rootNode(), &mRoot); - ensure_equals("root of gamma", gammaNode->rootNode(), &mRoot); - ensure_equals("root of aleph", alephNode->rootNode(), &mRoot); - } - - class IntegerNode : public LLHTTPNode - { - public: - virtual void get(ResponsePtr response, const LLSD& context) const - { - int n = context["extra"]["value"]; - - LLSD info; - info["value"] = n; - info["positive"] = n > 0; - info["zero"] = n == 0; - info["negative"] = n < 0; - - response->result(info); - } - - virtual bool validate(const std::string& name, LLSD& context) const - { - int n; - std::istringstream i_stream(name); - i_stream >> n; - - if (i_stream.fail() || i_stream.get() != EOF) - { - return false; - } - - context["extra"]["value"] = n; - return true; - } - }; - - class SquareNode : public LLHTTPNode - { - public: - virtual void get(ResponsePtr response, const LLSD& context) const - { - int n = context["extra"]["value"]; - response->result(n*n); - } - }; - - template<> template<> - void HTTPNodeTestObject::test<5>() - { - // wildcard nodes - - LLHTTPNode* miscNode = new LLHTTPNode; - LLHTTPNode* iNode = new IntegerNode; - LLHTTPNode* sqNode = new SquareNode; - - mRoot.addNode("test/misc", miscNode); - mRoot.addNode("test/<int>", iNode); - mRoot.addNode("test/<int>/square", sqNode); - - ensureRootTraversal("test/42", iNode, ""); - ensure_equals("stored integer", - context()["extra"]["value"].asInteger(), 42); - - ensureRootTraversal("test/bob", NULL, "bob"); - ensure("nothing stored", - context()["extra"]["value"].isUndefined()); - - ensureRootTraversal("test/3/square", sqNode, ""); - ResponsePtr response = Response::create(); - sqNode->get(LLHTTPNode::ResponsePtr(response), context()); - ensure_equals("square result", response->mResult.asInteger(), 9); - } - - class AlphaNode : public LLHTTPNode - { - public: - virtual bool handles(const LLSD& remainder, LLSD& context) const - { - LLSD::array_const_iterator i = remainder.beginArray(); - LLSD::array_const_iterator end = remainder.endArray(); - - for (; i != end; ++i) - { - std::string s = i->asString(); - if (s.empty() || s[0] != 'a') - { - return false; - } - } - - return true; - } - }; - - template<> template<> - void HTTPNodeTestObject::test<6>() - { - // nodes that handle remainders - - LLHTTPNode* miscNode = new LLHTTPNode; - LLHTTPNode* aNode = new AlphaNode; - LLHTTPNode* zNode = new LLHTTPNode; - - mRoot.addNode("test/misc", miscNode); - mRoot.addNode("test/alpha", aNode); - mRoot.addNode("test/alpha/zebra", zNode); - - ensureRootTraversal("test/alpha", aNode, ""); - ensureRootTraversal("test/alpha/abe", aNode, "abe"); - ensureRootTraversal("test/alpha/abe/amy", aNode, "abe/amy"); - ensureRootTraversal("test/alpha/abe/bea", NULL, "abe/bea"); - ensureRootTraversal("test/alpha/bob", NULL, "bob"); - ensureRootTraversal("test/alpha/zebra", zNode, ""); - } - - template<> template<> - void HTTPNodeTestObject::test<7>() - { - // test auto registration - - LLHTTPStandardServices::useServices(); - LLHTTPRegistrar::buildAllServices(mRoot); - - { - LLSD result = get("web/hello"); - ensure_equals("hello result", result.asString(), "hello"); - } - { - LLSD stuff = 3.14159; - LLSD result = post("web/echo", stuff); - ensure_equals("echo result", result, stuff); - } - } - - template<> template<> - void HTTPNodeTestObject::test<8>() - { - // test introspection - - LLHTTPRegistrar::buildAllServices(mRoot); - - mRoot.addNode("test/misc", new LLHTTPNode); - mRoot.addNode("test/<int>", new IntegerNode); - mRoot.addNode("test/<int>/square", new SquareNode); - - const LLSD result = get("web/server/api"); - - ensure("result is array", result.isArray()); - ensure("result size", result.size() >= 2); - - ensureInArray(result, "web/echo"); - ensureInArray(result, "web/hello"); - ensureInArray(result, "test/misc"); - ensureInArray(result, "test/<int>"); - ensureInArray(result, "test/<int>/square"); - } - - template<> template<> - void HTTPNodeTestObject::test<9>() - { - // test introspection details - - LLHTTPRegistrar::buildAllServices(mRoot); - - const LLSD helloDetails = get("web/server/api/web/hello"); - - ensure_contains("hello description", - helloDetails["description"].asString(), "hello"); - ensure_equals("method name", helloDetails["api"][0].asString(), std::string("GET")); - ensureMemberString("hello", helloDetails, "output", "\"hello\""); - ensure_contains("hello __file__", - helloDetails["__file__"].asString(), "llsdhttpserver.cpp"); - ensure("hello line", helloDetails["__line__"].isInteger()); - - - const LLSD echoDetails = get("web/server/api/web/echo"); - - ensure_contains("echo description", - echoDetails["description"].asString(), "echo"); - ensure_equals("method name", echoDetails["api"][0].asString(), std::string("POST")); - ensureMemberString("echo", echoDetails, "input", "<any>"); - ensureMemberString("echo", echoDetails, "output", "<the input>"); - ensure_contains("echo __file__", - echoDetails["__file__"].asString(), "llsdhttpserver.cpp"); - ensure("echo", echoDetails["__line__"].isInteger()); - } + struct HTTPNodeTestData + { + LLHTTPNode mRoot; + LLSD mContext; + + const LLSD& context() { return mContext; } + + std::string remainderPath() + { + std::ostringstream pathOutput; + bool addSlash = false; + + LLSD& remainder = mContext[CONTEXT_REQUEST]["remainder"]; + for (LLSD::array_const_iterator i = remainder.beginArray(); + i != remainder.endArray(); + ++i) + { + if (addSlash) { pathOutput << '/'; } + pathOutput << i->asString(); + addSlash = true; + } + + return pathOutput.str(); + } + + void ensureRootTraversal(const std::string& path, + const LLHTTPNode* expectedNode, + const char* expectedRemainder) + { + mContext.clear(); + + const LLHTTPNode* actualNode = mRoot.traverse(path, mContext); + + ensure_equals("traverse " + path + " node", + actualNode, expectedNode); + ensure_equals("traverse " + path + " remainder", + remainderPath(), expectedRemainder); + } + + class Response : public LLHTTPNode::Response + { + public: + static LLPointer<Response> create() {return new Response();} + + LLSD mResult; + + void result(const LLSD& result) { mResult = result; } + void status(S32 code, const std::string& message) { } + void extendedResult(S32 code, const std::string& message, const LLSD& headers) { } + void extendedResult(S32 code, const LLSD& result, const LLSD& headers) { } + + private: + Response() {;} // Must be accessed through LLPointer. + }; + + typedef LLPointer<Response> ResponsePtr; + + LLSD get(const std::string& path) + { + mContext.clear(); + const LLHTTPNode* node = mRoot.traverse(path, mContext); + ensure(path + " found", node != NULL); + + ResponsePtr response = Response::create(); + node->get(LLHTTPNode::ResponsePtr(response), mContext); + return response->mResult; + } + + LLSD post(const std::string& path, const LLSD& input) + { + mContext.clear(); + const LLHTTPNode* node = mRoot.traverse(path, mContext); + ensure(path + " found", node != NULL); + + ResponsePtr response = Response::create(); + node->post(LLHTTPNode::ResponsePtr(response), mContext, input); + return response->mResult; + } + + void ensureMemberString(const std::string& name, + const LLSD& actualMap, const std::string& member, + const std::string& expectedValue) + { + ensure_equals(name + " " + member, + actualMap[member].asString(), expectedValue); + } + + + void ensureInArray(const LLSD& actualArray, + const std::string& expectedValue) + { + LLSD::array_const_iterator i = actualArray.beginArray(); + LLSD::array_const_iterator end = actualArray.endArray(); + + for (; i != end; ++i) + { + std::string path = i->asString(); + + if (path == expectedValue) + { + return; + } + } + + fail("didn't find " + expectedValue); + } + + }; + + typedef test_group<HTTPNodeTestData> HTTPNodeTestGroup; + typedef HTTPNodeTestGroup::object HTTPNodeTestObject; + HTTPNodeTestGroup httpNodeTestGroup("http node"); + + template<> template<> + void HTTPNodeTestObject::test<1>() + { + // traversal of the lone node + + ensureRootTraversal("", &mRoot, ""); + ensureRootTraversal("/", &mRoot, ""); + ensureRootTraversal("foo", NULL, "foo"); + ensureRootTraversal("foo/bar", NULL, "foo/bar"); + + ensure_equals("root of root", mRoot.rootNode(), &mRoot); + } + + template<> template<> + void HTTPNodeTestObject::test<2>() + { + // simple traversal of a single node + + LLHTTPNode* helloNode = new LLHTTPNode; + mRoot.addNode("hello", helloNode); + + ensureRootTraversal("hello", helloNode, ""); + ensureRootTraversal("/hello", helloNode, ""); + ensureRootTraversal("hello/", helloNode, ""); + ensureRootTraversal("/hello/", helloNode, ""); + + ensureRootTraversal("hello/there", NULL, "there"); + + ensure_equals("root of hello", helloNode->rootNode(), &mRoot); + } + + template<> template<> + void HTTPNodeTestObject::test<3>() + { + // traversal of mutli-branched tree + + LLHTTPNode* greekNode = new LLHTTPNode; + LLHTTPNode* alphaNode = new LLHTTPNode; + LLHTTPNode* betaNode = new LLHTTPNode; + LLHTTPNode* gammaNode = new LLHTTPNode; + + greekNode->addNode("alpha", alphaNode); + greekNode->addNode("beta", betaNode); + greekNode->addNode("gamma", gammaNode); + mRoot.addNode("greek", greekNode); + + LLHTTPNode* hebrewNode = new LLHTTPNode; + LLHTTPNode* alephNode = new LLHTTPNode; + + hebrewNode->addNode("aleph", alephNode); + mRoot.addNode("hebrew", hebrewNode); + + ensureRootTraversal("greek/alpha", alphaNode, ""); + ensureRootTraversal("greek/beta", betaNode, ""); + ensureRootTraversal("greek/delta", NULL, "delta"); + ensureRootTraversal("greek/gamma", gammaNode, ""); + ensureRootTraversal("hebrew/aleph", alephNode, ""); + + ensure_equals("root of greek", greekNode->rootNode(), &mRoot); + ensure_equals("root of alpha", alphaNode->rootNode(), &mRoot); + ensure_equals("root of beta", betaNode->rootNode(), &mRoot); + ensure_equals("root of gamma", gammaNode->rootNode(), &mRoot); + ensure_equals("root of hebrew", hebrewNode->rootNode(), &mRoot); + ensure_equals("root of aleph", alephNode->rootNode(), &mRoot); + } + + template<> template<> + void HTTPNodeTestObject::test<4>() + { + // automatic creation of parent nodes and not overriding existing nodes + + LLHTTPNode* alphaNode = new LLHTTPNode; + LLHTTPNode* betaNode = new LLHTTPNode; + LLHTTPNode* gammaNode = new LLHTTPNode; + LLHTTPNode* gamma2Node = new LLHTTPNode; + + mRoot.addNode("greek/alpha", alphaNode); + mRoot.addNode("greek/beta", betaNode); + + mRoot.addNode("greek/gamma", gammaNode); + mRoot.addNode("greek/gamma", gamma2Node); + + LLHTTPNode* alephNode = new LLHTTPNode; + + mRoot.addNode("hebrew/aleph", alephNode); + + ensureRootTraversal("greek/alpha", alphaNode, ""); + ensureRootTraversal("greek/beta", betaNode, ""); + ensureRootTraversal("greek/delta", NULL, "delta"); + ensureRootTraversal("greek/gamma", gammaNode, ""); + ensureRootTraversal("hebrew/aleph", alephNode, ""); + + ensure_equals("root of alpha", alphaNode->rootNode(), &mRoot); + ensure_equals("root of beta", betaNode->rootNode(), &mRoot); + ensure_equals("root of gamma", gammaNode->rootNode(), &mRoot); + ensure_equals("root of aleph", alephNode->rootNode(), &mRoot); + } + + class IntegerNode : public LLHTTPNode + { + public: + virtual void get(ResponsePtr response, const LLSD& context) const + { + int n = context["extra"]["value"]; + + LLSD info; + info["value"] = n; + info["positive"] = n > 0; + info["zero"] = n == 0; + info["negative"] = n < 0; + + response->result(info); + } + + virtual bool validate(const std::string& name, LLSD& context) const + { + int n; + std::istringstream i_stream(name); + i_stream >> n; + + if (i_stream.fail() || i_stream.get() != EOF) + { + return false; + } + + context["extra"]["value"] = n; + return true; + } + }; + + class SquareNode : public LLHTTPNode + { + public: + virtual void get(ResponsePtr response, const LLSD& context) const + { + int n = context["extra"]["value"]; + response->result(n*n); + } + }; + + template<> template<> + void HTTPNodeTestObject::test<5>() + { + // wildcard nodes + + LLHTTPNode* miscNode = new LLHTTPNode; + LLHTTPNode* iNode = new IntegerNode; + LLHTTPNode* sqNode = new SquareNode; + + mRoot.addNode("test/misc", miscNode); + mRoot.addNode("test/<int>", iNode); + mRoot.addNode("test/<int>/square", sqNode); + + ensureRootTraversal("test/42", iNode, ""); + ensure_equals("stored integer", + context()["extra"]["value"].asInteger(), 42); + + ensureRootTraversal("test/bob", NULL, "bob"); + ensure("nothing stored", + context()["extra"]["value"].isUndefined()); + + ensureRootTraversal("test/3/square", sqNode, ""); + ResponsePtr response = Response::create(); + sqNode->get(LLHTTPNode::ResponsePtr(response), context()); + ensure_equals("square result", response->mResult.asInteger(), 9); + } + + class AlphaNode : public LLHTTPNode + { + public: + virtual bool handles(const LLSD& remainder, LLSD& context) const + { + LLSD::array_const_iterator i = remainder.beginArray(); + LLSD::array_const_iterator end = remainder.endArray(); + + for (; i != end; ++i) + { + std::string s = i->asString(); + if (s.empty() || s[0] != 'a') + { + return false; + } + } + + return true; + } + }; + + template<> template<> + void HTTPNodeTestObject::test<6>() + { + // nodes that handle remainders + + LLHTTPNode* miscNode = new LLHTTPNode; + LLHTTPNode* aNode = new AlphaNode; + LLHTTPNode* zNode = new LLHTTPNode; + + mRoot.addNode("test/misc", miscNode); + mRoot.addNode("test/alpha", aNode); + mRoot.addNode("test/alpha/zebra", zNode); + + ensureRootTraversal("test/alpha", aNode, ""); + ensureRootTraversal("test/alpha/abe", aNode, "abe"); + ensureRootTraversal("test/alpha/abe/amy", aNode, "abe/amy"); + ensureRootTraversal("test/alpha/abe/bea", NULL, "abe/bea"); + ensureRootTraversal("test/alpha/bob", NULL, "bob"); + ensureRootTraversal("test/alpha/zebra", zNode, ""); + } + + template<> template<> + void HTTPNodeTestObject::test<7>() + { + // test auto registration + + LLHTTPStandardServices::useServices(); + LLHTTPRegistrar::buildAllServices(mRoot); + + { + LLSD result = get("web/hello"); + ensure_equals("hello result", result.asString(), "hello"); + } + { + LLSD stuff = 3.14159; + LLSD result = post("web/echo", stuff); + ensure_equals("echo result", result, stuff); + } + } + + template<> template<> + void HTTPNodeTestObject::test<8>() + { + // test introspection + + LLHTTPRegistrar::buildAllServices(mRoot); + + mRoot.addNode("test/misc", new LLHTTPNode); + mRoot.addNode("test/<int>", new IntegerNode); + mRoot.addNode("test/<int>/square", new SquareNode); + + const LLSD result = get("web/server/api"); + + ensure("result is array", result.isArray()); + ensure("result size", result.size() >= 2); + + ensureInArray(result, "web/echo"); + ensureInArray(result, "web/hello"); + ensureInArray(result, "test/misc"); + ensureInArray(result, "test/<int>"); + ensureInArray(result, "test/<int>/square"); + } + + template<> template<> + void HTTPNodeTestObject::test<9>() + { + // test introspection details + + LLHTTPRegistrar::buildAllServices(mRoot); + + const LLSD helloDetails = get("web/server/api/web/hello"); + + ensure_contains("hello description", + helloDetails["description"].asString(), "hello"); + ensure_equals("method name", helloDetails["api"][0].asString(), std::string("GET")); + ensureMemberString("hello", helloDetails, "output", "\"hello\""); + ensure_contains("hello __file__", + helloDetails["__file__"].asString(), "llsdhttpserver.cpp"); + ensure("hello line", helloDetails["__line__"].isInteger()); + + + const LLSD echoDetails = get("web/server/api/web/echo"); + + ensure_contains("echo description", + echoDetails["description"].asString(), "echo"); + ensure_equals("method name", echoDetails["api"][0].asString(), std::string("POST")); + ensureMemberString("echo", echoDetails, "input", "<any>"); + ensureMemberString("echo", echoDetails, "output", "<the input>"); + ensure_contains("echo __file__", + echoDetails["__file__"].asString(), "llsdhttpserver.cpp"); + ensure("echo", echoDetails["__line__"].isInteger()); + } } diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp index 1513446788..7034f4a063 100644 --- a/indra/test/lliohttpserver_tut.cpp +++ b/indra/test/lliohttpserver_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lliohttpserver_tut.cpp * @date May 2006 * @brief HTTP server unit tests @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,313 +38,313 @@ namespace tut { - class HTTPServiceTestData - { - public: - class DelayedEcho : public LLHTTPNode - { - HTTPServiceTestData* mTester; - - public: - DelayedEcho(HTTPServiceTestData* tester) : mTester(tester) { } - - void post(ResponsePtr response, const LLSD& context, const LLSD& input) const - { - ensure("response already set", mTester->mResponse == ResponsePtr(NULL)); - mTester->mResponse = response; - mTester->mResult = input; - } - }; - - class WireHello : public LLIOPipe - { - protected: - virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) - { - if(!eos) return STATUS_BREAK; - LLSD sd = "yo!"; - LLBufferStream ostr(channels, buffer.get()); - ostr << LLSDXMLStreamer(sd); - return STATUS_DONE; - } - }; - - HTTPServiceTestData() - : mResponse(NULL) - { - LLHTTPStandardServices::useServices(); - LLHTTPRegistrar::buildAllServices(mRoot); - mRoot.addNode("/delayed/echo", new DelayedEcho(this)); - mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>); - } - - ~HTTPServiceTestData() - { - } - - LLHTTPNode mRoot; - LLHTTPNode::ResponsePtr mResponse; - LLSD mResult; - - void pumpPipe(LLPumpIO* pump, S32 iterations) - { - while(iterations > 0) - { - pump->pump(); - pump->callback(); - --iterations; - } - } - - std::string makeRequest( - const std::string& name, - const std::string& httpRequest, - bool timeout = false) - { - LLPipeStringInjector* injector = new LLPipeStringInjector(httpRequest); - LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); - - apr_pool_t* pool; - apr_pool_create(&pool, NULL); - - LLPumpIO* pump; - pump = new LLPumpIO(pool); - - LLPumpIO::chain_t chain; - LLSD context; - - chain.push_back(LLIOPipe::ptr_t(injector)); - LLIOHTTPServer::createPipe(chain, mRoot, LLSD()); - chain.push_back(LLIOPipe::ptr_t(extractor)); - - pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); - - pumpPipe(pump, 10); - if(mResponse.notNull() && (! timeout)) - { - mResponse->result(mResult); - mResponse = NULL; - } - pumpPipe(pump, 10); - - std::string httpResult = extractor->string(); - - chain.clear(); - delete pump; - apr_pool_destroy(pool); - - if(mResponse.notNull() && timeout) - { - mResponse->result(mResult); - mResponse = NULL; - } - - return httpResult; - } - - std::string httpGET(const std::string& uri, - bool timeout = false) - { - std::string httpRequest = "GET " + uri + " HTTP/1.0\r\n\r\n"; - return makeRequest(uri, httpRequest, timeout); - } - - std::string httpPOST(const std::string& uri, - const std::string& body, - bool timeout, - const std::string& evilExtra = "") - { - std::ostringstream httpRequest; - httpRequest << "POST " + uri + " HTTP/1.0\r\n"; - httpRequest << "Content-Length: " << body.size() << "\r\n"; - httpRequest << "\r\n"; - httpRequest << body; - httpRequest << evilExtra; - - return makeRequest(uri, httpRequest.str(), timeout); - } - - std::string httpPOST(const std::string& uri, - const std::string& body, - const std::string& evilExtra = "") - { - bool timeout = false; - return httpPOST(uri, body, timeout, evilExtra); - } - }; - - typedef test_group<HTTPServiceTestData> HTTPServiceTestGroup; - typedef HTTPServiceTestGroup::object HTTPServiceTestObject; - HTTPServiceTestGroup httpServiceTestGroup("http service"); - - template<> template<> - 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>" - ); - } - - template<> template<> - void HTTPServiceTestObject::test<2>() - { - // test various HTTP errors - - std::string actual; - - actual = httpGET("web/missing"); - ensure_starts_with("web/missing 404", actual, - "HTTP/1.0 404 Not Found\r\n"); - - actual = httpGET("web/echo"); - ensure_starts_with("web/echo 405", actual, - "HTTP/1.0 405 Method Not Allowed\r\n"); - } - - template<> template<> - 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>" - ); + class HTTPServiceTestData + { + public: + class DelayedEcho : public LLHTTPNode + { + HTTPServiceTestData* mTester; + + public: + DelayedEcho(HTTPServiceTestData* tester) : mTester(tester) { } + + void post(ResponsePtr response, const LLSD& context, const LLSD& input) const + { + ensure("response already set", mTester->mResponse == ResponsePtr(NULL)); + mTester->mResponse = response; + mTester->mResult = input; + } + }; + + class WireHello : public LLIOPipe + { + protected: + virtual EStatus process_impl( + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) + { + if(!eos) return STATUS_BREAK; + LLSD sd = "yo!"; + LLBufferStream ostr(channels, buffer.get()); + ostr << LLSDXMLStreamer(sd); + return STATUS_DONE; + } + }; + + HTTPServiceTestData() + : mResponse(NULL) + { + LLHTTPStandardServices::useServices(); + LLHTTPRegistrar::buildAllServices(mRoot); + mRoot.addNode("/delayed/echo", new DelayedEcho(this)); + mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>); + } + + ~HTTPServiceTestData() + { + } + + LLHTTPNode mRoot; + LLHTTPNode::ResponsePtr mResponse; + LLSD mResult; + + void pumpPipe(LLPumpIO* pump, S32 iterations) + { + while(iterations > 0) + { + pump->pump(); + pump->callback(); + --iterations; + } + } + + std::string makeRequest( + const std::string& name, + const std::string& httpRequest, + bool timeout = false) + { + LLPipeStringInjector* injector = new LLPipeStringInjector(httpRequest); + LLPipeStringExtractor* extractor = new LLPipeStringExtractor(); + + apr_pool_t* pool; + apr_pool_create(&pool, NULL); + + LLPumpIO* pump; + pump = new LLPumpIO(pool); + + LLPumpIO::chain_t chain; + LLSD context; + + chain.push_back(LLIOPipe::ptr_t(injector)); + LLIOHTTPServer::createPipe(chain, mRoot, LLSD()); + chain.push_back(LLIOPipe::ptr_t(extractor)); + + pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS); + + pumpPipe(pump, 10); + if(mResponse.notNull() && (! timeout)) + { + mResponse->result(mResult); + mResponse = NULL; + } + pumpPipe(pump, 10); + + std::string httpResult = extractor->string(); + + chain.clear(); + delete pump; + apr_pool_destroy(pool); + + if(mResponse.notNull() && timeout) + { + mResponse->result(mResult); + mResponse = NULL; + } + + return httpResult; + } + + std::string httpGET(const std::string& uri, + bool timeout = false) + { + std::string httpRequest = "GET " + uri + " HTTP/1.0\r\n\r\n"; + return makeRequest(uri, httpRequest, timeout); + } + + std::string httpPOST(const std::string& uri, + const std::string& body, + bool timeout, + const std::string& evilExtra = "") + { + std::ostringstream httpRequest; + httpRequest << "POST " + uri + " HTTP/1.0\r\n"; + httpRequest << "Content-Length: " << body.size() << "\r\n"; + httpRequest << "\r\n"; + httpRequest << body; + httpRequest << evilExtra; + + return makeRequest(uri, httpRequest.str(), timeout); + } + + std::string httpPOST(const std::string& uri, + const std::string& body, + const std::string& evilExtra = "") + { + bool timeout = false; + return httpPOST(uri, body, timeout, evilExtra); + } + }; + + typedef test_group<HTTPServiceTestData> HTTPServiceTestGroup; + typedef HTTPServiceTestGroup::object HTTPServiceTestObject; + HTTPServiceTestGroup httpServiceTestGroup("http service"); + + template<> template<> + 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>" + ); + } + + template<> template<> + void HTTPServiceTestObject::test<2>() + { + // test various HTTP errors + + std::string actual; + + actual = httpGET("web/missing"); + ensure_starts_with("web/missing 404", actual, + "HTTP/1.0 404 Not Found\r\n"); + + actual = httpGET("web/echo"); + ensure_starts_with("web/echo 405", actual, + "HTTP/1.0 405 Method Not Allowed\r\n"); + } + + template<> template<> + 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>" - ); + + 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>" + ); */ - } + } + + template<> template<> + void HTTPServiceTestObject::test<4>() + { + // test calling things based on pipes + + std::string result; + + result = httpGET("wire/hello"); - template<> template<> - void HTTPServiceTestObject::test<4>() - { - // test calling things based on pipes + ensure_contains("wire/hello", result, "yo!"); + } - std::string result; + template<> template<> + void HTTPServiceTestObject::test<5>() + { + // test timeout before async response + std::string result; + + bool timeout = true; + result = httpPOST("delayed/echo", + "<llsd><string>agent99</string></llsd>", timeout); - result = httpGET("wire/hello"); + ensure_equals("timeout delayed/echo status", result, std::string("")); + } + + template<> template<> + void HTTPServiceTestObject::test<6>() + { + // test delayed service + std::string result; - ensure_contains("wire/hello", result, "yo!"); - } + 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>" + ); + } + + template<> template<> + void HTTPServiceTestObject::test<7>() + { + // test large request + std::stringstream stream; + + //U32 size = 36 * 1024 * 1024; + //U32 size = 36 * 1024; + //std::vector<char> data(size); + //memset(&(data[0]), '1', size); + //data[size - 1] = '\0'; + + + //std::string result = httpPOST("web/echo", &(data[0])); + + stream << "<llsd><array>"; + for(U32 i = 0; i < 1000000; ++i) + { + stream << "<integer>42</integer>"; + } + stream << "</array></llsd>"; + LL_INFOS() << "HTTPServiceTestObject::test<7>" + << stream.str().length() << LL_ENDL; + std::string result = httpPOST("web/echo", stream.str()); + ensure_starts_with("large echo status", result, "HTTP/1.0 200 OK\r\n"); + } template<> template<> - void HTTPServiceTestObject::test<5>() + void HTTPServiceTestObject::test<8>() { - // test timeout before async response - std::string result; - - bool timeout = true; - result = httpPOST("delayed/echo", - "<llsd><string>agent99</string></llsd>", timeout); - - ensure_equals("timeout delayed/echo status", result, std::string("")); - } - - template<> template<> - 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>" - ); - } - - template<> template<> - void HTTPServiceTestObject::test<7>() - { - // test large request - std::stringstream stream; - - //U32 size = 36 * 1024 * 1024; - //U32 size = 36 * 1024; - //std::vector<char> data(size); - //memset(&(data[0]), '1', size); - //data[size - 1] = '\0'; - - - //std::string result = httpPOST("web/echo", &(data[0])); - - stream << "<llsd><array>"; - for(U32 i = 0; i < 1000000; ++i) - { - stream << "<integer>42</integer>"; - } - stream << "</array></llsd>"; - LL_INFOS() << "HTTPServiceTestObject::test<7>" - << stream.str().length() << LL_ENDL; - std::string result = httpPOST("web/echo", stream.str()); - ensure_starts_with("large echo status", result, "HTTP/1.0 200 OK\r\n"); - } - - template<> template<> - 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"); - } - - - /* TO DO: - test generation of not found and method not allowed errors - */ + // 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"); + } + + + /* TO DO: + test generation of not found and method not allowed errors + */ } diff --git a/indra/test/llmessageconfig_tut.cpp b/indra/test/llmessageconfig_tut.cpp index df2151b1b1..93443467a2 100644 --- a/indra/test/llmessageconfig_tut.cpp +++ b/indra/test/llmessageconfig_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llmessageconfig_tut.cpp * @date March 2007 * @brief LLMessageConfig unit tests @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,201 +36,201 @@ namespace tut { - struct LLMessageConfigTestData { - std::string mTestConfigDir; - - LLMessageConfigTestData() - { - LLUUID random; - random.generate(); - // generate temp dir - std::ostringstream oStr; -#if LL_WINDOWS - oStr << "llmessage-config-test-" << random; + struct LLMessageConfigTestData { + std::string mTestConfigDir; + + LLMessageConfigTestData() + { + LLUUID random; + random.generate(); + // generate temp dir + std::ostringstream oStr; +#if LL_WINDOWS + oStr << "llmessage-config-test-" << random; #else - oStr << "/tmp/llmessage-config-test-" << random; + oStr << "/tmp/llmessage-config-test-" << random; #endif - mTestConfigDir = oStr.str(); - LLFile::mkdir(mTestConfigDir); - writeConfigFile(LLSD()); - LLMessageConfig::initClass("simulator", mTestConfigDir); - } - - ~LLMessageConfigTestData() - { - // rm contents of temp dir - int rmfile = LLFile::remove((mTestConfigDir + "/message.xml")); - ensure_equals("rmfile value", rmfile, 0); - // rm temp dir - int rmdir = LLFile::rmdir(mTestConfigDir); - ensure_equals("rmdir value", rmdir, 0); - } - - void writeConfigFile(const LLSD& config) - { - llofstream file((mTestConfigDir + "/message.xml").c_str()); - if (file.is_open()) - { - LLSDSerialize::toPrettyXML(config, file); - } - file.close(); - } - }; - - typedef test_group<LLMessageConfigTestData> LLMessageConfigTestGroup; - typedef LLMessageConfigTestGroup::object LLMessageConfigTestObject; - LLMessageConfigTestGroup llMessageConfigTestGroup("LLMessageConfig"); - - template<> template<> - void LLMessageConfigTestObject::test<1>() - // tests server defaults - { - LLSD config; - config["serverDefaults"]["simulator"] = "template"; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure server default is not template", - LLMessageConfig::getServerDefaultFlavor(), - LLMessageConfig::TEMPLATE_FLAVOR); - } - - template<> template<> - void LLMessageConfigTestObject::test<2>() - // tests message flavors - { - LLSD config; - config["serverDefaults"]["simulator"] = "template"; - config["messages"]["msg1"]["flavor"] = "template"; - config["messages"]["msg2"]["flavor"] = "llsd"; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure msg template flavor", - LLMessageConfig::getMessageFlavor("msg1"), - LLMessageConfig::TEMPLATE_FLAVOR); - ensure_equals("Ensure msg llsd flavor", - LLMessageConfig::getMessageFlavor("msg2"), - LLMessageConfig::LLSD_FLAVOR); - } - - template<> template<> - void LLMessageConfigTestObject::test<4>() - // tests message flavor defaults - { - LLSD config; - config["serverDefaults"]["simulator"] = "llsd"; - config["messages"]["msg1"]["trusted-sender"] = true; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure missing message gives no flavor", - LLMessageConfig::getMessageFlavor("Test"), - LLMessageConfig::NO_FLAVOR); - ensure_equals("Ensure missing flavor is NO_FLAVOR even with sender trustedness set", - LLMessageConfig::getMessageFlavor("msg1"), - LLMessageConfig::NO_FLAVOR); - ensure_equals("Ensure server default is llsd", - LLMessageConfig::getServerDefaultFlavor(), - LLMessageConfig::LLSD_FLAVOR); - } - - template<> template<> - void LLMessageConfigTestObject::test<3>() - // tests trusted/untrusted senders - { - LLSD config; - config["serverDefaults"]["simulator"] = "template"; - config["messages"]["msg1"]["flavor"] = "llsd"; - config["messages"]["msg1"]["trusted-sender"] = false; - config["messages"]["msg2"]["flavor"] = "llsd"; - config["messages"]["msg2"]["trusted-sender"] = true; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure untrusted is untrusted", - LLMessageConfig::getSenderTrustedness("msg1"), - LLMessageConfig::UNTRUSTED); - ensure_equals("Ensure trusted is trusted", - LLMessageConfig::getSenderTrustedness("msg2"), - LLMessageConfig::TRUSTED); - ensure_equals("Ensure missing trustedness is NOT_SET", - LLMessageConfig::getSenderTrustedness("msg3"), - LLMessageConfig::NOT_SET); - } - - template<> template<> - void LLMessageConfigTestObject::test<5>() - // tests trusted/untrusted without flag, only flavor - { - LLSD config; - config["serverDefaults"]["simulator"] = "template"; - config["messages"]["msg1"]["flavor"] = "llsd"; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure msg1 exists, has llsd flavor", - LLMessageConfig::getMessageFlavor("msg1"), - LLMessageConfig::LLSD_FLAVOR); - ensure_equals("Ensure missing trusted is not set", - LLMessageConfig::getSenderTrustedness("msg1"), - LLMessageConfig::NOT_SET); - } - - template<> template<> - void LLMessageConfigTestObject::test<6>() - { - LLSD config; - config["capBans"]["MapLayer"] = true; - config["capBans"]["MapLayerGod"] = false; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure cap ban true MapLayer", - LLMessageConfig::isCapBanned("MapLayer"), - true); - ensure_equals("Ensure cap ban false", - LLMessageConfig::isCapBanned("MapLayerGod"), - false); - } - - template<> template<> - void LLMessageConfigTestObject::test<7>() - // tests that config changes are picked up/refreshed periodically - { - LLSD config; - config["serverDefaults"]["simulator"] = "llsd"; - writeConfigFile(config); - - // wait for it to reload after N seconds - ms_sleep(6*1000); - LLFrameTimer::updateFrameTime(); - ensure_equals("Ensure reload after 6 seconds", - LLMessageConfig::getServerDefaultFlavor(), - LLMessageConfig::LLSD_FLAVOR); - } - - template<> template<> - void LLMessageConfigTestObject::test<8>() - // tests that config changes are picked up/refreshed periodically - { - LLSD config; - config["serverDefaults"]["simulator"] = "template"; - config["messages"]["msg1"]["flavor"] = "llsd"; - config["messages"]["msg1"]["only-send-latest"] = true; - config["messages"]["msg2"]["flavor"] = "llsd"; - config["messages"]["msg2"]["only-send-latest"] = false; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure msg1 exists, sent latest-only", - LLMessageConfig::onlySendLatest("msg1"), - true); - ensure_equals("Ensure msg2 exists, sent latest-only", - LLMessageConfig::onlySendLatest("msg2"), - false); - } - - template<> template<> - void LLMessageConfigTestObject::test<9>() - // tests that event queue max is reloaded - { - LLSD config; - config["maxQueuedEvents"] = 200; - LLMessageConfig::useConfig(config); - ensure_equals("Ensure setting maxQueuedEvents", - LLMessageConfig::getMaxQueuedEvents(), - 200); - - LLMessageConfig::useConfig(LLSD()); - ensure_equals("Ensure default of event queue max 100", - LLMessageConfig::getMaxQueuedEvents(), - 100); - } + mTestConfigDir = oStr.str(); + LLFile::mkdir(mTestConfigDir); + writeConfigFile(LLSD()); + LLMessageConfig::initClass("simulator", mTestConfigDir); + } + + ~LLMessageConfigTestData() + { + // rm contents of temp dir + int rmfile = LLFile::remove((mTestConfigDir + "/message.xml")); + ensure_equals("rmfile value", rmfile, 0); + // rm temp dir + int rmdir = LLFile::rmdir(mTestConfigDir); + ensure_equals("rmdir value", rmdir, 0); + } + + void writeConfigFile(const LLSD& config) + { + llofstream file((mTestConfigDir + "/message.xml").c_str()); + if (file.is_open()) + { + LLSDSerialize::toPrettyXML(config, file); + } + file.close(); + } + }; + + typedef test_group<LLMessageConfigTestData> LLMessageConfigTestGroup; + typedef LLMessageConfigTestGroup::object LLMessageConfigTestObject; + LLMessageConfigTestGroup llMessageConfigTestGroup("LLMessageConfig"); + + template<> template<> + void LLMessageConfigTestObject::test<1>() + // tests server defaults + { + LLSD config; + config["serverDefaults"]["simulator"] = "template"; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure server default is not template", + LLMessageConfig::getServerDefaultFlavor(), + LLMessageConfig::TEMPLATE_FLAVOR); + } + + template<> template<> + void LLMessageConfigTestObject::test<2>() + // tests message flavors + { + LLSD config; + config["serverDefaults"]["simulator"] = "template"; + config["messages"]["msg1"]["flavor"] = "template"; + config["messages"]["msg2"]["flavor"] = "llsd"; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure msg template flavor", + LLMessageConfig::getMessageFlavor("msg1"), + LLMessageConfig::TEMPLATE_FLAVOR); + ensure_equals("Ensure msg llsd flavor", + LLMessageConfig::getMessageFlavor("msg2"), + LLMessageConfig::LLSD_FLAVOR); + } + + template<> template<> + void LLMessageConfigTestObject::test<4>() + // tests message flavor defaults + { + LLSD config; + config["serverDefaults"]["simulator"] = "llsd"; + config["messages"]["msg1"]["trusted-sender"] = true; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure missing message gives no flavor", + LLMessageConfig::getMessageFlavor("Test"), + LLMessageConfig::NO_FLAVOR); + ensure_equals("Ensure missing flavor is NO_FLAVOR even with sender trustedness set", + LLMessageConfig::getMessageFlavor("msg1"), + LLMessageConfig::NO_FLAVOR); + ensure_equals("Ensure server default is llsd", + LLMessageConfig::getServerDefaultFlavor(), + LLMessageConfig::LLSD_FLAVOR); + } + + template<> template<> + void LLMessageConfigTestObject::test<3>() + // tests trusted/untrusted senders + { + LLSD config; + config["serverDefaults"]["simulator"] = "template"; + config["messages"]["msg1"]["flavor"] = "llsd"; + config["messages"]["msg1"]["trusted-sender"] = false; + config["messages"]["msg2"]["flavor"] = "llsd"; + config["messages"]["msg2"]["trusted-sender"] = true; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure untrusted is untrusted", + LLMessageConfig::getSenderTrustedness("msg1"), + LLMessageConfig::UNTRUSTED); + ensure_equals("Ensure trusted is trusted", + LLMessageConfig::getSenderTrustedness("msg2"), + LLMessageConfig::TRUSTED); + ensure_equals("Ensure missing trustedness is NOT_SET", + LLMessageConfig::getSenderTrustedness("msg3"), + LLMessageConfig::NOT_SET); + } + + template<> template<> + void LLMessageConfigTestObject::test<5>() + // tests trusted/untrusted without flag, only flavor + { + LLSD config; + config["serverDefaults"]["simulator"] = "template"; + config["messages"]["msg1"]["flavor"] = "llsd"; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure msg1 exists, has llsd flavor", + LLMessageConfig::getMessageFlavor("msg1"), + LLMessageConfig::LLSD_FLAVOR); + ensure_equals("Ensure missing trusted is not set", + LLMessageConfig::getSenderTrustedness("msg1"), + LLMessageConfig::NOT_SET); + } + + template<> template<> + void LLMessageConfigTestObject::test<6>() + { + LLSD config; + config["capBans"]["MapLayer"] = true; + config["capBans"]["MapLayerGod"] = false; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure cap ban true MapLayer", + LLMessageConfig::isCapBanned("MapLayer"), + true); + ensure_equals("Ensure cap ban false", + LLMessageConfig::isCapBanned("MapLayerGod"), + false); + } + + template<> template<> + void LLMessageConfigTestObject::test<7>() + // tests that config changes are picked up/refreshed periodically + { + LLSD config; + config["serverDefaults"]["simulator"] = "llsd"; + writeConfigFile(config); + + // wait for it to reload after N seconds + ms_sleep(6*1000); + LLFrameTimer::updateFrameTime(); + ensure_equals("Ensure reload after 6 seconds", + LLMessageConfig::getServerDefaultFlavor(), + LLMessageConfig::LLSD_FLAVOR); + } + + template<> template<> + void LLMessageConfigTestObject::test<8>() + // tests that config changes are picked up/refreshed periodically + { + LLSD config; + config["serverDefaults"]["simulator"] = "template"; + config["messages"]["msg1"]["flavor"] = "llsd"; + config["messages"]["msg1"]["only-send-latest"] = true; + config["messages"]["msg2"]["flavor"] = "llsd"; + config["messages"]["msg2"]["only-send-latest"] = false; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure msg1 exists, sent latest-only", + LLMessageConfig::onlySendLatest("msg1"), + true); + ensure_equals("Ensure msg2 exists, sent latest-only", + LLMessageConfig::onlySendLatest("msg2"), + false); + } + + template<> template<> + void LLMessageConfigTestObject::test<9>() + // tests that event queue max is reloaded + { + LLSD config; + config["maxQueuedEvents"] = 200; + LLMessageConfig::useConfig(config); + ensure_equals("Ensure setting maxQueuedEvents", + LLMessageConfig::getMaxQueuedEvents(), + 200); + + LLMessageConfig::useConfig(LLSD()); + ensure_equals("Ensure default of event queue max 100", + LLMessageConfig::getMaxQueuedEvents(), + 100); + } } diff --git a/indra/test/llmessagetemplateparser_tut.cpp b/indra/test/llmessagetemplateparser_tut.cpp index 39f834a9fc..f665fdde4d 100644 --- a/indra/test/llmessagetemplateparser_tut.cpp +++ b/indra/test/llmessagetemplateparser_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llmessagetemplateparser_tut.cpp * @date April 2007 * @brief LLMessageTemplateParser unit tests @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,338 +31,338 @@ namespace tut { - struct LLMessageTemplateParserTestData { - LLMessageTemplateParserTestData() : mMessage("unset message") - { - } - - ~LLMessageTemplateParserTestData() - { - } - - void ensure_next(LLTemplateTokenizer & tokens, - std::string value, - U32 line) - { - std::string next = tokens.next(); - ensure_equals(mMessage + " token matches", next, value); - ensure_equals(mMessage + " line matches", tokens.line(), line); - } - - char * prehash(const char * name) - { - return LLMessageStringTable::getInstance()->getString(name); - } - - void ensure_block_attributes(std::string identifier, - const LLMessageTemplate * message, - const char * name, - EMsgBlockType type, - S32 number, - S32 total_size) - { - const LLMessageBlock * block = message->getBlock(prehash(name)); - identifier = identifier + ":" + message->mName + ":" + name + " block"; - ensure(identifier + " exists", block != NULL); - ensure_equals(identifier + " name", block->mName, prehash(name)); - ensure_equals(identifier + " type", block->mType, type); - ensure_equals(identifier + " number", block->mNumber, number); - ensure_equals(identifier + " total size", block->mTotalSize, total_size); - } - - void ensure_variable_attributes(std::string identifier, - const LLMessageBlock * block, - const char * name, - EMsgVariableType type, - S32 size) - { - const LLMessageVariable * var = block->getVariable(prehash(name)); - identifier = identifier + ":" + block->mName + ":" + name + " variable"; - ensure(identifier + " exists", var != NULL); - ensure_equals( - identifier + " name", var->getName(), prehash(name)); - ensure_equals( - identifier + " type", var->getType(), type); - ensure_equals(identifier + " size", var->getSize(), size); - } - - std::string mMessage; - - }; - - typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup; - typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject; - LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser"); - - template<> template<> - void LLMessageTemplateParserTestObject::test<1>() - // tests tokenizer constructor and next methods - { - mMessage = "test method 1 walkthrough"; - LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth"); - ensure_next(tokens, "first", 1); - ensure_next(tokens, "line", 1); - ensure_next(tokens, "next", 2); - ensure_next(tokens, "line", 2); - ensure_next(tokens, "fourth", 4); - - tokens = LLTemplateTokenizer("\n\t{ \t Test1 Fixed \n 523 }\n\n"); - ensure(tokens.want("{")); - ensure_next(tokens, "Test1", 2); - ensure_next(tokens, "Fixed", 2); - ensure_next(tokens, "523", 3); - ensure(tokens.want("}")); - - tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth"); - ensure(tokens.want("first")); - ensure_next(tokens, "line", 1); - ensure_next(tokens, "next", 2); - ensure_next(tokens, "line", 2); - ensure(tokens.want("fourth")); - } - - template<> template<> - void LLMessageTemplateParserTestObject::test<2>() - // tests tokenizer want method - { - // *NOTE: order matters - LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth"); - ensure_equals("wants first token", tokens.want("first"), true); - ensure_equals("doesn't want blar token", tokens.want("blar"), false); - ensure_equals("wants line token", tokens.want("line"), true); - } - - template<> template<> - void LLMessageTemplateParserTestObject::test<3>() - // tests tokenizer eof methods - { - LLTemplateTokenizer tokens("single\n\n"); - ensure_equals("is not at eof at beginning", tokens.atEOF(), false); - ensure_equals("doesn't want eof", tokens.wantEOF(), false); - ensure_equals("wants the first token just to consume it", - tokens.want("single"), true); - ensure_equals("is not at eof in middle", tokens.atEOF(), false); - ensure_equals("wants eof", tokens.wantEOF(), true); - ensure_equals("is at eof at end", tokens.atEOF(), true); - } - - template<> template<> - void LLMessageTemplateParserTestObject::test<4>() - // tests variable parsing method - { - LLTemplateTokenizer tokens(std::string("{ Test0 \n\t\n U32 \n\n }")); - LLMessageVariable * var = LLTemplateParser::parseVariable(tokens); - - ensure("test0 var parsed", var != 0); - ensure_equals("name of variable", std::string(var->getName()), std::string("Test0")); - ensure_equals("type of variable is U32", var->getType(), MVT_U32); - ensure_equals("size of variable", var->getSize(), 4); - - delete var; - - std::string message_string("\n\t{ \t Test1 Fixed \n 523 }\n\n"); - tokens = LLTemplateTokenizer(message_string); - var = LLTemplateParser::parseVariable(tokens); - - ensure("test1 var parsed", var != 0); - ensure_equals("name of variable", std::string(var->getName()), std::string("Test1")); - ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED); - ensure_equals("size of variable", var->getSize(), 523); - - delete var; - - // *NOTE: the parsers call LL_ERRS() on invalid input, so we can't really - // test that :-( - } - - template<> template<> - void LLMessageTemplateParserTestObject::test<5>() - // tests block parsing method - { - LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }"); - LLMessageBlock * block = LLTemplateParser::parseBlock(tokens); - - ensure("blockA block parsed", block != 0); - ensure_equals("name of block", std::string(block->mName), std::string("BlockA")); - ensure_equals("type of block is Single", block->mType, MBT_SINGLE); - ensure_equals("total size of block", block->mTotalSize, 4); - ensure_equals("number of block defaults to 1", block->mNumber, 1); - ensure_equals("variable type of VarX is F32", - block->getVariableType(prehash("VarX")), MVT_F32); - ensure_equals("variable size of VarX", - block->getVariableSize(prehash("VarX")), 4); - - delete block; - - tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }"); - block = LLTemplateParser::parseBlock(tokens); - - ensure("stuff block parsed", block != 0); - ensure_equals("name of block", std::string(block->mName), std::string("Stuff")); - ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE); - ensure_equals("total size of block", block->mTotalSize, 16); - ensure_equals("number of block defaults to 1", block->mNumber, 1); - ensure_equals("variable type of Id is LLUUID", - block->getVariableType(prehash("Id")), MVT_LLUUID); - ensure_equals("variable size of Id", - block->getVariableSize(prehash("Id")), 16); - - delete block; - - tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }"); - block = LLTemplateParser::parseBlock(tokens); - - ensure("stuff2 block parsed", block != 0); - ensure_equals("name of block", std::string(block->mName), std::string("Stuff2")); - ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE); - ensure_equals("total size of block", block->mTotalSize, 24); - ensure_equals("number of blocks", block->mNumber, 45); - ensure_equals("variable type of Shid is Vector3d", - block->getVariableType(prehash("Shid")), MVT_LLVector3d); - ensure_equals("variable size of Shid", - block->getVariableSize(prehash("Shid")), 24); - - delete block; - } - - template<> template<> - void LLMessageTemplateParserTestObject::test<6>() - // tests message parsing method on a simple message - { - std::string message_skel( - "{\n" - "TestMessage Low 1 NotTrusted Zerocoded\n" - "// comment \n" - " {\n" - "TestBlock1 Single\n" - " { Test1 U32 }\n" - " }\n" - " {\n" - " NeighborBlock Multiple 4\n" - " { Test0 U32 }\n" - " { Test1 U32 }\n" - " { Test2 U32 }\n" - " }\n" - "}"); - LLTemplateTokenizer tokens(message_skel); - LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens); - - ensure("simple message parsed", message != 0); - ensure_equals("name of message", std::string(message->mName), std::string("TestMessage")); - ensure_equals("frequency is Low", message->mFrequency, MFT_LOW); - ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST); - ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1)); - ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED); - ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED); - - LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock")); - ensure("Nonexistant block does not exist", block == 0); - - delete message; - } - - template<> template<> - void LLMessageTemplateParserTestObject::test<7>() - // tests message parsing method on a deprecated message - { - std::string message_skel( - "{\n" - "TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n" - " {\n" - "TestBlock2 Single\n" - " { Test2 S32 }\n" - " }\n" - "}"); - LLTemplateTokenizer tokens(message_skel); - LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens); - - ensure("deprecated message parsed", message != 0); - ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated")); - ensure_equals("frequency is High", message->mFrequency, MFT_HIGH); - ensure_equals("trust is trusted", message->mTrust, MT_TRUST); - ensure_equals("message number", message->mMessageNumber, (U32)34); - ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED); - ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED); - - delete message; - } - - template<> template<> void LLMessageTemplateParserTestObject::test<8>() - // tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message - { - std::string message_skel( - "{\n\ - RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\ - {\n\ - AgentData Single\n\ - { AgentID LLUUID }\n\ - { SessionID LLUUID }\n\ - } \n\ - {\n\ - HeaderData Single\n\ - { CompoundMsgID LLUUID } // All messages a single \"compound msg\" must have the same id\n\ - { TotalObjects U8 }\n\ - { FirstDetachAll BOOL }\n\ - }\n\ - {\n\ - ObjectData Variable // 1 to 4 of these per packet\n\ - { ItemID LLUUID }\n\ - { OwnerID LLUUID }\n\ - { AttachmentPt U8 } // 0 for default\n\ - { ItemFlags U32 }\n\ - { GroupMask U32 }\n\ - { EveryoneMask U32 }\n\ - { NextOwnerMask U32 }\n\ - { Name Variable 1 }\n\ - { Description Variable 1 }\n\ - }\n\ - }\n\ - "); - LLTemplateTokenizer tokens(message_skel); - LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens); - - ensure("RezMultipleAttachmentsFromInv message parsed", message != 0); - ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv")); - ensure_equals("frequency is low", message->mFrequency, MFT_LOW); - ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST); - ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452)); - ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED); - - ensure_block_attributes( - "RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16); - LLMessageBlock * block = message->getBlock(prehash("AgentData")); - ensure_variable_attributes("RMAFI", - block, "AgentID", MVT_LLUUID, 16); - ensure_variable_attributes("RMAFI", - block, "SessionID", MVT_LLUUID, 16); - - ensure_block_attributes( - "RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1); - block = message->getBlock(prehash("HeaderData")); - ensure_variable_attributes( - "RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16); - ensure_variable_attributes( - "RMAFI", block, "TotalObjects", MVT_U8, 1); - ensure_variable_attributes( - "RMAFI", block, "FirstDetachAll", MVT_BOOL, 1); - - - ensure_block_attributes( - "RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1); - block = message->getBlock(prehash("ObjectData")); - ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16); - ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16); - ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1); - ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4); - ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4); - ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4); - ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4); - ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1); - ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1); - - delete message; - } - - + struct LLMessageTemplateParserTestData { + LLMessageTemplateParserTestData() : mMessage("unset message") + { + } + + ~LLMessageTemplateParserTestData() + { + } + + void ensure_next(LLTemplateTokenizer & tokens, + std::string value, + U32 line) + { + std::string next = tokens.next(); + ensure_equals(mMessage + " token matches", next, value); + ensure_equals(mMessage + " line matches", tokens.line(), line); + } + + char * prehash(const char * name) + { + return LLMessageStringTable::getInstance()->getString(name); + } + + void ensure_block_attributes(std::string identifier, + const LLMessageTemplate * message, + const char * name, + EMsgBlockType type, + S32 number, + S32 total_size) + { + const LLMessageBlock * block = message->getBlock(prehash(name)); + identifier = identifier + ":" + message->mName + ":" + name + " block"; + ensure(identifier + " exists", block != NULL); + ensure_equals(identifier + " name", block->mName, prehash(name)); + ensure_equals(identifier + " type", block->mType, type); + ensure_equals(identifier + " number", block->mNumber, number); + ensure_equals(identifier + " total size", block->mTotalSize, total_size); + } + + void ensure_variable_attributes(std::string identifier, + const LLMessageBlock * block, + const char * name, + EMsgVariableType type, + S32 size) + { + const LLMessageVariable * var = block->getVariable(prehash(name)); + identifier = identifier + ":" + block->mName + ":" + name + " variable"; + ensure(identifier + " exists", var != NULL); + ensure_equals( + identifier + " name", var->getName(), prehash(name)); + ensure_equals( + identifier + " type", var->getType(), type); + ensure_equals(identifier + " size", var->getSize(), size); + } + + std::string mMessage; + + }; + + typedef test_group<LLMessageTemplateParserTestData> LLMessageTemplateParserTestGroup; + typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject; + LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser"); + + template<> template<> + void LLMessageTemplateParserTestObject::test<1>() + // tests tokenizer constructor and next methods + { + mMessage = "test method 1 walkthrough"; + LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth"); + ensure_next(tokens, "first", 1); + ensure_next(tokens, "line", 1); + ensure_next(tokens, "next", 2); + ensure_next(tokens, "line", 2); + ensure_next(tokens, "fourth", 4); + + tokens = LLTemplateTokenizer("\n\t{ \t Test1 Fixed \n 523 }\n\n"); + ensure(tokens.want("{")); + ensure_next(tokens, "Test1", 2); + ensure_next(tokens, "Fixed", 2); + ensure_next(tokens, "523", 3); + ensure(tokens.want("}")); + + tokens = LLTemplateTokenizer("first line\nnext\t line\n\nfourth"); + ensure(tokens.want("first")); + ensure_next(tokens, "line", 1); + ensure_next(tokens, "next", 2); + ensure_next(tokens, "line", 2); + ensure(tokens.want("fourth")); + } + + template<> template<> + void LLMessageTemplateParserTestObject::test<2>() + // tests tokenizer want method + { + // *NOTE: order matters + LLTemplateTokenizer tokens("first line\nnext\t line\n\nfourth"); + ensure_equals("wants first token", tokens.want("first"), true); + ensure_equals("doesn't want blar token", tokens.want("blar"), false); + ensure_equals("wants line token", tokens.want("line"), true); + } + + template<> template<> + void LLMessageTemplateParserTestObject::test<3>() + // tests tokenizer eof methods + { + LLTemplateTokenizer tokens("single\n\n"); + ensure_equals("is not at eof at beginning", tokens.atEOF(), false); + ensure_equals("doesn't want eof", tokens.wantEOF(), false); + ensure_equals("wants the first token just to consume it", + tokens.want("single"), true); + ensure_equals("is not at eof in middle", tokens.atEOF(), false); + ensure_equals("wants eof", tokens.wantEOF(), true); + ensure_equals("is at eof at end", tokens.atEOF(), true); + } + + template<> template<> + void LLMessageTemplateParserTestObject::test<4>() + // tests variable parsing method + { + LLTemplateTokenizer tokens(std::string("{ Test0 \n\t\n U32 \n\n }")); + LLMessageVariable * var = LLTemplateParser::parseVariable(tokens); + + ensure("test0 var parsed", var != 0); + ensure_equals("name of variable", std::string(var->getName()), std::string("Test0")); + ensure_equals("type of variable is U32", var->getType(), MVT_U32); + ensure_equals("size of variable", var->getSize(), 4); + + delete var; + + std::string message_string("\n\t{ \t Test1 Fixed \n 523 }\n\n"); + tokens = LLTemplateTokenizer(message_string); + var = LLTemplateParser::parseVariable(tokens); + + ensure("test1 var parsed", var != 0); + ensure_equals("name of variable", std::string(var->getName()), std::string("Test1")); + ensure_equals("type of variable is Fixed", var->getType(), MVT_FIXED); + ensure_equals("size of variable", var->getSize(), 523); + + delete var; + + // *NOTE: the parsers call LL_ERRS() on invalid input, so we can't really + // test that :-( + } + + template<> template<> + void LLMessageTemplateParserTestObject::test<5>() + // tests block parsing method + { + LLTemplateTokenizer tokens("{ BlockA Single { VarX F32 } }"); + LLMessageBlock * block = LLTemplateParser::parseBlock(tokens); + + ensure("blockA block parsed", block != 0); + ensure_equals("name of block", std::string(block->mName), std::string("BlockA")); + ensure_equals("type of block is Single", block->mType, MBT_SINGLE); + ensure_equals("total size of block", block->mTotalSize, 4); + ensure_equals("number of block defaults to 1", block->mNumber, 1); + ensure_equals("variable type of VarX is F32", + block->getVariableType(prehash("VarX")), MVT_F32); + ensure_equals("variable size of VarX", + block->getVariableSize(prehash("VarX")), 4); + + delete block; + + tokens = LLTemplateTokenizer("{ Stuff Variable { Id LLUUID } }"); + block = LLTemplateParser::parseBlock(tokens); + + ensure("stuff block parsed", block != 0); + ensure_equals("name of block", std::string(block->mName), std::string("Stuff")); + ensure_equals("type of block is Multiple", block->mType, MBT_VARIABLE); + ensure_equals("total size of block", block->mTotalSize, 16); + ensure_equals("number of block defaults to 1", block->mNumber, 1); + ensure_equals("variable type of Id is LLUUID", + block->getVariableType(prehash("Id")), MVT_LLUUID); + ensure_equals("variable size of Id", + block->getVariableSize(prehash("Id")), 16); + + delete block; + + tokens = LLTemplateTokenizer("{ Stuff2 Multiple 45 { Shid LLVector3d } }"); + block = LLTemplateParser::parseBlock(tokens); + + ensure("stuff2 block parsed", block != 0); + ensure_equals("name of block", std::string(block->mName), std::string("Stuff2")); + ensure_equals("type of block is Multiple", block->mType, MBT_MULTIPLE); + ensure_equals("total size of block", block->mTotalSize, 24); + ensure_equals("number of blocks", block->mNumber, 45); + ensure_equals("variable type of Shid is Vector3d", + block->getVariableType(prehash("Shid")), MVT_LLVector3d); + ensure_equals("variable size of Shid", + block->getVariableSize(prehash("Shid")), 24); + + delete block; + } + + template<> template<> + void LLMessageTemplateParserTestObject::test<6>() + // tests message parsing method on a simple message + { + std::string message_skel( + "{\n" + "TestMessage Low 1 NotTrusted Zerocoded\n" + "// comment \n" + " {\n" + "TestBlock1 Single\n" + " { Test1 U32 }\n" + " }\n" + " {\n" + " NeighborBlock Multiple 4\n" + " { Test0 U32 }\n" + " { Test1 U32 }\n" + " { Test2 U32 }\n" + " }\n" + "}"); + LLTemplateTokenizer tokens(message_skel); + LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens); + + ensure("simple message parsed", message != 0); + ensure_equals("name of message", std::string(message->mName), std::string("TestMessage")); + ensure_equals("frequency is Low", message->mFrequency, MFT_LOW); + ensure_equals("trust is untrusted", message->mTrust, MT_NOTRUST); + ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 1)); + ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED); + ensure_equals("message deprecation is notdeprecated", message->mDeprecation, MD_NOTDEPRECATED); + + LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock")); + ensure("Nonexistant block does not exist", block == 0); + + delete message; + } + + template<> template<> + void LLMessageTemplateParserTestObject::test<7>() + // tests message parsing method on a deprecated message + { + std::string message_skel( + "{\n" + "TestMessageDeprecated High 34 Trusted Unencoded Deprecated\n" + " {\n" + "TestBlock2 Single\n" + " { Test2 S32 }\n" + " }\n" + "}"); + LLTemplateTokenizer tokens(message_skel); + LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens); + + ensure("deprecated message parsed", message != 0); + ensure_equals("name of message", std::string(message->mName), std::string("TestMessageDeprecated")); + ensure_equals("frequency is High", message->mFrequency, MFT_HIGH); + ensure_equals("trust is trusted", message->mTrust, MT_TRUST); + ensure_equals("message number", message->mMessageNumber, (U32)34); + ensure_equals("message encoding is unencoded", message->mEncoding, ME_UNENCODED); + ensure_equals("message deprecation is deprecated", message->mDeprecation, MD_DEPRECATED); + + delete message; + } + + template<> template<> void LLMessageTemplateParserTestObject::test<8>() + // tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message + { + std::string message_skel( + "{\n\ + RezMultipleAttachmentsFromInv Low 452 NotTrusted Zerocoded\n\ + {\n\ + AgentData Single\n\ + { AgentID LLUUID }\n\ + { SessionID LLUUID }\n\ + } \n\ + {\n\ + HeaderData Single\n\ + { CompoundMsgID LLUUID } // All messages a single \"compound msg\" must have the same id\n\ + { TotalObjects U8 }\n\ + { FirstDetachAll BOOL }\n\ + }\n\ + {\n\ + ObjectData Variable // 1 to 4 of these per packet\n\ + { ItemID LLUUID }\n\ + { OwnerID LLUUID }\n\ + { AttachmentPt U8 } // 0 for default\n\ + { ItemFlags U32 }\n\ + { GroupMask U32 }\n\ + { EveryoneMask U32 }\n\ + { NextOwnerMask U32 }\n\ + { Name Variable 1 }\n\ + { Description Variable 1 }\n\ + }\n\ + }\n\ + "); + LLTemplateTokenizer tokens(message_skel); + LLMessageTemplate * message = LLTemplateParser::parseMessage(tokens); + + ensure("RezMultipleAttachmentsFromInv message parsed", message != 0); + ensure_equals("name of message", message->mName, prehash("RezMultipleAttachmentsFromInv")); + ensure_equals("frequency is low", message->mFrequency, MFT_LOW); + ensure_equals("trust is not trusted", message->mTrust, MT_NOTRUST); + ensure_equals("message number", message->mMessageNumber, (U32)((255 << 24) | (255 << 16) | 452)); + ensure_equals("message encoding is zerocoded", message->mEncoding, ME_ZEROCODED); + + ensure_block_attributes( + "RMAFI", message, "AgentData", MBT_SINGLE, 1, 16+16); + LLMessageBlock * block = message->getBlock(prehash("AgentData")); + ensure_variable_attributes("RMAFI", + block, "AgentID", MVT_LLUUID, 16); + ensure_variable_attributes("RMAFI", + block, "SessionID", MVT_LLUUID, 16); + + ensure_block_attributes( + "RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1); + block = message->getBlock(prehash("HeaderData")); + ensure_variable_attributes( + "RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16); + ensure_variable_attributes( + "RMAFI", block, "TotalObjects", MVT_U8, 1); + ensure_variable_attributes( + "RMAFI", block, "FirstDetachAll", MVT_BOOL, 1); + + + ensure_block_attributes( + "RMAFI", message, "ObjectData", MBT_VARIABLE, 1, -1); + block = message->getBlock(prehash("ObjectData")); + ensure_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16); + ensure_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16); + ensure_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1); + ensure_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4); + ensure_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4); + ensure_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4); + ensure_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4); + ensure_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1); + ensure_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1); + + delete message; + } + + } diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp index eb237fcae2..c79a0dae83 100644 --- a/indra/test/llpermissions_tut.cpp +++ b/indra/test/llpermissions_tut.cpp @@ -1,491 +1,491 @@ -/** - * @file llpermissions_tut.cpp - * @author Adroit - * @date March 2007 - * @brief llpermissions test cases. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> -#include "linden_common.h" - -#include "lltut.h" - -#include "message.h" -#include "llpermissions.h" - - -namespace tut -{ - struct permission - { - }; - typedef test_group<permission> permission_t; - typedef permission_t::object permission_object_t; - tut::permission_t tut_permission("permission"); - - template<> template<> - void permission_object_t::test<1>() - { - LLPermissions permissions; - LLUUID uuid = permissions.getCreator(); - LLUUID uuid1 = permissions.getOwner(); - LLUUID uuid2 = permissions.getGroup(); - LLUUID uuid3 = permissions.getLastOwner(); - - ensure("LLPermission Get Functions failed", (uuid == LLUUID::null && uuid1 == LLUUID::null && - uuid2 == LLUUID::null && uuid3 == LLUUID::null)); - ensure("LLPermission Get Functions failed", (permissions.getMaskBase() == PERM_ALL && permissions.getMaskOwner() == PERM_ALL && - permissions.getMaskGroup() == PERM_ALL && permissions.getMaskEveryone() == PERM_ALL && permissions.getMaskNextOwner() == PERM_ALL)); - ensure("Ownership functions failed", ((! permissions.isGroupOwned()) && (! permissions.isOwned()))); - } - - template<> template<> - void permission_object_t::test<2>() - { - LLPermissions permissions; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - permissions.init(creator, owner, lastOwner, group); - - ensure_equals("init/getCreator():failed to return the creator ", creator, permissions.getCreator()); - ensure_equals("init/getOwner():failed to return the owner ", owner, permissions.getOwner()); - ensure_equals("init/getLastOwner():failed to return the group ", lastOwner, permissions.getLastOwner()); - ensure_equals("init/getGroup():failed to return the group ", group, permissions.getGroup()); - } - - template<> template<> - void permission_object_t::test<3>() - { - LLPermissions permissions; - U32 base = PERM_ALL; - U32 owner = PERM_ITEM_UNRESTRICTED; //PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER; - U32 group = PERM_TRANSFER | PERM_MOVE | PERM_COPY|PERM_MODIFY; - U32 everyone = PERM_TRANSFER | PERM_MOVE | PERM_MODIFY; - U32 next = PERM_NONE; - - U32 fixedbase = base; - U32 fixedowner = PERM_ITEM_UNRESTRICTED; //owner & fixedbase - U32 fixedgroup = PERM_ITEM_UNRESTRICTED; // no PERM_MOVE as owner does not have that perm either - U32 fixedeveryone = PERM_TRANSFER; // no PERM_MOVE. Everyone can never modify. - U32 fixednext = PERM_NONE; - - permissions.initMasks(base, owner, everyone, group, next); // will fix perms if not allowed. - ensure_equals("initMasks/getMaskBase():failed to return the MaskBase ", fixedbase, permissions.getMaskBase()); - ensure_equals("initMasks/getMaskOwner():failed to return the MaskOwner ", fixedowner, permissions.getMaskOwner()); - ensure_equals("initMasks/getMaskEveryone():failed to return the MaskGroup ", fixedgroup, permissions.getMaskGroup()); - ensure_equals("initMasks/getMaskEveryone():failed to return the MaskEveryone ", fixedeveryone, permissions.getMaskEveryone()); - ensure_equals("initMasks/getMaskNextOwner():failed to return the MaskNext ", fixednext, permissions.getMaskNextOwner()); - - // explictly set should maintain the values - permissions.setMaskBase(base); //no fixing - ensure_equals("setMaskBase/getMaskBase():failed to return the MaskBase ", base, permissions.getMaskBase()); - - permissions.setMaskOwner(owner); - ensure_equals("setMaskOwner/getMaskOwner():failed to return the MaskOwner ", owner, permissions.getMaskOwner()); - - permissions.setMaskEveryone(everyone); - ensure_equals("setMaskEveryone/getMaskEveryone():failed to return the MaskEveryone ", everyone, permissions.getMaskEveryone()); - - permissions.setMaskGroup(group); - ensure_equals("setMaskGroup/getMaskEveryone():failed to return the MaskGroup ", group, permissions.getMaskGroup()); - - permissions.setMaskNext(next); - ensure_equals("setMaskNext/getMaskNextOwner():failed to return the MaskNext ", next, permissions.getMaskNextOwner()); - - // further tests can be added to ensure perms for owner/group/everyone etc. get properly fixed. - // code however suggests that there is no explict check if the perms are correct and the user of this - // class is expected to know how to use them correctly. skipping further test cases for now for various - // perm combinations. - } - - template<> template<> - void permission_object_t::test<4>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm1.init(creator,owner,lastOwner,group); - perm.set(perm1); - ensure("set():failed to set ", (creator == perm.getCreator()) && (owner == perm.getOwner())&& - (lastOwner == perm.getLastOwner())&& (group == perm.getGroup())); - } - - template<> template<> - void permission_object_t::test<5>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm1.init(creator,owner,lastOwner,group); - - U32 base = PERM_TRANSFER; - U32 ownerp = PERM_TRANSFER; - U32 groupp = PERM_TRANSFER; - U32 everyone = PERM_TRANSFER; - U32 next = PERM_NONE; - - perm1.initMasks(base, ownerp, everyone, groupp, next); - - base = PERM_ALL; - ownerp = PERM_ITEM_UNRESTRICTED; //PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER; - groupp = PERM_TRANSFER | PERM_COPY|PERM_MODIFY; - everyone = PERM_TRANSFER; - next = PERM_NONE; - - perm.init(creator,owner,lastOwner,group); - perm.initMasks(base, ownerp, everyone, groupp, next); - - // restrict permissions by accumulation - perm.accumulate(perm1); - - U32 fixedbase = PERM_TRANSFER | PERM_MOVE; - U32 fixedowner = PERM_TRANSFER; - U32 fixedgroup = PERM_TRANSFER; - U32 fixedeveryone = PERM_TRANSFER; - U32 fixednext = PERM_NONE; - - ensure_equals("accumulate failed ", fixedbase, perm.getMaskBase()); - ensure_equals("accumulate failed ", fixedowner, perm.getMaskOwner()); - ensure_equals("accumulate failed ", fixedgroup, perm.getMaskGroup()); - ensure_equals("accumulate failed ", fixedeveryone, perm.getMaskEveryone()); - ensure_equals("accumulate failed ", fixednext, perm.getMaskNextOwner()); - } - - template<> template<> - void permission_object_t::test<6>() - { - LLPermissions perm; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - ensure_equals("getSafeOwner:failed ", owner,perm.getSafeOwner()); - - ///NULL Owner - perm.init(creator,LLUUID::null,lastOwner,group); - ensure_equals("getSafeOwner:failed ", group, perm.getSafeOwner()); - } - - template<> template<> - void permission_object_t::test<7>() - { - LLPermissions perm1; - LLUUID uuid; - bool is_group_owned = false; - ensure("1:getOwnership:failed ", ! perm1.getOwnership(uuid,is_group_owned)); - - LLPermissions perm; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - perm.getOwnership(uuid,is_group_owned); - ensure("2:getOwnership:failed ", ((uuid == owner) && (! is_group_owned))); - - perm.init(creator,LLUUID::null,lastOwner,group); - perm.getOwnership(uuid,is_group_owned); - ensure("3:getOwnership:failed ", ((uuid == group) && is_group_owned)); - } - - template<> template<> - void permission_object_t::test<8>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - perm1.init(creator,owner,lastOwner,group); - ensure_equals("getCRC32:failed ", perm.getCRC32(),perm1.getCRC32()); - } - - template<> template<> - void permission_object_t::test<9>() - { - LLPermissions perm; - LLUUID agent("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - bool is_atomic = true; - ensure("setOwnerAndGroup():failed ", perm.setOwnerAndGroup(agent,owner,group,is_atomic)); - - LLUUID owner2("68edcf47-ccd7-45b8-9f90-1649d7f12807"); - LLUUID group2("9c8eca51-53d5-42a7-bb58-cef070395db9"); - - // cant change - agent need to be current owner - ensure("setOwnerAndGroup():failed ", ! perm.setOwnerAndGroup(agent,owner2,group2,is_atomic)); - - // should be able to change - agent and owner same as current owner - ensure("setOwnerAndGroup():failed ", perm.setOwnerAndGroup(owner,owner,group2,is_atomic)); - } - - template<> template<> - void permission_object_t::test<10>() - { - LLPermissions perm; - LLUUID agent; - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - ensure("deedToGroup():failed ", perm.deedToGroup(agent,group)); - } - template<> template<> - void permission_object_t::test<11>() - { - LLPermissions perm; - LLUUID agent; - bool set = true; - U32 bits = PERM_TRANSFER | PERM_MODIFY; - ensure("setBaseBits():failed ", perm.setBaseBits(agent, set, bits)); - ensure("setOwnerBits():failed ", perm.setOwnerBits(agent, set, bits)); - - LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8"); - ensure("setBaseBits():failed ", ! perm.setBaseBits(agent1, set, bits)); - ensure("setOwnerBits():failed ", ! perm.setOwnerBits(agent1, set, bits)); - } - - template<> template<> - void permission_object_t::test<12>() - { - LLPermissions perm; - LLUUID agent; - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - bool set = true; - U32 bits = 10; - ensure("setGroupBits():failed ", perm.setGroupBits(agent,group, set, bits)); - ensure("setEveryoneBits():failed ", perm.setEveryoneBits(agent,group, set, bits)); - ensure("setNextOwnerBits():failed ", perm.setNextOwnerBits(agent,group, set, bits)); - - LLUUID agent1("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - ensure("setGroupBits():failed ", ! perm.setGroupBits(agent1,group, set, bits)); - ensure("setEveryoneBits():failed ", ! perm.setEveryoneBits(agent1,group, set, bits)); - ensure("setNextOwnerBits():failed ", ! perm.setNextOwnerBits(agent1,group, set, bits)); - } - - template<> template<> - void permission_object_t::test<13>() - { - LLPermissions perm; - LLUUID agent; - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - U32 bits = 10; - ensure("allowOperationBy():failed ", perm.allowOperationBy(bits,agent,group)); - - LLUUID agent1("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - perm.init(creator,owner,lastOwner,group); - ensure("allowOperationBy():failed ", perm.allowOperationBy(bits,agent1,group)); - } - - template<> template<> - void permission_object_t::test<14>() - { - LLPermissions perm; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner; - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - LLUUID agent; - ensure("1:allowModifyBy():failed ", perm.allowModifyBy(agent)); - ensure("2:allowModifyBy():failed ", perm.allowModifyBy(agent,group)); - - LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8"); - ensure("3:allowModifyBy():failed ", perm.allowModifyBy(agent1)); - ensure("4:allowModifyBy():failed ", perm.allowModifyBy(agent1,group)); - } - - template<> template<> - void permission_object_t::test<15>() - { - LLPermissions perm; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner; - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - LLUUID agent; - ensure("1:allowCopyBy():failed ", perm.allowModifyBy(agent)); - ensure("2:allowCopyBy():failed ", perm.allowModifyBy(agent,group)); - - LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8"); - ensure("3:allowCopyBy():failed ", perm.allowCopyBy(agent1)); - ensure("4:allowCopyBy():failed ", perm.allowCopyBy(agent1,group)); - } - - template<> template<> - void permission_object_t::test<16>() - { - LLPermissions perm; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner; - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - LLUUID agent; - ensure("1:allowMoveBy():failed ", perm.allowMoveBy(agent)); - ensure("2:allowMoveBy():failed ", perm.allowMoveBy(agent,group)); - - LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8"); - ensure("3:allowMoveBy():failed ", perm.allowMoveBy(agent1)); - ensure("4:allowMoveBy():failed ", perm.allowMoveBy(agent1,group)); - } - - template<> template<> - void permission_object_t::test<17>() - { - LLPermissions perm; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner; - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - LLUUID agent; - ensure("1:allowMoveBy():failed ", perm.allowTransferTo(agent)); - - perm.init(creator,owner,lastOwner,group); - ensure("2:allowMoveBy():failed ", perm.allowTransferTo(agent)); - } - - template<> template<> - void permission_object_t::test<18>() - { - LLPermissions perm,perm1; - ensure_equals("1:Operator==:failed ", perm, perm1); - - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - perm = perm1; - ensure_equals("2:Operator==:failed ", perm, perm1); - } - - template<> template<> - void permission_object_t::test<19>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - ensure_not_equals("2:Operator==:failed ", perm, perm1); - } - - template<> template<> - void permission_object_t::test<20>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - - U32 base = PERM_TRANSFER | PERM_COPY; - U32 ownerp = PERM_TRANSFER; - U32 groupp = PERM_TRANSFER; - U32 everyone = PERM_TRANSFER; - U32 next = PERM_NONE; - - perm.initMasks(base, ownerp, everyone, groupp, next); - - std::ostringstream ostream; - perm.exportLegacyStream(ostream); - std::istringstream istream(ostream.str()); - perm1.importLegacyStream(istream); - - ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm); - } - - template<> template<> - void permission_object_t::test<21>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - std::ostringstream stream1, stream2; - stream1 << perm; - perm1.init(creator,owner,lastOwner,group); - stream2 << perm1; - ensure_equals("1:operator << failed", stream1.str(), stream2.str()); - } - - template<> template<> - void permission_object_t::test<22>() - { - LLPermissions perm,perm1; - LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); - LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806"); - LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); - LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8"); - perm.init(creator,owner,lastOwner,group); - - U32 base = PERM_TRANSFER | PERM_COPY; - U32 ownerp = PERM_TRANSFER; - U32 groupp = PERM_TRANSFER; - U32 everyone = PERM_TRANSFER; - U32 next = PERM_NONE; - - perm.initMasks(base, ownerp, everyone, groupp, next); - - LLSD sd = ll_create_sd_from_permissions(perm); - perm1 = ll_permissions_from_sd(sd); - ensure_equals("ll_permissions_from_sd() and ll_create_sd_from_permissions()functions failed", perm, perm1); - } - - template<> template<> - void permission_object_t::test<23>() - { - LLAggregatePermissions AggrPermission; - LLAggregatePermissions AggrPermission1; - ensure_equals("getU8() function failed", AggrPermission.getU8(), 0); - ensure("isEmpty() function failed", AggrPermission.isEmpty()); - AggrPermission.getValue(PERM_TRANSFER); - ensure_equals("getValue() function failed", AggrPermission.getValue(PERM_TRANSFER), 0x00); - - AggrPermission.aggregate(PERM_ITEM_UNRESTRICTED); - ensure("aggregate() function failed", ! AggrPermission.isEmpty()); - - AggrPermission1.aggregate(AggrPermission); - ensure("aggregate() function failed", ! AggrPermission1.isEmpty()); - - std::ostringstream stream1; - stream1 << AggrPermission; - ensure_equals("operator<< failed", stream1.str(), "{PI_COPY=All, PI_MODIFY=All, PI_TRANSFER=All}"); - } -} +/**
+ * @file llpermissions_tut.cpp
+ * @author Adroit
+ * @date March 2007
+ * @brief llpermissions test cases.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+#include "linden_common.h"
+
+#include "lltut.h"
+
+#include "message.h"
+#include "llpermissions.h"
+
+
+namespace tut
+{
+ struct permission
+ {
+ };
+ typedef test_group<permission> permission_t;
+ typedef permission_t::object permission_object_t;
+ tut::permission_t tut_permission("permission");
+
+ template<> template<>
+ void permission_object_t::test<1>()
+ {
+ LLPermissions permissions;
+ LLUUID uuid = permissions.getCreator();
+ LLUUID uuid1 = permissions.getOwner();
+ LLUUID uuid2 = permissions.getGroup();
+ LLUUID uuid3 = permissions.getLastOwner();
+
+ ensure("LLPermission Get Functions failed", (uuid == LLUUID::null && uuid1 == LLUUID::null &&
+ uuid2 == LLUUID::null && uuid3 == LLUUID::null));
+ ensure("LLPermission Get Functions failed", (permissions.getMaskBase() == PERM_ALL && permissions.getMaskOwner() == PERM_ALL &&
+ permissions.getMaskGroup() == PERM_ALL && permissions.getMaskEveryone() == PERM_ALL && permissions.getMaskNextOwner() == PERM_ALL));
+ ensure("Ownership functions failed", ((! permissions.isGroupOwned()) && (! permissions.isOwned())));
+ }
+
+ template<> template<>
+ void permission_object_t::test<2>()
+ {
+ LLPermissions permissions;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ permissions.init(creator, owner, lastOwner, group);
+
+ ensure_equals("init/getCreator():failed to return the creator ", creator, permissions.getCreator());
+ ensure_equals("init/getOwner():failed to return the owner ", owner, permissions.getOwner());
+ ensure_equals("init/getLastOwner():failed to return the group ", lastOwner, permissions.getLastOwner());
+ ensure_equals("init/getGroup():failed to return the group ", group, permissions.getGroup());
+ }
+
+ template<> template<>
+ void permission_object_t::test<3>()
+ {
+ LLPermissions permissions;
+ U32 base = PERM_ALL;
+ U32 owner = PERM_ITEM_UNRESTRICTED; //PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER;
+ U32 group = PERM_TRANSFER | PERM_MOVE | PERM_COPY|PERM_MODIFY;
+ U32 everyone = PERM_TRANSFER | PERM_MOVE | PERM_MODIFY;
+ U32 next = PERM_NONE;
+
+ U32 fixedbase = base;
+ U32 fixedowner = PERM_ITEM_UNRESTRICTED; //owner & fixedbase
+ U32 fixedgroup = PERM_ITEM_UNRESTRICTED; // no PERM_MOVE as owner does not have that perm either
+ U32 fixedeveryone = PERM_TRANSFER; // no PERM_MOVE. Everyone can never modify.
+ U32 fixednext = PERM_NONE;
+
+ permissions.initMasks(base, owner, everyone, group, next); // will fix perms if not allowed.
+ ensure_equals("initMasks/getMaskBase():failed to return the MaskBase ", fixedbase, permissions.getMaskBase());
+ ensure_equals("initMasks/getMaskOwner():failed to return the MaskOwner ", fixedowner, permissions.getMaskOwner());
+ ensure_equals("initMasks/getMaskEveryone():failed to return the MaskGroup ", fixedgroup, permissions.getMaskGroup());
+ ensure_equals("initMasks/getMaskEveryone():failed to return the MaskEveryone ", fixedeveryone, permissions.getMaskEveryone());
+ ensure_equals("initMasks/getMaskNextOwner():failed to return the MaskNext ", fixednext, permissions.getMaskNextOwner());
+
+ // explictly set should maintain the values
+ permissions.setMaskBase(base); //no fixing
+ ensure_equals("setMaskBase/getMaskBase():failed to return the MaskBase ", base, permissions.getMaskBase());
+
+ permissions.setMaskOwner(owner);
+ ensure_equals("setMaskOwner/getMaskOwner():failed to return the MaskOwner ", owner, permissions.getMaskOwner());
+
+ permissions.setMaskEveryone(everyone);
+ ensure_equals("setMaskEveryone/getMaskEveryone():failed to return the MaskEveryone ", everyone, permissions.getMaskEveryone());
+
+ permissions.setMaskGroup(group);
+ ensure_equals("setMaskGroup/getMaskEveryone():failed to return the MaskGroup ", group, permissions.getMaskGroup());
+
+ permissions.setMaskNext(next);
+ ensure_equals("setMaskNext/getMaskNextOwner():failed to return the MaskNext ", next, permissions.getMaskNextOwner());
+
+ // further tests can be added to ensure perms for owner/group/everyone etc. get properly fixed.
+ // code however suggests that there is no explict check if the perms are correct and the user of this
+ // class is expected to know how to use them correctly. skipping further test cases for now for various
+ // perm combinations.
+ }
+
+ template<> template<>
+ void permission_object_t::test<4>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm1.init(creator,owner,lastOwner,group);
+ perm.set(perm1);
+ ensure("set():failed to set ", (creator == perm.getCreator()) && (owner == perm.getOwner())&&
+ (lastOwner == perm.getLastOwner())&& (group == perm.getGroup()));
+ }
+
+ template<> template<>
+ void permission_object_t::test<5>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm1.init(creator,owner,lastOwner,group);
+
+ U32 base = PERM_TRANSFER;
+ U32 ownerp = PERM_TRANSFER;
+ U32 groupp = PERM_TRANSFER;
+ U32 everyone = PERM_TRANSFER;
+ U32 next = PERM_NONE;
+
+ perm1.initMasks(base, ownerp, everyone, groupp, next);
+
+ base = PERM_ALL;
+ ownerp = PERM_ITEM_UNRESTRICTED; //PERM_ITEM_UNRESTRICTED = PERM_MODIFY | PERM_COPY | PERM_TRANSFER;
+ groupp = PERM_TRANSFER | PERM_COPY|PERM_MODIFY;
+ everyone = PERM_TRANSFER;
+ next = PERM_NONE;
+
+ perm.init(creator,owner,lastOwner,group);
+ perm.initMasks(base, ownerp, everyone, groupp, next);
+
+ // restrict permissions by accumulation
+ perm.accumulate(perm1);
+
+ U32 fixedbase = PERM_TRANSFER | PERM_MOVE;
+ U32 fixedowner = PERM_TRANSFER;
+ U32 fixedgroup = PERM_TRANSFER;
+ U32 fixedeveryone = PERM_TRANSFER;
+ U32 fixednext = PERM_NONE;
+
+ ensure_equals("accumulate failed ", fixedbase, perm.getMaskBase());
+ ensure_equals("accumulate failed ", fixedowner, perm.getMaskOwner());
+ ensure_equals("accumulate failed ", fixedgroup, perm.getMaskGroup());
+ ensure_equals("accumulate failed ", fixedeveryone, perm.getMaskEveryone());
+ ensure_equals("accumulate failed ", fixednext, perm.getMaskNextOwner());
+ }
+
+ template<> template<>
+ void permission_object_t::test<6>()
+ {
+ LLPermissions perm;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ ensure_equals("getSafeOwner:failed ", owner,perm.getSafeOwner());
+
+ ///NULL Owner
+ perm.init(creator,LLUUID::null,lastOwner,group);
+ ensure_equals("getSafeOwner:failed ", group, perm.getSafeOwner());
+ }
+
+ template<> template<>
+ void permission_object_t::test<7>()
+ {
+ LLPermissions perm1;
+ LLUUID uuid;
+ bool is_group_owned = false;
+ ensure("1:getOwnership:failed ", ! perm1.getOwnership(uuid,is_group_owned));
+
+ LLPermissions perm;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ perm.getOwnership(uuid,is_group_owned);
+ ensure("2:getOwnership:failed ", ((uuid == owner) && (! is_group_owned)));
+
+ perm.init(creator,LLUUID::null,lastOwner,group);
+ perm.getOwnership(uuid,is_group_owned);
+ ensure("3:getOwnership:failed ", ((uuid == group) && is_group_owned));
+ }
+
+ template<> template<>
+ void permission_object_t::test<8>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ perm1.init(creator,owner,lastOwner,group);
+ ensure_equals("getCRC32:failed ", perm.getCRC32(),perm1.getCRC32());
+ }
+
+ template<> template<>
+ void permission_object_t::test<9>()
+ {
+ LLPermissions perm;
+ LLUUID agent("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ bool is_atomic = true;
+ ensure("setOwnerAndGroup():failed ", perm.setOwnerAndGroup(agent,owner,group,is_atomic));
+
+ LLUUID owner2("68edcf47-ccd7-45b8-9f90-1649d7f12807");
+ LLUUID group2("9c8eca51-53d5-42a7-bb58-cef070395db9");
+
+ // cant change - agent need to be current owner
+ ensure("setOwnerAndGroup():failed ", ! perm.setOwnerAndGroup(agent,owner2,group2,is_atomic));
+
+ // should be able to change - agent and owner same as current owner
+ ensure("setOwnerAndGroup():failed ", perm.setOwnerAndGroup(owner,owner,group2,is_atomic));
+ }
+
+ template<> template<>
+ void permission_object_t::test<10>()
+ {
+ LLPermissions perm;
+ LLUUID agent;
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ ensure("deedToGroup():failed ", perm.deedToGroup(agent,group));
+ }
+ template<> template<>
+ void permission_object_t::test<11>()
+ {
+ LLPermissions perm;
+ LLUUID agent;
+ bool set = true;
+ U32 bits = PERM_TRANSFER | PERM_MODIFY;
+ ensure("setBaseBits():failed ", perm.setBaseBits(agent, set, bits));
+ ensure("setOwnerBits():failed ", perm.setOwnerBits(agent, set, bits));
+
+ LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ ensure("setBaseBits():failed ", ! perm.setBaseBits(agent1, set, bits));
+ ensure("setOwnerBits():failed ", ! perm.setOwnerBits(agent1, set, bits));
+ }
+
+ template<> template<>
+ void permission_object_t::test<12>()
+ {
+ LLPermissions perm;
+ LLUUID agent;
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ bool set = true;
+ U32 bits = 10;
+ ensure("setGroupBits():failed ", perm.setGroupBits(agent,group, set, bits));
+ ensure("setEveryoneBits():failed ", perm.setEveryoneBits(agent,group, set, bits));
+ ensure("setNextOwnerBits():failed ", perm.setNextOwnerBits(agent,group, set, bits));
+
+ LLUUID agent1("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ ensure("setGroupBits():failed ", ! perm.setGroupBits(agent1,group, set, bits));
+ ensure("setEveryoneBits():failed ", ! perm.setEveryoneBits(agent1,group, set, bits));
+ ensure("setNextOwnerBits():failed ", ! perm.setNextOwnerBits(agent1,group, set, bits));
+ }
+
+ template<> template<>
+ void permission_object_t::test<13>()
+ {
+ LLPermissions perm;
+ LLUUID agent;
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ U32 bits = 10;
+ ensure("allowOperationBy():failed ", perm.allowOperationBy(bits,agent,group));
+
+ LLUUID agent1("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ perm.init(creator,owner,lastOwner,group);
+ ensure("allowOperationBy():failed ", perm.allowOperationBy(bits,agent1,group));
+ }
+
+ template<> template<>
+ void permission_object_t::test<14>()
+ {
+ LLPermissions perm;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner;
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ LLUUID agent;
+ ensure("1:allowModifyBy():failed ", perm.allowModifyBy(agent));
+ ensure("2:allowModifyBy():failed ", perm.allowModifyBy(agent,group));
+
+ LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ ensure("3:allowModifyBy():failed ", perm.allowModifyBy(agent1));
+ ensure("4:allowModifyBy():failed ", perm.allowModifyBy(agent1,group));
+ }
+
+ template<> template<>
+ void permission_object_t::test<15>()
+ {
+ LLPermissions perm;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner;
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ LLUUID agent;
+ ensure("1:allowCopyBy():failed ", perm.allowModifyBy(agent));
+ ensure("2:allowCopyBy():failed ", perm.allowModifyBy(agent,group));
+
+ LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ ensure("3:allowCopyBy():failed ", perm.allowCopyBy(agent1));
+ ensure("4:allowCopyBy():failed ", perm.allowCopyBy(agent1,group));
+ }
+
+ template<> template<>
+ void permission_object_t::test<16>()
+ {
+ LLPermissions perm;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner;
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ LLUUID agent;
+ ensure("1:allowMoveBy():failed ", perm.allowMoveBy(agent));
+ ensure("2:allowMoveBy():failed ", perm.allowMoveBy(agent,group));
+
+ LLUUID agent1("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ ensure("3:allowMoveBy():failed ", perm.allowMoveBy(agent1));
+ ensure("4:allowMoveBy():failed ", perm.allowMoveBy(agent1,group));
+ }
+
+ template<> template<>
+ void permission_object_t::test<17>()
+ {
+ LLPermissions perm;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner;
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ LLUUID agent;
+ ensure("1:allowMoveBy():failed ", perm.allowTransferTo(agent));
+
+ perm.init(creator,owner,lastOwner,group);
+ ensure("2:allowMoveBy():failed ", perm.allowTransferTo(agent));
+ }
+
+ template<> template<>
+ void permission_object_t::test<18>()
+ {
+ LLPermissions perm,perm1;
+ ensure_equals("1:Operator==:failed ", perm, perm1);
+
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ perm = perm1;
+ ensure_equals("2:Operator==:failed ", perm, perm1);
+ }
+
+ template<> template<>
+ void permission_object_t::test<19>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ ensure_not_equals("2:Operator==:failed ", perm, perm1);
+ }
+
+ template<> template<>
+ void permission_object_t::test<20>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+
+ U32 base = PERM_TRANSFER | PERM_COPY;
+ U32 ownerp = PERM_TRANSFER;
+ U32 groupp = PERM_TRANSFER;
+ U32 everyone = PERM_TRANSFER;
+ U32 next = PERM_NONE;
+
+ perm.initMasks(base, ownerp, everyone, groupp, next);
+
+ std::ostringstream ostream;
+ perm.exportLegacyStream(ostream);
+ std::istringstream istream(ostream.str());
+ perm1.importLegacyStream(istream);
+
+ ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);
+ }
+
+ template<> template<>
+ void permission_object_t::test<21>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+ std::ostringstream stream1, stream2;
+ stream1 << perm;
+ perm1.init(creator,owner,lastOwner,group);
+ stream2 << perm1;
+ ensure_equals("1:operator << failed", stream1.str(), stream2.str());
+ }
+
+ template<> template<>
+ void permission_object_t::test<22>()
+ {
+ LLPermissions perm,perm1;
+ LLUUID creator("abf0d56b-82e5-47a2-a8ad-74741bb2c29e");
+ LLUUID owner("68edcf47-ccd7-45b8-9f90-1649d7f12806");
+ LLUUID lastOwner("5e47a0dc-97bf-44e0-8b40-de06718cee9d");
+ LLUUID group("9c8eca51-53d5-42a7-bb58-cef070395db8");
+ perm.init(creator,owner,lastOwner,group);
+
+ U32 base = PERM_TRANSFER | PERM_COPY;
+ U32 ownerp = PERM_TRANSFER;
+ U32 groupp = PERM_TRANSFER;
+ U32 everyone = PERM_TRANSFER;
+ U32 next = PERM_NONE;
+
+ perm.initMasks(base, ownerp, everyone, groupp, next);
+
+ LLSD sd = ll_create_sd_from_permissions(perm);
+ perm1 = ll_permissions_from_sd(sd);
+ ensure_equals("ll_permissions_from_sd() and ll_create_sd_from_permissions()functions failed", perm, perm1);
+ }
+
+ template<> template<>
+ void permission_object_t::test<23>()
+ {
+ LLAggregatePermissions AggrPermission;
+ LLAggregatePermissions AggrPermission1;
+ ensure_equals("getU8() function failed", AggrPermission.getU8(), 0);
+ ensure("isEmpty() function failed", AggrPermission.isEmpty());
+ AggrPermission.getValue(PERM_TRANSFER);
+ ensure_equals("getValue() function failed", AggrPermission.getValue(PERM_TRANSFER), 0x00);
+
+ AggrPermission.aggregate(PERM_ITEM_UNRESTRICTED);
+ ensure("aggregate() function failed", ! AggrPermission.isEmpty());
+
+ AggrPermission1.aggregate(AggrPermission);
+ ensure("aggregate() function failed", ! AggrPermission1.isEmpty());
+
+ std::ostringstream stream1;
+ stream1 << AggrPermission;
+ ensure_equals("operator<< failed", stream1.str(), "{PI_COPY=All, PI_MODIFY=All, PI_TRANSFER=All}");
+ }
+}
diff --git a/indra/test/llpipeutil.cpp b/indra/test/llpipeutil.cpp index bb706b58d5..c64cf21326 100644 --- a/indra/test/llpipeutil.cpp +++ b/indra/test/llpipeutil.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpipeutil.cpp * @date 2006-05-18 * @brief Utility pipe fittings for injecting and extracting strings @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,33 +41,33 @@ F32 pump_loop(LLPumpIO* pump, F32 seconds) { - LLTimer timer; - timer.setTimerExpirySec(seconds); - while(!timer.hasExpired()) - { - LLFrameTimer::updateFrameTime(); - pump->pump(); - pump->callback(); - } - return timer.getElapsedTimeF32(); + LLTimer timer; + timer.setTimerExpirySec(seconds); + while(!timer.hasExpired()) + { + LLFrameTimer::updateFrameTime(); + pump->pump(); + pump->callback(); + } + return timer.getElapsedTimeF32(); } -//virtual +//virtual LLIOPipe::EStatus LLPipeStringInjector::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - buffer->append(channels.out(), (U8*) mString.data(), mString.size()); - eos = true; - return STATUS_DONE; + buffer->append(channels.out(), (U8*) mString.data(), mString.size()); + eos = true; + return STATUS_DONE; } LLIOPipe::EStatus LLPipeStringExtractor::process_impl( - const LLChannelDescriptors& channels, + const LLChannelDescriptors& channels, buffer_ptr_t& buffer, bool& eos, LLSD& context, @@ -76,108 +76,108 @@ LLIOPipe::EStatus LLPipeStringExtractor::process_impl( if(!eos) return STATUS_BREAK; if(!pump || !buffer) return STATUS_PRECONDITION_NOT_MET; - LLBufferStream istr(channels, buffer.get()); - std::ostringstream ostr; - while (istr.good()) - { - char buf[1024]; /* Flawfinder: ignore */ - istr.read(buf, sizeof(buf)); /* Flawfinder: ignore */ - ostr.write(buf, istr.gcount()); - } - mString = ostr.str(); - mDone = true; - - return STATUS_DONE; + LLBufferStream istr(channels, buffer.get()); + std::ostringstream ostr; + while (istr.good()) + { + char buf[1024]; /* Flawfinder: ignore */ + istr.read(buf, sizeof(buf)); /* Flawfinder: ignore */ + ostr.write(buf, istr.gcount()); + } + mString = ostr.str(); + mDone = true; + + return STATUS_DONE; } // virtual LLIOPipe::EStatus LLIOFuzz::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - while(mByteCount) - { - std::vector<U8> data; - data.reserve(10000); - int size = llmin(10000, mByteCount); - std::generate_n( - std::back_insert_iterator< std::vector<U8> >(data), - size, - rand); - buffer->append(channels.out(), &data[0], size); - mByteCount -= size; - } - return STATUS_OK; + while(mByteCount) + { + std::vector<U8> data; + data.reserve(10000); + int size = llmin(10000, mByteCount); + std::generate_n( + std::back_insert_iterator< std::vector<U8> >(data), + size, + rand); + buffer->append(channels.out(), &data[0], size); + mByteCount -= size; + } + return STATUS_OK; } struct random_ascii_generator { - random_ascii_generator() {} - U8 operator()() - { - int rv = rand(); - rv %= (127 - 32); - rv += 32; - return rv; - } + random_ascii_generator() {} + U8 operator()() + { + int rv = rand(); + rv %= (127 - 32); + rv += 32; + return rv; + } }; // virtual LLIOPipe::EStatus LLIOASCIIFuzz::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - while(mByteCount) - { - std::vector<U8> data; - data.reserve(10000); - int size = llmin(10000, mByteCount); - std::generate_n( - std::back_insert_iterator< std::vector<U8> >(data), - size, - random_ascii_generator()); - buffer->append(channels.out(), &data[0], size); - mByteCount -= size; - } - return STATUS_OK; + while(mByteCount) + { + std::vector<U8> data; + data.reserve(10000); + int size = llmin(10000, mByteCount); + std::generate_n( + std::back_insert_iterator< std::vector<U8> >(data), + size, + random_ascii_generator()); + buffer->append(channels.out(), &data[0], size); + mByteCount -= size; + } + return STATUS_OK; } // virtual LLIOPipe::EStatus LLIONull::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - return STATUS_OK; + return STATUS_OK; } // virtual LLIOPipe::EStatus LLIOSleeper::process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump) + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump) { - if(!mRespond) - { - LL_DEBUGS() << "LLIOSleeper::process_impl() sleeping." << LL_ENDL; - mRespond = true; - static const F64 SLEEP_TIME = 2.0; - pump->sleepChain(SLEEP_TIME); - return STATUS_BREAK; - } - LL_DEBUGS() << "LLIOSleeper::process_impl() responding." << LL_ENDL; - LLBufferStream ostr(channels, buffer.get()); - ostr << "huh? sorry, I was sleeping." << std::endl; - return STATUS_DONE; + if(!mRespond) + { + LL_DEBUGS() << "LLIOSleeper::process_impl() sleeping." << LL_ENDL; + mRespond = true; + static const F64 SLEEP_TIME = 2.0; + pump->sleepChain(SLEEP_TIME); + return STATUS_BREAK; + } + LL_DEBUGS() << "LLIOSleeper::process_impl() responding." << LL_ENDL; + LLBufferStream ostr(channels, buffer.get()); + ostr << "huh? sorry, I was sleeping." << std::endl; + return STATUS_DONE; } diff --git a/indra/test/llpipeutil.h b/indra/test/llpipeutil.h index 5deb26764f..97d9e1c85c 100644 --- a/indra/test/llpipeutil.h +++ b/indra/test/llpipeutil.h @@ -1,4 +1,4 @@ -/** +/** * @file llpipeutil.h * @date 2006-05-18 * @brief Utility pipe fittings for injecting and extracting strings @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -43,34 +43,34 @@ F32 pump_loop(LLPumpIO* pump, F32 seconds); class LLPipeStringInjector : public LLIOPipe { public: - LLPipeStringInjector(const std::string& string) - : mString(string) - { } - + LLPipeStringInjector(const std::string& string) + : mString(string) + { } + protected: virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); private: - std::string mString; + std::string mString; }; class LLPipeStringExtractor : public LLIOPipe { public: - LLPipeStringExtractor() : mDone(false) { } - - bool done() { return mDone; } - std::string string() { return mString; } - + LLPipeStringExtractor() : mDone(false) { } + + bool done() { return mDone; } + std::string string() { return mString; } + protected: - // LLIOPipe API implementation. - virtual EStatus process_impl( + // LLIOPipe API implementation. + virtual EStatus process_impl( const LLChannelDescriptors& channels, LLIOPipe::buffer_ptr_t& buffer, bool& eos, @@ -78,8 +78,8 @@ protected: LLPumpIO* pump); private: - bool mDone; - std::string mString; + bool mDone; + std::string mString; }; /** @@ -88,18 +88,18 @@ private: class LLIOFuzz : public LLIOPipe { public: - LLIOFuzz(int byte_count) : mByteCount(byte_count) {} - + LLIOFuzz(int byte_count) : mByteCount(byte_count) {} + protected: virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); private: - int mByteCount; + int mByteCount; }; /** @@ -108,18 +108,18 @@ private: class LLIOASCIIFuzz : public LLIOPipe { public: - LLIOASCIIFuzz(int byte_count) : mByteCount(byte_count) {} - + LLIOASCIIFuzz(int byte_count) : mByteCount(byte_count) {} + protected: virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); private: - int mByteCount; + int mByteCount; }; @@ -129,15 +129,15 @@ private: class LLIONull : public LLIOPipe { public: - LLIONull() {} - + LLIONull() {} + protected: virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); }; /** @@ -146,17 +146,17 @@ protected: class LLIOSleeper : public LLIOPipe { public: - LLIOSleeper() : mRespond(false) {} - + LLIOSleeper() : mRespond(false) {} + protected: virtual EStatus process_impl( - const LLChannelDescriptors& channels, - buffer_ptr_t& buffer, - bool& eos, - LLSD& context, - LLPumpIO* pump); + const LLChannelDescriptors& channels, + buffer_ptr_t& buffer, + bool& eos, + LLSD& context, + LLPumpIO* pump); private: - bool mRespond; + bool mRespond; }; diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp index 2973824e62..469aca0b6e 100644 --- a/indra/test/llsaleinfo_tut.cpp +++ b/indra/test/llsaleinfo_tut.cpp @@ -1,194 +1,194 @@ -/** - * @file LLSaleInfo_tut.cpp - * @author Adroit - * @date 2007-03 - * @brief Test cases of llsaleinfo.h - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> -#include "linden_common.h" -#include "lltut.h" -#include "llsaleinfo.h" - -namespace tut -{ - struct llsaleinfo_tut - { - }; - typedef test_group<llsaleinfo_tut> llsaleinfo_tut_t; - typedef llsaleinfo_tut_t::object llsaleinfo_test_t; - tut::llsaleinfo_tut_t tut_llsaleinfo_test("llsaleinfo"); - - template<> template<> - void llsaleinfo_test_t::test<1>() - { - //test case for getSaleType(), getSalePrice(), getCRC32() fn. - //test case for setSaleType(), setSalePrice() fn. - - S32 sale_price = 10000; - LLSaleInfo llsaleinfo(LLSaleInfo::FS_COPY, sale_price); - const char* sale= "copy"; - - LLSD llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo); - LLSaleInfo saleinfo1 = ll_sale_info_from_sd(llsd_obj1); - - ensure("1. The getSaleType() fn failed", LLSaleInfo::FS_COPY == llsaleinfo.getSaleType()); - ensure("2. LLSaleInfo::isForSale() fn failed", true == llsaleinfo.isForSale()); - ensure("3. The getSalePrice() fn failed", sale_price == llsaleinfo.getSalePrice()); - ensure("4. The getCRC32() fn failed", 235833404 == llsaleinfo.getCRC32()); - ensure("5. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_COPY == llsaleinfo.lookup(sale)); - ensure_equals("6. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice()); - ensure_equals("7. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType()); - - llsaleinfo.setSalePrice(10000000); - llsaleinfo.setSaleType(LLSaleInfo::FS_ORIGINAL); - sale = "cntn"; - llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo); - saleinfo1 = ll_sale_info_from_sd(llsd_obj1); - - ensure("8. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_ORIGINAL == llsaleinfo.getSaleType()); - ensure("9. LLSaleInfo::isForSale() fn failed", true == llsaleinfo.isForSale()); - ensure("10. The getSalePrice() fn failed", 10000000 == llsaleinfo.getSalePrice()); - ensure("11. The getCRC32() fn failed", 127911702 == llsaleinfo.getCRC32()); - ensure("12. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_CONTENTS == llsaleinfo.lookup(sale)); - ensure_equals("13. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice()); - ensure_equals("14. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType()); - - llsaleinfo.setSalePrice(55000550); - llsaleinfo.setSaleType(LLSaleInfo::FS_CONTENTS); - sale = "orig"; - llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo); - saleinfo1 = ll_sale_info_from_sd(llsd_obj1); - - ensure("15. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_CONTENTS == llsaleinfo.getSaleType()); - ensure("16. LLSaleInfo::isForSale() fn failed", true == llsaleinfo.isForSale()); - ensure("17. The getSalePrice() fn failed", 55000550 == llsaleinfo.getSalePrice()); - ensure("18. The getCRC32() fn failed", 408735656 == llsaleinfo.getCRC32()); - ensure("19. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_ORIGINAL == llsaleinfo.lookup(sale)); - ensure_equals("20. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice()); - ensure_equals("21. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType()); - - llsaleinfo.setSalePrice(-6432); - llsaleinfo.setSaleType(LLSaleInfo::FS_NOT); - sale = "not"; - llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo); - saleinfo1 = ll_sale_info_from_sd(llsd_obj1); - - ensure("22. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_NOT == llsaleinfo.getSaleType()); - ensure("23. LLSaleInfo::isForSale() fn failed", false == llsaleinfo.isForSale()); - ensure("24. The getSalePrice() fn failed", 0 == llsaleinfo.getSalePrice()); - ensure("25. The getCRC32() fn failed", 0 == llsaleinfo.getCRC32()); - ensure("26. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_NOT == llsaleinfo.lookup(sale)); - ensure_equals("27. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice()); - ensure_equals("28. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType()); - } - - template<> template<> - void llsaleinfo_test_t::test<2>() - { - S32 sale_price = 525452; - LLSaleInfo llsaleinfo(LLSaleInfo::FS_ORIGINAL, sale_price); - - std::ostringstream ostream; - llsaleinfo.exportLegacyStream(ostream); - - std::istringstream istream(ostream.str()); - LLSaleInfo llsaleinfo1; - U32 perm_mask = 0; - bool has_perm_mask = false; - llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask); - - ensure("importStream() fn failed ", - llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() && - llsaleinfo.getSaleType() == llsaleinfo1.getSaleType()); - } - - template<> template<> - void llsaleinfo_test_t::test<3>() - { - S32 sale_price = 99000; - LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price); - - LLSD sd_result = saleinfo.asLLSD(); - - U32 perm_mask = 0 ; - bool has_perm_mask = false; - - LLSaleInfo saleinfo1; - saleinfo1.fromLLSD( sd_result, has_perm_mask, perm_mask); - - ensure_equals("asLLSD and fromLLSD failed", saleinfo.getSalePrice(), saleinfo1.getSalePrice()); - ensure_equals("asLLSD and fromLLSD failed", saleinfo.getSaleType(), saleinfo1.getSaleType()); - } - - //static EForSale lookup(const char* name) fn test - template<> template<> - void llsaleinfo_test_t::test<4>() - { - S32 sale_price = 233223; - LLSaleInfo::EForSale ret_type = LLSaleInfo::lookup("orig"); - - ensure_equals("lookup(const char* name) fn failed", ret_type, LLSaleInfo::FS_ORIGINAL); - - LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price); - const char* result = LLSaleInfo::lookup(LLSaleInfo::FS_COPY); - ensure("char* lookup(EForSale type) fn failed", 0 == strcmp("copy", result)); - } - - //void LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn test - template<> template<> - void llsaleinfo_test_t::test<5>() - { - S32 sale_price = 20; - LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price); - LLSaleInfo saleinfo1(LLSaleInfo::FS_COPY, sale_price); - saleinfo1.accumulate(saleinfo); - ensure_equals("LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn failed", saleinfo1.getSalePrice(), 40); - - } - - // test cases of bool operator==(const LLSaleInfo &rhs) fn - // test case of bool operator!=(const LLSaleInfo &rhs) fn - template<> template<> - void llsaleinfo_test_t::test<6>() - { - S32 sale_price = 55000; - LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price); - LLSaleInfo saleinfoequal(LLSaleInfo::FS_ORIGINAL, sale_price); - LLSaleInfo saleinfonotequal(LLSaleInfo::FS_ORIGINAL, sale_price*2); - - ensure("operator == fn. failed", true == (saleinfo == saleinfoequal)); - ensure("operator != fn. failed", true == (saleinfo != saleinfonotequal)); - } - - template<> template<> - void llsaleinfo_test_t::test<7>() - { - - //TBD: void LLSaleInfo::packMessage(LLMessageSystem* msg) const - //TBD: void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block) - //TBD: void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block, S32 block_num) - } - -} +/**
+ * @file LLSaleInfo_tut.cpp
+ * @author Adroit
+ * @date 2007-03
+ * @brief Test cases of llsaleinfo.h
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+#include "linden_common.h"
+#include "lltut.h"
+#include "llsaleinfo.h"
+
+namespace tut
+{
+ struct llsaleinfo_tut
+ {
+ };
+ typedef test_group<llsaleinfo_tut> llsaleinfo_tut_t;
+ typedef llsaleinfo_tut_t::object llsaleinfo_test_t;
+ tut::llsaleinfo_tut_t tut_llsaleinfo_test("llsaleinfo");
+
+ template<> template<>
+ void llsaleinfo_test_t::test<1>()
+ {
+ //test case for getSaleType(), getSalePrice(), getCRC32() fn.
+ //test case for setSaleType(), setSalePrice() fn.
+
+ S32 sale_price = 10000;
+ LLSaleInfo llsaleinfo(LLSaleInfo::FS_COPY, sale_price);
+ const char* sale= "copy";
+
+ LLSD llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
+ LLSaleInfo saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
+
+ ensure("1. The getSaleType() fn failed", LLSaleInfo::FS_COPY == llsaleinfo.getSaleType());
+ ensure("2. LLSaleInfo::isForSale() fn failed", true == llsaleinfo.isForSale());
+ ensure("3. The getSalePrice() fn failed", sale_price == llsaleinfo.getSalePrice());
+ ensure("4. The getCRC32() fn failed", 235833404 == llsaleinfo.getCRC32());
+ ensure("5. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_COPY == llsaleinfo.lookup(sale));
+ ensure_equals("6. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
+ ensure_equals("7. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
+
+ llsaleinfo.setSalePrice(10000000);
+ llsaleinfo.setSaleType(LLSaleInfo::FS_ORIGINAL);
+ sale = "cntn";
+ llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
+ saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
+
+ ensure("8. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_ORIGINAL == llsaleinfo.getSaleType());
+ ensure("9. LLSaleInfo::isForSale() fn failed", true == llsaleinfo.isForSale());
+ ensure("10. The getSalePrice() fn failed", 10000000 == llsaleinfo.getSalePrice());
+ ensure("11. The getCRC32() fn failed", 127911702 == llsaleinfo.getCRC32());
+ ensure("12. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_CONTENTS == llsaleinfo.lookup(sale));
+ ensure_equals("13. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
+ ensure_equals("14. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
+
+ llsaleinfo.setSalePrice(55000550);
+ llsaleinfo.setSaleType(LLSaleInfo::FS_CONTENTS);
+ sale = "orig";
+ llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
+ saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
+
+ ensure("15. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_CONTENTS == llsaleinfo.getSaleType());
+ ensure("16. LLSaleInfo::isForSale() fn failed", true == llsaleinfo.isForSale());
+ ensure("17. The getSalePrice() fn failed", 55000550 == llsaleinfo.getSalePrice());
+ ensure("18. The getCRC32() fn failed", 408735656 == llsaleinfo.getCRC32());
+ ensure("19. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_ORIGINAL == llsaleinfo.lookup(sale));
+ ensure_equals("20. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
+ ensure_equals("21. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
+
+ llsaleinfo.setSalePrice(-6432);
+ llsaleinfo.setSaleType(LLSaleInfo::FS_NOT);
+ sale = "not";
+ llsd_obj1 = ll_create_sd_from_sale_info(llsaleinfo);
+ saleinfo1 = ll_sale_info_from_sd(llsd_obj1);
+
+ ensure("22. The getSaleType() and setSaleType() fn failed", LLSaleInfo::FS_NOT == llsaleinfo.getSaleType());
+ ensure("23. LLSaleInfo::isForSale() fn failed", false == llsaleinfo.isForSale());
+ ensure("24. The getSalePrice() fn failed", 0 == llsaleinfo.getSalePrice());
+ ensure("25. The getCRC32() fn failed", 0 == llsaleinfo.getCRC32());
+ ensure("26. LLSaleInfo::lookup(const char* name) fn failed", LLSaleInfo::FS_NOT == llsaleinfo.lookup(sale));
+ ensure_equals("27. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSalePrice(), saleinfo1.getSalePrice());
+ ensure_equals("28. ll_create_sd_from_sale_info() fn failed", llsaleinfo.getSaleType(), saleinfo1.getSaleType());
+ }
+
+ template<> template<>
+ void llsaleinfo_test_t::test<2>()
+ {
+ S32 sale_price = 525452;
+ LLSaleInfo llsaleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
+
+ std::ostringstream ostream;
+ llsaleinfo.exportLegacyStream(ostream);
+
+ std::istringstream istream(ostream.str());
+ LLSaleInfo llsaleinfo1;
+ U32 perm_mask = 0;
+ bool has_perm_mask = false;
+ llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask);
+
+ ensure("importStream() fn failed ",
+ llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
+ llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
+ }
+
+ template<> template<>
+ void llsaleinfo_test_t::test<3>()
+ {
+ S32 sale_price = 99000;
+ LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
+
+ LLSD sd_result = saleinfo.asLLSD();
+
+ U32 perm_mask = 0 ;
+ bool has_perm_mask = false;
+
+ LLSaleInfo saleinfo1;
+ saleinfo1.fromLLSD( sd_result, has_perm_mask, perm_mask);
+
+ ensure_equals("asLLSD and fromLLSD failed", saleinfo.getSalePrice(), saleinfo1.getSalePrice());
+ ensure_equals("asLLSD and fromLLSD failed", saleinfo.getSaleType(), saleinfo1.getSaleType());
+ }
+
+ //static EForSale lookup(const char* name) fn test
+ template<> template<>
+ void llsaleinfo_test_t::test<4>()
+ {
+ S32 sale_price = 233223;
+ LLSaleInfo::EForSale ret_type = LLSaleInfo::lookup("orig");
+
+ ensure_equals("lookup(const char* name) fn failed", ret_type, LLSaleInfo::FS_ORIGINAL);
+
+ LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price);
+ const char* result = LLSaleInfo::lookup(LLSaleInfo::FS_COPY);
+ ensure("char* lookup(EForSale type) fn failed", 0 == strcmp("copy", result));
+ }
+
+ //void LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn test
+ template<> template<>
+ void llsaleinfo_test_t::test<5>()
+ {
+ S32 sale_price = 20;
+ LLSaleInfo saleinfo(LLSaleInfo::FS_COPY, sale_price);
+ LLSaleInfo saleinfo1(LLSaleInfo::FS_COPY, sale_price);
+ saleinfo1.accumulate(saleinfo);
+ ensure_equals("LLSaleInfo::accumulate(const LLSaleInfo& sale_info) fn failed", saleinfo1.getSalePrice(), 40);
+
+ }
+
+ // test cases of bool operator==(const LLSaleInfo &rhs) fn
+ // test case of bool operator!=(const LLSaleInfo &rhs) fn
+ template<> template<>
+ void llsaleinfo_test_t::test<6>()
+ {
+ S32 sale_price = 55000;
+ LLSaleInfo saleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
+ LLSaleInfo saleinfoequal(LLSaleInfo::FS_ORIGINAL, sale_price);
+ LLSaleInfo saleinfonotequal(LLSaleInfo::FS_ORIGINAL, sale_price*2);
+
+ ensure("operator == fn. failed", true == (saleinfo == saleinfoequal));
+ ensure("operator != fn. failed", true == (saleinfo != saleinfonotequal));
+ }
+
+ template<> template<>
+ void llsaleinfo_test_t::test<7>()
+ {
+
+ //TBD: void LLSaleInfo::packMessage(LLMessageSystem* msg) const
+ //TBD: void LLSaleInfo::unpackMessage(LLMessageSystem* msg, const char* block)
+ //TBD: void LLSaleInfo::unpackMultiMessage(LLMessageSystem* msg, const char* block, S32 block_num)
+ }
+
+}
diff --git a/indra/test/llsd_new_tut.cpp b/indra/test/llsd_new_tut.cpp index 458df3361e..cc084df045 100644 --- a/indra/test/llsd_new_tut.cpp +++ b/indra/test/llsd_new_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llsd_new_tut.cpp * @date February 2006 * @brief LLSD unit tests @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2006-2011, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -37,794 +37,794 @@ using std::fpclassify; namespace tut { - class SDCleanupCheck - { - private: - U32 mOutstandingAtStart; - public: - SDCleanupCheck() : mOutstandingAtStart(llsd::outstandingCount()) { } - ~SDCleanupCheck() - { - ensure_equals("SDCleanupCheck", - llsd::outstandingCount(), mOutstandingAtStart); - } - }; - - class SDAllocationCheck : public SDCleanupCheck - { - private: - std::string mMessage; - U32 mExpectedAllocations; - U32 mAllocationAtStart; - public: - SDAllocationCheck(const std::string& message, int expectedAllocations) - : mMessage(message), - mExpectedAllocations(expectedAllocations), - mAllocationAtStart(llsd::allocationCount()) - { } - ~SDAllocationCheck() - { - ensure_equals(mMessage + " SDAllocationCheck", - llsd::allocationCount() - mAllocationAtStart, - mExpectedAllocations); - } - }; - - struct SDTestData { - template<class T> - static void ensureTypeAndValue(const char* msg, const LLSD& actual, - T expectedValue) - { - LLSDTraits<T> traits; - - std::string s(msg); - - ensure( s + " type", traits.checkType(actual)); - ensure_equals( s + " value", traits.get(actual), expectedValue); - } - - template<class T> - static void ensureTypeAndRefValue(const char* msg, const LLSD& actual, - const T& expectedValue) - { - LLSDTraits<const T&> traits; - - std::string s(msg); - - ensure( s + " type", traits.checkType(actual)); - ensure_equals( s + " value", traits.get(actual), expectedValue); - } - }; - - typedef test_group<SDTestData> SDTestGroup; - typedef SDTestGroup::object SDTestObject; - - SDTestGroup sdTestGroup("LLSD(new)"); - - // template<> template<> - // void SDTestObject::test<1>() - // // construction and test of undefined - // { - // SDCleanupCheck check; - - // LLSD u; - // ensure("is undefined", u.isUndefined()); - // } - - template<> template<> - void SDTestObject::test<2>() - // setting and fetching scalar types - { - SDCleanupCheck check; - - LLSD v; - - v = true; ensureTypeAndValue("set true", v, true); - v = false; ensureTypeAndValue("set false", v, false); - v = true; ensureTypeAndValue("set true again", v, true); - - v = 42; ensureTypeAndValue("set to 42", v, 42); - v = 0; ensureTypeAndValue("set to zero", v, 0); - v = -12345; ensureTypeAndValue("set to neg", v, -12345); - v = 2000000000; ensureTypeAndValue("set to big", v, 2000000000); - - v = 3.14159265359; - ensureTypeAndValue("set to pi", v, 3.14159265359); - ensure_not_equals("isn't float", v.asReal(), - (float)3.14159265359); - v = 6.7e256; ensureTypeAndValue("set to big", v, 6.7e256); - - LLUUID nullUUID; - LLUUID newUUID; - newUUID.generate(); - - v = nullUUID; ensureTypeAndValue("set to null UUID", v, nullUUID); - v = newUUID; ensureTypeAndValue("set to new UUID", v, newUUID); - v = nullUUID; ensureTypeAndValue("set to null again", v, nullUUID); - - // strings must be tested with two types of string objects - std::string s = "now is the time"; - const char* cs = "for all good zorks"; - - v = s; ensureTypeAndValue("set to std::string", v, s); - v = cs; ensureTypeAndValue("set to const char*", v, cs); - - LLDate epoch; - LLDate aDay("2001-10-22T10:11:12.00Z"); - - v = epoch; ensureTypeAndValue("set to epoch", v, epoch); - v = aDay; ensureTypeAndValue("set to a day", v, aDay); - - LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); - - v = path; ensureTypeAndValue("set to a uri", v, path); - - const char source[] = "once in a blue moon"; - std::vector<U8> data; - copy(&source[0], &source[sizeof(source)], back_inserter(data)); - - v = data; ensureTypeAndRefValue("set to data", v, data); - - v.clear(); - ensure("reset to undefined", v.type() == LLSD::TypeUndefined); - } - - template<> template<> - void SDTestObject::test<3>() - // construction via scalar values - // tests both constructor and initialize forms - { - SDCleanupCheck check; - - LLSD b1(true); ensureTypeAndValue("construct boolean", b1, true); - LLSD b2 = true; ensureTypeAndValue("initialize boolean", b2, true); - LLSD i1(42); ensureTypeAndValue("construct int", i1, 42); - LLSD i2 =42; ensureTypeAndValue("initialize int", i2, 42); - LLSD d1(1.2); ensureTypeAndValue("construct double", d1, 1.2); - LLSD d2 = 1.2; ensureTypeAndValue("initialize double", d2, 1.2); - - LLUUID newUUID; - newUUID.generate(); - LLSD u1(newUUID); - ensureTypeAndValue("construct UUID", u1, newUUID); - LLSD u2 = newUUID; - ensureTypeAndValue("initialize UUID", u2, newUUID); - - LLSD ss1(std::string("abc")); - ensureTypeAndValue("construct std::string", ss1, "abc"); - LLSD ss2 = std::string("abc"); - ensureTypeAndValue("initialize std::string",ss2, "abc"); - LLSD sl1(std::string("def")); - ensureTypeAndValue("construct std::string", sl1, "def"); - LLSD sl2 = std::string("def"); - ensureTypeAndValue("initialize std::string", sl2, "def"); - LLSD sc1("ghi"); - ensureTypeAndValue("construct const char*", sc1, "ghi"); - LLSD sc2 = "ghi"; - ensureTypeAndValue("initialize const char*",sc2, "ghi"); - - LLDate aDay("2001-10-22T10:11:12.00Z"); - LLSD t1(aDay); ensureTypeAndValue("construct LLDate", t1, aDay); - LLSD t2 = aDay; ensureTypeAndValue("initialize LLDate", t2, aDay); - - LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); - LLSD p1(path); ensureTypeAndValue("construct LLURI", p1, path); - LLSD p2 = path; ensureTypeAndValue("initialize LLURI", p2, path); - - const char source[] = "once in a blue moon"; - std::vector<U8> data; - copy(&source[0], &source[sizeof(source)], back_inserter(data)); - LLSD x1(data); ensureTypeAndRefValue("construct vector<U8>", x1, data); - LLSD x2 = data; ensureTypeAndRefValue("initialize vector<U8>", x2, data); - } - - void checkConversions(const char* msg, const LLSD& v, - LLSD::Boolean eBoolean, LLSD::Integer eInteger, - LLSD::Real eReal, const LLSD::String& eString) - { - std::string s(msg); - - ensure_equals(s+" to bool", v.asBoolean(), eBoolean); - ensure_equals(s+" to int", v.asInteger(), eInteger); - if (eReal == eReal) - { - ensure_equals(s+" to real", v.asReal(), eReal); - ensure_equals(s+" to string", v.asString(), eString); - } - else - { - int left = fpclassify(v.asReal()); - int right = fpclassify(eReal); - - ensure_equals(s+" to real", left, right); - // ensure_equals(s+" to string", v.asString(), eString); - // I've commented this check out, since there doesn't - // seem to be uniform string representation for NaN on - // all platforms. For example, on my Ubuntu 8.10 laptop - // with libc 2.11.1, sqrt(-1.0) will return '-nan', not - // 'nan'. - } - } - - template<> template<> - void SDTestObject::test<4>() - // conversion between undefined and basic scalar types: - // boolean, integer, real and string - { - SDCleanupCheck check; - - LLSD v; checkConversions("untitled", v, false, 0, 0.0, ""); - - v = false; checkConversions("false", v, false, 0, 0.0, ""); - v = true; checkConversions("true", v, true, 1, 1.0, "true"); - - v = 0; checkConversions("zero", v, false, 0, 0.0, "0"); - v = 1; checkConversions("one", v, true, 1, 1.0, "1"); - v = -33; checkConversions("neg33", v, true, -33, -33.0, "-33"); - - v = 0.0; checkConversions("0.0", v, false, 0, 0.0, "0"); - v = 0.5; checkConversions("point5", v, true, 0, 0.5, "0.5"); - v = 0.9; checkConversions("point9", v, true, 0, 0.9, "0.9"); - v = -3.9; checkConversions("neg3dot9", v, true, -3, -3.9, "-3.9"); - // Get rid of NaN test. First, some libraries don't reliably return - // NaN for sqrt(-1.0) -- meaning that I don't even know how to - // portably, reliably produce a NaN value. Second, we observe failures - // on different platforms in the asString() test. But LLSD's - // ImplReal::asString() does not itself recognize NaN! It merely - // passes the value through to llformat(), which passes it through to - // the library vsnprintf(). That is, even when we do produce NaN, - // we're not testing any LLSD code: we're testing the local library's - // vsnprintf() function, which (empirically) produces idiosyncratic - // results. This is just not a good test case. -// v = sqrt(-1.0); checkConversions("NaN", v, false, 0, sqrt(-1.0), "nan"); - - v = ""; checkConversions("empty", v, false, 0, 0.0, ""); - v = "0"; checkConversions("digit0", v, true, 0, 0.0, "0"); - v = "10"; checkConversions("digit10", v, true, 10, 10.0, "10"); - v = "-2.345"; checkConversions("decdigits", v, - true, -2, -2.345, "-2.345"); - v = "apple"; checkConversions("apple", v, true, 0, 0.0, "apple"); - v = "33bob"; checkConversions("digialpha", v, true, 0, 0.0, "33bob"); - v = " "; checkConversions("space", v, true, 0, 0.0, " "); - v = "\n"; checkConversions("newline", v, true, 0, 0.0, "\n"); - } - - template<class T> - void checkRoundTrip(const std::string& msg, const LLSD& actual, - const char* sExpected, T vExpected) - { - std::string str = actual.asString(); - - if (sExpected) { - ensure_equals(msg + " string", str, sExpected); - } - - LLSD u(str); - LLSDTraits<T> traits; - - ensure_equals(msg + " value", traits.get(u), vExpected); - } - - - template<> template<> - void SDTestObject::test<5>() - // conversion of String to and from UUID, Date and URI. - { - SDCleanupCheck check; - - LLSD v; - - LLUUID nullUUID; - LLUUID someUUID; - someUUID.generate(); - - v = nullUUID; checkRoundTrip("null uuid", v, - "00000000-0000-0000-0000-000000000000", nullUUID); - v = someUUID; checkRoundTrip("random uuid", v, 0, someUUID); - - LLDate epoch; - LLDate beta("2003-04-30T04:00:00Z"); - LLDate oneOh("2003-06-23T04:00:00Z"); - - v = epoch; checkRoundTrip("epoch date", v, 0, epoch); - v = beta; checkRoundTrip("beta date", v, - "2003-04-30T04:00:00Z", beta); - v = oneOh; checkRoundTrip("1.0 date", v, - "2003-06-23T04:00:00Z", oneOh); - - LLURI empty; - LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); - LLURI mail("mailto:zero.linden@secondlife.com"); - - v = empty; checkRoundTrip("empty URI", v, 0, empty); - v = path; checkRoundTrip("path URI", v, - "http://slurl.com/secondlife/Ambleside/57/104/26/", - path); - v = mail; checkRoundTrip("mail URI", v, - "mailto:zero.linden@secondlife.com", mail); - } - - template<> template<> - void SDTestObject::test<6>() - // copy construction and assignment - // checking for shared values after constr. or assignment - // checking in both the same type and change of type case - { - SDCleanupCheck check; - - { - LLSD v = 42; - - LLSD w0(v); - ensureTypeAndValue("int constr.", w0, 42); - - LLSD w1(v); - w1 = 13; - ensureTypeAndValue("int constr. change case 1", w1, 13); - ensureTypeAndValue("int constr. change case 2", v, 42); - - LLSD w2(v); - v = 7; - ensureTypeAndValue("int constr. change case 3", w2, 42); - ensureTypeAndValue("int constr. change case 4", v, 7); - } - - { - LLSD v = 42; - - LLSD w1(v); - w1 = "bob"; - ensureTypeAndValue("string constr. change case 1", w1, "bob"); - ensureTypeAndValue("string constr. change case 2", v, 42); - - LLSD w2(v); - v = "amy"; - ensureTypeAndValue("string constr. change case 3", w2, 42); - ensureTypeAndValue("string constr. change case 4", v, "amy"); - } - - { - LLSD v = 42; - - LLSD w0; - w0 = v; - ensureTypeAndValue("int assign", w0, 42); - - LLSD w1; - w1 = v; - w1 = 13; - ensureTypeAndValue("int assign change case 1", w1, 13); - ensureTypeAndValue("int assign change case 2", v, 42); - - LLSD w2; - w2 = v; - v = 7; - ensureTypeAndValue("int assign change case 3", w2, 42); - ensureTypeAndValue("int assign change case 4", v, 7); - } - - { - LLSD v = 42; - - LLSD w1; - w1 = v; - w1 = "bob"; - ensureTypeAndValue("string assign change case 1", w1, "bob"); - ensureTypeAndValue("string assign change case 2", v, 42); - - LLSD w2; - w2 = v; - v = "amy"; - ensureTypeAndValue("string assign change case 3", w2, 42); - ensureTypeAndValue("string assign change case 4", v, "amy"); - } - } - - - template<> template<> - void SDTestObject::test<7>() - // Test assignment and casting to various scalar types. These - // assignments should invoke the right conversion without it being - // mentioned explicitly. The few exceptions are marked SAD. - { - SDCleanupCheck check; - - LLSD v(" 42.375"); - - bool b = false; - b = v; ensure_equals("assign to bool", b, true); - b = (bool)v; ensure_equals("cast to bool", b, true); - - int i = 99; - i = v; ensure_equals("assign to int", i, 42); - i = (int)v; ensure_equals("cast to int", i, 42); - - double d = 3.14159; - d = v; ensure_equals("assign to double", d, 42.375); - d = (double)v; ensure_equals("cast to double", d, 42.375); - - std::string s = "yo"; -// SAD s = v; ensure_equals("assign to string", s, " 42.375"); - s = (std::string)v; ensure_equals("cast to string", s, " 42.375"); - - std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b"; - v = uuidStr; - LLUUID u; - u = v; - ensure_equals("assign to LLUUID", u, LLUUID(uuidStr)); -// SAD u = (LLUUID)v; -// ensure_equals("cast to LLUUID", u, LLUUID(uuidStr)); - - std::string dateStr = "2005-10-24T15:00:00Z"; - v = dateStr; - LLDate date; - date = v; - ensure_equals("assign to LLDate", date.asString(), dateStr); -// SAD date = (LLDate)v; -// ensure_equals("cast to LLDate", date.asString(), dateStr); - - std::string uriStr = "http://secondlife.com"; - v = uriStr; - LLURI uri; - uri = v; - ensure_equals("assign to LLURI", uri.asString(), uriStr); -// SAD uri = (LLURI)v; -// ensure_equals("cast to LLURI", uri.asString(), uriStr); - } - - template<> template<> - void SDTestObject::test<8>() - // Test construction of various scalar types from LLSD. - // Test both construction and initialization forms. - // These should invoke the right conversion without it being - // mentioned explicitly. The few exceptions are marked SAD. - { - SDCleanupCheck check; - - LLSD v(" 42.375"); - - bool b1(v); ensure_equals("contruct bool", b1, true); - bool b2 = v; ensure_equals("initialize bool", b2, true); - - int i1(v); ensure_equals("contruct int", i1, 42); - int i2 = v; ensure_equals("initialize int", i2, 42); - - double d1(v); ensure_equals("contruct double", d1, 42.375); - double d2 = v; ensure_equals("initialize double", d2, 42.375); - - std::string s1(v); - std::string s2 = v; - ensure_equals("contruct string", s1, " 42.375"); - ensure_equals("initialize string", s2, " 42.375"); - - std::string t1(v); - std::string t2 = v.asString(); // SAD - ensure_equals("contruct std::string", t1, " 42.375"); - ensure_equals("initialize std::string", t2, " 42.375"); - - std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b"; - v = uuidStr; - LLUUID uuid1(v.asUUID()); // SAD - LLUUID uuid2 = v; - ensure_equals("contruct LLUUID", uuid1, LLUUID(uuidStr)); - ensure_equals("initialize LLUUID", uuid2, LLUUID(uuidStr)); - - std::string dateStr = "2005-10-24T15:00:00Z"; - v = dateStr; - LLDate date1(v.asDate()); // SAD - LLDate date2 = v; - ensure_equals("contruct LLDate", date1.asString(), dateStr); - ensure_equals("initialize LLDate", date2.asString(), dateStr); - - std::string uriStr = "http://secondlife.com"; - v = uriStr; - LLURI uri1(v.asURI()); // SAD - LLURI uri2 = v; - ensure_equals("contruct LLURI", uri1.asString(), uriStr); - ensure_equals("initialize LLURI", uri2.asString(), uriStr); - } - - - template<> template<> - void SDTestObject::test<9>() - // test to make sure v is interpreted as a bool in a various - // scenarios. - { - SDCleanupCheck check; - - LLSD v = "0"; - // magic value that is interpreted as boolean true, but integer false! - - ensure_equals("trinary operator bool", (v ? true : false), true); - ensure_equals("convert to int, then bool", - ((int)v ? true : false), false); - - if(v) - { - ensure("if converted to bool", true); - } - else - { - fail("bool did not convert to a bool in if statement."); - } - - if(!v) - { - fail("bool did not convert to a bool in negated if statement."); - } - } - - template<> template<> - void SDTestObject::test<10>() - // map operations - { - SDCleanupCheck check; - - LLSD v; - ensure("undefined has no members", !v.has("amy")); - ensure("undefined get() is undefined", v.get("bob").isUndefined()); - - v = LLSD::emptyMap(); - ensure("empty map is a map", v.isMap()); - ensure("empty map has no members", !v.has("cam")); - ensure("empty map get() is undefined", v.get("don").isUndefined()); - - v.clear(); - v.insert("eli", 43); - ensure("insert converts to map", v.isMap()); - ensure("inserted key is present", v.has("eli")); - ensureTypeAndValue("inserted value", v.get("eli"), 43); - - v.insert("fra", false); - ensure("first key still present", v.has("eli")); - ensure("second key is present", v.has("fra")); - ensureTypeAndValue("first value", v.get("eli"), 43); - ensureTypeAndValue("second value", v.get("fra"), false); - - v.erase("eli"); - ensure("first key now gone", !v.has("eli")); - ensure("second key still present", v.has("fra")); - ensure("first value gone", v.get("eli").isUndefined()); - ensureTypeAndValue("second value sill there", v.get("fra"), false); - - v.erase("fra"); - ensure("second key now gone", !v.has("fra")); - ensure("second value gone", v.get("fra").isUndefined()); - - v["gil"] = (std::string)"good morning"; - ensure("third key present", v.has("gil")); - ensureTypeAndValue("third key value", v.get("gil"), "good morning"); - - const LLSD& cv = v; // FIX ME IF POSSIBLE - ensure("missing key", cv["ham"].isUndefined()); - ensure("key not present", !v.has("ham")); - - LLSD w = 43; - const LLSD& cw = w; // FIX ME IF POSSIBLE - int i = cw["ian"]; - ensureTypeAndValue("other missing value", i, 0); - ensure("other missing key", !w.has("ian")); - ensure("no conversion", w.isInteger()); - - LLSD x; - x = v; - ensure("copy map type", x.isMap()); - ensureTypeAndValue("copy map value gil", x.get("gil"), "good morning"); - } - - - template<> template<> - void SDTestObject::test<11>() - // array operations - { - SDCleanupCheck check; - - LLSD v; - ensure_equals("undefined has no size", v.size(), 0); - ensure("undefined get() is undefined", v.get(0).isUndefined()); - - v = LLSD::emptyArray(); - ensure("empty array is an array", v.isArray()); - ensure_equals("empty array has no size", v.size(), 0); - ensure("empty map get() is undefined", v.get(0).isUndefined()); - - v.clear(); - v.append(88); - v.append("noodle"); - v.append(true); - ensure_equals("appened array size", v.size(), 3); - ensure("append array is an array", v.isArray()); - ensureTypeAndValue("append 0", v[0], 88); - ensureTypeAndValue("append 1", v[1], "noodle"); - ensureTypeAndValue("append 2", v[2], true); - - v.insert(0, 77); - v.insert(2, "soba"); - v.insert(4, false); - ensure_equals("inserted array size", v.size(), 6); - ensureTypeAndValue("post insert 0", v[0], 77); - ensureTypeAndValue("post insert 1", v[1], 88); - ensureTypeAndValue("post insert 2", v[2], "soba"); - ensureTypeAndValue("post insert 3", v[3], "noodle"); - ensureTypeAndValue("post insert 4", v[4], false); - ensureTypeAndValue("post insert 5", v[5], true); - - ensureTypeAndValue("get 1", v.get(1), 88); - v.set(1, "hot"); - ensureTypeAndValue("set 1", v.get(1), "hot"); - - v.erase(3); - ensure_equals("post erase array size", v.size(), 5); - ensureTypeAndValue("post erase 0", v[0], 77); - ensureTypeAndValue("post erase 1", v[1], "hot"); - ensureTypeAndValue("post erase 2", v[2], "soba"); - ensureTypeAndValue("post erase 3", v[3], false); - ensureTypeAndValue("post erase 4", v[4], true); - - v.append(34); - ensure_equals("size after append", v.size(), 6); - ensureTypeAndValue("post append 5", v[5], 34); - - LLSD w; - w = v; - ensure("copy array type", w.isArray()); - ensure_equals("copy array size", w.size(), 6); - ensureTypeAndValue("copy array 0", w[0], 77); - ensureTypeAndValue("copy array 1", w[1], "hot"); - ensureTypeAndValue("copy array 2", w[2], "soba"); - ensureTypeAndValue("copy array 3", w[3], false); - ensureTypeAndValue("copy array 4", w[4], true); - ensureTypeAndValue("copy array 5", w[5], 34); - } - - - template<> template<> - void SDTestObject::test<12>() - // no sharing - { - SDCleanupCheck check; - - LLSD a = 99; - LLSD b = a; - a = 34; - ensureTypeAndValue("top level original changed", a, 34); - ensureTypeAndValue("top level copy unaltered", b, 99); - b = a; - b = 66; - ensureTypeAndValue("top level original unaltered", a, 34); - ensureTypeAndValue("top level copy changed", b, 66); - - a[0] = "uno"; - a[1] = 99; - a[2] = 1.414; - b = a; - a[1] = 34; - ensureTypeAndValue("array member original changed", a[1], 34); - ensureTypeAndValue("array member copy unaltered", b[1], 99); - b = a; - b[1] = 66; - ensureTypeAndValue("array member original unaltered", a[1], 34); - ensureTypeAndValue("array member copy changed", b[1], 66); - - a["alpha"] = "uno"; - a["beta"] = 99; - a["gamma"] = 1.414; - b = a; - a["beta"] = 34; - ensureTypeAndValue("map member original changed", a["beta"], 34); - ensureTypeAndValue("map member copy unaltered", b["beta"], 99); - b = a; - b["beta"] = 66; - ensureTypeAndValue("map member original unaltered", a["beta"], 34); - ensureTypeAndValue("map member copy changed", b["beta"], 66); - } - - template<> template<> - void SDTestObject::test<13>() - // sharing implementation - { - SDCleanupCheck check; - - { - SDAllocationCheck check("copy construct undefinded", 0); - LLSD v; - LLSD w = v; - } - - { - SDAllocationCheck check("assign undefined", 0); - LLSD v; - LLSD w; - w = v; - } - - { - SDAllocationCheck check("assign integer value", 1); - LLSD v = 45; - v = 33; - v = 0; - } - - { - SDAllocationCheck check("copy construct integer", 1); - LLSD v = 45; - LLSD w = v; - } - - { - SDAllocationCheck check("assign integer", 1); - LLSD v = 45; - LLSD w; - w = v; - } - - { - SDAllocationCheck check("avoids extra clone", 2); - LLSD v = 45; - LLSD w = v; - w = "nice day"; - } - - { - SDAllocationCheck check("shared values test for threaded work", 9); - - //U32 start_llsd_count = LLSD::outstandingCount(); - - LLSD m = LLSD::emptyMap(); - - m["one"] = 1; - m["two"] = 2; - m["one_copy"] = m["one"]; // 3 (m, "one" and "two") - - m["undef_one"] = LLSD(); - m["undef_two"] = LLSD(); - m["undef_one_copy"] = m["undef_one"]; - - { // Ensure first_array gets freed to avoid counting it - LLSD first_array = LLSD::emptyArray(); - first_array.append(1.0f); - first_array.append(2.0f); - first_array.append(3.0f); // 7 - - m["array"] = first_array; - m["array_clone"] = first_array; - m["array_copy"] = m["array"]; // 7 - } - - m["string_one"] = "string one value"; - m["string_two"] = "string two value"; - m["string_one_copy"] = m["string_one"]; // 9 - - //U32 llsd_object_count = LLSD::outstandingCount(); - //std::cout << "Using " << (llsd_object_count - start_llsd_count) << " LLSD objects" << std::endl; - - //m.dumpStats(); - } - } - - template<> template<> - void SDTestObject::test<14>() - // make sure that assignment of char* NULL in a string does not crash. - { - LLSD v; - v = (const char*)NULL; - ensure("type is a string", v.isString()); - } - - /* TO DO: - conversion of undefined to UUID, Date, URI and Binary - conversion of undefined to map and array - test map operations - test array operations - test array extension - - test copying and assign maps and arrays (clone) - test iteration over map - test iteration over array - test iteration over scalar - - test empty map and empty array are indeed shared - test serializations - */ + class SDCleanupCheck + { + private: + U32 mOutstandingAtStart; + public: + SDCleanupCheck() : mOutstandingAtStart(llsd::outstandingCount()) { } + ~SDCleanupCheck() + { + ensure_equals("SDCleanupCheck", + llsd::outstandingCount(), mOutstandingAtStart); + } + }; + + class SDAllocationCheck : public SDCleanupCheck + { + private: + std::string mMessage; + U32 mExpectedAllocations; + U32 mAllocationAtStart; + public: + SDAllocationCheck(const std::string& message, int expectedAllocations) + : mMessage(message), + mExpectedAllocations(expectedAllocations), + mAllocationAtStart(llsd::allocationCount()) + { } + ~SDAllocationCheck() + { + ensure_equals(mMessage + " SDAllocationCheck", + llsd::allocationCount() - mAllocationAtStart, + mExpectedAllocations); + } + }; + + struct SDTestData { + template<class T> + static void ensureTypeAndValue(const char* msg, const LLSD& actual, + T expectedValue) + { + LLSDTraits<T> traits; + + std::string s(msg); + + ensure( s + " type", traits.checkType(actual)); + ensure_equals( s + " value", traits.get(actual), expectedValue); + } + + template<class T> + static void ensureTypeAndRefValue(const char* msg, const LLSD& actual, + const T& expectedValue) + { + LLSDTraits<const T&> traits; + + std::string s(msg); + + ensure( s + " type", traits.checkType(actual)); + ensure_equals( s + " value", traits.get(actual), expectedValue); + } + }; + + typedef test_group<SDTestData> SDTestGroup; + typedef SDTestGroup::object SDTestObject; + + SDTestGroup sdTestGroup("LLSD(new)"); + + // template<> template<> + // void SDTestObject::test<1>() + // // construction and test of undefined + // { + // SDCleanupCheck check; + + // LLSD u; + // ensure("is undefined", u.isUndefined()); + // } + + template<> template<> + void SDTestObject::test<2>() + // setting and fetching scalar types + { + SDCleanupCheck check; + + LLSD v; + + v = true; ensureTypeAndValue("set true", v, true); + v = false; ensureTypeAndValue("set false", v, false); + v = true; ensureTypeAndValue("set true again", v, true); + + v = 42; ensureTypeAndValue("set to 42", v, 42); + v = 0; ensureTypeAndValue("set to zero", v, 0); + v = -12345; ensureTypeAndValue("set to neg", v, -12345); + v = 2000000000; ensureTypeAndValue("set to big", v, 2000000000); + + v = 3.14159265359; + ensureTypeAndValue("set to pi", v, 3.14159265359); + ensure_not_equals("isn't float", v.asReal(), + (float)3.14159265359); + v = 6.7e256; ensureTypeAndValue("set to big", v, 6.7e256); + + LLUUID nullUUID; + LLUUID newUUID; + newUUID.generate(); + + v = nullUUID; ensureTypeAndValue("set to null UUID", v, nullUUID); + v = newUUID; ensureTypeAndValue("set to new UUID", v, newUUID); + v = nullUUID; ensureTypeAndValue("set to null again", v, nullUUID); + + // strings must be tested with two types of string objects + std::string s = "now is the time"; + const char* cs = "for all good zorks"; + + v = s; ensureTypeAndValue("set to std::string", v, s); + v = cs; ensureTypeAndValue("set to const char*", v, cs); + + LLDate epoch; + LLDate aDay("2001-10-22T10:11:12.00Z"); + + v = epoch; ensureTypeAndValue("set to epoch", v, epoch); + v = aDay; ensureTypeAndValue("set to a day", v, aDay); + + LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); + + v = path; ensureTypeAndValue("set to a uri", v, path); + + const char source[] = "once in a blue moon"; + std::vector<U8> data; + copy(&source[0], &source[sizeof(source)], back_inserter(data)); + + v = data; ensureTypeAndRefValue("set to data", v, data); + + v.clear(); + ensure("reset to undefined", v.type() == LLSD::TypeUndefined); + } + + template<> template<> + void SDTestObject::test<3>() + // construction via scalar values + // tests both constructor and initialize forms + { + SDCleanupCheck check; + + LLSD b1(true); ensureTypeAndValue("construct boolean", b1, true); + LLSD b2 = true; ensureTypeAndValue("initialize boolean", b2, true); + LLSD i1(42); ensureTypeAndValue("construct int", i1, 42); + LLSD i2 =42; ensureTypeAndValue("initialize int", i2, 42); + LLSD d1(1.2); ensureTypeAndValue("construct double", d1, 1.2); + LLSD d2 = 1.2; ensureTypeAndValue("initialize double", d2, 1.2); + + LLUUID newUUID; + newUUID.generate(); + LLSD u1(newUUID); + ensureTypeAndValue("construct UUID", u1, newUUID); + LLSD u2 = newUUID; + ensureTypeAndValue("initialize UUID", u2, newUUID); + + LLSD ss1(std::string("abc")); + ensureTypeAndValue("construct std::string", ss1, "abc"); + LLSD ss2 = std::string("abc"); + ensureTypeAndValue("initialize std::string",ss2, "abc"); + LLSD sl1(std::string("def")); + ensureTypeAndValue("construct std::string", sl1, "def"); + LLSD sl2 = std::string("def"); + ensureTypeAndValue("initialize std::string", sl2, "def"); + LLSD sc1("ghi"); + ensureTypeAndValue("construct const char*", sc1, "ghi"); + LLSD sc2 = "ghi"; + ensureTypeAndValue("initialize const char*",sc2, "ghi"); + + LLDate aDay("2001-10-22T10:11:12.00Z"); + LLSD t1(aDay); ensureTypeAndValue("construct LLDate", t1, aDay); + LLSD t2 = aDay; ensureTypeAndValue("initialize LLDate", t2, aDay); + + LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); + LLSD p1(path); ensureTypeAndValue("construct LLURI", p1, path); + LLSD p2 = path; ensureTypeAndValue("initialize LLURI", p2, path); + + const char source[] = "once in a blue moon"; + std::vector<U8> data; + copy(&source[0], &source[sizeof(source)], back_inserter(data)); + LLSD x1(data); ensureTypeAndRefValue("construct vector<U8>", x1, data); + LLSD x2 = data; ensureTypeAndRefValue("initialize vector<U8>", x2, data); + } + + void checkConversions(const char* msg, const LLSD& v, + LLSD::Boolean eBoolean, LLSD::Integer eInteger, + LLSD::Real eReal, const LLSD::String& eString) + { + std::string s(msg); + + ensure_equals(s+" to bool", v.asBoolean(), eBoolean); + ensure_equals(s+" to int", v.asInteger(), eInteger); + if (eReal == eReal) + { + ensure_equals(s+" to real", v.asReal(), eReal); + ensure_equals(s+" to string", v.asString(), eString); + } + else + { + int left = fpclassify(v.asReal()); + int right = fpclassify(eReal); + + ensure_equals(s+" to real", left, right); + // ensure_equals(s+" to string", v.asString(), eString); + // I've commented this check out, since there doesn't + // seem to be uniform string representation for NaN on + // all platforms. For example, on my Ubuntu 8.10 laptop + // with libc 2.11.1, sqrt(-1.0) will return '-nan', not + // 'nan'. + } + } + + template<> template<> + void SDTestObject::test<4>() + // conversion between undefined and basic scalar types: + // boolean, integer, real and string + { + SDCleanupCheck check; + + LLSD v; checkConversions("untitled", v, false, 0, 0.0, ""); + + v = false; checkConversions("false", v, false, 0, 0.0, ""); + v = true; checkConversions("true", v, true, 1, 1.0, "true"); + + v = 0; checkConversions("zero", v, false, 0, 0.0, "0"); + v = 1; checkConversions("one", v, true, 1, 1.0, "1"); + v = -33; checkConversions("neg33", v, true, -33, -33.0, "-33"); + + v = 0.0; checkConversions("0.0", v, false, 0, 0.0, "0"); + v = 0.5; checkConversions("point5", v, true, 0, 0.5, "0.5"); + v = 0.9; checkConversions("point9", v, true, 0, 0.9, "0.9"); + v = -3.9; checkConversions("neg3dot9", v, true, -3, -3.9, "-3.9"); + // Get rid of NaN test. First, some libraries don't reliably return + // NaN for sqrt(-1.0) -- meaning that I don't even know how to + // portably, reliably produce a NaN value. Second, we observe failures + // on different platforms in the asString() test. But LLSD's + // ImplReal::asString() does not itself recognize NaN! It merely + // passes the value through to llformat(), which passes it through to + // the library vsnprintf(). That is, even when we do produce NaN, + // we're not testing any LLSD code: we're testing the local library's + // vsnprintf() function, which (empirically) produces idiosyncratic + // results. This is just not a good test case. +// v = sqrt(-1.0); checkConversions("NaN", v, false, 0, sqrt(-1.0), "nan"); + + v = ""; checkConversions("empty", v, false, 0, 0.0, ""); + v = "0"; checkConversions("digit0", v, true, 0, 0.0, "0"); + v = "10"; checkConversions("digit10", v, true, 10, 10.0, "10"); + v = "-2.345"; checkConversions("decdigits", v, + true, -2, -2.345, "-2.345"); + v = "apple"; checkConversions("apple", v, true, 0, 0.0, "apple"); + v = "33bob"; checkConversions("digialpha", v, true, 0, 0.0, "33bob"); + v = " "; checkConversions("space", v, true, 0, 0.0, " "); + v = "\n"; checkConversions("newline", v, true, 0, 0.0, "\n"); + } + + template<class T> + void checkRoundTrip(const std::string& msg, const LLSD& actual, + const char* sExpected, T vExpected) + { + std::string str = actual.asString(); + + if (sExpected) { + ensure_equals(msg + " string", str, sExpected); + } + + LLSD u(str); + LLSDTraits<T> traits; + + ensure_equals(msg + " value", traits.get(u), vExpected); + } + + + template<> template<> + void SDTestObject::test<5>() + // conversion of String to and from UUID, Date and URI. + { + SDCleanupCheck check; + + LLSD v; + + LLUUID nullUUID; + LLUUID someUUID; + someUUID.generate(); + + v = nullUUID; checkRoundTrip("null uuid", v, + "00000000-0000-0000-0000-000000000000", nullUUID); + v = someUUID; checkRoundTrip("random uuid", v, 0, someUUID); + + LLDate epoch; + LLDate beta("2003-04-30T04:00:00Z"); + LLDate oneOh("2003-06-23T04:00:00Z"); + + v = epoch; checkRoundTrip("epoch date", v, 0, epoch); + v = beta; checkRoundTrip("beta date", v, + "2003-04-30T04:00:00Z", beta); + v = oneOh; checkRoundTrip("1.0 date", v, + "2003-06-23T04:00:00Z", oneOh); + + LLURI empty; + LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); + LLURI mail("mailto:zero.linden@secondlife.com"); + + v = empty; checkRoundTrip("empty URI", v, 0, empty); + v = path; checkRoundTrip("path URI", v, + "http://slurl.com/secondlife/Ambleside/57/104/26/", + path); + v = mail; checkRoundTrip("mail URI", v, + "mailto:zero.linden@secondlife.com", mail); + } + + template<> template<> + void SDTestObject::test<6>() + // copy construction and assignment + // checking for shared values after constr. or assignment + // checking in both the same type and change of type case + { + SDCleanupCheck check; + + { + LLSD v = 42; + + LLSD w0(v); + ensureTypeAndValue("int constr.", w0, 42); + + LLSD w1(v); + w1 = 13; + ensureTypeAndValue("int constr. change case 1", w1, 13); + ensureTypeAndValue("int constr. change case 2", v, 42); + + LLSD w2(v); + v = 7; + ensureTypeAndValue("int constr. change case 3", w2, 42); + ensureTypeAndValue("int constr. change case 4", v, 7); + } + + { + LLSD v = 42; + + LLSD w1(v); + w1 = "bob"; + ensureTypeAndValue("string constr. change case 1", w1, "bob"); + ensureTypeAndValue("string constr. change case 2", v, 42); + + LLSD w2(v); + v = "amy"; + ensureTypeAndValue("string constr. change case 3", w2, 42); + ensureTypeAndValue("string constr. change case 4", v, "amy"); + } + + { + LLSD v = 42; + + LLSD w0; + w0 = v; + ensureTypeAndValue("int assign", w0, 42); + + LLSD w1; + w1 = v; + w1 = 13; + ensureTypeAndValue("int assign change case 1", w1, 13); + ensureTypeAndValue("int assign change case 2", v, 42); + + LLSD w2; + w2 = v; + v = 7; + ensureTypeAndValue("int assign change case 3", w2, 42); + ensureTypeAndValue("int assign change case 4", v, 7); + } + + { + LLSD v = 42; + + LLSD w1; + w1 = v; + w1 = "bob"; + ensureTypeAndValue("string assign change case 1", w1, "bob"); + ensureTypeAndValue("string assign change case 2", v, 42); + + LLSD w2; + w2 = v; + v = "amy"; + ensureTypeAndValue("string assign change case 3", w2, 42); + ensureTypeAndValue("string assign change case 4", v, "amy"); + } + } + + + template<> template<> + void SDTestObject::test<7>() + // Test assignment and casting to various scalar types. These + // assignments should invoke the right conversion without it being + // mentioned explicitly. The few exceptions are marked SAD. + { + SDCleanupCheck check; + + LLSD v(" 42.375"); + + bool b = false; + b = v; ensure_equals("assign to bool", b, true); + b = (bool)v; ensure_equals("cast to bool", b, true); + + int i = 99; + i = v; ensure_equals("assign to int", i, 42); + i = (int)v; ensure_equals("cast to int", i, 42); + + double d = 3.14159; + d = v; ensure_equals("assign to double", d, 42.375); + d = (double)v; ensure_equals("cast to double", d, 42.375); + + std::string s = "yo"; +// SAD s = v; ensure_equals("assign to string", s, " 42.375"); + s = (std::string)v; ensure_equals("cast to string", s, " 42.375"); + + std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b"; + v = uuidStr; + LLUUID u; + u = v; + ensure_equals("assign to LLUUID", u, LLUUID(uuidStr)); +// SAD u = (LLUUID)v; +// ensure_equals("cast to LLUUID", u, LLUUID(uuidStr)); + + std::string dateStr = "2005-10-24T15:00:00Z"; + v = dateStr; + LLDate date; + date = v; + ensure_equals("assign to LLDate", date.asString(), dateStr); +// SAD date = (LLDate)v; +// ensure_equals("cast to LLDate", date.asString(), dateStr); + + std::string uriStr = "http://secondlife.com"; + v = uriStr; + LLURI uri; + uri = v; + ensure_equals("assign to LLURI", uri.asString(), uriStr); +// SAD uri = (LLURI)v; +// ensure_equals("cast to LLURI", uri.asString(), uriStr); + } + + template<> template<> + void SDTestObject::test<8>() + // Test construction of various scalar types from LLSD. + // Test both construction and initialization forms. + // These should invoke the right conversion without it being + // mentioned explicitly. The few exceptions are marked SAD. + { + SDCleanupCheck check; + + LLSD v(" 42.375"); + + bool b1(v); ensure_equals("contruct bool", b1, true); + bool b2 = v; ensure_equals("initialize bool", b2, true); + + int i1(v); ensure_equals("contruct int", i1, 42); + int i2 = v; ensure_equals("initialize int", i2, 42); + + double d1(v); ensure_equals("contruct double", d1, 42.375); + double d2 = v; ensure_equals("initialize double", d2, 42.375); + + std::string s1(v); + std::string s2 = v; + ensure_equals("contruct string", s1, " 42.375"); + ensure_equals("initialize string", s2, " 42.375"); + + std::string t1(v); + std::string t2 = v.asString(); // SAD + ensure_equals("contruct std::string", t1, " 42.375"); + ensure_equals("initialize std::string", t2, " 42.375"); + + std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b"; + v = uuidStr; + LLUUID uuid1(v.asUUID()); // SAD + LLUUID uuid2 = v; + ensure_equals("contruct LLUUID", uuid1, LLUUID(uuidStr)); + ensure_equals("initialize LLUUID", uuid2, LLUUID(uuidStr)); + + std::string dateStr = "2005-10-24T15:00:00Z"; + v = dateStr; + LLDate date1(v.asDate()); // SAD + LLDate date2 = v; + ensure_equals("contruct LLDate", date1.asString(), dateStr); + ensure_equals("initialize LLDate", date2.asString(), dateStr); + + std::string uriStr = "http://secondlife.com"; + v = uriStr; + LLURI uri1(v.asURI()); // SAD + LLURI uri2 = v; + ensure_equals("contruct LLURI", uri1.asString(), uriStr); + ensure_equals("initialize LLURI", uri2.asString(), uriStr); + } + + + template<> template<> + void SDTestObject::test<9>() + // test to make sure v is interpreted as a bool in a various + // scenarios. + { + SDCleanupCheck check; + + LLSD v = "0"; + // magic value that is interpreted as boolean true, but integer false! + + ensure_equals("trinary operator bool", (v ? true : false), true); + ensure_equals("convert to int, then bool", + ((int)v ? true : false), false); + + if(v) + { + ensure("if converted to bool", true); + } + else + { + fail("bool did not convert to a bool in if statement."); + } + + if(!v) + { + fail("bool did not convert to a bool in negated if statement."); + } + } + + template<> template<> + void SDTestObject::test<10>() + // map operations + { + SDCleanupCheck check; + + LLSD v; + ensure("undefined has no members", !v.has("amy")); + ensure("undefined get() is undefined", v.get("bob").isUndefined()); + + v = LLSD::emptyMap(); + ensure("empty map is a map", v.isMap()); + ensure("empty map has no members", !v.has("cam")); + ensure("empty map get() is undefined", v.get("don").isUndefined()); + + v.clear(); + v.insert("eli", 43); + ensure("insert converts to map", v.isMap()); + ensure("inserted key is present", v.has("eli")); + ensureTypeAndValue("inserted value", v.get("eli"), 43); + + v.insert("fra", false); + ensure("first key still present", v.has("eli")); + ensure("second key is present", v.has("fra")); + ensureTypeAndValue("first value", v.get("eli"), 43); + ensureTypeAndValue("second value", v.get("fra"), false); + + v.erase("eli"); + ensure("first key now gone", !v.has("eli")); + ensure("second key still present", v.has("fra")); + ensure("first value gone", v.get("eli").isUndefined()); + ensureTypeAndValue("second value sill there", v.get("fra"), false); + + v.erase("fra"); + ensure("second key now gone", !v.has("fra")); + ensure("second value gone", v.get("fra").isUndefined()); + + v["gil"] = (std::string)"good morning"; + ensure("third key present", v.has("gil")); + ensureTypeAndValue("third key value", v.get("gil"), "good morning"); + + const LLSD& cv = v; // FIX ME IF POSSIBLE + ensure("missing key", cv["ham"].isUndefined()); + ensure("key not present", !v.has("ham")); + + LLSD w = 43; + const LLSD& cw = w; // FIX ME IF POSSIBLE + int i = cw["ian"]; + ensureTypeAndValue("other missing value", i, 0); + ensure("other missing key", !w.has("ian")); + ensure("no conversion", w.isInteger()); + + LLSD x; + x = v; + ensure("copy map type", x.isMap()); + ensureTypeAndValue("copy map value gil", x.get("gil"), "good morning"); + } + + + template<> template<> + void SDTestObject::test<11>() + // array operations + { + SDCleanupCheck check; + + LLSD v; + ensure_equals("undefined has no size", v.size(), 0); + ensure("undefined get() is undefined", v.get(0).isUndefined()); + + v = LLSD::emptyArray(); + ensure("empty array is an array", v.isArray()); + ensure_equals("empty array has no size", v.size(), 0); + ensure("empty map get() is undefined", v.get(0).isUndefined()); + + v.clear(); + v.append(88); + v.append("noodle"); + v.append(true); + ensure_equals("appened array size", v.size(), 3); + ensure("append array is an array", v.isArray()); + ensureTypeAndValue("append 0", v[0], 88); + ensureTypeAndValue("append 1", v[1], "noodle"); + ensureTypeAndValue("append 2", v[2], true); + + v.insert(0, 77); + v.insert(2, "soba"); + v.insert(4, false); + ensure_equals("inserted array size", v.size(), 6); + ensureTypeAndValue("post insert 0", v[0], 77); + ensureTypeAndValue("post insert 1", v[1], 88); + ensureTypeAndValue("post insert 2", v[2], "soba"); + ensureTypeAndValue("post insert 3", v[3], "noodle"); + ensureTypeAndValue("post insert 4", v[4], false); + ensureTypeAndValue("post insert 5", v[5], true); + + ensureTypeAndValue("get 1", v.get(1), 88); + v.set(1, "hot"); + ensureTypeAndValue("set 1", v.get(1), "hot"); + + v.erase(3); + ensure_equals("post erase array size", v.size(), 5); + ensureTypeAndValue("post erase 0", v[0], 77); + ensureTypeAndValue("post erase 1", v[1], "hot"); + ensureTypeAndValue("post erase 2", v[2], "soba"); + ensureTypeAndValue("post erase 3", v[3], false); + ensureTypeAndValue("post erase 4", v[4], true); + + v.append(34); + ensure_equals("size after append", v.size(), 6); + ensureTypeAndValue("post append 5", v[5], 34); + + LLSD w; + w = v; + ensure("copy array type", w.isArray()); + ensure_equals("copy array size", w.size(), 6); + ensureTypeAndValue("copy array 0", w[0], 77); + ensureTypeAndValue("copy array 1", w[1], "hot"); + ensureTypeAndValue("copy array 2", w[2], "soba"); + ensureTypeAndValue("copy array 3", w[3], false); + ensureTypeAndValue("copy array 4", w[4], true); + ensureTypeAndValue("copy array 5", w[5], 34); + } + + + template<> template<> + void SDTestObject::test<12>() + // no sharing + { + SDCleanupCheck check; + + LLSD a = 99; + LLSD b = a; + a = 34; + ensureTypeAndValue("top level original changed", a, 34); + ensureTypeAndValue("top level copy unaltered", b, 99); + b = a; + b = 66; + ensureTypeAndValue("top level original unaltered", a, 34); + ensureTypeAndValue("top level copy changed", b, 66); + + a[0] = "uno"; + a[1] = 99; + a[2] = 1.414; + b = a; + a[1] = 34; + ensureTypeAndValue("array member original changed", a[1], 34); + ensureTypeAndValue("array member copy unaltered", b[1], 99); + b = a; + b[1] = 66; + ensureTypeAndValue("array member original unaltered", a[1], 34); + ensureTypeAndValue("array member copy changed", b[1], 66); + + a["alpha"] = "uno"; + a["beta"] = 99; + a["gamma"] = 1.414; + b = a; + a["beta"] = 34; + ensureTypeAndValue("map member original changed", a["beta"], 34); + ensureTypeAndValue("map member copy unaltered", b["beta"], 99); + b = a; + b["beta"] = 66; + ensureTypeAndValue("map member original unaltered", a["beta"], 34); + ensureTypeAndValue("map member copy changed", b["beta"], 66); + } + + template<> template<> + void SDTestObject::test<13>() + // sharing implementation + { + SDCleanupCheck check; + + { + SDAllocationCheck check("copy construct undefinded", 0); + LLSD v; + LLSD w = v; + } + + { + SDAllocationCheck check("assign undefined", 0); + LLSD v; + LLSD w; + w = v; + } + + { + SDAllocationCheck check("assign integer value", 1); + LLSD v = 45; + v = 33; + v = 0; + } + + { + SDAllocationCheck check("copy construct integer", 1); + LLSD v = 45; + LLSD w = v; + } + + { + SDAllocationCheck check("assign integer", 1); + LLSD v = 45; + LLSD w; + w = v; + } + + { + SDAllocationCheck check("avoids extra clone", 2); + LLSD v = 45; + LLSD w = v; + w = "nice day"; + } + + { + SDAllocationCheck check("shared values test for threaded work", 9); + + //U32 start_llsd_count = LLSD::outstandingCount(); + + LLSD m = LLSD::emptyMap(); + + m["one"] = 1; + m["two"] = 2; + m["one_copy"] = m["one"]; // 3 (m, "one" and "two") + + m["undef_one"] = LLSD(); + m["undef_two"] = LLSD(); + m["undef_one_copy"] = m["undef_one"]; + + { // Ensure first_array gets freed to avoid counting it + LLSD first_array = LLSD::emptyArray(); + first_array.append(1.0f); + first_array.append(2.0f); + first_array.append(3.0f); // 7 + + m["array"] = first_array; + m["array_clone"] = first_array; + m["array_copy"] = m["array"]; // 7 + } + + m["string_one"] = "string one value"; + m["string_two"] = "string two value"; + m["string_one_copy"] = m["string_one"]; // 9 + + //U32 llsd_object_count = LLSD::outstandingCount(); + //std::cout << "Using " << (llsd_object_count - start_llsd_count) << " LLSD objects" << std::endl; + + //m.dumpStats(); + } + } + + template<> template<> + void SDTestObject::test<14>() + // make sure that assignment of char* NULL in a string does not crash. + { + LLSD v; + v = (const char*)NULL; + ensure("type is a string", v.isString()); + } + + /* TO DO: + conversion of undefined to UUID, Date, URI and Binary + conversion of undefined to map and array + test map operations + test array operations + test array extension + + test copying and assign maps and arrays (clone) + test iteration over map + test iteration over array + test iteration over scalar + + test empty map and empty array are indeed shared + test serializations + */ } diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp index 8f54450cc6..0675dc6c80 100644 --- a/indra/test/llsdmessagebuilder_tut.cpp +++ b/indra/test/llsdmessagebuilder_tut.cpp @@ -1,837 +1,837 @@ -/** - * @file llsdmessagebuilder_tut.cpp - * @date February 2006 - * @brief LLSDMessageBuilder unit tests - * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> - -#include "linden_common.h" -#include "lltut.h" -#include "llmessagetemplate.h" -#include "llsdmessagebuilder.h" -#include "llsdmessagereader.h" -#include "llsdtraits.h" -#include "llmath.h" -#include "llquaternion.h" -#include "u64.h" -#include "v3dmath.h" -#include "v3math.h" -#include "v4math.h" -#include "llsdutil.h" -//#include "llsdutil.cpp" -#include "llsdutil_math.cpp" -#include "lltemplatemessagebuilder.h" - -namespace tut -{ - static LLTemplateMessageBuilder::message_template_name_map_t templateNameMap; - - LLMsgData* messageData = NULL; - LLMsgBlkData* messageBlockData = NULL; - - struct LLSDMessageBuilderTestData { - - LLSDMessageBuilderTestData() - { - messageData = new LLMsgData("testMessage"); - messageBlockData = new LLMsgBlkData("testBlock", 0); - } - - static LLSDMessageBuilder defaultBuilder() - { - LLSDMessageBuilder builder; - builder.newMessage("name"); - builder.nextBlock("block"); - return builder; - } - - static LLSDMessageReader setReader(const LLSDMessageBuilder& builder) - { - LLSDMessageReader reader; - reader.setMessage("name", builder.getMessage()); - return reader; - } - - static void addValue(LLMsgBlkData* mbd, char* name, void* v, EMsgVariableType type, int size, int data_size = -1) - { - LLMsgVarData tmp(name, type); - tmp.addData(v, size, type, data_size); - mbd->mMemberVarData[name] = tmp; - } - - - static LLMessageBlock* defaultTemplateBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) - { - return createTemplateBlock(_PREHASH_Test0, type, size, block); - } - - static LLMessageBlock* createTemplateBlock(const char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) - { - LLMessageBlock* result = new LLMessageBlock(name, block); - if(type != MVT_NULL) - { - result->addVariable(const_cast<char*>(_PREHASH_Test0), type, size); - } - return result; - } - - static LLTemplateMessageBuilder* defaultTemplateBuilder(LLMessageTemplate& messageTemplate, char* name = const_cast<char*>(_PREHASH_Test0)) - { - templateNameMap[_PREHASH_TestMessage] = &messageTemplate; - LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(templateNameMap); - builder->newMessage(_PREHASH_TestMessage); - builder->nextBlock(name); - return builder; - } - - static LLMessageTemplate defaultTemplate() - { - return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH); - } - }; - - typedef test_group<LLSDMessageBuilderTestData> LLSDMessageBuilderTestGroup; - typedef LLSDMessageBuilderTestGroup::object LLSDMessageBuilderTestObject; - LLSDMessageBuilderTestGroup llsdMessageBuilderTestGroup("LLSDMessageBuilder"); - - template<> template<> - void LLSDMessageBuilderTestObject::test<1>() - // construction and test of undefined - { - LLSDMessageBuilder builder = defaultBuilder(); - LLSDMessageReader reader = setReader(builder); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<2>() - // bool - { - bool outValue, inValue = true; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addBOOL("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getBOOL("block", "var", outValue); - ensure_equals("Ensure bool", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<3>() - // U8 - { - U8 outValue, inValue = 2; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addU8("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getU8("block", "var", outValue); - ensure_equals("Ensure U8", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<4>() - // S16 - { - S16 outValue, inValue = 90; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addS16("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getS16("block", "var", outValue); - ensure_equals("Ensure S16", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<5>() - // U16 - { - U16 outValue, inValue = 3; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addU16("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getU16("block", "var", outValue); - ensure_equals("Ensure U16", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<6>() - // S32 - { - S32 outValue, inValue = 44; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addS32("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getS32("block", "var", outValue); - ensure_equals("Ensure S32", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<7>() - // F32 - { - F32 outValue, inValue = 121.44f; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addF32("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getF32("block", "var", outValue); - ensure_equals("Ensure F32", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<8>() - // U32 - { - U32 outValue, inValue = 88; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addU32("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getU32("block", "var", outValue); - ensure_equals("Ensure U32", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<9>() - // U64 - { - U64 outValue, inValue = 121; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addU64("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getU64("block", "var", outValue); - ensure_equals("Ensure U64", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<10>() - // F64 - { - F64 outValue, inValue = 3232143.33; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addF64("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getF64("block", "var", outValue); - ensure_equals("Ensure F64", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<11>() - // Vector3 - { - LLVector3 outValue, inValue = LLVector3(1,2,3); - LLSDMessageBuilder builder = defaultBuilder(); - builder.addVector3("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getVector3("block", "var", outValue); - ensure_equals("Ensure Vector3", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<12>() - // Vector4 - { - LLVector4 outValue, inValue = LLVector4(1,2,3,4); - LLSDMessageBuilder builder = defaultBuilder(); - builder.addVector4("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getVector4("block", "var", outValue); - ensure_equals("Ensure Vector4", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<13>() - // Vector3d - { - LLVector3d outValue, inValue = LLVector3d(1,2,3); - LLSDMessageBuilder builder = defaultBuilder(); - builder.addVector3d("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getVector3d("block", "var", outValue); - ensure_equals("Ensure Vector3d", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<14>() - // Quaternion - { - LLQuaternion outValue, inValue = LLQuaternion(1,LLVector3(2,3,4)); - LLSDMessageBuilder builder = defaultBuilder(); - builder.addQuat("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getQuat("block", "var", outValue); - ensure_equals("Ensure Quaternion", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<15>() - // UUID - { - LLUUID outValue, inValue; - inValue.generate(); - LLSDMessageBuilder builder = defaultBuilder(); - builder.addUUID("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getUUID("block", "var", outValue); - ensure_equals("Ensure UUID", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<16>() - // IPAddr - { - U32 outValue, inValue = 12344556; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addIPAddr("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getIPAddr("block", "var", outValue); - ensure_equals("Ensure IPAddr", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<17>() - // IPPort - { - U16 outValue, inValue = 80; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addIPPort("var", inValue); - LLSDMessageReader reader = setReader(builder); - reader.getIPPort("block", "var", outValue); - ensure_equals("Ensure IPPort", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<18>() - { - std::string outValue, inValue = "testing"; - LLSDMessageBuilder builder = defaultBuilder(); - builder.addString("var", inValue.c_str()); - LLSDMessageReader reader = setReader(builder); - char buffer[MAX_STRING]; - reader.getString("block", "var", MAX_STRING, buffer); - outValue = buffer; - ensure_equals("Ensure String", inValue, outValue); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<19>() - { - LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); - LLMsgData* md = new LLMsgData("testMessage"); - md->addBlock(mbd); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*md); - LLSD output = builder.getMessage(); - - ensure("Ensure message block created when copied from legacy message to llsd", output["testBlock"].isDefined()); - } - - // MVT_FIXED - template<> template<> - void LLSDMessageBuilderTestObject::test<20>() - { - char binData[] = "abcdefghijklmnop"; - - addValue(messageBlockData, (char *)"testBinData", &binData, MVT_FIXED, sizeof(binData)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure fixed binary data works in a message copied from legacy to llsd", - &v[0], sizeof(binData), binData, sizeof(binData)); - } - - // MVT_VARIABLE data_size 1 (U8's) - template<> template<> - void LLSDMessageBuilderTestObject::test<21>() - { - /* U8 binData[] = "abcdefghijklmnop"; - - addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData), 1); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure MVT_VARIABLE U8 binary data works in a message copied from legacy to llsd", - &v[0], sizeof(binData), binData, sizeof(binData));*/ - } - - // MVT_VARIABLE data_size 2 (U16's) - template<> template<> - void LLSDMessageBuilderTestObject::test<22>() - { - U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts - - addValue(messageBlockData, (char *)"testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure MVT_VARIABLE U16 binary data works in a message copied from legacy to llsd", - &v[0], sizeof(binData) >> 1, binData, sizeof(binData) >> 1); - } - - // MVT_VARIABLE data_size 4 (S32's) - template<> template<> - void LLSDMessageBuilderTestObject::test<23>() - { - U32 binData[] = {9,8,7,6,5,4,3,2,1}; - - addValue(messageBlockData, (char *)"testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure MVT_VARIABLE S32 binary data works in a message copied from legacy to llsd", - &v[0], sizeof(binData) >> 2, binData, sizeof(binData) >> 2); - } - - // MVT_U8 - template<> template<> - void LLSDMessageBuilderTestObject::test<24>() - { - U8 data = 0xa5; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_U8, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_U8 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), data); - } - - // MVT_U16 - template<> template<> - void LLSDMessageBuilderTestObject::test<25>() - { - U16 data = 0xa55a; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_U16 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), data); - } - - // MVT_U32 - template<> template<> - void LLSDMessageBuilderTestObject::test<26>() - { - U32 data = 0xa55a7117; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_U32, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_U32 data works in a message copied from legacy to llsd", - ll_U32_from_sd(output["testBlock"][0]["testBinData"]), data); - } - - // MVT_U64 - crush into an s32: LLSD does not support 64 bit values - template<> template<> - void LLSDMessageBuilderTestObject::test<27>() - { - U64 data = U64L(0xa55a711711223344); - addValue(messageBlockData, (char *)"testBinData", &data, MVT_U64, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_U64 data works in a message copied from legacy to llsd", - ll_U64_from_sd(output["testBlock"][0]["testBinData"]), data); - } - - // MVT_S8 - template<> template<> - void LLSDMessageBuilderTestObject::test<28>() - { - S8 data = -31; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_S8, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_S8 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), data); - } - - // MVT_S16 - template<> template<> - void LLSDMessageBuilderTestObject::test<29>() - { - S16 data = -31; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_S16, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_S16 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), data); - } - - // MVT_S32 - template<> template<> - void LLSDMessageBuilderTestObject::test<30>() - { - S32 data = -3100; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_S32, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_S32 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), data); - } - - // MVT_S64 - crush into an s32: LLSD does not support 64 bit values - template<> template<> - void LLSDMessageBuilderTestObject::test<31>() - { - S64 data = -31003100; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_S64, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_S64 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), (S32)data); - } - - // MVT_F32 - template<> template<> - void LLSDMessageBuilderTestObject::test<32>() - { - F32 data = 1234.1234f; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_F32, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_F32 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asReal(), data); - } - - // MVT_F64 - template<> template<> - void LLSDMessageBuilderTestObject::test<33>() - { - F64 data = 1234.1234; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_F64, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_F64 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asReal(), data); - } - - // MVT_LLVector3 - template<> template<> - void LLSDMessageBuilderTestObject::test<34>() - { - LLVector3 data(1,2,3); - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector3, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd", - ll_vector3_from_sd(output["testBlock"][0]["testBinData"]), data); - } - - // MVT_LLVector3d - template<> template<> - void LLSDMessageBuilderTestObject::test<35>() - { - LLVector3d data(1,2,3); - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector3d, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd", - ll_vector3d_from_sd(output["testBlock"][0]["testBinData"]), data); - } - - // MVT_LLVector4 - template<> template<> - void LLSDMessageBuilderTestObject::test<36>() - { - LLVector4 data(1,2,3,4); - LLSD v = ll_sd_from_vector4(data); - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector4, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_LLVector4 data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"], v); - } - - // MVT_LLQuaternion - template<> template<> - void LLSDMessageBuilderTestObject::test<37>() - { - LLQuaternion data(0.3713907f, 0.5570861f, 0.7427813f,0.0f); - - //we send a quaternion packed into a vec3 (w is infered) - so sizeof(vec) == 12 bytes not 16. - LLVector3 vec = data.packToVector3(); - - addValue(messageBlockData, (char *)"testBinData", &vec, MVT_LLQuaternion, sizeof(vec)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_LLQuaternion data works in a message copied from legacy to llsd", - ll_quaternion_from_sd(output["testBlock"][0]["testBinData"]), data); - } - - // MVT_LLUUID - template<> template<> - void LLSDMessageBuilderTestObject::test<38>() - { - LLUUID data("01234567-0123-0123-0123-234567abcdef"); - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLUUID, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::string v = output["testBlock"][0]["testBinData"].asUUID().asString(); - - ensure_equals("Ensure MVT_LLUUID data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asUUID(), data); - } - - // MVT_BOOL - template<> template<> - void LLSDMessageBuilderTestObject::test<39>() - { - bool valueTrue = true; - bool valueFalse = false; - - LLMsgData* md = new LLMsgData("testMessage"); - LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); - addValue(mbd, (char *)"testBoolFalse", &valueFalse, MVT_BOOL, sizeof(bool)); - addValue(mbd, (char *)"testBoolTrue", &valueTrue, MVT_BOOL, sizeof(bool)); - md->addBlock(mbd); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*md); - LLSD output = builder.getMessage(); - - ensure("Ensure bools work in a message copied from legacy to llsd", - output["testBlock"][0]["testBoolTrue"].asBoolean() && !output["testBlock"][0]["testBoolFalse"].asBoolean()); - } - - // MVT_IP_ADDR - template<> template<> - void LLSDMessageBuilderTestObject::test<40>() - { - U32 data(0xff887766); - LLSD v = ll_sd_from_ipaddr(data); - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_IP_ADDR, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_IP_ADDR data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"], v); - } - - // MVT_IP_PORT - template<> template<> - void LLSDMessageBuilderTestObject::test<41>() - { - U16 data = 0xff88; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_IP_PORT, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - ensure_equals("Ensure MVT_IP_PORT data works in a message copied from legacy to llsd", - output["testBlock"][0]["testBinData"].asInteger(), data); - } - - // MVT_U16Vec3 - template<> template<> - void LLSDMessageBuilderTestObject::test<42>() - { - U16 data[3] = {0,1,2}; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16Vec3, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_U16Vec3 data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure MVT_U16Vec3 data works in a message copied from legacy to llsd", - (U16*)&v[0], 6, data, 6); - } - - // MVT_U16Quat - template<> template<> - void LLSDMessageBuilderTestObject::test<43>() - { - U16 data[4] = {0,1,2,4}; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16Quat, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_U16Quat data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure MVT_U16Quat data works in a message copied from legacy to llsd", - (U16*)&v[0], 8, data, 8); - } - - // MVT_S16Array - template<> template<> - void LLSDMessageBuilderTestObject::test<44>() - { - S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18}; - - addValue(messageBlockData, (char *)"testBinData", &data, MVT_S16Array, sizeof(data)); - messageData->addBlock(messageBlockData); - LLSDMessageBuilder builder = defaultBuilder(); - - builder.copyFromMessageData(*messageData); - LLSD output = builder.getMessage(); - - std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); - - ensure_memory_matches("Ensure MVT_S16Array data works in a message copied from legacy to llsd", - (U16*)&v[0], 19, data, 19); - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<45>() - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultTemplateBlock(MVT_U8, 1)); - U8 inValue = 2; - LLTemplateMessageBuilder* template_builder = defaultTemplateBuilder(messageTemplate); - template_builder->addU8(_PREHASH_Test0, inValue); - - LLSDMessageBuilder builder; - builder.copyFromMessageData(*template_builder->getCurrentMessage()); - LLSD output = builder.getMessage(); - - ensure_equals(output["Test0"][0]["Test0"].asInteger(), 2); - - } - - template<> template<> - void LLSDMessageBuilderTestObject::test<46>() - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultTemplateBlock(MVT_VARIABLE, 1)); - std::string inValue = "testing"; - LLTemplateMessageBuilder* builder = defaultTemplateBuilder(messageTemplate); - builder->addString(_PREHASH_Test0, inValue.c_str()); - - LLSDMessageBuilder sd_builder; - sd_builder.copyFromMessageData(*builder->getCurrentMessage()); - LLSD output = sd_builder.getMessage(); - - ensure_equals(output["Test0"][0]["Test0"].asString(), std::string("testing")); - } - -} - +/**
+ * @file llsdmessagebuilder_tut.cpp
+ * @date February 2006
+ * @brief LLSDMessageBuilder unit tests
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+
+#include "linden_common.h"
+#include "lltut.h"
+#include "llmessagetemplate.h"
+#include "llsdmessagebuilder.h"
+#include "llsdmessagereader.h"
+#include "llsdtraits.h"
+#include "llmath.h"
+#include "llquaternion.h"
+#include "u64.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "llsdutil.h"
+//#include "llsdutil.cpp"
+#include "llsdutil_math.cpp"
+#include "lltemplatemessagebuilder.h"
+
+namespace tut
+{
+ static LLTemplateMessageBuilder::message_template_name_map_t templateNameMap;
+
+ LLMsgData* messageData = NULL;
+ LLMsgBlkData* messageBlockData = NULL;
+
+ struct LLSDMessageBuilderTestData {
+
+ LLSDMessageBuilderTestData()
+ {
+ messageData = new LLMsgData("testMessage");
+ messageBlockData = new LLMsgBlkData("testBlock", 0);
+ }
+
+ static LLSDMessageBuilder defaultBuilder()
+ {
+ LLSDMessageBuilder builder;
+ builder.newMessage("name");
+ builder.nextBlock("block");
+ return builder;
+ }
+
+ static LLSDMessageReader setReader(const LLSDMessageBuilder& builder)
+ {
+ LLSDMessageReader reader;
+ reader.setMessage("name", builder.getMessage());
+ return reader;
+ }
+
+ static void addValue(LLMsgBlkData* mbd, char* name, void* v, EMsgVariableType type, int size, int data_size = -1)
+ {
+ LLMsgVarData tmp(name, type);
+ tmp.addData(v, size, type, data_size);
+ mbd->mMemberVarData[name] = tmp;
+ }
+
+
+ static LLMessageBlock* defaultTemplateBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
+ {
+ return createTemplateBlock(_PREHASH_Test0, type, size, block);
+ }
+
+ static LLMessageBlock* createTemplateBlock(const char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
+ {
+ LLMessageBlock* result = new LLMessageBlock(name, block);
+ if(type != MVT_NULL)
+ {
+ result->addVariable(const_cast<char*>(_PREHASH_Test0), type, size);
+ }
+ return result;
+ }
+
+ static LLTemplateMessageBuilder* defaultTemplateBuilder(LLMessageTemplate& messageTemplate, char* name = const_cast<char*>(_PREHASH_Test0))
+ {
+ templateNameMap[_PREHASH_TestMessage] = &messageTemplate;
+ LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(templateNameMap);
+ builder->newMessage(_PREHASH_TestMessage);
+ builder->nextBlock(name);
+ return builder;
+ }
+
+ static LLMessageTemplate defaultTemplate()
+ {
+ return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
+ }
+ };
+
+ typedef test_group<LLSDMessageBuilderTestData> LLSDMessageBuilderTestGroup;
+ typedef LLSDMessageBuilderTestGroup::object LLSDMessageBuilderTestObject;
+ LLSDMessageBuilderTestGroup llsdMessageBuilderTestGroup("LLSDMessageBuilder");
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<1>()
+ // construction and test of undefined
+ {
+ LLSDMessageBuilder builder = defaultBuilder();
+ LLSDMessageReader reader = setReader(builder);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<2>()
+ // bool
+ {
+ bool outValue, inValue = true;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addBOOL("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getBOOL("block", "var", outValue);
+ ensure_equals("Ensure bool", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<3>()
+ // U8
+ {
+ U8 outValue, inValue = 2;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU8("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU8("block", "var", outValue);
+ ensure_equals("Ensure U8", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<4>()
+ // S16
+ {
+ S16 outValue, inValue = 90;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addS16("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getS16("block", "var", outValue);
+ ensure_equals("Ensure S16", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<5>()
+ // U16
+ {
+ U16 outValue, inValue = 3;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU16("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU16("block", "var", outValue);
+ ensure_equals("Ensure U16", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<6>()
+ // S32
+ {
+ S32 outValue, inValue = 44;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addS32("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getS32("block", "var", outValue);
+ ensure_equals("Ensure S32", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<7>()
+ // F32
+ {
+ F32 outValue, inValue = 121.44f;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addF32("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getF32("block", "var", outValue);
+ ensure_equals("Ensure F32", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<8>()
+ // U32
+ {
+ U32 outValue, inValue = 88;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU32("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU32("block", "var", outValue);
+ ensure_equals("Ensure U32", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<9>()
+ // U64
+ {
+ U64 outValue, inValue = 121;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addU64("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getU64("block", "var", outValue);
+ ensure_equals("Ensure U64", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<10>()
+ // F64
+ {
+ F64 outValue, inValue = 3232143.33;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addF64("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getF64("block", "var", outValue);
+ ensure_equals("Ensure F64", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<11>()
+ // Vector3
+ {
+ LLVector3 outValue, inValue = LLVector3(1,2,3);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addVector3("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getVector3("block", "var", outValue);
+ ensure_equals("Ensure Vector3", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<12>()
+ // Vector4
+ {
+ LLVector4 outValue, inValue = LLVector4(1,2,3,4);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addVector4("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getVector4("block", "var", outValue);
+ ensure_equals("Ensure Vector4", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<13>()
+ // Vector3d
+ {
+ LLVector3d outValue, inValue = LLVector3d(1,2,3);
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addVector3d("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getVector3d("block", "var", outValue);
+ ensure_equals("Ensure Vector3d", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<14>()
+ // Quaternion
+ {
+ LLQuaternion outValue, inValue = LLQuaternion(1,LLVector3(2,3,4));
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addQuat("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getQuat("block", "var", outValue);
+ ensure_equals("Ensure Quaternion", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<15>()
+ // UUID
+ {
+ LLUUID outValue, inValue;
+ inValue.generate();
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addUUID("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getUUID("block", "var", outValue);
+ ensure_equals("Ensure UUID", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<16>()
+ // IPAddr
+ {
+ U32 outValue, inValue = 12344556;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addIPAddr("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getIPAddr("block", "var", outValue);
+ ensure_equals("Ensure IPAddr", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<17>()
+ // IPPort
+ {
+ U16 outValue, inValue = 80;
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addIPPort("var", inValue);
+ LLSDMessageReader reader = setReader(builder);
+ reader.getIPPort("block", "var", outValue);
+ ensure_equals("Ensure IPPort", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<18>()
+ {
+ std::string outValue, inValue = "testing";
+ LLSDMessageBuilder builder = defaultBuilder();
+ builder.addString("var", inValue.c_str());
+ LLSDMessageReader reader = setReader(builder);
+ char buffer[MAX_STRING];
+ reader.getString("block", "var", MAX_STRING, buffer);
+ outValue = buffer;
+ ensure_equals("Ensure String", inValue, outValue);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<19>()
+ {
+ LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0);
+ LLMsgData* md = new LLMsgData("testMessage");
+ md->addBlock(mbd);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*md);
+ LLSD output = builder.getMessage();
+
+ ensure("Ensure message block created when copied from legacy message to llsd", output["testBlock"].isDefined());
+ }
+
+ // MVT_FIXED
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<20>()
+ {
+ char binData[] = "abcdefghijklmnop";
+
+ addValue(messageBlockData, (char *)"testBinData", &binData, MVT_FIXED, sizeof(binData));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure fixed binary data works in a message copied from legacy to llsd",
+ &v[0], sizeof(binData), binData, sizeof(binData));
+ }
+
+ // MVT_VARIABLE data_size 1 (U8's)
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<21>()
+ {
+ /* U8 binData[] = "abcdefghijklmnop";
+
+ addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData), 1);
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure MVT_VARIABLE U8 binary data works in a message copied from legacy to llsd",
+ &v[0], sizeof(binData), binData, sizeof(binData));*/
+ }
+
+ // MVT_VARIABLE data_size 2 (U16's)
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<22>()
+ {
+ U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts
+
+ addValue(messageBlockData, (char *)"testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2);
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure MVT_VARIABLE U16 binary data works in a message copied from legacy to llsd",
+ &v[0], sizeof(binData) >> 1, binData, sizeof(binData) >> 1);
+ }
+
+ // MVT_VARIABLE data_size 4 (S32's)
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<23>()
+ {
+ U32 binData[] = {9,8,7,6,5,4,3,2,1};
+
+ addValue(messageBlockData, (char *)"testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4);
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure MVT_VARIABLE S32 binary data works in a message copied from legacy to llsd",
+ &v[0], sizeof(binData) >> 2, binData, sizeof(binData) >> 2);
+ }
+
+ // MVT_U8
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<24>()
+ {
+ U8 data = 0xa5;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_U8, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_U8 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), data);
+ }
+
+ // MVT_U16
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<25>()
+ {
+ U16 data = 0xa55a;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_U16 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), data);
+ }
+
+ // MVT_U32
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<26>()
+ {
+ U32 data = 0xa55a7117;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_U32, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_U32 data works in a message copied from legacy to llsd",
+ ll_U32_from_sd(output["testBlock"][0]["testBinData"]), data);
+ }
+
+ // MVT_U64 - crush into an s32: LLSD does not support 64 bit values
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<27>()
+ {
+ U64 data = U64L(0xa55a711711223344);
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_U64, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_U64 data works in a message copied from legacy to llsd",
+ ll_U64_from_sd(output["testBlock"][0]["testBinData"]), data);
+ }
+
+ // MVT_S8
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<28>()
+ {
+ S8 data = -31;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_S8, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_S8 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), data);
+ }
+
+ // MVT_S16
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<29>()
+ {
+ S16 data = -31;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_S16, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_S16 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), data);
+ }
+
+ // MVT_S32
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<30>()
+ {
+ S32 data = -3100;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_S32, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_S32 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), data);
+ }
+
+ // MVT_S64 - crush into an s32: LLSD does not support 64 bit values
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<31>()
+ {
+ S64 data = -31003100;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_S64, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_S64 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), (S32)data);
+ }
+
+ // MVT_F32
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<32>()
+ {
+ F32 data = 1234.1234f;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_F32, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_F32 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asReal(), data);
+ }
+
+ // MVT_F64
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<33>()
+ {
+ F64 data = 1234.1234;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_F64, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_F64 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asReal(), data);
+ }
+
+ // MVT_LLVector3
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<34>()
+ {
+ LLVector3 data(1,2,3);
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector3, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd",
+ ll_vector3_from_sd(output["testBlock"][0]["testBinData"]), data);
+ }
+
+ // MVT_LLVector3d
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<35>()
+ {
+ LLVector3d data(1,2,3);
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector3d, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd",
+ ll_vector3d_from_sd(output["testBlock"][0]["testBinData"]), data);
+ }
+
+ // MVT_LLVector4
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<36>()
+ {
+ LLVector4 data(1,2,3,4);
+ LLSD v = ll_sd_from_vector4(data);
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLVector4, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_LLVector4 data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"], v);
+ }
+
+ // MVT_LLQuaternion
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<37>()
+ {
+ LLQuaternion data(0.3713907f, 0.5570861f, 0.7427813f,0.0f);
+
+ //we send a quaternion packed into a vec3 (w is infered) - so sizeof(vec) == 12 bytes not 16.
+ LLVector3 vec = data.packToVector3();
+
+ addValue(messageBlockData, (char *)"testBinData", &vec, MVT_LLQuaternion, sizeof(vec));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_LLQuaternion data works in a message copied from legacy to llsd",
+ ll_quaternion_from_sd(output["testBlock"][0]["testBinData"]), data);
+ }
+
+ // MVT_LLUUID
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<38>()
+ {
+ LLUUID data("01234567-0123-0123-0123-234567abcdef");
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_LLUUID, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::string v = output["testBlock"][0]["testBinData"].asUUID().asString();
+
+ ensure_equals("Ensure MVT_LLUUID data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asUUID(), data);
+ }
+
+ // MVT_BOOL
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<39>()
+ {
+ bool valueTrue = true;
+ bool valueFalse = false;
+
+ LLMsgData* md = new LLMsgData("testMessage");
+ LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0);
+ addValue(mbd, (char *)"testBoolFalse", &valueFalse, MVT_BOOL, sizeof(bool));
+ addValue(mbd, (char *)"testBoolTrue", &valueTrue, MVT_BOOL, sizeof(bool));
+ md->addBlock(mbd);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*md);
+ LLSD output = builder.getMessage();
+
+ ensure("Ensure bools work in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBoolTrue"].asBoolean() && !output["testBlock"][0]["testBoolFalse"].asBoolean());
+ }
+
+ // MVT_IP_ADDR
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<40>()
+ {
+ U32 data(0xff887766);
+ LLSD v = ll_sd_from_ipaddr(data);
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_IP_ADDR, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_IP_ADDR data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"], v);
+ }
+
+ // MVT_IP_PORT
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<41>()
+ {
+ U16 data = 0xff88;
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_IP_PORT, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ ensure_equals("Ensure MVT_IP_PORT data works in a message copied from legacy to llsd",
+ output["testBlock"][0]["testBinData"].asInteger(), data);
+ }
+
+ // MVT_U16Vec3
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<42>()
+ {
+ U16 data[3] = {0,1,2};
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16Vec3, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_U16Vec3 data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure MVT_U16Vec3 data works in a message copied from legacy to llsd",
+ (U16*)&v[0], 6, data, 6);
+ }
+
+ // MVT_U16Quat
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<43>()
+ {
+ U16 data[4] = {0,1,2,4};
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_U16Quat, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_U16Quat data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure MVT_U16Quat data works in a message copied from legacy to llsd",
+ (U16*)&v[0], 8, data, 8);
+ }
+
+ // MVT_S16Array
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<44>()
+ {
+ S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18};
+
+ addValue(messageBlockData, (char *)"testBinData", &data, MVT_S16Array, sizeof(data));
+ messageData->addBlock(messageBlockData);
+ LLSDMessageBuilder builder = defaultBuilder();
+
+ builder.copyFromMessageData(*messageData);
+ LLSD output = builder.getMessage();
+
+ std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary();
+ ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0);
+
+ ensure_memory_matches("Ensure MVT_S16Array data works in a message copied from legacy to llsd",
+ (U16*)&v[0], 19, data, 19);
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<45>()
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultTemplateBlock(MVT_U8, 1));
+ U8 inValue = 2;
+ LLTemplateMessageBuilder* template_builder = defaultTemplateBuilder(messageTemplate);
+ template_builder->addU8(_PREHASH_Test0, inValue);
+
+ LLSDMessageBuilder builder;
+ builder.copyFromMessageData(*template_builder->getCurrentMessage());
+ LLSD output = builder.getMessage();
+
+ ensure_equals(output["Test0"][0]["Test0"].asInteger(), 2);
+
+ }
+
+ template<> template<>
+ void LLSDMessageBuilderTestObject::test<46>()
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultTemplateBlock(MVT_VARIABLE, 1));
+ std::string inValue = "testing";
+ LLTemplateMessageBuilder* builder = defaultTemplateBuilder(messageTemplate);
+ builder->addString(_PREHASH_Test0, inValue.c_str());
+
+ LLSDMessageBuilder sd_builder;
+ sd_builder.copyFromMessageData(*builder->getCurrentMessage());
+ LLSD output = sd_builder.getMessage();
+
+ ensure_equals(output["Test0"][0]["Test0"].asString(), std::string("testing"));
+ }
+
+}
+
diff --git a/indra/test/llsdmessagereader_tut.cpp b/indra/test/llsdmessagereader_tut.cpp index 0ada5b8132..98f92fd9f5 100644 --- a/indra/test/llsdmessagereader_tut.cpp +++ b/indra/test/llsdmessagereader_tut.cpp @@ -1,324 +1,324 @@ -/** - * @file llsdmessagereader_tut.cpp - * @date February 2006 - * @brief LLSDMessageReader unit tests - * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> -#include "linden_common.h" -#include "lltut.h" -#include "v3dmath.h" -#include "v3math.h" -#include "v4math.h" -#include "llquaternion.h" - -#include "message.h" -#include "llsdmessagereader.h" -#include "llsdutil.h" -#include "llsdutil_math.h" - -namespace tut -{ - struct LLSDMessageReaderTestData { - static void ensureMessageName(const std::string& msg_name, - const LLSD& msg_data, - const std::string& expected_name) - { - LLSDMessageReader msg; - msg.setMessage(LLMessageStringTable::getInstance()->getString(msg_name.c_str()), msg_data); - ensure_equals("Ensure name", std::string(msg.getMessageName()), - expected_name); - } - - static void ensureNumberOfBlocks(const LLSD& msg_data, - const std::string& block, - S32 expected_number) - { - LLSDMessageReader msg; - msg.setMessage("fakename", msg_data); - ensure_equals("Ensure number of blocks", msg.getNumberOfBlocks(block.c_str()), - expected_number); - } - - static void ensureMessageSize(const LLSD& msg_data, - S32 expected_size) - { - LLSDMessageReader msg; - msg.setMessage("fakename", msg_data); - ensure_equals( "Ensure size", msg.getMessageSize(), expected_size); - } - - static void ensureBool(const LLSD& msg_data, - const std::string& block, - const std::string& var, - S32 blocknum, - bool expected) - { - LLSDMessageReader msg; - msg.setMessage("fakename", msg_data); - bool test_data; - msg.getBOOL(block.c_str(), var.c_str(), test_data, blocknum); - ensure_equals( "Ensure bool field", test_data, expected); - } - }; - - typedef test_group<LLSDMessageReaderTestData> LLSDMessageReaderTestGroup; - typedef LLSDMessageReaderTestGroup::object LLSDMessageReaderTestObject; - LLSDMessageReaderTestGroup llsdMessageReaderTestGroup("LLSDMessageReader"); - - template<> template<> - void LLSDMessageReaderTestObject::test<1>() - // construction and test of empty LLSD - { - LLSD message = LLSD::emptyMap(); - - ensureMessageName("", message, ""); - ensureNumberOfBlocks(message, "Fakeblock", 0); - ensureMessageSize(message, 0); - } - - template<> template<> - void LLSDMessageReaderTestObject::test<2>() - // construction and test of simple message with one block - { - LLSD message = LLSD::emptyMap(); - message["block1"] = LLSD::emptyArray(); - message["block1"][0] = LLSD::emptyMap(); - message["block1"][0]["Field1"] = 0; - - ensureMessageName("name2", message, "name2"); - ensureNumberOfBlocks(message, "block1", 1); - ensureMessageSize(message, 0); - } - - template<> template<> - void LLSDMessageReaderTestObject::test<3>() - // multiple blocks - { - LLSD message = LLSD::emptyMap(); - message["block1"] = LLSD::emptyArray(); - bool bool_true = true; - bool bool_false = false; - message["block1"][0] = LLSD::emptyMap(); - message["block1"][0]["BoolField1"] = bool_true; - message["block1"][1] = LLSD::emptyMap(); - message["block1"][1]["BoolField1"] = bool_false; - message["block1"][1]["BoolField2"] = bool_true; - - ensureMessageName("name3", message, "name3"); - ensureBool(message, "block1", "BoolField1", 0, true); - ensureBool(message, "block1", "BoolField1", 1, false); - ensureBool(message, "block1", "BoolField2", 1, true); - ensureNumberOfBlocks(message, "block1", 2); - ensureMessageSize(message, 0); - } - - template<typename T> - LLSDMessageReader testType(const T& value) - { - LLSD message = LLSD::emptyMap(); - message["block"][0]["var"] = value; - LLSDMessageReader msg; - msg.setMessage("fakename", message); - return msg; - } - - template<> template<> - void LLSDMessageReaderTestObject::test<4>() - // S8 - { - S8 outValue, inValue = -3; - LLSDMessageReader msg = testType(inValue); - msg.getS8("block", "var", outValue); - ensure_equals("Ensure S8", outValue, inValue); - } - template<> template<> - void - LLSDMessageReaderTestObject::test<5>() - // U8 - { - U8 outValue, inValue = 2; - LLSDMessageReader msg = testType(inValue); - msg.getU8("block", "var", outValue); - ensure_equals("Ensure U8", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<6>() - // S16 - { - S16 outValue, inValue = 90; - LLSDMessageReader msg = testType(inValue); - msg.getS16("block", "var", outValue); - ensure_equals("Ensure S16", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<7>() - // U16 - { - U16 outValue, inValue = 3; - LLSDMessageReader msg = testType(inValue); - msg.getU16("block", "var", outValue); - ensure_equals("Ensure S16", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<8>() - // S32 - { - S32 outValue, inValue = 44; - LLSDMessageReader msg = testType(inValue); - msg.getS32("block", "var", outValue); - ensure_equals("Ensure S32", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<9>() - // F32 - { - F32 outValue, inValue = 121.44f; - LLSDMessageReader msg = testType(inValue); - msg.getF32("block", "var", outValue); - ensure_equals("Ensure F32", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<10>() - // U32 - { - U32 outValue, inValue = 88; - LLSD sdValue = ll_sd_from_U32(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getU32("block", "var", outValue); - ensure_equals("Ensure U32", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<11>() - // U64 - { - U64 outValue, inValue = 121; - LLSD sdValue = ll_sd_from_U64(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getU64("block", "var", outValue); - ensure_equals("Ensure U64", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<12>() - // F64 - { - F64 outValue, inValue = 3232143.33; - LLSDMessageReader msg = testType(inValue); - msg.getF64("block", "var", outValue); - ensure_equals("Ensure F64", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<13>() - // String - { - std::string outValue, inValue = "testing"; - LLSDMessageReader msg = testType<std::string>(inValue.c_str()); - - char buffer[MAX_STRING]; - msg.getString("block", "var", MAX_STRING, buffer); - outValue = buffer; - ensure_equals("Ensure String", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<14>() - // Vector3 - { - LLVector3 outValue, inValue = LLVector3(1,2,3); - LLSD sdValue = ll_sd_from_vector3(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getVector3("block", "var", outValue); - ensure_equals("Ensure Vector3", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<15>() - // Vector4 - { - LLVector4 outValue, inValue = LLVector4(1,2,3,4); - LLSD sdValue = ll_sd_from_vector4(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getVector4("block", "var", outValue); - ensure_equals("Ensure Vector4", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<16>() - // Vector3d - { - LLVector3d outValue, inValue = LLVector3d(1,2,3); - LLSD sdValue = ll_sd_from_vector3d(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getVector3d("block", "var", outValue); - ensure_equals("Ensure Vector3d", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<17>() - // Quaternion - { - LLQuaternion outValue, inValue = LLQuaternion(1,LLVector3(2,3,4)); - LLSD sdValue = ll_sd_from_quaternion(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getQuat("block", "var", outValue); - ensure_equals("Ensure Quaternion", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<18>() - // UUID - { - LLUUID outValue, inValue; - inValue.generate(); - LLSDMessageReader msg = testType(inValue); - msg.getUUID("block", "var", outValue); - ensure_equals("Ensure UUID", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<19>() - // IPAddr - { - U32 outValue, inValue = 12344556; - LLSD sdValue = ll_sd_from_ipaddr(inValue); - LLSDMessageReader msg = testType(sdValue); - msg.getIPAddr("block", "var", outValue); - ensure_equals("Ensure IPAddr", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<20>() - // IPPort - { - U16 outValue, inValue = 80; - LLSDMessageReader msg = testType(inValue); - msg.getIPPort("block", "var", outValue); - ensure_equals("Ensure IPPort", outValue, inValue); - } - template<> template<> - void LLSDMessageReaderTestObject::test<21>() - // Binary - { - std::vector<U8> outValue(2), inValue(2); - inValue[0] = 0; - inValue[1] = 1; - - LLSDMessageReader msg = testType(inValue); - msg.getBinaryData("block", "var", &(outValue[0]), inValue.size()); - ensure_equals("Ensure Binary", outValue, inValue); - } -} +/**
+ * @file llsdmessagereader_tut.cpp
+ * @date February 2006
+ * @brief LLSDMessageReader unit tests
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+#include "linden_common.h"
+#include "lltut.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "llquaternion.h"
+
+#include "message.h"
+#include "llsdmessagereader.h"
+#include "llsdutil.h"
+#include "llsdutil_math.h"
+
+namespace tut
+{
+ struct LLSDMessageReaderTestData {
+ static void ensureMessageName(const std::string& msg_name,
+ const LLSD& msg_data,
+ const std::string& expected_name)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage(LLMessageStringTable::getInstance()->getString(msg_name.c_str()), msg_data);
+ ensure_equals("Ensure name", std::string(msg.getMessageName()),
+ expected_name);
+ }
+
+ static void ensureNumberOfBlocks(const LLSD& msg_data,
+ const std::string& block,
+ S32 expected_number)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", msg_data);
+ ensure_equals("Ensure number of blocks", msg.getNumberOfBlocks(block.c_str()),
+ expected_number);
+ }
+
+ static void ensureMessageSize(const LLSD& msg_data,
+ S32 expected_size)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", msg_data);
+ ensure_equals( "Ensure size", msg.getMessageSize(), expected_size);
+ }
+
+ static void ensureBool(const LLSD& msg_data,
+ const std::string& block,
+ const std::string& var,
+ S32 blocknum,
+ bool expected)
+ {
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", msg_data);
+ bool test_data;
+ msg.getBOOL(block.c_str(), var.c_str(), test_data, blocknum);
+ ensure_equals( "Ensure bool field", test_data, expected);
+ }
+ };
+
+ typedef test_group<LLSDMessageReaderTestData> LLSDMessageReaderTestGroup;
+ typedef LLSDMessageReaderTestGroup::object LLSDMessageReaderTestObject;
+ LLSDMessageReaderTestGroup llsdMessageReaderTestGroup("LLSDMessageReader");
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<1>()
+ // construction and test of empty LLSD
+ {
+ LLSD message = LLSD::emptyMap();
+
+ ensureMessageName("", message, "");
+ ensureNumberOfBlocks(message, "Fakeblock", 0);
+ ensureMessageSize(message, 0);
+ }
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<2>()
+ // construction and test of simple message with one block
+ {
+ LLSD message = LLSD::emptyMap();
+ message["block1"] = LLSD::emptyArray();
+ message["block1"][0] = LLSD::emptyMap();
+ message["block1"][0]["Field1"] = 0;
+
+ ensureMessageName("name2", message, "name2");
+ ensureNumberOfBlocks(message, "block1", 1);
+ ensureMessageSize(message, 0);
+ }
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<3>()
+ // multiple blocks
+ {
+ LLSD message = LLSD::emptyMap();
+ message["block1"] = LLSD::emptyArray();
+ bool bool_true = true;
+ bool bool_false = false;
+ message["block1"][0] = LLSD::emptyMap();
+ message["block1"][0]["BoolField1"] = bool_true;
+ message["block1"][1] = LLSD::emptyMap();
+ message["block1"][1]["BoolField1"] = bool_false;
+ message["block1"][1]["BoolField2"] = bool_true;
+
+ ensureMessageName("name3", message, "name3");
+ ensureBool(message, "block1", "BoolField1", 0, true);
+ ensureBool(message, "block1", "BoolField1", 1, false);
+ ensureBool(message, "block1", "BoolField2", 1, true);
+ ensureNumberOfBlocks(message, "block1", 2);
+ ensureMessageSize(message, 0);
+ }
+
+ template<typename T>
+ LLSDMessageReader testType(const T& value)
+ {
+ LLSD message = LLSD::emptyMap();
+ message["block"][0]["var"] = value;
+ LLSDMessageReader msg;
+ msg.setMessage("fakename", message);
+ return msg;
+ }
+
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<4>()
+ // S8
+ {
+ S8 outValue, inValue = -3;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getS8("block", "var", outValue);
+ ensure_equals("Ensure S8", outValue, inValue);
+ }
+ template<> template<>
+ void
+ LLSDMessageReaderTestObject::test<5>()
+ // U8
+ {
+ U8 outValue, inValue = 2;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getU8("block", "var", outValue);
+ ensure_equals("Ensure U8", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<6>()
+ // S16
+ {
+ S16 outValue, inValue = 90;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getS16("block", "var", outValue);
+ ensure_equals("Ensure S16", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<7>()
+ // U16
+ {
+ U16 outValue, inValue = 3;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getU16("block", "var", outValue);
+ ensure_equals("Ensure S16", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<8>()
+ // S32
+ {
+ S32 outValue, inValue = 44;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getS32("block", "var", outValue);
+ ensure_equals("Ensure S32", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<9>()
+ // F32
+ {
+ F32 outValue, inValue = 121.44f;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getF32("block", "var", outValue);
+ ensure_equals("Ensure F32", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<10>()
+ // U32
+ {
+ U32 outValue, inValue = 88;
+ LLSD sdValue = ll_sd_from_U32(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getU32("block", "var", outValue);
+ ensure_equals("Ensure U32", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<11>()
+ // U64
+ {
+ U64 outValue, inValue = 121;
+ LLSD sdValue = ll_sd_from_U64(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getU64("block", "var", outValue);
+ ensure_equals("Ensure U64", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<12>()
+ // F64
+ {
+ F64 outValue, inValue = 3232143.33;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getF64("block", "var", outValue);
+ ensure_equals("Ensure F64", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<13>()
+ // String
+ {
+ std::string outValue, inValue = "testing";
+ LLSDMessageReader msg = testType<std::string>(inValue.c_str());
+
+ char buffer[MAX_STRING];
+ msg.getString("block", "var", MAX_STRING, buffer);
+ outValue = buffer;
+ ensure_equals("Ensure String", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<14>()
+ // Vector3
+ {
+ LLVector3 outValue, inValue = LLVector3(1,2,3);
+ LLSD sdValue = ll_sd_from_vector3(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getVector3("block", "var", outValue);
+ ensure_equals("Ensure Vector3", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<15>()
+ // Vector4
+ {
+ LLVector4 outValue, inValue = LLVector4(1,2,3,4);
+ LLSD sdValue = ll_sd_from_vector4(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getVector4("block", "var", outValue);
+ ensure_equals("Ensure Vector4", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<16>()
+ // Vector3d
+ {
+ LLVector3d outValue, inValue = LLVector3d(1,2,3);
+ LLSD sdValue = ll_sd_from_vector3d(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getVector3d("block", "var", outValue);
+ ensure_equals("Ensure Vector3d", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<17>()
+ // Quaternion
+ {
+ LLQuaternion outValue, inValue = LLQuaternion(1,LLVector3(2,3,4));
+ LLSD sdValue = ll_sd_from_quaternion(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getQuat("block", "var", outValue);
+ ensure_equals("Ensure Quaternion", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<18>()
+ // UUID
+ {
+ LLUUID outValue, inValue;
+ inValue.generate();
+ LLSDMessageReader msg = testType(inValue);
+ msg.getUUID("block", "var", outValue);
+ ensure_equals("Ensure UUID", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<19>()
+ // IPAddr
+ {
+ U32 outValue, inValue = 12344556;
+ LLSD sdValue = ll_sd_from_ipaddr(inValue);
+ LLSDMessageReader msg = testType(sdValue);
+ msg.getIPAddr("block", "var", outValue);
+ ensure_equals("Ensure IPAddr", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<20>()
+ // IPPort
+ {
+ U16 outValue, inValue = 80;
+ LLSDMessageReader msg = testType(inValue);
+ msg.getIPPort("block", "var", outValue);
+ ensure_equals("Ensure IPPort", outValue, inValue);
+ }
+ template<> template<>
+ void LLSDMessageReaderTestObject::test<21>()
+ // Binary
+ {
+ std::vector<U8> outValue(2), inValue(2);
+ inValue[0] = 0;
+ inValue[1] = 1;
+
+ LLSDMessageReader msg = testType(inValue);
+ msg.getBinaryData("block", "var", &(outValue[0]), inValue.size());
+ ensure_equals("Ensure Binary", outValue, inValue);
+ }
+}
diff --git a/indra/test/llsdtraits.h b/indra/test/llsdtraits.h index 07f6193ce2..c872f101d0 100644 --- a/indra/test/llsdtraits.h +++ b/indra/test/llsdtraits.h @@ -5,21 +5,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,48 +34,48 @@ template<class T> class LLSDTraits { protected: - typedef T (LLSD::*Getter)() const; - - LLSD::Type type; - Getter getter; - + typedef T (LLSD::*Getter)() const; + + LLSD::Type type; + Getter getter; + public: - LLSDTraits(); - - T get(const LLSD& actual) - { - return (actual.*getter)(); - } - - bool checkType(const LLSD& actual) - { - return actual.type() == type; - } + LLSDTraits(); + + T get(const LLSD& actual) + { + return (actual.*getter)(); + } + + bool checkType(const LLSD& actual) + { + return actual.type() == type; + } }; template<> inline LLSDTraits<LLSD::Boolean>::LLSDTraits() - : type(LLSD::TypeBoolean), getter(&LLSD::asBoolean) + : type(LLSD::TypeBoolean), getter(&LLSD::asBoolean) { } template<> inline LLSDTraits<LLSD::Integer>::LLSDTraits() - : type(LLSD::TypeInteger), getter(&LLSD::asInteger) + : type(LLSD::TypeInteger), getter(&LLSD::asInteger) { } template<> inline LLSDTraits<LLSD::Real>::LLSDTraits() - : type(LLSD::TypeReal), getter(&LLSD::asReal) + : type(LLSD::TypeReal), getter(&LLSD::asReal) { } template<> inline LLSDTraits<LLSD::UUID>::LLSDTraits() - : type(LLSD::TypeUUID), getter(&LLSD::asUUID) + : type(LLSD::TypeUUID), getter(&LLSD::asUUID) { } template<> inline LLSDTraits<LLSD::String>::LLSDTraits() - : type(LLSD::TypeString), getter(&LLSD::asString) + : type(LLSD::TypeString), getter(&LLSD::asString) { } template<> @@ -84,17 +84,17 @@ class LLSDTraits<const char*> : public LLSDTraits<LLSD::String> template<> inline LLSDTraits<LLSD::Date>::LLSDTraits() - : type(LLSD::TypeDate), getter(&LLSD::asDate) + : type(LLSD::TypeDate), getter(&LLSD::asDate) { } template<> inline LLSDTraits<LLSD::URI>::LLSDTraits() - : type(LLSD::TypeURI), getter(&LLSD::asURI) + : type(LLSD::TypeURI), getter(&LLSD::asURI) { } template<> inline LLSDTraits<const LLSD::Binary&>::LLSDTraits() - : type(LLSD::TypeBinary), getter(&LLSD::asBinary) + : type(LLSD::TypeBinary), getter(&LLSD::asBinary) { } #endif // LLSDTRAITS_H diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp index 22efd5439a..4b25a02f30 100644 --- a/indra/test/llsdutil_tut.cpp +++ b/indra/test/llsdutil_tut.cpp @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -45,8 +45,8 @@ namespace tut { - struct llsdutil_data - { + struct llsdutil_data + { void test_matches(const std::string& proto_key, const LLSD& possibles, const char** begin, const char** end) { @@ -74,115 +74,115 @@ namespace tut } } } - }; - typedef test_group<llsdutil_data> llsdutil_test;; - typedef llsdutil_test::object llsdutil_object; - tut::llsdutil_test tutil("llsdutil"); - - template<> template<> - void llsdutil_object::test<1>() - { - LLSD sd; - U64 valueIn , valueOut; - valueIn = U64L(0xFEDCBA9876543210); - sd = ll_sd_from_U64(valueIn); - valueOut = ll_U64_from_sd(sd); - ensure_equals("U64 valueIn->sd->valueOut", valueIn, valueOut); - } - - template<> template<> - void llsdutil_object::test<2>() - { - LLSD sd; - U32 valueIn, valueOut; - valueIn = 0x87654321; - sd = ll_sd_from_U32(valueIn); - valueOut = ll_U32_from_sd(sd); - ensure_equals("U32 valueIn->sd->valueOut", valueIn, valueOut); - } - - template<> template<> - void llsdutil_object::test<3>() - { - U32 valueIn, valueOut; - valueIn = 0x87654321; - LLSD sd; - sd = ll_sd_from_ipaddr(valueIn); - valueOut = ll_ipaddr_from_sd(sd); - ensure_equals("valueIn->sd->valueOut", valueIn, valueOut); - } - - template<> template<> - void llsdutil_object::test<4>() - { - LLSD sd; - LLVector3 vec1(-1.0, 2.0, -3.0); - sd = ll_sd_from_vector3(vec1); - LLVector3 vec2 = ll_vector3_from_sd(sd); - ensure_equals("vector3 -> sd -> vector3: 1", vec1, vec2); - - LLVector3 vec3(sd); - ensure_equals("vector3 -> sd -> vector3: 2", vec1, vec3); - - sd.clear(); - vec1.setVec(0., 0., 0.); - sd = ll_sd_from_vector3(vec1); - vec2 = ll_vector3_from_sd(sd); - ensure_equals("vector3 -> sd -> vector3: 3", vec1, vec2); - sd.clear(); - } - - template<> template<> - void llsdutil_object::test<5>() - { - LLSD sd; - LLVector3d vec1((F64)(U64L(0xFEDCBA9876543210) << 2), -1., 0); - sd = ll_sd_from_vector3d(vec1); - LLVector3d vec2 = ll_vector3d_from_sd(sd); - ensure_equals("vector3d -> sd -> vector3d: 1", vec1, vec2); - - LLVector3d vec3(sd); - ensure_equals("vector3d -> sd -> vector3d : 2", vec1, vec3); - } - - template<> template<> - void llsdutil_object::test<6>() - { - LLSD sd; - LLVector2 vec((F32) -3., (F32) 4.2); - sd = ll_sd_from_vector2(vec); - LLVector2 vec1 = ll_vector2_from_sd(sd); - ensure_equals("vector2 -> sd -> vector2", vec, vec1); - - LLSD sd2 = ll_sd_from_vector2(vec1); - ensure_equals("sd -> vector2 -> sd: 2", sd, sd2); - } - - template<> template<> - void llsdutil_object::test<7>() - { - LLSD sd; - LLQuaternion quat((F32) 1., (F32) -0.98, (F32) 2.3, (F32) 0xffff); - sd = ll_sd_from_quaternion(quat); - LLQuaternion quat1 = ll_quaternion_from_sd(sd); - ensure_equals("LLQuaternion -> sd -> LLQuaternion", quat, quat1); - - LLSD sd2 = ll_sd_from_quaternion(quat1); - ensure_equals("sd -> LLQuaternion -> sd ", sd, sd2); - } - - template<> template<> - void llsdutil_object::test<8>() - { - LLSD sd; - LLColor4 c(1.0f, 2.2f, 4.0f, 7.f); - sd = ll_sd_from_color4(c); - LLColor4 c1 =ll_color4_from_sd(sd); - ensure_equals("LLColor4 -> sd -> LLColor4", c, c1); - - LLSD sd1 = ll_sd_from_color4(c1); - ensure_equals("sd -> LLColor4 -> sd", sd, sd1); - } + }; + typedef test_group<llsdutil_data> llsdutil_test;; + typedef llsdutil_test::object llsdutil_object; + tut::llsdutil_test tutil("llsdutil"); + + template<> template<> + void llsdutil_object::test<1>() + { + LLSD sd; + U64 valueIn , valueOut; + valueIn = U64L(0xFEDCBA9876543210); + sd = ll_sd_from_U64(valueIn); + valueOut = ll_U64_from_sd(sd); + ensure_equals("U64 valueIn->sd->valueOut", valueIn, valueOut); + } + + template<> template<> + void llsdutil_object::test<2>() + { + LLSD sd; + U32 valueIn, valueOut; + valueIn = 0x87654321; + sd = ll_sd_from_U32(valueIn); + valueOut = ll_U32_from_sd(sd); + ensure_equals("U32 valueIn->sd->valueOut", valueIn, valueOut); + } + + template<> template<> + void llsdutil_object::test<3>() + { + U32 valueIn, valueOut; + valueIn = 0x87654321; + LLSD sd; + sd = ll_sd_from_ipaddr(valueIn); + valueOut = ll_ipaddr_from_sd(sd); + ensure_equals("valueIn->sd->valueOut", valueIn, valueOut); + } + + template<> template<> + void llsdutil_object::test<4>() + { + LLSD sd; + LLVector3 vec1(-1.0, 2.0, -3.0); + sd = ll_sd_from_vector3(vec1); + LLVector3 vec2 = ll_vector3_from_sd(sd); + ensure_equals("vector3 -> sd -> vector3: 1", vec1, vec2); + + LLVector3 vec3(sd); + ensure_equals("vector3 -> sd -> vector3: 2", vec1, vec3); + + sd.clear(); + vec1.setVec(0., 0., 0.); + sd = ll_sd_from_vector3(vec1); + vec2 = ll_vector3_from_sd(sd); + ensure_equals("vector3 -> sd -> vector3: 3", vec1, vec2); + sd.clear(); + } + + template<> template<> + void llsdutil_object::test<5>() + { + LLSD sd; + LLVector3d vec1((F64)(U64L(0xFEDCBA9876543210) << 2), -1., 0); + sd = ll_sd_from_vector3d(vec1); + LLVector3d vec2 = ll_vector3d_from_sd(sd); + ensure_equals("vector3d -> sd -> vector3d: 1", vec1, vec2); + + LLVector3d vec3(sd); + ensure_equals("vector3d -> sd -> vector3d : 2", vec1, vec3); + } + + template<> template<> + void llsdutil_object::test<6>() + { + LLSD sd; + LLVector2 vec((F32) -3., (F32) 4.2); + sd = ll_sd_from_vector2(vec); + LLVector2 vec1 = ll_vector2_from_sd(sd); + ensure_equals("vector2 -> sd -> vector2", vec, vec1); + + LLSD sd2 = ll_sd_from_vector2(vec1); + ensure_equals("sd -> vector2 -> sd: 2", sd, sd2); + } + + template<> template<> + void llsdutil_object::test<7>() + { + LLSD sd; + LLQuaternion quat((F32) 1., (F32) -0.98, (F32) 2.3, (F32) 0xffff); + sd = ll_sd_from_quaternion(quat); + LLQuaternion quat1 = ll_quaternion_from_sd(sd); + ensure_equals("LLQuaternion -> sd -> LLQuaternion", quat, quat1); + + LLSD sd2 = ll_sd_from_quaternion(quat1); + ensure_equals("sd -> LLQuaternion -> sd ", sd, sd2); + } + + template<> template<> + void llsdutil_object::test<8>() + { + LLSD sd; + LLColor4 c(1.0f, 2.2f, 4.0f, 7.f); + sd = ll_sd_from_color4(c); + LLColor4 c1 =ll_color4_from_sd(sd); + ensure_equals("LLColor4 -> sd -> LLColor4", c, c1); + + LLSD sd1 = ll_sd_from_color4(c1); + ensure_equals("sd -> LLColor4 -> sd", sd, sd1); + } template<> template<> void llsdutil_object::test<9>() @@ -387,7 +387,7 @@ namespace tut ensure("llsd_equals(superset left map)", ! llsd_equals(lmap, rmap)); } - template<> template<> + template<> template<> void llsdutil_object::test<10>() { set_test_name("llsd_hashing"); diff --git a/indra/test/llservicebuilder_tut.cpp b/indra/test/llservicebuilder_tut.cpp index 8f5be3011c..0bc17865d6 100644 --- a/indra/test/llservicebuilder_tut.cpp +++ b/indra/test/llservicebuilder_tut.cpp @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. -* +* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. -* +* * This library 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 * Lesser General Public License for more details. -* +* * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* +* * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,139 +35,139 @@ namespace tut { - struct ServiceBuilderTestData { - LLServiceBuilder mServiceBuilder; - }; - - typedef test_group<ServiceBuilderTestData> ServiceBuilderTestGroup; - typedef ServiceBuilderTestGroup::object ServiceBuilderTestObject; - - ServiceBuilderTestGroup serviceBuilderTestGroup("ServiceBuilder"); - - template<> template<> - void ServiceBuilderTestObject::test<1>() - { - //Simple service build and reply with no mapping - LLSD test_block; - test_block["service-builder"] = "/agent/name"; - mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); - std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest"); - ensure_equals("Basic URL Creation", test_url , "/agent/name"); - } - - template<> template<> - void ServiceBuilderTestObject::test<2>() - { - //Simple replace test - LLSD test_block; - test_block["service-builder"] = "/agent/{$agent-id}/name"; - mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); - LLSD data_map; - data_map["agent-id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6"; - std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); - ensure_equals("Replacement URL Creation", test_url , "/agent/257c631f-a0c5-4f29-8a9f-9031feaae6c6/name"); - } - - template<> template<> - void ServiceBuilderTestObject::test<3>() - { - //Incorrect service test - LLSD test_block; - test_block["service-builder"] = "/agent/{$agent-id}/name"; - mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); - std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilder"); - ensure_equals("Replacement URL Creation for Non-existant Service", test_url , ""); - } - - template<> template<> - void ServiceBuilderTestObject::test<4>() - { - //Incorrect service test - LLSD test_block; - test_block["service-builder"] = "/agent/{$agent-id}/name"; - mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); - LLSD data_map; - data_map["agent_id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6"; - std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); - ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "/agent/{$agent-id}/name"); - } - - template<> template<> - void ServiceBuilderTestObject::test<5>() - { - LLSD test_block; - test_block["service-builder"] = "/proc/{$proc}{%params}"; - mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); - LLSD data_map; - data_map["proc"] = "do/something/useful"; - data_map["params"]["estate_id"] = 1; - data_map["params"]["query"] = "public"; - std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); - ensure_equals( - "two part URL Creation", - test_url , - "/proc/do/something/useful?estate_id=1&query=public"); - } - - template<> template<> - void ServiceBuilderTestObject::test<6>() - { - LLSD test_block; - test_block["service-builder"] = "Which way to the {${$baz}}?"; - mServiceBuilder.createServiceDefinition( - "ServiceBuilderTest", - test_block["service-builder"]); - - LLSD data_map; - data_map["foo"] = "bar"; - data_map["baz"] = "foo"; - std::string test_url = mServiceBuilder.buildServiceURI( - "ServiceBuilderTest", - data_map); - ensure_equals( - "recursive url creation", - test_url , - "Which way to the bar?"); - } - - template<> template<> - void ServiceBuilderTestObject::test<7>() - { - LLSD test_block; - test_block["service-builder"] = "Which way to the {$foo}?"; - mServiceBuilder.createServiceDefinition( - "ServiceBuilderTest", - test_block["service-builder"]); - - LLSD data_map; - data_map["baz"] = "foo"; - std::string test_url = mServiceBuilder.buildServiceURI( - "ServiceBuilderTest", - data_map); - ensure_equals( - "fails to do replacement", - test_url , - "Which way to the {$foo}?"); - } - - template<> template<> - void ServiceBuilderTestObject::test<8>() - { - LLSD test_block; - test_block["service-builder"] = "/proc/{$proc}{%params}"; - mServiceBuilder.createServiceDefinition( - "ServiceBuilderTest", - test_block["service-builder"]); - LLSD data_map; - data_map["proc"] = "do/something/useful"; - data_map["params"] = LLSD(); - std::string test_url = mServiceBuilder.buildServiceURI( - "ServiceBuilderTest", - data_map); - ensure_equals( - "strip params", - test_url , - "/proc/do/something/useful"); - } + struct ServiceBuilderTestData { + LLServiceBuilder mServiceBuilder; + }; + + typedef test_group<ServiceBuilderTestData> ServiceBuilderTestGroup; + typedef ServiceBuilderTestGroup::object ServiceBuilderTestObject; + + ServiceBuilderTestGroup serviceBuilderTestGroup("ServiceBuilder"); + + template<> template<> + void ServiceBuilderTestObject::test<1>() + { + //Simple service build and reply with no mapping + LLSD test_block; + test_block["service-builder"] = "/agent/name"; + mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); + std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest"); + ensure_equals("Basic URL Creation", test_url , "/agent/name"); + } + + template<> template<> + void ServiceBuilderTestObject::test<2>() + { + //Simple replace test + LLSD test_block; + test_block["service-builder"] = "/agent/{$agent-id}/name"; + mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); + LLSD data_map; + data_map["agent-id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6"; + std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); + ensure_equals("Replacement URL Creation", test_url , "/agent/257c631f-a0c5-4f29-8a9f-9031feaae6c6/name"); + } + + template<> template<> + void ServiceBuilderTestObject::test<3>() + { + //Incorrect service test + LLSD test_block; + test_block["service-builder"] = "/agent/{$agent-id}/name"; + mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); + std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilder"); + ensure_equals("Replacement URL Creation for Non-existant Service", test_url , ""); + } + + template<> template<> + void ServiceBuilderTestObject::test<4>() + { + //Incorrect service test + LLSD test_block; + test_block["service-builder"] = "/agent/{$agent-id}/name"; + mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); + LLSD data_map; + data_map["agent_id"] = "257c631f-a0c5-4f29-8a9f-9031feaae6c6"; + std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); + ensure_equals("Replacement URL Creation for Non-existant Service", test_url , "/agent/{$agent-id}/name"); + } + + template<> template<> + void ServiceBuilderTestObject::test<5>() + { + LLSD test_block; + test_block["service-builder"] = "/proc/{$proc}{%params}"; + mServiceBuilder.createServiceDefinition("ServiceBuilderTest", test_block["service-builder"]); + LLSD data_map; + data_map["proc"] = "do/something/useful"; + data_map["params"]["estate_id"] = 1; + data_map["params"]["query"] = "public"; + std::string test_url = mServiceBuilder.buildServiceURI("ServiceBuilderTest", data_map); + ensure_equals( + "two part URL Creation", + test_url , + "/proc/do/something/useful?estate_id=1&query=public"); + } + + template<> template<> + void ServiceBuilderTestObject::test<6>() + { + LLSD test_block; + test_block["service-builder"] = "Which way to the {${$baz}}?"; + mServiceBuilder.createServiceDefinition( + "ServiceBuilderTest", + test_block["service-builder"]); + + LLSD data_map; + data_map["foo"] = "bar"; + data_map["baz"] = "foo"; + std::string test_url = mServiceBuilder.buildServiceURI( + "ServiceBuilderTest", + data_map); + ensure_equals( + "recursive url creation", + test_url , + "Which way to the bar?"); + } + + template<> template<> + void ServiceBuilderTestObject::test<7>() + { + LLSD test_block; + test_block["service-builder"] = "Which way to the {$foo}?"; + mServiceBuilder.createServiceDefinition( + "ServiceBuilderTest", + test_block["service-builder"]); + + LLSD data_map; + data_map["baz"] = "foo"; + std::string test_url = mServiceBuilder.buildServiceURI( + "ServiceBuilderTest", + data_map); + ensure_equals( + "fails to do replacement", + test_url , + "Which way to the {$foo}?"); + } + + template<> template<> + void ServiceBuilderTestObject::test<8>() + { + LLSD test_block; + test_block["service-builder"] = "/proc/{$proc}{%params}"; + mServiceBuilder.createServiceDefinition( + "ServiceBuilderTest", + test_block["service-builder"]); + LLSD data_map; + data_map["proc"] = "do/something/useful"; + data_map["params"] = LLSD(); + std::string test_url = mServiceBuilder.buildServiceURI( + "ServiceBuilderTest", + data_map); + ensure_equals( + "strip params", + test_url , + "/proc/do/something/useful"); + } } diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp index 2f027b688f..68bd5e0ec9 100644 --- a/indra/test/llstreamtools_tut.cpp +++ b/indra/test/llstreamtools_tut.cpp @@ -7,25 +7,25 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + #include <tut/tut.hpp> #include "linden_common.h" @@ -35,849 +35,849 @@ namespace tut { - struct streamtools_data - { - }; - typedef test_group<streamtools_data> streamtools_test; - typedef streamtools_test::object streamtools_object; - tut::streamtools_test streamtools_testcase("streamtools"); - - //test cases for skip_whitespace() - template<> template<> - void streamtools_object::test<1>() - { - char arr[255]; - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - - is.str(str = ""); - ensure("skip_whitespace: empty string", (false == skip_whitespace(is))); - - is.clear(); - is.str(str = " SecondLife is a 3D World"); - skip_whitespace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World"; - ensure_equals("skip_whitespace: space", arr, expected_result); - - is.clear(); - is.str(str = "\t \tSecondLife is a 3D World"); - skip_whitespace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World"; - ensure_equals("skip_whitespace: space and tabs", arr, expected_result); - - is.clear(); - is.str(str = "\t \tSecondLife is a 3D World "); - skip_whitespace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World "; - ensure_equals("skip_whitespace: space at end", arr, expected_result); - - is.clear(); - is.str(str = "\t \r\nSecondLife is a 3D World"); - skip_whitespace(is); - is.get(arr, 255, '\0'); - expected_result = "\r\nSecondLife is a 3D World"; - ensure_equals("skip_whitespace: space at end", arr, expected_result); - } - - //testcases for skip_emptyspaces() - template<> template<> - void streamtools_object::test<2>() - { - char arr[255]; - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = " \tSecondLife is a 3D World.\n"); - skip_emptyspace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World.\n"; - ensure_equals("skip_emptyspace: space and tabs", arr, expected_result); - - is.clear(); - is.str(str = " \t\r\n \r SecondLife is a 3D World.\n"); - skip_emptyspace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World.\n"; - ensure_equals("skip_emptyspace: space, tabs, carriage return, newline", arr, expected_result); - - is.clear(); - is.str(str = ""); - ret = skip_emptyspace(is); - is.get(arr, 255, '\0'); - ensure("skip_emptyspace: empty string", ret == false); - - is.clear(); - is.str(str = " \r\n \t "); - ret = skip_emptyspace(is); - is.get(arr, 255, '\0'); - ensure("skip_emptyspace: space newline empty", ret == false); - } - - //testcases for skip_comments_and_emptyspace() - template<> template<> - void streamtools_object::test<3>() - { - char arr[255]; - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = " \t\r\n \r SecondLife is a 3D World.\n"); - skip_comments_and_emptyspace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World.\n"; - ensure_equals("skip_comments_and_emptyspace: space, tabs, carriage return, newline", arr, expected_result); - - is.clear(); - is.str(str = "# \r\n SecondLife is a 3D World."); - skip_comments_and_emptyspace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World."; - ensure_equals("skip_comments_and_emptyspace: skip comment - 1", arr, expected_result); - - is.clear(); - is.str(str = "# \r\n # SecondLife is a 3D World. ##"); - ensure("should not be good()", ! skip_comments_and_emptyspace(is)); - ensure("should be at eof()", is.eof()); - // don't get(): given bad state, we can't rely on results - - is.clear(); - is.str(str = " \r\n SecondLife is a 3D World. ##"); - skip_comments_and_emptyspace(is); - is.get(arr, 255, '\0'); - expected_result = "SecondLife is a 3D World. ##"; - ensure_equals("skip_comments_and_emptyspace: skip comment - 3", arr, expected_result); - - is.clear(); - is.str(str = ""); - ret = skip_comments_and_emptyspace(is); - ensure("skip_comments_and_emptyspace: empty string", ! ret); - - is.clear(); - is.str(str = " \r\n \t # SecondLife is a 3D World"); - ret = skip_comments_and_emptyspace(is); - ensure("skip_comments_and_emptyspace: space newline comment empty", ! ret); - } - - //testcases for skip_line() - template<> template<> - void streamtools_object::test<4>() - { - char arr[255]; - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = "SecondLife is a 3D World.\n\n It provides an opportunity to the site \nuser to perform real life activities in virtual world."); - skip_line(is); - is.get(arr, 255, '\0'); - expected_result = "\n It provides an opportunity to the site \nuser to perform real life activities in virtual world."; - ensure_equals("skip_line: 1 newline", arr, expected_result); - - is.clear(); - is.str(expected_result); - skip_line(is); - is.get(arr, 255, '\0'); - expected_result = " It provides an opportunity to the site \nuser to perform real life activities in virtual world."; - ensure_equals("skip_line: 2 newline", arr, expected_result); - - is.clear(); - is.str(expected_result); - skip_line(is); - is.get(arr, 255, '\0'); - expected_result = "user to perform real life activities in virtual world."; - ensure_equals("skip_line: 3 newline", arr, expected_result); - - is.clear(); - is.str(str = ""); - ret = skip_line(is); - ensure("skip_line: empty string", ret == false); - } - - - // testcases for skip_to_next_word() - template<> template<> - void streamtools_object::test<5>() - { - char arr[255]; - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = "SecondLife is a 3D_World.\n\n It-provides an opportunity to the site \nuser to perform real life activities in virtual world."); - skip_to_next_word(is); // get past SecondLife - is.get(arr, 255, '\0'); - expected_result = "is a 3D_World.\n\n It-provides an opportunity to the site \nuser to perform real life activities in virtual world."; - ensure_equals("skip_to_next_word: 1", arr, expected_result); - - is.clear(); - is.str(expected_result); - skip_to_next_word(is); // get past is - skip_to_next_word(is); // get past a - skip_to_next_word(is); // get past 3D_World.\n\n - is.get(arr, 255, '\0'); - expected_result = "It-provides an opportunity to the site \nuser to perform real life activities in virtual world."; - ensure_equals("skip_to_next_word: get past .\n\n 2", arr, expected_result); - - is.clear(); - is.str(expected_result); - skip_to_next_word(is); // get past It- - expected_result = "provides an opportunity to the site \nuser to perform real life activities in virtual world."; - is.get(arr, 255, '\0'); - ensure_equals("skip_to_next_word: get past -", arr, expected_result); - - is.clear(); - is.str(str = ""); - ret = skip_to_next_word(is); - ensure("skip_line: empty string", ret == false); - - is.clear(); - is.str(str = " \r\n\r\n"); - ret = skip_to_next_word(is); - ensure("skip_line: space new lines", ret == false); - } - - - //testcases for skip_to_end_of_next_keyword() - template<> template<> - void streamtools_object::test<6>() - { - char arr[255]; - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = "FIRSTKEY followed by second delimiter\nSECONDKEY\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld."); - ret = skip_to_end_of_next_keyword("FIRSTKEY", is); - is.get(arr, 255, '\0'); - expected_result = " followed by second delimiter\nSECONDKEY\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld."; - ensure_equals("skip_to_end_of_next_keyword: 1", arr, expected_result); - - is.clear(); - is.str(expected_result); - ret = skip_to_end_of_next_keyword("SECONDKEY", is); - is.get(arr, 255, '\0'); - expected_result = "\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld."; - ensure_equals("skip_to_end_of_next_keyword: 2", arr, expected_result); - - is.clear(); - is.str(expected_result); - ret = skip_to_end_of_next_keyword("SECONDKEY", is); - is.get(arr, 255, '\0'); - expected_result = "\nFOURTHKEY FOURTHVALUEis a 3DWorld."; - ensure_equals("skip_to_end_of_next_keyword: 3", arr, expected_result); - - is.clear(); - is.str(expected_result); - ret = skip_to_end_of_next_keyword("FOURTHKEY", is); - is.get(arr, 255, '\0'); - expected_result = " FOURTHVALUEis a 3DWorld."; - ensure_equals("skip_to_end_of_next_keyword: 4", arr, expected_result); - - is.clear(); - is.str(str = "{should be skipped as newline/space/tab does not follow but this one should be picked\n { Does it?\n"); - ret = skip_to_end_of_next_keyword("{", is); - is.get(arr, 255, '\0'); - expected_result = " Does it?\n"; - ensure_equals("skip_to_end_of_next_keyword: multiple delim matches on same line", arr, expected_result); - - is.clear(); - is.str(str = "Delim { could not be found at start"); - ret = skip_to_end_of_next_keyword("{", is); - ensure("skip_to_end_of_next_keyword: delim should not be present", ret == false); - - is.clear(); - is.str(str = "Empty Delim"); - ret = skip_to_end_of_next_keyword("", is); - ensure("skip_to_end_of_next_keyword: empty delim should not be valid", ret == false); - - is.clear(); - is.str(str = ""); - ret = skip_to_end_of_next_keyword("}", is); - ensure("skip_to_end_of_next_keyword: empty string", ret == false); - } - - //testcases for get_word(std::string& output_string, std::istream& input_stream) - template<> template<> - void streamtools_object::test<7>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n"); - actual_result = ""; - ret = get_word(actual_result, is); - expected_result = "First"; - ensure_equals("get_word: 1", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is); - expected_result = "Second"; - ensure_equals("get_word: 2", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is); - expected_result = "Third"; - ensure_equals("get_word: 3", actual_result, expected_result); - - // the current implementation of get_word seems inconsistent with - // skip_to_next_word. skip_to_next_word treats any character other - // than alhpa-numeric and '_' as a delimter, while get_word() - // treats only isspace() (i.e. space, form-feed('\f'), newline ('\n'), - // carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v') - // as delimiters - actual_result = ""; - ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth - expected_result = "Fourth-ShouldThisBePartOfFourth"; // as per current impl. - ensure_equals("get_word: 4", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is); // will copy Fifth - expected_result = "Fifth"; // as per current impl. - ensure_equals("get_word: 5", actual_result, expected_result); - - is.clear(); - is.str(str = " \t \r \n "); - actual_result = ""; - ret = get_word(actual_result, is); - ensure("get_word: empty all spaces, newline tabs", ret == false); - - is.clear(); - is.str(str = ""); - actual_result = ""; - ret = get_word(actual_result, is); - ensure("get_word: empty string", ret == false); - } - - // testcase for get_word and skip_to_next_word compatibility - template<> template<> - void streamtools_object::test<8>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - - is.clear(); - is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n"); - actual_result = ""; - get_word(actual_result, is); // First - actual_result = ""; - get_word(actual_result, is); // Second - actual_result = ""; - get_word(actual_result, is); // Third - - // the current implementation of get_word seems inconsistent with - // skip_to_next_word. skip_to_next_word treats any character other - // than alhpa-numeric and '_' as a delimter, while get_word() - // treats only isspace() (i.e. space, form-feed('\f'), newline ('\n'), - // carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v') - // as delimiters - actual_result = ""; - get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth - - actual_result = ""; - get_word(actual_result, is); // will copy Fifth - - is.clear(); - is.str(str = " First Second \t \r \n Third Fourth_ShouldThisBePartOfFourth Fifth\n"); - skip_to_next_word(is); // should now point to First - skip_to_next_word(is); // should now point to Second - skip_to_next_word(is); // should now point to Third - skip_to_next_word(is); // should now point to Fourth - skip_to_next_word(is); // should now point to ShouldThisBePartOfFourth - expected_result = ""; - // will copy ShouldThisBePartOfFourth, the fifth word, - // while using get_word above five times result in getting "Fifth" - get_word(expected_result, is); - ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result); - } - - //testcases for get_word(std::string& output_string, std::istream& input_stream, int n) - template<> template<> - void streamtools_object::test<9>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n"); - actual_result = ""; - ret = get_word(actual_result, is, 255); - expected_result = "First"; - ensure_equals("get_word: 1", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is, 4); - expected_result = "Seco"; // should be cut short - ensure_equals("get_word: 2", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is, 255); - expected_result = "nd"; // get remainder of Second - ensure_equals("get_word: 3", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is, 0); // 0 size string - expected_result = ""; // get remainder of Second - ensure_equals("get_word: 0 sized output", actual_result, expected_result); - - actual_result = ""; - ret = get_word(actual_result, is, 255); - expected_result = "Third"; - ensure_equals("get_word: 4", actual_result, expected_result); - - is.clear(); - is.str(str = " \t \r \n "); - actual_result = ""; - ret = get_word(actual_result, is, 255); - ensure("get_word: empty all spaces, newline tabs", ret == false); - - is.clear(); - is.str(str = ""); - actual_result = ""; - ret = get_word(actual_result, is, 255); - ensure("get_word: empty string", ret == false); - } - - //test cases for get_line(std::string& output_string, std::istream& input_stream) - template<> template<> - void streamtools_object::test<10>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - - is.clear(); - is.str(str = "First Second \t \r\n Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n"); - actual_result = ""; - get_line(actual_result, is); - expected_result = "First Second \t \r\n"; - ensure_equals("get_line: 1", actual_result, expected_result); - - actual_result = ""; - get_line(actual_result, is); - expected_result = " Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n"; - ensure_equals("get_line: 2", actual_result, expected_result); - - is.clear(); - is.str(str = "\nFirst Line.\n\nSecond Line.\n"); - actual_result = ""; - get_line(actual_result, is); - expected_result = "\n"; - ensure_equals("get_line: First char as newline", actual_result, expected_result); - - actual_result = ""; - get_line(actual_result, is); - expected_result = "First Line.\n"; - ensure_equals("get_line: 3", actual_result, expected_result); - - actual_result = ""; - get_line(actual_result, is); - expected_result = "\n"; - ensure_equals("get_line: 4", actual_result, expected_result); - - actual_result = ""; - get_line(actual_result, is); - expected_result = "Second Line.\n"; - ensure_equals("get_line: 5", actual_result, expected_result); - } - - //test cases for get_line(std::string& output_string, std::istream& input_stream) - template<> template<> - void streamtools_object::test<11>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = "One Line only with no newline"); - actual_result = ""; - ret = get_line(actual_result, is); - expected_result = "One Line only with no newline"; - ensure_equals("get_line: No newline", actual_result, expected_result); - ensure_equals("return value is good state of stream", ret, is.good()); - } - - //test cases for get_line(std::string& output_string, std::istream& input_stream) - template<> template<> - void streamtools_object::test<12>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - - // need to be check if this test case is wrong or the implementation is wrong. - is.clear(); - is.str(str = "Should not skip lone \r.\r\n"); - actual_result = ""; - get_line(actual_result, is); - expected_result = "Should not skip lone \r.\r\n"; - ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result); - } - - //test cases for get_line(std::string& output_string, std::istream& input_stream) - template<> template<> - void streamtools_object::test<13>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - - is.clear(); - is.str(str = "\n"); - actual_result = ""; - get_line(actual_result, is); - expected_result = "\n"; - ensure_equals("get_line: Just newline", actual_result, expected_result); - } - - - //testcases for get_line(std::string& output_string, std::istream& input_stream, int n) - template<> template<> - void streamtools_object::test<14>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - - is.clear(); - is.str(str = "First Line.\nSecond Line.\n"); - actual_result = ""; - get_line(actual_result, is, 255); - expected_result = "First Line.\n"; - ensure_equals("get_line: Basic Operation", actual_result, expected_result); - - actual_result = ""; - get_line(actual_result, is, sizeof("Second")-1); - expected_result = "Second\n"; - ensure_equals("get_line: Insufficient length 1", actual_result, expected_result); - - actual_result = ""; - get_line(actual_result, is, 255); - expected_result = " Line.\n"; - ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result); - - is.clear(); - is.str(str = "One Line only with no newline with limited length"); - actual_result = ""; - get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1); - expected_result = "One Line only with no newline with limited length\n"; - ensure_equals("get_line: No newline with limited length", actual_result, expected_result); - - is.clear(); - is.str(str = "One Line only with no newline"); - actual_result = ""; - get_line(actual_result, is, 255); - expected_result = "One Line only with no newline"; - ensure_equals("get_line: No newline", actual_result, expected_result); - } - - //testcases for get_line(std::string& output_string, std::istream& input_stream, int n) - template<> template<> - void streamtools_object::test<15>() - { - std::string str; - std::string expected_result; - std::string actual_result; - std::istringstream is; - bool ret; - - is.clear(); - is.str(str = "One Line only with no newline"); - actual_result = ""; - ret = get_line(actual_result, is, 255); - expected_result = "One Line only with no newline"; - ensure_equals("get_line: No newline", actual_result, expected_result); - ensure_equals("return value is good state of stream", ret, is.good()); - } - - //testcases for remove_last_char() - template<> template<> - void streamtools_object::test<16>() - { - std::string str; - std::string expected_result; - bool ret; - - str = "SecondLife is a 3D World"; - - ret = remove_last_char('d',str); - expected_result = "SecondLife is a 3D Worl"; - ensure_equals("remove_last_char: should remove last char", str, expected_result); - - str = "SecondLife is a 3D World"; - ret = remove_last_char('W',str); - expected_result = "SecondLife is a 3D World"; - ensure_equals("remove_last_char: should not remove as it is not last char", str, expected_result); - ensure("remove_last_char: should return false", ret == false); - - str = "SecondLife is a 3D World\n"; - ret = remove_last_char('\n',str); - expected_result = "SecondLife is a 3D World"; - ensure_equals("remove_last_char: should remove last newline", str, expected_result); - ensure("remove_last_char: should remove newline and return true", ret == true); - } - - - //testcases for unescaped_string() - template<> template<> - void streamtools_object::test<17>() - { - std::string str; - std::string expected_result; - - str = "SecondLife is a 3D world \\n"; - unescape_string(str); - expected_result = "SecondLife is a 3D world \n"; - ensure_equals("unescape_string: newline", str, expected_result); - - str = "SecondLife is a 3D world \\\\t \\n"; - unescape_string(str); - expected_result = "SecondLife is a 3D world \\t \n"; - ensure_equals("unescape_string: backslash and newline", str, expected_result); - - str = "SecondLife is a 3D world \\ "; - unescape_string(str); - expected_result = "SecondLife is a 3D world \\ "; - ensure_equals("unescape_string: insufficient to unescape", str, expected_result); - - str = "SecondLife is a 3D world \\n \\n \\n \\\\\\n"; - unescape_string(str); - expected_result = "SecondLife is a 3D world \n \n \n \\\n"; - ensure_equals("unescape_string: multipel newline and backslash", str, expected_result); - - str = "SecondLife is a 3D world \\t"; - unescape_string(str); - expected_result = "SecondLife is a 3D world \\t"; - ensure_equals("unescape_string: leaves tab as is", str, expected_result); - - str = "\\n"; - unescape_string(str); - expected_result = "\n"; - ensure_equals("unescape_string: only a newline", str, expected_result); - } - - //testcases for escape_string() - template<> template<> - void streamtools_object::test<18>() - { - std::string str; - std::string expected_result; - - str = "SecondLife is a 3D world \n"; - escape_string(str); - expected_result = "SecondLife is a 3D world \\n"; - ensure_equals("escape_string: newline", str, expected_result); - - str = "SecondLife is a 3D world \\t \n"; - escape_string(str); - expected_result = "SecondLife is a 3D world \\\\t \\n"; - ensure_equals("escape_string: backslash and newline", str, expected_result); - - str = "SecondLife is a 3D world \n \n \n \\\n"; - escape_string(str); - expected_result = "SecondLife is a 3D world \\n \\n \\n \\\\\\n"; - ensure_equals("escape_string: multipel newline and backslash", str, expected_result); - - str = "SecondLife is a 3D world \t"; - escape_string(str); - expected_result = "SecondLife is a 3D world \t"; - ensure_equals("unescape_string: leaves tab as is", str, expected_result); - - str = "\n"; - escape_string(str); - expected_result = "\\n"; - ensure_equals("unescape_string: only a newline", str, expected_result); - - // serialization/deserialization escape->unescape - str = "SecondLife is a 3D world \n \n \n \\\n"; - escape_string(str); - unescape_string(str); - expected_result = "SecondLife is a 3D world \n \n \n \\\n"; - ensure_equals("escape_string: should preserve with escape/unescape", str, expected_result); - - // serialization/deserialization unescape->escape - str = "SecondLife is a 3D world \\n \\n \\n \\\\"; - unescape_string(str); - escape_string(str); - expected_result = "SecondLife is a 3D world \\n \\n \\n \\\\"; - ensure_equals("escape_string: should preserve with unescape/escape", str, expected_result); - } - - // testcases for replace_newlines_with_whitespace() - template<> template<> - void streamtools_object::test<19>() - { - std::string str; - std::string expected_result; - - str = "SecondLife is a 3D \n\nworld\n"; - replace_newlines_with_whitespace(str); - expected_result = "SecondLife is a 3D world "; - ensure_equals("replace_newlines_with_whitespace: replace all newline", str, expected_result); - - str = "\nSecondLife is a 3D world\n"; - replace_newlines_with_whitespace(str); - expected_result = " SecondLife is a 3D world "; - ensure_equals("replace_newlines_with_whitespace: begin and newline", str, expected_result); - - str = "SecondLife is a 3D world\r\t"; - replace_newlines_with_whitespace(str); - expected_result = "SecondLife is a 3D world\r\t"; - ensure_equals("replace_newlines_with_whitespace: should only replace newline", str, expected_result); - - str = ""; - replace_newlines_with_whitespace(str); - expected_result = ""; - ensure_equals("replace_newlines_with_whitespace: empty string", str, expected_result); - } - - //testcases for remove_double_quotes() - template<> template<> - void streamtools_object::test<20>() - { - std::string str; - std::string expected_result; - - str = "SecondLife is a \"\"3D world"; - remove_double_quotes(str); - expected_result = "SecondLife is a 3D world"; - ensure_equals("remove_double_quotes: replace empty doube quotes", str, expected_result); - - str = "SecondLife is a \"3D world"; - remove_double_quotes(str); - expected_result = "SecondLife is a 3D world"; - ensure_equals("remove_double_quotes: keep as is it matching quote not found", str, expected_result); - } - - // testcases for get_brace_count() - template<> template<> - void streamtools_object::test<21>() - { - } - - //testcases for get_keyword_and_value() - template<> template<> - void streamtools_object::test<22>() - { - std::string s = "SecondLife is a 3D World"; - std::string keyword; - std::string value; - get_keyword_and_value(keyword, value, s); - ensure("get_keyword_and_value: Unable to get Keyword and Value", ((keyword == "SecondLife") && (value == "is a 3D World"))); - - s = "SecondLife"; - get_keyword_and_value(keyword, value, s); - ensure("get_keyword_and_value: value should be empty", ((keyword == "SecondLife") && (value == ""))); - - s = "SecondLife \t is cool! \n"; - get_keyword_and_value(keyword, value, s); - ensure("get_keyword_and_value: remove space before value but not after", ((keyword == "SecondLife") && (value == "is cool! "))); - } - - //testcases for get_keyword_and_value() - template<> template<> - void streamtools_object::test<23>() - { - std::string s; - std::string keyword = "SOME PRIOR KEYWORD"; - std::string value = "SOME PRIOR VALUE"; - - s = "SecondLife\n"; - get_keyword_and_value(keyword, value, s); - ensure("get_keyword_and_value: terminated with newline. value should be empty", ((keyword == "SecondLife") && (value == ""))); - } - - //testcases for get_keyword_and_value() - template<> template<> - void streamtools_object::test<24>() - { - std::string s; - std::string keyword = "SOME PRIOR KEYWORD"; - std::string value = "SOME PRIOR VALUE"; - - s = ""; - get_keyword_and_value(keyword, value, s); - ensure("get_keyword_and_value: empty string. keyword value should empty", ((keyword == "") && (value == ""))); - } - - //testcase for fullread() - template<> template<> - void streamtools_object::test<25>() - { - std::string str = "First Line.\nSecond Line\n"; - std::istringstream is(str); - char buf[255] = {0}; - - fullread(is, buf, 255); - ensure_memory_matches("fullread: read with newlines", (void*) buf, str.size()-1, (void*) str.c_str(), str.size()-1); - - is.clear(); - is.str(str = "First Line.\nSecond Line\n"); - memset(buf, 0, 255); - - char expected_string[] = "First Line.\nSecond"; - int len = sizeof(expected_string)-1; - fullread(is, buf, len); - ensure_memory_matches("fullread: read with newlines", (void*) buf, len, (void*) &expected_string, len); - } + struct streamtools_data + { + }; + typedef test_group<streamtools_data> streamtools_test; + typedef streamtools_test::object streamtools_object; + tut::streamtools_test streamtools_testcase("streamtools"); + + //test cases for skip_whitespace() + template<> template<> + void streamtools_object::test<1>() + { + char arr[255]; + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + + is.str(str = ""); + ensure("skip_whitespace: empty string", (false == skip_whitespace(is))); + + is.clear(); + is.str(str = " SecondLife is a 3D World"); + skip_whitespace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World"; + ensure_equals("skip_whitespace: space", arr, expected_result); + + is.clear(); + is.str(str = "\t \tSecondLife is a 3D World"); + skip_whitespace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World"; + ensure_equals("skip_whitespace: space and tabs", arr, expected_result); + + is.clear(); + is.str(str = "\t \tSecondLife is a 3D World "); + skip_whitespace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World "; + ensure_equals("skip_whitespace: space at end", arr, expected_result); + + is.clear(); + is.str(str = "\t \r\nSecondLife is a 3D World"); + skip_whitespace(is); + is.get(arr, 255, '\0'); + expected_result = "\r\nSecondLife is a 3D World"; + ensure_equals("skip_whitespace: space at end", arr, expected_result); + } + + //testcases for skip_emptyspaces() + template<> template<> + void streamtools_object::test<2>() + { + char arr[255]; + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = " \tSecondLife is a 3D World.\n"); + skip_emptyspace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World.\n"; + ensure_equals("skip_emptyspace: space and tabs", arr, expected_result); + + is.clear(); + is.str(str = " \t\r\n \r SecondLife is a 3D World.\n"); + skip_emptyspace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World.\n"; + ensure_equals("skip_emptyspace: space, tabs, carriage return, newline", arr, expected_result); + + is.clear(); + is.str(str = ""); + ret = skip_emptyspace(is); + is.get(arr, 255, '\0'); + ensure("skip_emptyspace: empty string", ret == false); + + is.clear(); + is.str(str = " \r\n \t "); + ret = skip_emptyspace(is); + is.get(arr, 255, '\0'); + ensure("skip_emptyspace: space newline empty", ret == false); + } + + //testcases for skip_comments_and_emptyspace() + template<> template<> + void streamtools_object::test<3>() + { + char arr[255]; + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = " \t\r\n \r SecondLife is a 3D World.\n"); + skip_comments_and_emptyspace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World.\n"; + ensure_equals("skip_comments_and_emptyspace: space, tabs, carriage return, newline", arr, expected_result); + + is.clear(); + is.str(str = "# \r\n SecondLife is a 3D World."); + skip_comments_and_emptyspace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World."; + ensure_equals("skip_comments_and_emptyspace: skip comment - 1", arr, expected_result); + + is.clear(); + is.str(str = "# \r\n # SecondLife is a 3D World. ##"); + ensure("should not be good()", ! skip_comments_and_emptyspace(is)); + ensure("should be at eof()", is.eof()); + // don't get(): given bad state, we can't rely on results + + is.clear(); + is.str(str = " \r\n SecondLife is a 3D World. ##"); + skip_comments_and_emptyspace(is); + is.get(arr, 255, '\0'); + expected_result = "SecondLife is a 3D World. ##"; + ensure_equals("skip_comments_and_emptyspace: skip comment - 3", arr, expected_result); + + is.clear(); + is.str(str = ""); + ret = skip_comments_and_emptyspace(is); + ensure("skip_comments_and_emptyspace: empty string", ! ret); + + is.clear(); + is.str(str = " \r\n \t # SecondLife is a 3D World"); + ret = skip_comments_and_emptyspace(is); + ensure("skip_comments_and_emptyspace: space newline comment empty", ! ret); + } + + //testcases for skip_line() + template<> template<> + void streamtools_object::test<4>() + { + char arr[255]; + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = "SecondLife is a 3D World.\n\n It provides an opportunity to the site \nuser to perform real life activities in virtual world."); + skip_line(is); + is.get(arr, 255, '\0'); + expected_result = "\n It provides an opportunity to the site \nuser to perform real life activities in virtual world."; + ensure_equals("skip_line: 1 newline", arr, expected_result); + + is.clear(); + is.str(expected_result); + skip_line(is); + is.get(arr, 255, '\0'); + expected_result = " It provides an opportunity to the site \nuser to perform real life activities in virtual world."; + ensure_equals("skip_line: 2 newline", arr, expected_result); + + is.clear(); + is.str(expected_result); + skip_line(is); + is.get(arr, 255, '\0'); + expected_result = "user to perform real life activities in virtual world."; + ensure_equals("skip_line: 3 newline", arr, expected_result); + + is.clear(); + is.str(str = ""); + ret = skip_line(is); + ensure("skip_line: empty string", ret == false); + } + + + // testcases for skip_to_next_word() + template<> template<> + void streamtools_object::test<5>() + { + char arr[255]; + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = "SecondLife is a 3D_World.\n\n It-provides an opportunity to the site \nuser to perform real life activities in virtual world."); + skip_to_next_word(is); // get past SecondLife + is.get(arr, 255, '\0'); + expected_result = "is a 3D_World.\n\n It-provides an opportunity to the site \nuser to perform real life activities in virtual world."; + ensure_equals("skip_to_next_word: 1", arr, expected_result); + + is.clear(); + is.str(expected_result); + skip_to_next_word(is); // get past is + skip_to_next_word(is); // get past a + skip_to_next_word(is); // get past 3D_World.\n\n + is.get(arr, 255, '\0'); + expected_result = "It-provides an opportunity to the site \nuser to perform real life activities in virtual world."; + ensure_equals("skip_to_next_word: get past .\n\n 2", arr, expected_result); + + is.clear(); + is.str(expected_result); + skip_to_next_word(is); // get past It- + expected_result = "provides an opportunity to the site \nuser to perform real life activities in virtual world."; + is.get(arr, 255, '\0'); + ensure_equals("skip_to_next_word: get past -", arr, expected_result); + + is.clear(); + is.str(str = ""); + ret = skip_to_next_word(is); + ensure("skip_line: empty string", ret == false); + + is.clear(); + is.str(str = " \r\n\r\n"); + ret = skip_to_next_word(is); + ensure("skip_line: space new lines", ret == false); + } + + + //testcases for skip_to_end_of_next_keyword() + template<> template<> + void streamtools_object::test<6>() + { + char arr[255]; + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = "FIRSTKEY followed by second delimiter\nSECONDKEY\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld."); + ret = skip_to_end_of_next_keyword("FIRSTKEY", is); + is.get(arr, 255, '\0'); + expected_result = " followed by second delimiter\nSECONDKEY\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld."; + ensure_equals("skip_to_end_of_next_keyword: 1", arr, expected_result); + + is.clear(); + is.str(expected_result); + ret = skip_to_end_of_next_keyword("SECONDKEY", is); + is.get(arr, 255, '\0'); + expected_result = "\t SecondValue followed by third delimiter \nSECONDKEY\nFOURTHKEY FOURTHVALUEis a 3DWorld."; + ensure_equals("skip_to_end_of_next_keyword: 2", arr, expected_result); + + is.clear(); + is.str(expected_result); + ret = skip_to_end_of_next_keyword("SECONDKEY", is); + is.get(arr, 255, '\0'); + expected_result = "\nFOURTHKEY FOURTHVALUEis a 3DWorld."; + ensure_equals("skip_to_end_of_next_keyword: 3", arr, expected_result); + + is.clear(); + is.str(expected_result); + ret = skip_to_end_of_next_keyword("FOURTHKEY", is); + is.get(arr, 255, '\0'); + expected_result = " FOURTHVALUEis a 3DWorld."; + ensure_equals("skip_to_end_of_next_keyword: 4", arr, expected_result); + + is.clear(); + is.str(str = "{should be skipped as newline/space/tab does not follow but this one should be picked\n { Does it?\n"); + ret = skip_to_end_of_next_keyword("{", is); + is.get(arr, 255, '\0'); + expected_result = " Does it?\n"; + ensure_equals("skip_to_end_of_next_keyword: multiple delim matches on same line", arr, expected_result); + + is.clear(); + is.str(str = "Delim { could not be found at start"); + ret = skip_to_end_of_next_keyword("{", is); + ensure("skip_to_end_of_next_keyword: delim should not be present", ret == false); + + is.clear(); + is.str(str = "Empty Delim"); + ret = skip_to_end_of_next_keyword("", is); + ensure("skip_to_end_of_next_keyword: empty delim should not be valid", ret == false); + + is.clear(); + is.str(str = ""); + ret = skip_to_end_of_next_keyword("}", is); + ensure("skip_to_end_of_next_keyword: empty string", ret == false); + } + + //testcases for get_word(std::string& output_string, std::istream& input_stream) + template<> template<> + void streamtools_object::test<7>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n"); + actual_result = ""; + ret = get_word(actual_result, is); + expected_result = "First"; + ensure_equals("get_word: 1", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is); + expected_result = "Second"; + ensure_equals("get_word: 2", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is); + expected_result = "Third"; + ensure_equals("get_word: 3", actual_result, expected_result); + + // the current implementation of get_word seems inconsistent with + // skip_to_next_word. skip_to_next_word treats any character other + // than alhpa-numeric and '_' as a delimter, while get_word() + // treats only isspace() (i.e. space, form-feed('\f'), newline ('\n'), + // carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v') + // as delimiters + actual_result = ""; + ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth + expected_result = "Fourth-ShouldThisBePartOfFourth"; // as per current impl. + ensure_equals("get_word: 4", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is); // will copy Fifth + expected_result = "Fifth"; // as per current impl. + ensure_equals("get_word: 5", actual_result, expected_result); + + is.clear(); + is.str(str = " \t \r \n "); + actual_result = ""; + ret = get_word(actual_result, is); + ensure("get_word: empty all spaces, newline tabs", ret == false); + + is.clear(); + is.str(str = ""); + actual_result = ""; + ret = get_word(actual_result, is); + ensure("get_word: empty string", ret == false); + } + + // testcase for get_word and skip_to_next_word compatibility + template<> template<> + void streamtools_object::test<8>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + + is.clear(); + is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n"); + actual_result = ""; + get_word(actual_result, is); // First + actual_result = ""; + get_word(actual_result, is); // Second + actual_result = ""; + get_word(actual_result, is); // Third + + // the current implementation of get_word seems inconsistent with + // skip_to_next_word. skip_to_next_word treats any character other + // than alhpa-numeric and '_' as a delimter, while get_word() + // treats only isspace() (i.e. space, form-feed('\f'), newline ('\n'), + // carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v') + // as delimiters + actual_result = ""; + get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth + + actual_result = ""; + get_word(actual_result, is); // will copy Fifth + + is.clear(); + is.str(str = " First Second \t \r \n Third Fourth_ShouldThisBePartOfFourth Fifth\n"); + skip_to_next_word(is); // should now point to First + skip_to_next_word(is); // should now point to Second + skip_to_next_word(is); // should now point to Third + skip_to_next_word(is); // should now point to Fourth + skip_to_next_word(is); // should now point to ShouldThisBePartOfFourth + expected_result = ""; + // will copy ShouldThisBePartOfFourth, the fifth word, + // while using get_word above five times result in getting "Fifth" + get_word(expected_result, is); + ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result); + } + + //testcases for get_word(std::string& output_string, std::istream& input_stream, int n) + template<> template<> + void streamtools_object::test<9>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = " First Second \t \r \n Third Fourth-ShouldThisBePartOfFourth Fifth\n"); + actual_result = ""; + ret = get_word(actual_result, is, 255); + expected_result = "First"; + ensure_equals("get_word: 1", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is, 4); + expected_result = "Seco"; // should be cut short + ensure_equals("get_word: 2", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is, 255); + expected_result = "nd"; // get remainder of Second + ensure_equals("get_word: 3", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is, 0); // 0 size string + expected_result = ""; // get remainder of Second + ensure_equals("get_word: 0 sized output", actual_result, expected_result); + + actual_result = ""; + ret = get_word(actual_result, is, 255); + expected_result = "Third"; + ensure_equals("get_word: 4", actual_result, expected_result); + + is.clear(); + is.str(str = " \t \r \n "); + actual_result = ""; + ret = get_word(actual_result, is, 255); + ensure("get_word: empty all spaces, newline tabs", ret == false); + + is.clear(); + is.str(str = ""); + actual_result = ""; + ret = get_word(actual_result, is, 255); + ensure("get_word: empty string", ret == false); + } + + //test cases for get_line(std::string& output_string, std::istream& input_stream) + template<> template<> + void streamtools_object::test<10>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + + is.clear(); + is.str(str = "First Second \t \r\n Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n"); + actual_result = ""; + get_line(actual_result, is); + expected_result = "First Second \t \r\n"; + ensure_equals("get_line: 1", actual_result, expected_result); + + actual_result = ""; + get_line(actual_result, is); + expected_result = " Third Fourth-ShouldThisBePartOfFourth IsThisFifth\n"; + ensure_equals("get_line: 2", actual_result, expected_result); + + is.clear(); + is.str(str = "\nFirst Line.\n\nSecond Line.\n"); + actual_result = ""; + get_line(actual_result, is); + expected_result = "\n"; + ensure_equals("get_line: First char as newline", actual_result, expected_result); + + actual_result = ""; + get_line(actual_result, is); + expected_result = "First Line.\n"; + ensure_equals("get_line: 3", actual_result, expected_result); + + actual_result = ""; + get_line(actual_result, is); + expected_result = "\n"; + ensure_equals("get_line: 4", actual_result, expected_result); + + actual_result = ""; + get_line(actual_result, is); + expected_result = "Second Line.\n"; + ensure_equals("get_line: 5", actual_result, expected_result); + } + + //test cases for get_line(std::string& output_string, std::istream& input_stream) + template<> template<> + void streamtools_object::test<11>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = "One Line only with no newline"); + actual_result = ""; + ret = get_line(actual_result, is); + expected_result = "One Line only with no newline"; + ensure_equals("get_line: No newline", actual_result, expected_result); + ensure_equals("return value is good state of stream", ret, is.good()); + } + + //test cases for get_line(std::string& output_string, std::istream& input_stream) + template<> template<> + void streamtools_object::test<12>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + + // need to be check if this test case is wrong or the implementation is wrong. + is.clear(); + is.str(str = "Should not skip lone \r.\r\n"); + actual_result = ""; + get_line(actual_result, is); + expected_result = "Should not skip lone \r.\r\n"; + ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result); + } + + //test cases for get_line(std::string& output_string, std::istream& input_stream) + template<> template<> + void streamtools_object::test<13>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + + is.clear(); + is.str(str = "\n"); + actual_result = ""; + get_line(actual_result, is); + expected_result = "\n"; + ensure_equals("get_line: Just newline", actual_result, expected_result); + } + + + //testcases for get_line(std::string& output_string, std::istream& input_stream, int n) + template<> template<> + void streamtools_object::test<14>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + + is.clear(); + is.str(str = "First Line.\nSecond Line.\n"); + actual_result = ""; + get_line(actual_result, is, 255); + expected_result = "First Line.\n"; + ensure_equals("get_line: Basic Operation", actual_result, expected_result); + + actual_result = ""; + get_line(actual_result, is, sizeof("Second")-1); + expected_result = "Second\n"; + ensure_equals("get_line: Insufficient length 1", actual_result, expected_result); + + actual_result = ""; + get_line(actual_result, is, 255); + expected_result = " Line.\n"; + ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result); + + is.clear(); + is.str(str = "One Line only with no newline with limited length"); + actual_result = ""; + get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1); + expected_result = "One Line only with no newline with limited length\n"; + ensure_equals("get_line: No newline with limited length", actual_result, expected_result); + + is.clear(); + is.str(str = "One Line only with no newline"); + actual_result = ""; + get_line(actual_result, is, 255); + expected_result = "One Line only with no newline"; + ensure_equals("get_line: No newline", actual_result, expected_result); + } + + //testcases for get_line(std::string& output_string, std::istream& input_stream, int n) + template<> template<> + void streamtools_object::test<15>() + { + std::string str; + std::string expected_result; + std::string actual_result; + std::istringstream is; + bool ret; + + is.clear(); + is.str(str = "One Line only with no newline"); + actual_result = ""; + ret = get_line(actual_result, is, 255); + expected_result = "One Line only with no newline"; + ensure_equals("get_line: No newline", actual_result, expected_result); + ensure_equals("return value is good state of stream", ret, is.good()); + } + + //testcases for remove_last_char() + template<> template<> + void streamtools_object::test<16>() + { + std::string str; + std::string expected_result; + bool ret; + + str = "SecondLife is a 3D World"; + + ret = remove_last_char('d',str); + expected_result = "SecondLife is a 3D Worl"; + ensure_equals("remove_last_char: should remove last char", str, expected_result); + + str = "SecondLife is a 3D World"; + ret = remove_last_char('W',str); + expected_result = "SecondLife is a 3D World"; + ensure_equals("remove_last_char: should not remove as it is not last char", str, expected_result); + ensure("remove_last_char: should return false", ret == false); + + str = "SecondLife is a 3D World\n"; + ret = remove_last_char('\n',str); + expected_result = "SecondLife is a 3D World"; + ensure_equals("remove_last_char: should remove last newline", str, expected_result); + ensure("remove_last_char: should remove newline and return true", ret == true); + } + + + //testcases for unescaped_string() + template<> template<> + void streamtools_object::test<17>() + { + std::string str; + std::string expected_result; + + str = "SecondLife is a 3D world \\n"; + unescape_string(str); + expected_result = "SecondLife is a 3D world \n"; + ensure_equals("unescape_string: newline", str, expected_result); + + str = "SecondLife is a 3D world \\\\t \\n"; + unescape_string(str); + expected_result = "SecondLife is a 3D world \\t \n"; + ensure_equals("unescape_string: backslash and newline", str, expected_result); + + str = "SecondLife is a 3D world \\ "; + unescape_string(str); + expected_result = "SecondLife is a 3D world \\ "; + ensure_equals("unescape_string: insufficient to unescape", str, expected_result); + + str = "SecondLife is a 3D world \\n \\n \\n \\\\\\n"; + unescape_string(str); + expected_result = "SecondLife is a 3D world \n \n \n \\\n"; + ensure_equals("unescape_string: multipel newline and backslash", str, expected_result); + + str = "SecondLife is a 3D world \\t"; + unescape_string(str); + expected_result = "SecondLife is a 3D world \\t"; + ensure_equals("unescape_string: leaves tab as is", str, expected_result); + + str = "\\n"; + unescape_string(str); + expected_result = "\n"; + ensure_equals("unescape_string: only a newline", str, expected_result); + } + + //testcases for escape_string() + template<> template<> + void streamtools_object::test<18>() + { + std::string str; + std::string expected_result; + + str = "SecondLife is a 3D world \n"; + escape_string(str); + expected_result = "SecondLife is a 3D world \\n"; + ensure_equals("escape_string: newline", str, expected_result); + + str = "SecondLife is a 3D world \\t \n"; + escape_string(str); + expected_result = "SecondLife is a 3D world \\\\t \\n"; + ensure_equals("escape_string: backslash and newline", str, expected_result); + + str = "SecondLife is a 3D world \n \n \n \\\n"; + escape_string(str); + expected_result = "SecondLife is a 3D world \\n \\n \\n \\\\\\n"; + ensure_equals("escape_string: multipel newline and backslash", str, expected_result); + + str = "SecondLife is a 3D world \t"; + escape_string(str); + expected_result = "SecondLife is a 3D world \t"; + ensure_equals("unescape_string: leaves tab as is", str, expected_result); + + str = "\n"; + escape_string(str); + expected_result = "\\n"; + ensure_equals("unescape_string: only a newline", str, expected_result); + + // serialization/deserialization escape->unescape + str = "SecondLife is a 3D world \n \n \n \\\n"; + escape_string(str); + unescape_string(str); + expected_result = "SecondLife is a 3D world \n \n \n \\\n"; + ensure_equals("escape_string: should preserve with escape/unescape", str, expected_result); + + // serialization/deserialization unescape->escape + str = "SecondLife is a 3D world \\n \\n \\n \\\\"; + unescape_string(str); + escape_string(str); + expected_result = "SecondLife is a 3D world \\n \\n \\n \\\\"; + ensure_equals("escape_string: should preserve with unescape/escape", str, expected_result); + } + + // testcases for replace_newlines_with_whitespace() + template<> template<> + void streamtools_object::test<19>() + { + std::string str; + std::string expected_result; + + str = "SecondLife is a 3D \n\nworld\n"; + replace_newlines_with_whitespace(str); + expected_result = "SecondLife is a 3D world "; + ensure_equals("replace_newlines_with_whitespace: replace all newline", str, expected_result); + + str = "\nSecondLife is a 3D world\n"; + replace_newlines_with_whitespace(str); + expected_result = " SecondLife is a 3D world "; + ensure_equals("replace_newlines_with_whitespace: begin and newline", str, expected_result); + + str = "SecondLife is a 3D world\r\t"; + replace_newlines_with_whitespace(str); + expected_result = "SecondLife is a 3D world\r\t"; + ensure_equals("replace_newlines_with_whitespace: should only replace newline", str, expected_result); + + str = ""; + replace_newlines_with_whitespace(str); + expected_result = ""; + ensure_equals("replace_newlines_with_whitespace: empty string", str, expected_result); + } + + //testcases for remove_double_quotes() + template<> template<> + void streamtools_object::test<20>() + { + std::string str; + std::string expected_result; + + str = "SecondLife is a \"\"3D world"; + remove_double_quotes(str); + expected_result = "SecondLife is a 3D world"; + ensure_equals("remove_double_quotes: replace empty doube quotes", str, expected_result); + + str = "SecondLife is a \"3D world"; + remove_double_quotes(str); + expected_result = "SecondLife is a 3D world"; + ensure_equals("remove_double_quotes: keep as is it matching quote not found", str, expected_result); + } + + // testcases for get_brace_count() + template<> template<> + void streamtools_object::test<21>() + { + } + + //testcases for get_keyword_and_value() + template<> template<> + void streamtools_object::test<22>() + { + std::string s = "SecondLife is a 3D World"; + std::string keyword; + std::string value; + get_keyword_and_value(keyword, value, s); + ensure("get_keyword_and_value: Unable to get Keyword and Value", ((keyword == "SecondLife") && (value == "is a 3D World"))); + + s = "SecondLife"; + get_keyword_and_value(keyword, value, s); + ensure("get_keyword_and_value: value should be empty", ((keyword == "SecondLife") && (value == ""))); + + s = "SecondLife \t is cool! \n"; + get_keyword_and_value(keyword, value, s); + ensure("get_keyword_and_value: remove space before value but not after", ((keyword == "SecondLife") && (value == "is cool! "))); + } + + //testcases for get_keyword_and_value() + template<> template<> + void streamtools_object::test<23>() + { + std::string s; + std::string keyword = "SOME PRIOR KEYWORD"; + std::string value = "SOME PRIOR VALUE"; + + s = "SecondLife\n"; + get_keyword_and_value(keyword, value, s); + ensure("get_keyword_and_value: terminated with newline. value should be empty", ((keyword == "SecondLife") && (value == ""))); + } + + //testcases for get_keyword_and_value() + template<> template<> + void streamtools_object::test<24>() + { + std::string s; + std::string keyword = "SOME PRIOR KEYWORD"; + std::string value = "SOME PRIOR VALUE"; + + s = ""; + get_keyword_and_value(keyword, value, s); + ensure("get_keyword_and_value: empty string. keyword value should empty", ((keyword == "") && (value == ""))); + } + + //testcase for fullread() + template<> template<> + void streamtools_object::test<25>() + { + std::string str = "First Line.\nSecond Line\n"; + std::istringstream is(str); + char buf[255] = {0}; + + fullread(is, buf, 255); + ensure_memory_matches("fullread: read with newlines", (void*) buf, str.size()-1, (void*) str.c_str(), str.size()-1); + + is.clear(); + is.str(str = "First Line.\nSecond Line\n"); + memset(buf, 0, 255); + + char expected_string[] = "First Line.\nSecond"; + int len = sizeof(expected_string)-1; + fullread(is, buf, len); + ensure_memory_matches("fullread: read with newlines", (void*) buf, len, (void*) &expected_string, len); + } // testcases for operator >> - template<> template<> - void streamtools_object::test<26>() - { - char arr[255]; - std::string str; - std::string toCheck = "SecondLife" ; - std::string expected_result; - std::istringstream stream("SecondLife is a 3D World"); - stream >> toCheck.c_str(); - stream.get(arr, 255, '\0'); - expected_result = " is a 3D World"; - ensure_equals("istream << operator", arr, expected_result); - - stream.clear(); - stream.str(str = "SecondLife is a 3D World"); - toCheck = "is"; - stream >> toCheck.c_str(); - ensure("istream << operator should have failed", stream.good() == false); - } + template<> template<> + void streamtools_object::test<26>() + { + char arr[255]; + std::string str; + std::string toCheck = "SecondLife" ; + std::string expected_result; + std::istringstream stream("SecondLife is a 3D World"); + stream >> toCheck.c_str(); + stream.get(arr, 255, '\0'); + expected_result = " is a 3D World"; + ensure_equals("istream << operator", arr, expected_result); + + stream.clear(); + stream.str(str = "SecondLife is a 3D World"); + toCheck = "is"; + stream >> toCheck.c_str(); + ensure("istream << operator should have failed", stream.good() == false); + } } diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp index c7b953b99e..d4a59249cc 100644 --- a/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/indra/test/lltemplatemessagebuilder_tut.cpp @@ -1,971 +1,971 @@ -/** - * @file lltemplatemessagebuilder_tut.cpp - * @date 2007-04 - * @brief Tests for building messages. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> -#include "linden_common.h" -#include "lltut.h" - -#include "llapr.h" -#include "llmessagetemplate.h" -#include "llmath.h" -#include "llquaternion.h" -#include "lltemplatemessagebuilder.h" -#include "lltemplatemessagereader.h" -#include "message_prehash.h" -#include "u64.h" -#include "v3dmath.h" -#include "v3math.h" -#include "v4math.h" - -namespace tut -{ - static LLTemplateMessageBuilder::message_template_name_map_t nameMap; - static LLTemplateMessageReader::message_template_number_map_t numberMap; - - struct LLTemplateMessageBuilderTestData - { - static LLMessageTemplate defaultTemplate() - { - static bool init = false; - if(! init) - { - ll_init_apr(); - const F32 circuit_heartbeat_interval=5; - const F32 circuit_timeout=100; - - start_messaging_system("notafile", 13035, - 1, - 0, - 0, - false, - "notasharedsecret", - NULL, - false, - circuit_heartbeat_interval, - circuit_timeout); - //init_prehash_data(); - init = true; - } - return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH); - } - - static LLMessageBlock* defaultBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) - { - return createBlock(const_cast<char*>(_PREHASH_Test0), type, size, block); - } - - static LLMessageBlock* createBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) - { - LLMessageBlock* result = new LLMessageBlock(name, block); - if(type != MVT_NULL) - { - result->addVariable(const_cast<char*>(_PREHASH_Test0), type, size); - } - return result; - } - - static LLTemplateMessageBuilder* defaultBuilder(LLMessageTemplate& messageTemplate, char* name = const_cast<char*>(_PREHASH_Test0)) - { - nameMap[_PREHASH_TestMessage] = &messageTemplate; - LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(nameMap); - builder->newMessage(_PREHASH_TestMessage); - builder->nextBlock(name); - return builder; - } - - /** Takes ownership of builder */ - static LLTemplateMessageReader* setReader( - LLMessageTemplate& messageTemplate, - LLTemplateMessageBuilder* builder, - U8 offset = 0) - { - numberMap[1] = &messageTemplate; - const U32 bufferSize = 1024; - U8 buffer[bufferSize]; - // zero out the packet ID field - memset(buffer, 0, LL_PACKET_ID_SIZE); - U32 builtSize = builder->buildMessage(buffer, bufferSize, offset); - delete builder; - LLTemplateMessageReader* reader = new LLTemplateMessageReader(numberMap); - reader->validateMessage(buffer, builtSize, LLHost()); - reader->readMessage(buffer, LLHost()); - return reader; - } - - }; - - typedef test_group<LLTemplateMessageBuilderTestData> LLTemplateMessageBuilderTestGroup; - typedef LLTemplateMessageBuilderTestGroup::object LLTemplateMessageBuilderTestObject; - LLTemplateMessageBuilderTestGroup templateMessageBuilderTestGroup("LLTemplateMessageBuilder"); - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<1>() - // construction and test of undefined - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock()); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<2>() - // bool - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1)); - bool outValue, inValue = true; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addBOOL(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure bool", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<3>() - // U8 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U8, 1)); - U8 outValue, inValue = 2; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU8(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U8", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<4>() - // S16 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_S16, 2)); - S16 outValue, inValue = 90; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addS16(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S16", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<5>() - // U16 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U16, 2)); - U16 outValue, inValue = 3; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU16(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U16", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<6>() - // S32 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_S32, 4)); - S32 outValue, inValue = 44; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addS32(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S32", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<7>() - // F32 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_F32, 4)); - F32 outValue, inValue = 121.44f; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addF32(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F32", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<8>() - // U32 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U32, 4)); - U32 outValue, inValue = 88; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U32", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<9>() - // U64 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U64, 8)); - U64 outValue, inValue = 121; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU64(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U64", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<10>() - // F64 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_F64, 8)); - F64 outValue, inValue = 3232143.33; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addF64(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F64", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<11>() - // Vector3 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12)); - LLVector3 outValue, inValue = LLVector3(1,2,3); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addVector3(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<12>() - // Vector4 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16)); - LLVector4 outValue, inValue = LLVector4(1,2,3,4); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addVector4(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector4", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<13>() - // Vector3d - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24)); - LLVector3d outValue, inValue = LLVector3d(1,2,3); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addVector3d(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3d", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<14>() - // Quaternion - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12)); - LLQuaternion outValue, inValue = LLQuaternion(0.0f, LLVector3(0.3713907f, 0.5570861f, 0.7427813f)); - - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addQuat(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLQuaternion", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<15>() - // UUID - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16)); - LLUUID outValue, inValue; - inValue.generate(); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addUUID(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure UUID", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<16>() - // IPAddr - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4)); - U32 outValue, inValue = 12344556; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addIPAddr(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPAddr", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<17>() - // IPPort - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2)); - U16 outValue, inValue = 80; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addIPPort(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPPort", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<18>() - // String - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1)); - std::string outValue, inValue = "testing"; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addString(_PREHASH_Test0, inValue.c_str()); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - char buffer[MAX_STRING]; - reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer); - outValue = buffer; - ensure_equals("Ensure String", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<19>() - // block name !-> binary order - { - U8 buffer1[MAX_BUFFER_SIZE]; - memset(buffer1, 0, MAX_BUFFER_SIZE); - U8 buffer2[MAX_BUFFER_SIZE]; - memset(buffer2, 0, MAX_BUFFER_SIZE); - U32 bufferSize1, bufferSize2; - - // build template: Test0 before Test1 - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE)); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE)); - - // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0)); - builder->addU32(_PREHASH_Test0, 0xaaaa); - builder->nextBlock(_PREHASH_Test1); - builder->addU32(_PREHASH_Test0, 0xbbbb); - bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0); - delete builder; - - // build template: Test1 before Test0 - messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE)); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE)); - - // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb - builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test1)); - builder->addU32(_PREHASH_Test0, 0xaaaa); - builder->nextBlock(_PREHASH_Test0); - builder->addU32(_PREHASH_Test0, 0xbbbb); - bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0); - delete builder; - - ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2); - ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0); - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<20>() - // block build order !-> binary order - { - U8 buffer1[MAX_BUFFER_SIZE]; - memset(buffer1, 0, MAX_BUFFER_SIZE); - U8 buffer2[MAX_BUFFER_SIZE]; - memset(buffer2, 0, MAX_BUFFER_SIZE); - U32 bufferSize1, bufferSize2; - - // build template: Test0 before Test1 - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE)); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE)); - - // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0)); - builder->addU32(_PREHASH_Test0, 0xaaaa); - builder->nextBlock(_PREHASH_Test1); - builder->addU32(_PREHASH_Test0, 0xbbbb); - bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0); - delete builder; - - // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb - builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test1)); - builder->addU32(_PREHASH_Test0, 0xbbbb); - builder->nextBlock(_PREHASH_Test0); - builder->addU32(_PREHASH_Test0, 0xaaaa); - bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0); - delete builder; - - ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2); - ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0); - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<21>() - // block appended in declaration -> data appended in binary - { - U8 buffer1[MAX_BUFFER_SIZE]; - memset(buffer1, 0, MAX_BUFFER_SIZE); - U8 buffer2[MAX_BUFFER_SIZE]; - memset(buffer2, 0, MAX_BUFFER_SIZE); - U32 bufferSize1, bufferSize2; - - // Build template: Test0 only - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE)); - - // Build message - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0)); - builder->addU32(_PREHASH_Test0, 0xaaaa); - bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0); - delete builder; - - // Build template: Test0 before Test1 - messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE)); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE)); - - // Build message - builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0)); - builder->addU32(_PREHASH_Test0, 0xaaaa); - builder->nextBlock(_PREHASH_Test1); - builder->addU32(_PREHASH_Test0, 0xbbbb); - bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0); - delete builder; - - ensure_not_equals("Ensure Buffer Sizes Not Equal", bufferSize1, bufferSize2); - ensure_equals("Ensure Buffer Prefix Equal", memcmp(buffer1, buffer2, bufferSize1), 0); - ensure_not_equals("Ensure Buffer Contents Not Equal", memcmp(buffer1, buffer2, bufferSize2), 0); - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<22>() - // repeated penultimate block (crashes when data in LLDynamicArrayIndexed) - { - U32 inTest00 = 0, inTest01 = 1, inTest1 = 2; - U32 outTest00, outTest01, outTest1; - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4)); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4)); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inTest00); - builder->nextBlock(_PREHASH_Test0); - builder->addU32(_PREHASH_Test0, inTest01); - builder->nextBlock(_PREHASH_Test1); - builder->addU32(_PREHASH_Test0, inTest1); - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest00, 0); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest01, 1); - reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outTest1); - ensure_equals("Ensure Test0[0]", inTest00, outTest00); - ensure_equals("Ensure Test0[1]", inTest01, outTest01); - ensure_equals("Ensure Test1", inTest1, outTest1); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<23>() - // variable repeated block name never accessed - { - U32 inTest = 1, outTest; - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock( - createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE)); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4)); - - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inTest); - - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest); - S32 blockCount = reader->getNumberOfBlocks(const_cast<char*>(_PREHASH_Test1)); - ensure_equals("Ensure block count", blockCount, 0); - ensure_equals("Ensure Test0", inTest, outTest); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<24>() - // forwarding message - { - // build template - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4)); - - // build message - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, 42); - - // read message - LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - - // forward message - builder = defaultBuilder(messageTemplate); - builder->newMessage(_PREHASH_TestMessage); - reader->copyToBuilder(*builder); - U8 buffer[MAX_BUFFER_SIZE]; - builder->buildMessage(buffer, MAX_BUFFER_SIZE, 0); - - delete builder; - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<25>() - // non-zero offset with undefined - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock()); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 10); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<26>() - // non-zero offset with bool - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1)); - bool outValue, inValue = true; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addBOOL(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 1); - reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure bool", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<27>() - // non-zero offset with U8 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U8, 1)); - U8 outValue, inValue = 2; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU8(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 255); - reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U8", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<28>() - // non-zero offset with S16 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_S16, 2)); - S16 outValue, inValue = 90; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addS16(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 2); - reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S16", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<29>() - // non-zero offset with U16 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U16, 2)); - U16 outValue, inValue = 3; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU16(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 4); - reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U16", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<30>() - // non-zero offset with S32 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_S32, 4)); - S32 outValue, inValue = 44; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addS32(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 4); - reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S32", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<31>() - // non-zero offset with F32 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_F32, 4)); - F32 outValue, inValue = 121.44f; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addF32(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 16); - reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F32", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<32>() - // non-zero offset with U32 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U32, 4)); - U32 outValue, inValue = 88; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 127); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U32", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<33>() - // non-zero offset with U64 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U64, 8)); - U64 outValue, inValue = 121; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU64(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 32); - reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U64", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<34>() - // non-zero offset with F64 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_F64, 8)); - F64 outValue, inValue = 3232143.33; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addF64(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 128); - reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F64", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<35>() - // non-zero offset with Vector3 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12)); - LLVector3 outValue, inValue = LLVector3(1,2,3); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addVector3(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 63); - reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<36>() - // non-zero offset with Vector4 - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16)); - LLVector4 outValue, inValue = LLVector4(1,2,3,4); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addVector4(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 64); - reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector4", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<37>() - // non-zero offset with Vector3d - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24)); - LLVector3d outValue, inValue = LLVector3d(1,2,3); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addVector3d(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 64); - reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3d", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<38>() - // non-zero offset with Quaternion - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12)); - LLQuaternion outValue, inValue = LLQuaternion(0.0f, LLVector3(0.3713907f, 0.5570861f, 0.7427813f)); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addQuat(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 12); - reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLQuaternion", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<39>() - // non-zero offset with UUID - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16)); - LLUUID outValue, inValue; - inValue.generate(); - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addUUID(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 31); - reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure UUID", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<40>() - // non-zero offset with IPAddr - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4)); - U32 outValue, inValue = 12344556; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addIPAddr(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 32); - reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPAddr", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<41>() - // non-zero offset with IPPort - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2)); - U16 outValue, inValue = 80; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addIPPort(_PREHASH_Test0, inValue); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 6); - reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPPort", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<42>() - // non-zero offset with String - { - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1)); - std::string outValue, inValue = "testing"; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addString(_PREHASH_Test0, inValue.c_str()); - LLTemplateMessageReader* reader = setReader( - messageTemplate, builder, 255); - char buffer[MAX_STRING]; - reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer); - outValue = buffer; - ensure_equals("Ensure String", inValue, outValue); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<43>() - // read past end of message -> default values (forward compatibility) - { - // build message with single block - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE)); - U32 outValue, outValue2, inValue = 0xbbbbbbbb; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inValue); - const U32 bufferSize = 1024; - U8 buffer[bufferSize]; - memset(buffer, 0xaa, bufferSize); - memset(buffer, 0, LL_PACKET_ID_SIZE); - U32 builtSize = builder->buildMessage(buffer, bufferSize, 0); - delete builder; - - // add block to reader template - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE)); - - // read message value and default value - numberMap[1] = &messageTemplate; - LLTemplateMessageReader* reader = - new LLTemplateMessageReader(numberMap); - reader->validateMessage(buffer, builtSize, LLHost()); - reader->readMessage(buffer, LLHost()); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outValue2); - ensure_equals("Ensure present value ", outValue, inValue); - ensure_equals("Ensure default value ", outValue2, 0); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<44>() - // read variable block past end of message -> 0 repeats - { - // build message with single block - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE)); - U32 outValue, outValue2, inValue = 0xbbbbbbbb; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inValue); - const U32 bufferSize = 1024; - U8 buffer[bufferSize]; - memset(buffer, 0xaa, bufferSize); - memset(buffer, 0, LL_PACKET_ID_SIZE); - U32 builtSize = builder->buildMessage(buffer, bufferSize, 0); - delete builder; - - // add variable block to reader template - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4)); - - // read message value and check block repeat count - numberMap[1] = &messageTemplate; - LLTemplateMessageReader* reader = - new LLTemplateMessageReader(numberMap); - reader->validateMessage(buffer, builtSize, LLHost()); - reader->readMessage(buffer, LLHost()); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1); - ensure_equals("Ensure present value ", outValue, inValue); - ensure_equals("Ensure 0 repeats ", outValue2, 0); - delete reader; - } - - template<> template<> - void LLTemplateMessageBuilderTestObject::test<45>() - // read variable length data past end of message -> 0 length - { - // build message with single block - LLMessageTemplate messageTemplate = defaultTemplate(); - messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE)); - U32 outValue, inValue = 0xbbbbbbbb; - LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); - builder->addU32(_PREHASH_Test0, inValue); - const U32 bufferSize = 1024; - U8 buffer[bufferSize]; - memset(buffer, 0xaa, bufferSize); - memset(buffer, 0, LL_PACKET_ID_SIZE); - U32 builtSize = builder->buildMessage(buffer, bufferSize, 0); - delete builder; - - // add variable block to reader template - messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_VARIABLE, 4, - MBT_SINGLE)); - - // read message value and default string - numberMap[1] = &messageTemplate; - LLTemplateMessageReader* reader = - new LLTemplateMessageReader(numberMap); - reader->validateMessage(buffer, builtSize, LLHost()); - reader->readMessage(buffer, LLHost()); - reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - (void)outValue; - char outBuffer[bufferSize]; - memset(buffer, 0xcc, bufferSize); - reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize, - outBuffer); - ensure_equals("Ensure present value ", outValue, inValue); - ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0); - delete reader; - } -} - +/**
+ * @file lltemplatemessagebuilder_tut.cpp
+ * @date 2007-04
+ * @brief Tests for building messages.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+#include "linden_common.h"
+#include "lltut.h"
+
+#include "llapr.h"
+#include "llmessagetemplate.h"
+#include "llmath.h"
+#include "llquaternion.h"
+#include "lltemplatemessagebuilder.h"
+#include "lltemplatemessagereader.h"
+#include "message_prehash.h"
+#include "u64.h"
+#include "v3dmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+namespace tut
+{
+ static LLTemplateMessageBuilder::message_template_name_map_t nameMap;
+ static LLTemplateMessageReader::message_template_number_map_t numberMap;
+
+ struct LLTemplateMessageBuilderTestData
+ {
+ static LLMessageTemplate defaultTemplate()
+ {
+ static bool init = false;
+ if(! init)
+ {
+ ll_init_apr();
+ const F32 circuit_heartbeat_interval=5;
+ const F32 circuit_timeout=100;
+
+ start_messaging_system("notafile", 13035,
+ 1,
+ 0,
+ 0,
+ false,
+ "notasharedsecret",
+ NULL,
+ false,
+ circuit_heartbeat_interval,
+ circuit_timeout);
+ //init_prehash_data();
+ init = true;
+ }
+ return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH);
+ }
+
+ static LLMessageBlock* defaultBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
+ {
+ return createBlock(const_cast<char*>(_PREHASH_Test0), type, size, block);
+ }
+
+ static LLMessageBlock* createBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE)
+ {
+ LLMessageBlock* result = new LLMessageBlock(name, block);
+ if(type != MVT_NULL)
+ {
+ result->addVariable(const_cast<char*>(_PREHASH_Test0), type, size);
+ }
+ return result;
+ }
+
+ static LLTemplateMessageBuilder* defaultBuilder(LLMessageTemplate& messageTemplate, char* name = const_cast<char*>(_PREHASH_Test0))
+ {
+ nameMap[_PREHASH_TestMessage] = &messageTemplate;
+ LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(nameMap);
+ builder->newMessage(_PREHASH_TestMessage);
+ builder->nextBlock(name);
+ return builder;
+ }
+
+ /** Takes ownership of builder */
+ static LLTemplateMessageReader* setReader(
+ LLMessageTemplate& messageTemplate,
+ LLTemplateMessageBuilder* builder,
+ U8 offset = 0)
+ {
+ numberMap[1] = &messageTemplate;
+ const U32 bufferSize = 1024;
+ U8 buffer[bufferSize];
+ // zero out the packet ID field
+ memset(buffer, 0, LL_PACKET_ID_SIZE);
+ U32 builtSize = builder->buildMessage(buffer, bufferSize, offset);
+ delete builder;
+ LLTemplateMessageReader* reader = new LLTemplateMessageReader(numberMap);
+ reader->validateMessage(buffer, builtSize, LLHost());
+ reader->readMessage(buffer, LLHost());
+ return reader;
+ }
+
+ };
+
+ typedef test_group<LLTemplateMessageBuilderTestData> LLTemplateMessageBuilderTestGroup;
+ typedef LLTemplateMessageBuilderTestGroup::object LLTemplateMessageBuilderTestObject;
+ LLTemplateMessageBuilderTestGroup templateMessageBuilderTestGroup("LLTemplateMessageBuilder");
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<1>()
+ // construction and test of undefined
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock());
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<2>()
+ // bool
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1));
+ bool outValue, inValue = true;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addBOOL(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure bool", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<3>()
+ // U8
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U8, 1));
+ U8 outValue, inValue = 2;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU8(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U8", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<4>()
+ // S16
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_S16, 2));
+ S16 outValue, inValue = 90;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addS16(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure S16", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<5>()
+ // U16
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U16, 2));
+ U16 outValue, inValue = 3;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU16(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U16", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<6>()
+ // S32
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_S32, 4));
+ S32 outValue, inValue = 44;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addS32(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure S32", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<7>()
+ // F32
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_F32, 4));
+ F32 outValue, inValue = 121.44f;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addF32(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure F32", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<8>()
+ // U32
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U32, 4));
+ U32 outValue, inValue = 88;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U32", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<9>()
+ // U64
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U64, 8));
+ U64 outValue, inValue = 121;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU64(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U64", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<10>()
+ // F64
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_F64, 8));
+ F64 outValue, inValue = 3232143.33;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addF64(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure F64", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<11>()
+ // Vector3
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12));
+ LLVector3 outValue, inValue = LLVector3(1,2,3);
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addVector3(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLVector3", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<12>()
+ // Vector4
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16));
+ LLVector4 outValue, inValue = LLVector4(1,2,3,4);
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addVector4(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLVector4", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<13>()
+ // Vector3d
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24));
+ LLVector3d outValue, inValue = LLVector3d(1,2,3);
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addVector3d(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLVector3d", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<14>()
+ // Quaternion
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
+ LLQuaternion outValue, inValue = LLQuaternion(0.0f, LLVector3(0.3713907f, 0.5570861f, 0.7427813f));
+
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addQuat(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLQuaternion", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<15>()
+ // UUID
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16));
+ LLUUID outValue, inValue;
+ inValue.generate();
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addUUID(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure UUID", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<16>()
+ // IPAddr
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4));
+ U32 outValue, inValue = 12344556;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addIPAddr(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure IPAddr", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<17>()
+ // IPPort
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2));
+ U16 outValue, inValue = 80;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addIPPort(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure IPPort", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<18>()
+ // String
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1));
+ std::string outValue, inValue = "testing";
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addString(_PREHASH_Test0, inValue.c_str());
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ char buffer[MAX_STRING];
+ reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer);
+ outValue = buffer;
+ ensure_equals("Ensure String", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<19>()
+ // block name !-> binary order
+ {
+ U8 buffer1[MAX_BUFFER_SIZE];
+ memset(buffer1, 0, MAX_BUFFER_SIZE);
+ U8 buffer2[MAX_BUFFER_SIZE];
+ memset(buffer2, 0, MAX_BUFFER_SIZE);
+ U32 bufferSize1, bufferSize2;
+
+ // build template: Test0 before Test1
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
+
+ // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
+ builder->addU32(_PREHASH_Test0, 0xaaaa);
+ builder->nextBlock(_PREHASH_Test1);
+ builder->addU32(_PREHASH_Test0, 0xbbbb);
+ bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
+ delete builder;
+
+ // build template: Test1 before Test0
+ messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
+
+ // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
+ builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test1));
+ builder->addU32(_PREHASH_Test0, 0xaaaa);
+ builder->nextBlock(_PREHASH_Test0);
+ builder->addU32(_PREHASH_Test0, 0xbbbb);
+ bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
+ delete builder;
+
+ ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2);
+ ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<20>()
+ // block build order !-> binary order
+ {
+ U8 buffer1[MAX_BUFFER_SIZE];
+ memset(buffer1, 0, MAX_BUFFER_SIZE);
+ U8 buffer2[MAX_BUFFER_SIZE];
+ memset(buffer2, 0, MAX_BUFFER_SIZE);
+ U32 bufferSize1, bufferSize2;
+
+ // build template: Test0 before Test1
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
+
+ // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
+ builder->addU32(_PREHASH_Test0, 0xaaaa);
+ builder->nextBlock(_PREHASH_Test1);
+ builder->addU32(_PREHASH_Test0, 0xbbbb);
+ bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
+ delete builder;
+
+ // build message: 1st declared block var == 0xaaaa, 2nd declared block var == 0xbbbb
+ builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test1));
+ builder->addU32(_PREHASH_Test0, 0xbbbb);
+ builder->nextBlock(_PREHASH_Test0);
+ builder->addU32(_PREHASH_Test0, 0xaaaa);
+ bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
+ delete builder;
+
+ ensure_equals("Ensure Buffer Sizes Equal", bufferSize1, bufferSize2);
+ ensure_equals("Ensure Buffer Contents Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<21>()
+ // block appended in declaration -> data appended in binary
+ {
+ U8 buffer1[MAX_BUFFER_SIZE];
+ memset(buffer1, 0, MAX_BUFFER_SIZE);
+ U8 buffer2[MAX_BUFFER_SIZE];
+ memset(buffer2, 0, MAX_BUFFER_SIZE);
+ U32 bufferSize1, bufferSize2;
+
+ // Build template: Test0 only
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
+
+ // Build message
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
+ builder->addU32(_PREHASH_Test0, 0xaaaa);
+ bufferSize1 = builder->buildMessage(buffer1, MAX_BUFFER_SIZE, 0);
+ delete builder;
+
+ // Build template: Test0 before Test1
+ messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
+
+ // Build message
+ builder = defaultBuilder(messageTemplate, const_cast<char*>(_PREHASH_Test0));
+ builder->addU32(_PREHASH_Test0, 0xaaaa);
+ builder->nextBlock(_PREHASH_Test1);
+ builder->addU32(_PREHASH_Test0, 0xbbbb);
+ bufferSize2 = builder->buildMessage(buffer2, MAX_BUFFER_SIZE, 0);
+ delete builder;
+
+ ensure_not_equals("Ensure Buffer Sizes Not Equal", bufferSize1, bufferSize2);
+ ensure_equals("Ensure Buffer Prefix Equal", memcmp(buffer1, buffer2, bufferSize1), 0);
+ ensure_not_equals("Ensure Buffer Contents Not Equal", memcmp(buffer1, buffer2, bufferSize2), 0);
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<22>()
+ // repeated penultimate block (crashes when data in LLDynamicArrayIndexed)
+ {
+ U32 inTest00 = 0, inTest01 = 1, inTest1 = 2;
+ U32 outTest00, outTest01, outTest1;
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4));
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4));
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inTest00);
+ builder->nextBlock(_PREHASH_Test0);
+ builder->addU32(_PREHASH_Test0, inTest01);
+ builder->nextBlock(_PREHASH_Test1);
+ builder->addU32(_PREHASH_Test0, inTest1);
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest00, 0);
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest01, 1);
+ reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outTest1);
+ ensure_equals("Ensure Test0[0]", inTest00, outTest00);
+ ensure_equals("Ensure Test0[1]", inTest01, outTest01);
+ ensure_equals("Ensure Test1", inTest1, outTest1);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<23>()
+ // variable repeated block name never accessed
+ {
+ U32 inTest = 1, outTest;
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(
+ createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4, MBT_SINGLE));
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4));
+
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inTest);
+
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest);
+ S32 blockCount = reader->getNumberOfBlocks(const_cast<char*>(_PREHASH_Test1));
+ ensure_equals("Ensure block count", blockCount, 0);
+ ensure_equals("Ensure Test0", inTest, outTest);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<24>()
+ // forwarding message
+ {
+ // build template
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test0), MVT_U32, 4));
+
+ // build message
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, 42);
+
+ // read message
+ LLTemplateMessageReader* reader = setReader(messageTemplate, builder);
+
+ // forward message
+ builder = defaultBuilder(messageTemplate);
+ builder->newMessage(_PREHASH_TestMessage);
+ reader->copyToBuilder(*builder);
+ U8 buffer[MAX_BUFFER_SIZE];
+ builder->buildMessage(buffer, MAX_BUFFER_SIZE, 0);
+
+ delete builder;
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<25>()
+ // non-zero offset with undefined
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock());
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 10);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<26>()
+ // non-zero offset with bool
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1));
+ bool outValue, inValue = true;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addBOOL(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 1);
+ reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure bool", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<27>()
+ // non-zero offset with U8
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U8, 1));
+ U8 outValue, inValue = 2;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU8(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 255);
+ reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U8", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<28>()
+ // non-zero offset with S16
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_S16, 2));
+ S16 outValue, inValue = 90;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addS16(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 2);
+ reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure S16", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<29>()
+ // non-zero offset with U16
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U16, 2));
+ U16 outValue, inValue = 3;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU16(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 4);
+ reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U16", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<30>()
+ // non-zero offset with S32
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_S32, 4));
+ S32 outValue, inValue = 44;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addS32(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 4);
+ reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure S32", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<31>()
+ // non-zero offset with F32
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_F32, 4));
+ F32 outValue, inValue = 121.44f;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addF32(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 16);
+ reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure F32", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<32>()
+ // non-zero offset with U32
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U32, 4));
+ U32 outValue, inValue = 88;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 127);
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U32", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<33>()
+ // non-zero offset with U64
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U64, 8));
+ U64 outValue, inValue = 121;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU64(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 32);
+ reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure U64", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<34>()
+ // non-zero offset with F64
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_F64, 8));
+ F64 outValue, inValue = 3232143.33;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addF64(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 128);
+ reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure F64", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<35>()
+ // non-zero offset with Vector3
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12));
+ LLVector3 outValue, inValue = LLVector3(1,2,3);
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addVector3(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 63);
+ reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLVector3", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<36>()
+ // non-zero offset with Vector4
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16));
+ LLVector4 outValue, inValue = LLVector4(1,2,3,4);
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addVector4(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 64);
+ reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLVector4", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<37>()
+ // non-zero offset with Vector3d
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24));
+ LLVector3d outValue, inValue = LLVector3d(1,2,3);
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addVector3d(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 64);
+ reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLVector3d", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<38>()
+ // non-zero offset with Quaternion
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12));
+ LLQuaternion outValue, inValue = LLQuaternion(0.0f, LLVector3(0.3713907f, 0.5570861f, 0.7427813f));
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addQuat(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 12);
+ reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure LLQuaternion", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<39>()
+ // non-zero offset with UUID
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16));
+ LLUUID outValue, inValue;
+ inValue.generate();
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addUUID(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 31);
+ reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure UUID", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<40>()
+ // non-zero offset with IPAddr
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4));
+ U32 outValue, inValue = 12344556;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addIPAddr(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 32);
+ reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure IPAddr", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<41>()
+ // non-zero offset with IPPort
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2));
+ U16 outValue, inValue = 80;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addIPPort(_PREHASH_Test0, inValue);
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 6);
+ reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ ensure_equals("Ensure IPPort", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<42>()
+ // non-zero offset with String
+ {
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1));
+ std::string outValue, inValue = "testing";
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addString(_PREHASH_Test0, inValue.c_str());
+ LLTemplateMessageReader* reader = setReader(
+ messageTemplate, builder, 255);
+ char buffer[MAX_STRING];
+ reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer);
+ outValue = buffer;
+ ensure_equals("Ensure String", inValue, outValue);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<43>()
+ // read past end of message -> default values (forward compatibility)
+ {
+ // build message with single block
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
+ U32 outValue, outValue2, inValue = 0xbbbbbbbb;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inValue);
+ const U32 bufferSize = 1024;
+ U8 buffer[bufferSize];
+ memset(buffer, 0xaa, bufferSize);
+ memset(buffer, 0, LL_PACKET_ID_SIZE);
+ U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
+ delete builder;
+
+ // add block to reader template
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4, MBT_SINGLE));
+
+ // read message value and default value
+ numberMap[1] = &messageTemplate;
+ LLTemplateMessageReader* reader =
+ new LLTemplateMessageReader(numberMap);
+ reader->validateMessage(buffer, builtSize, LLHost());
+ reader->readMessage(buffer, LLHost());
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ reader->getU32(_PREHASH_Test1, _PREHASH_Test0, outValue2);
+ ensure_equals("Ensure present value ", outValue, inValue);
+ ensure_equals("Ensure default value ", outValue2, 0);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<44>()
+ // read variable block past end of message -> 0 repeats
+ {
+ // build message with single block
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
+ U32 outValue, outValue2, inValue = 0xbbbbbbbb;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inValue);
+ const U32 bufferSize = 1024;
+ U8 buffer[bufferSize];
+ memset(buffer, 0xaa, bufferSize);
+ memset(buffer, 0, LL_PACKET_ID_SIZE);
+ U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
+ delete builder;
+
+ // add variable block to reader template
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_U32, 4));
+
+ // read message value and check block repeat count
+ numberMap[1] = &messageTemplate;
+ LLTemplateMessageReader* reader =
+ new LLTemplateMessageReader(numberMap);
+ reader->validateMessage(buffer, builtSize, LLHost());
+ reader->readMessage(buffer, LLHost());
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
+ ensure_equals("Ensure present value ", outValue, inValue);
+ ensure_equals("Ensure 0 repeats ", outValue2, 0);
+ delete reader;
+ }
+
+ template<> template<>
+ void LLTemplateMessageBuilderTestObject::test<45>()
+ // read variable length data past end of message -> 0 length
+ {
+ // build message with single block
+ LLMessageTemplate messageTemplate = defaultTemplate();
+ messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
+ U32 outValue, inValue = 0xbbbbbbbb;
+ LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
+ builder->addU32(_PREHASH_Test0, inValue);
+ const U32 bufferSize = 1024;
+ U8 buffer[bufferSize];
+ memset(buffer, 0xaa, bufferSize);
+ memset(buffer, 0, LL_PACKET_ID_SIZE);
+ U32 builtSize = builder->buildMessage(buffer, bufferSize, 0);
+ delete builder;
+
+ // add variable block to reader template
+ messageTemplate.addBlock(createBlock(const_cast<char*>(_PREHASH_Test1), MVT_VARIABLE, 4,
+ MBT_SINGLE));
+
+ // read message value and default string
+ numberMap[1] = &messageTemplate;
+ LLTemplateMessageReader* reader =
+ new LLTemplateMessageReader(numberMap);
+ reader->validateMessage(buffer, builtSize, LLHost());
+ reader->readMessage(buffer, LLHost());
+ reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue);
+ (void)outValue;
+ char outBuffer[bufferSize];
+ memset(buffer, 0xcc, bufferSize);
+ reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize,
+ outBuffer);
+ ensure_equals("Ensure present value ", outValue, inValue);
+ ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);
+ delete reader;
+ }
+}
+
diff --git a/indra/test/lltestapp.h b/indra/test/lltestapp.h index 382516cd2b..466bc6fe16 100644 --- a/indra/test/lltestapp.h +++ b/indra/test/lltestapp.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2019-10-21 * @brief LLApp subclass useful for testing. - * + * * $LicenseInfo:firstyear=2019&license=viewerlgpl$ * Copyright (c) 2019, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/lltimestampcache_tut.cpp b/indra/test/lltimestampcache_tut.cpp index 857a17a6d5..857dfe6e6e 100644 --- a/indra/test/lltimestampcache_tut.cpp +++ b/indra/test/lltimestampcache_tut.cpp @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -34,91 +34,91 @@ namespace tut { - struct LLTimestampCacheTestData - { - }; + struct LLTimestampCacheTestData + { + }; - typedef test_group<LLTimestampCacheTestData> LLTimestampCacheTestGroup; - typedef LLTimestampCacheTestGroup::object LLTimestampCacheTestObject; + typedef test_group<LLTimestampCacheTestData> LLTimestampCacheTestGroup; + typedef LLTimestampCacheTestGroup::object LLTimestampCacheTestObject; - LLTimestampCacheTestGroup timestampCacheTestGroup("LLTimestampCache"); + LLTimestampCacheTestGroup timestampCacheTestGroup("LLTimestampCache"); - // Most common usage - template<> template<> - void LLTimestampCacheTestObject::test<1>() - { - LLTimestampCache<std::string, std::string> cache; - // put in some data - cache.insert("key1", "val1", 1); - cache.insert("key2", "val2", 2); - cache.insert("key3", "val3", 3); - ensure_equals("size is 3", cache.size(), 3); - // check some items - ensure("has key1", cache.has("key1")); - ensure("no invalid key", !cache.has("invalid key")); - // get some items - ensure_equals("get key1", cache.get("key1", 4), "val1"); - ensure_equals("get invalid key", - cache.get("invalid key", 4), std::string() ); - // timestamps - ensure_equals("key1 timestamp updated", cache.getTimestamp("key1"), 4); - ensure_equals("invalid key timestamp", - cache.getTimestamp("invalid key"), 0); - } + // Most common usage + template<> template<> + void LLTimestampCacheTestObject::test<1>() + { + LLTimestampCache<std::string, std::string> cache; + // put in some data + cache.insert("key1", "val1", 1); + cache.insert("key2", "val2", 2); + cache.insert("key3", "val3", 3); + ensure_equals("size is 3", cache.size(), 3); + // check some items + ensure("has key1", cache.has("key1")); + ensure("no invalid key", !cache.has("invalid key")); + // get some items + ensure_equals("get key1", cache.get("key1", 4), "val1"); + ensure_equals("get invalid key", + cache.get("invalid key", 4), std::string() ); + // timestamps + ensure_equals("key1 timestamp updated", cache.getTimestamp("key1"), 4); + ensure_equals("invalid key timestamp", + cache.getTimestamp("invalid key"), 0); + } - // New empty cache shouldn't have any entries - template<> template<> - void LLTimestampCacheTestObject::test<2>() - { - LLTimestampCache<std::string, std::string> cache; - ensure_equals("starts empty", cache.size(), 0); - ensure_equals("has nothing", cache.has("foo"), false); - ensure_equals("gets nothing", cache.get("foo", 0), std::string() ); - U32 max_time = 0xFFFFFFFF; - ensure_equals("erases nothing", cache.eraseBefore(max_time), 0); - } + // New empty cache shouldn't have any entries + template<> template<> + void LLTimestampCacheTestObject::test<2>() + { + LLTimestampCache<std::string, std::string> cache; + ensure_equals("starts empty", cache.size(), 0); + ensure_equals("has nothing", cache.has("foo"), false); + ensure_equals("gets nothing", cache.get("foo", 0), std::string() ); + U32 max_time = 0xFFFFFFFF; + ensure_equals("erases nothing", cache.eraseBefore(max_time), 0); + } - // Non empty cache - template<> template<> - void LLTimestampCacheTestObject::test<3>() - { - LLTimestampCache<std::string, std::string> cache; - cache.insert("foo", "bar", 123); - ensure_equals("size one", cache.size(), 1); - ensure_equals("has it", cache.has("foo"), true); - ensure_equals("timestamp correct", cache.getTimestamp("foo"), 123); - std::string value = cache.get("foo", 456); - ensure_equals("get value", value, "bar"); - ensure_equals("timestamp updated", cache.getTimestamp("foo"), 456); - ensure_equals("erase nothing", cache.eraseBefore(0), 0); - ensure_equals("erase one", cache.eraseBefore(789), 1); - ensure_equals("empty after erase", cache.size(), 0); - } + // Non empty cache + template<> template<> + void LLTimestampCacheTestObject::test<3>() + { + LLTimestampCache<std::string, std::string> cache; + cache.insert("foo", "bar", 123); + ensure_equals("size one", cache.size(), 1); + ensure_equals("has it", cache.has("foo"), true); + ensure_equals("timestamp correct", cache.getTimestamp("foo"), 123); + std::string value = cache.get("foo", 456); + ensure_equals("get value", value, "bar"); + ensure_equals("timestamp updated", cache.getTimestamp("foo"), 456); + ensure_equals("erase nothing", cache.eraseBefore(0), 0); + ensure_equals("erase one", cache.eraseBefore(789), 1); + ensure_equals("empty after erase", cache.size(), 0); + } - // Recache of item should update timestamp - template<> template<> - void LLTimestampCacheTestObject::test<4>() - { - LLTimestampCache<std::string, std::string> cache; - cache.insert("foo", "bar", 123); - cache.insert("foo", "bar", 456); - ensure_equals("duplicate suppressed", cache.size(), 1); - ensure_equals("timestamp replaced", cache.getTimestamp("foo"), 456); - } + // Recache of item should update timestamp + template<> template<> + void LLTimestampCacheTestObject::test<4>() + { + LLTimestampCache<std::string, std::string> cache; + cache.insert("foo", "bar", 123); + cache.insert("foo", "bar", 456); + ensure_equals("duplicate suppressed", cache.size(), 1); + ensure_equals("timestamp replaced", cache.getTimestamp("foo"), 456); + } - // Erasing some items - template<> template<> - void LLTimestampCacheTestObject::test<5>() - { - LLTimestampCache<std::string, std::string> cache; - cache.insert("key1", "val1", 1); - cache.insert("key2", "val2", 2); - cache.insert("key3", "val3", 3); - cache.insert("key4", "val4", 4); - size_t erased = cache.eraseBefore(3); - ensure_equals("erase range", erased, 2); - ensure_equals("cache post erase", cache.size(), 2); - ensure_equals("has key3", cache.has("key3"), true); - ensure_equals("not has key2", cache.has("key2"), false); - } + // Erasing some items + template<> template<> + void LLTimestampCacheTestObject::test<5>() + { + LLTimestampCache<std::string, std::string> cache; + cache.insert("key1", "val1", 1); + cache.insert("key2", "val2", 2); + cache.insert("key3", "val3", 3); + cache.insert("key4", "val4", 4); + size_t erased = cache.eraseBefore(3); + ensure_equals("erase range", erased, 2); + ensure_equals("cache post erase", cache.size(), 2); + ensure_equals("has key3", cache.has("key3"), true); + ensure_equals("not has key2", cache.has("key2"), false); + } } diff --git a/indra/test/lltranscode_tut.cpp b/indra/test/lltranscode_tut.cpp index 3fce6e0e2b..23d554d46d 100644 --- a/indra/test/lltranscode_tut.cpp +++ b/indra/test/lltranscode_tut.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llscriptresource_tut.cpp * @brief Test LLScriptResource * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,49 +38,49 @@ static const char test_latin2[] = "Edelwei\xdf"; namespace tut { - class LLTranscodeTestData - { - }; - - typedef test_group<LLTranscodeTestData> LLTranscodeTestGroup; - typedef LLTranscodeTestGroup::object LLTranscodeTestObject; - LLTranscodeTestGroup transcodeTestGroup("transcode"); + class LLTranscodeTestData + { + }; + + typedef test_group<LLTranscodeTestData> LLTranscodeTestGroup; + typedef LLTranscodeTestGroup::object LLTranscodeTestObject; + LLTranscodeTestGroup transcodeTestGroup("transcode"); + + template<> template<> + void LLTranscodeTestObject::test<1>() + { + // Test utf8 + std::stringstream input; + std::stringstream output; + + input.str(test_utf7); + output.clear(); + LLTranscode::transcode("charset=UTF-7", input, output); + ensure_equals("UTF-7 to UTF-8 transcoding", output.str(), + std::string(test_utf8)); + + input.str(test_latin1); + output.clear(); + LLTranscode::transcode("", input, output); + ensure_equals("Default (latin_1) to UTF8 transcoding", output.str(), + std::string(test_utf8)); - template<> template<> - void LLTranscodeTestObject::test<1>() - { - // Test utf8 - std::stringstream input; - std::stringstream output; + input.str(test_latin1); + output.clear(); + LLTranscode::transcode("charset=iso-8859-1", input, output); + ensure_equals("latin_1 (ISO-8859-1) to UTF8 transcoding", output.str(), + std::string(test_utf8)); - input.str(test_utf7); - output.clear(); - LLTranscode::transcode("charset=UTF-7", input, output); - ensure_equals("UTF-7 to UTF-8 transcoding", output.str(), - std::string(test_utf8)); + input.str(test_latin2); + output.clear(); + LLTranscode::transcode("charset=iso-8859-2", input, output); + ensure_equals("latin_2 (ISO-8859-2) to UTF8 transcoding", output.str(), + std::string(test_utf8)); - input.str(test_latin1); - output.clear(); - LLTranscode::transcode("", input, output); - ensure_equals("Default (latin_1) to UTF8 transcoding", output.str(), - std::string(test_utf8)); - - input.str(test_latin1); - output.clear(); - LLTranscode::transcode("charset=iso-8859-1", input, output); - ensure_equals("latin_1 (ISO-8859-1) to UTF8 transcoding", output.str(), - std::string(test_utf8)); - - input.str(test_latin2); - output.clear(); - LLTranscode::transcode("charset=iso-8859-2", input, output); - ensure_equals("latin_2 (ISO-8859-2) to UTF8 transcoding", output.str(), - std::string(test_utf8)); - - input.str(test_utf8); - output.clear(); - LLTranscode::transcode("charset=utf-8", input, output); - ensure_equals("UTF8 to UTF8 transcoding", output.str(), - std::string(test_utf8)); - } + input.str(test_utf8); + output.clear(); + LLTranscode::transcode("charset=utf-8", input, output); + ensure_equals("UTF8 to UTF8 transcoding", output.str(), + std::string(test_utf8)); + } } diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp index 5a8ee87afd..36c8fe4078 100644 --- a/indra/test/lltut.cpp +++ b/indra/test/lltut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lltut.cpp * @author Mark Lentczner * @date 5/16/06 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,169 +38,169 @@ namespace tut { - void ensure_equals(const std::string& msg, const LLDate& actual, - const LLDate& expected) - { - ensure_equals(msg, - actual.secondsSinceEpoch(), expected.secondsSinceEpoch()); - } - - void ensure_equals(const std::string& msg, const LLURI& actual, - const LLURI& expected) - { - ensure_equals(msg, - actual.asString(), expected.asString()); - } - - // The lexical param types here intentionally diverge from the declaration - // in our header file. In lltut.h, LLSD is only a forward-declared type; - // we have no access to its LLSD::Binary nested type, and so must restate - // it explicitly to declare this overload. However, an overload that does - // NOT match LLSD::Binary does us no good whatsoever: it would never be - // engaged. Stating LLSD::Binary for this definition at least means that - // if the LLSD::Binary type ever diverges from what we expect in lltut.h, - // that divergence will produce an error: no definition will match that - // declaration. - void ensure_equals(const std::string& msg, - const LLSD::Binary& actual, const LLSD::Binary& expected) - { - ensure_equals(msg + " size", actual.size(), expected.size()); - - LLSD::Binary::const_iterator i, j; - int k; - for (i = actual.begin(), j = expected.begin(), k = 0; - i != actual.end(); - ++i, ++j, ++k) - { - ensure_equals(msg + " field", *i, *j); - } - } - - void ensure_equals(const std::string& msg, const LLSD& actual, - const LLSD& expected) - { - ensure_equals(msg + " type", actual.type(), expected.type()); - switch (actual.type()) - { - case LLSD::TypeUndefined: - return; - - case LLSD::TypeBoolean: - ensure_equals(msg + " boolean", actual.asBoolean(), expected.asBoolean()); - return; - - case LLSD::TypeInteger: - ensure_equals(msg + " integer", actual.asInteger(), expected.asInteger()); - return; - - case LLSD::TypeReal: - ensure_equals(msg + " real", actual.asReal(), expected.asReal()); - return; - - case LLSD::TypeString: - ensure_equals(msg + " string", actual.asString(), expected.asString()); - return; - - case LLSD::TypeUUID: - ensure_equals(msg + " uuid", actual.asUUID(), expected.asUUID()); - return; - - case LLSD::TypeDate: - ensure_equals(msg + " date", actual.asDate(), expected.asDate()); - return; - - case LLSD::TypeURI: - ensure_equals(msg + " uri", actual.asURI(), expected.asURI()); - return; - - case LLSD::TypeBinary: - ensure_equals(msg + " binary", actual.asBinary(), expected.asBinary()); - return; - - case LLSD::TypeMap: - { - ensure_equals(msg + " map size", actual.size(), expected.size()); - - LLSD::map_const_iterator actual_iter = actual.beginMap(); - LLSD::map_const_iterator expected_iter = expected.beginMap(); - - while(actual_iter != actual.endMap()) - { - ensure_equals(msg + " map keys", - actual_iter->first, expected_iter->first); - ensure_equals(msg + "[" + actual_iter->first + "]", - actual_iter->second, expected_iter->second); - ++actual_iter; - ++expected_iter; - } - return; - } - case LLSD::TypeArray: - { - ensure_equals(msg + " array size", actual.size(), expected.size()); - - for(int i = 0; i < actual.size(); ++i) - { - ensure_equals(msg + llformat("[%d]", i), - actual[i], expected[i]); - } - return; - } - default: - // should never get here, but compiler produces warning if we - // don't cover this case, and at Linden warnings are fatal. - throw failure(STRINGIZE("invalid type field " << actual.type())); - } - } - - void ensure_starts_with(const std::string& msg, - const std::string& actual, const std::string& expectedStart) - { - if( actual.find(expectedStart, 0) != 0 ) - { - std::stringstream ss; - ss << msg << ": " << "expected to find '" << expectedStart - << "' at start of actual '" << actual << "'"; - throw failure(ss.str().c_str()); - } - } - - void ensure_ends_with(const std::string& msg, - const std::string& actual, const std::string& expectedEnd) - { - if( actual.size() < expectedEnd.size() - || actual.rfind(expectedEnd) - != (actual.size() - expectedEnd.size()) ) - { - std::stringstream ss; - ss << msg << ": " << "expected to find '" << expectedEnd - << "' at end of actual '" << actual << "'"; - throw failure(ss.str().c_str()); - } - } - - void ensure_contains(const std::string& msg, - const std::string& actual, const std::string& expectedSubString) - { - if( actual.find(expectedSubString, 0) == std::string::npos ) - { - std::stringstream ss; - ss << msg << ": " << "expected to find '" << expectedSubString - << "' in actual '" << actual << "'"; - throw failure(ss.str().c_str()); - } - } - - void ensure_does_not_contain(const std::string& msg, - const std::string& actual, const std::string& expectedSubString) - { - if( actual.find(expectedSubString, 0) != std::string::npos ) - { - std::stringstream ss; - ss << msg << ": " << "expected not to find " << expectedSubString - << " in actual " << actual; - throw failure(ss.str().c_str()); - } - } + void ensure_equals(const std::string& msg, const LLDate& actual, + const LLDate& expected) + { + ensure_equals(msg, + actual.secondsSinceEpoch(), expected.secondsSinceEpoch()); + } + + void ensure_equals(const std::string& msg, const LLURI& actual, + const LLURI& expected) + { + ensure_equals(msg, + actual.asString(), expected.asString()); + } + + // The lexical param types here intentionally diverge from the declaration + // in our header file. In lltut.h, LLSD is only a forward-declared type; + // we have no access to its LLSD::Binary nested type, and so must restate + // it explicitly to declare this overload. However, an overload that does + // NOT match LLSD::Binary does us no good whatsoever: it would never be + // engaged. Stating LLSD::Binary for this definition at least means that + // if the LLSD::Binary type ever diverges from what we expect in lltut.h, + // that divergence will produce an error: no definition will match that + // declaration. + void ensure_equals(const std::string& msg, + const LLSD::Binary& actual, const LLSD::Binary& expected) + { + ensure_equals(msg + " size", actual.size(), expected.size()); + + LLSD::Binary::const_iterator i, j; + int k; + for (i = actual.begin(), j = expected.begin(), k = 0; + i != actual.end(); + ++i, ++j, ++k) + { + ensure_equals(msg + " field", *i, *j); + } + } + + void ensure_equals(const std::string& msg, const LLSD& actual, + const LLSD& expected) + { + ensure_equals(msg + " type", actual.type(), expected.type()); + switch (actual.type()) + { + case LLSD::TypeUndefined: + return; + + case LLSD::TypeBoolean: + ensure_equals(msg + " boolean", actual.asBoolean(), expected.asBoolean()); + return; + + case LLSD::TypeInteger: + ensure_equals(msg + " integer", actual.asInteger(), expected.asInteger()); + return; + + case LLSD::TypeReal: + ensure_equals(msg + " real", actual.asReal(), expected.asReal()); + return; + + case LLSD::TypeString: + ensure_equals(msg + " string", actual.asString(), expected.asString()); + return; + + case LLSD::TypeUUID: + ensure_equals(msg + " uuid", actual.asUUID(), expected.asUUID()); + return; + + case LLSD::TypeDate: + ensure_equals(msg + " date", actual.asDate(), expected.asDate()); + return; + + case LLSD::TypeURI: + ensure_equals(msg + " uri", actual.asURI(), expected.asURI()); + return; + + case LLSD::TypeBinary: + ensure_equals(msg + " binary", actual.asBinary(), expected.asBinary()); + return; + + case LLSD::TypeMap: + { + ensure_equals(msg + " map size", actual.size(), expected.size()); + + LLSD::map_const_iterator actual_iter = actual.beginMap(); + LLSD::map_const_iterator expected_iter = expected.beginMap(); + + while(actual_iter != actual.endMap()) + { + ensure_equals(msg + " map keys", + actual_iter->first, expected_iter->first); + ensure_equals(msg + "[" + actual_iter->first + "]", + actual_iter->second, expected_iter->second); + ++actual_iter; + ++expected_iter; + } + return; + } + case LLSD::TypeArray: + { + ensure_equals(msg + " array size", actual.size(), expected.size()); + + for(int i = 0; i < actual.size(); ++i) + { + ensure_equals(msg + llformat("[%d]", i), + actual[i], expected[i]); + } + return; + } + default: + // should never get here, but compiler produces warning if we + // don't cover this case, and at Linden warnings are fatal. + throw failure(STRINGIZE("invalid type field " << actual.type())); + } + } + + void ensure_starts_with(const std::string& msg, + const std::string& actual, const std::string& expectedStart) + { + if( actual.find(expectedStart, 0) != 0 ) + { + std::stringstream ss; + ss << msg << ": " << "expected to find '" << expectedStart + << "' at start of actual '" << actual << "'"; + throw failure(ss.str().c_str()); + } + } + + void ensure_ends_with(const std::string& msg, + const std::string& actual, const std::string& expectedEnd) + { + if( actual.size() < expectedEnd.size() + || actual.rfind(expectedEnd) + != (actual.size() - expectedEnd.size()) ) + { + std::stringstream ss; + ss << msg << ": " << "expected to find '" << expectedEnd + << "' at end of actual '" << actual << "'"; + throw failure(ss.str().c_str()); + } + } + + void ensure_contains(const std::string& msg, + const std::string& actual, const std::string& expectedSubString) + { + if( actual.find(expectedSubString, 0) == std::string::npos ) + { + std::stringstream ss; + ss << msg << ": " << "expected to find '" << expectedSubString + << "' in actual '" << actual << "'"; + throw failure(ss.str().c_str()); + } + } + + void ensure_does_not_contain(const std::string& msg, + const std::string& actual, const std::string& expectedSubString) + { + if( actual.find(expectedSubString, 0) != std::string::npos ) + { + std::stringstream ss; + ss << msg << ": " << "expected not to find " << expectedSubString + << " in actual " << actual; + throw failure(ss.str().c_str()); + } + } } diff --git a/indra/test/lltut.h b/indra/test/lltut.h index 9835565bb6..e56b4e8d1c 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -1,4 +1,4 @@ -/** +/** * @file lltut.h * @author Phoenix * @date 2005-09-26 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -38,35 +38,35 @@ class LLURI; namespace tut { - void ensure_equals(const std::string& msg, - const LLDate& actual, const LLDate& expected); + void ensure_equals(const std::string& msg, + const LLDate& actual, const LLDate& expected); - void ensure_equals(const std::string& msg, - const LLURI& actual, const LLURI& expected); + void ensure_equals(const std::string& msg, + const LLURI& actual, const LLURI& expected); - // std::vector<U8> is the current definition of LLSD::Binary. Because - // we're only forward-declaring LLSD in this header file, we can't - // directly reference that nested type. If the build complains that - // there's no definition for this declaration, it could be that - // LLSD::Binary has changed, and that this declaration must be adjusted to - // match. - void ensure_equals(const std::string& msg, - const std::vector<U8>& actual, const std::vector<U8>& expected); + // std::vector<U8> is the current definition of LLSD::Binary. Because + // we're only forward-declaring LLSD in this header file, we can't + // directly reference that nested type. If the build complains that + // there's no definition for this declaration, it could be that + // LLSD::Binary has changed, and that this declaration must be adjusted to + // match. + void ensure_equals(const std::string& msg, + const std::vector<U8>& actual, const std::vector<U8>& expected); - void ensure_equals(const std::string& msg, - const LLSD& actual, const LLSD& expected); + void ensure_equals(const std::string& msg, + const LLSD& actual, const LLSD& expected); - void ensure_starts_with(const std::string& msg, - const std::string& actual, const std::string& expectedStart); + void ensure_starts_with(const std::string& msg, + const std::string& actual, const std::string& expectedStart); - void ensure_ends_with(const std::string& msg, - const std::string& actual, const std::string& expectedEnd); + void ensure_ends_with(const std::string& msg, + const std::string& actual, const std::string& expectedEnd); - void ensure_contains(const std::string& msg, - const std::string& actual, const std::string& expectedSubString); + void ensure_contains(const std::string& msg, + const std::string& actual, const std::string& expectedSubString); - void ensure_does_not_contain(const std::string& msg, - const std::string& actual, const std::string& expectedSubString); + void ensure_does_not_contain(const std::string& msg, + const std::string& actual, const std::string& expectedSubString); } // This is an odd place to #include an important contributor -- but the usual @@ -87,73 +87,73 @@ namespace tut // The functions BELOW this point actually consume tut.hpp functionality. namespace tut { - inline void ensure_approximately_equals(const char* msg, F64 actual, F64 expected, U32 frac_bits) - { - if(!is_approx_equal_fraction(actual, expected, frac_bits)) - { - std::stringstream ss; - ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected; - throw tut::failure(ss.str().c_str()); - } - } - - inline void ensure_approximately_equals(const char* msg, F32 actual, F32 expected, U32 frac_bits) - { - if(!is_approx_equal_fraction(actual, expected, frac_bits)) - { - std::stringstream ss; - ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected; - throw tut::failure(ss.str().c_str()); - } - } - - inline void ensure_approximately_equals(F32 actual, F32 expected, U32 frac_bits) - { - ensure_approximately_equals(NULL, actual, expected, frac_bits); - } - - inline void ensure_approximately_equals_range(const char *msg, F32 actual, F32 expected, F32 delta) - { - if (fabs(actual-expected)>delta) - { - std::stringstream ss; - ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected << " tolerance: " << delta; - throw tut::failure(ss.str().c_str()); - } - } - - inline void ensure_memory_matches(const char* msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len) - { - if((expected_len != actual_len) || - (std::memcmp(actual, expected, actual_len) != 0)) - { - std::stringstream ss; - ss << (msg?msg:"") << (msg?": ":"") << "not equal"; - throw tut::failure(ss.str().c_str()); - } - } - - inline void ensure_memory_matches(const void* actual, U32 actual_len, const void* expected,U32 expected_len) - { - ensure_memory_matches(NULL, actual, actual_len, expected, expected_len); - } - - template <class T,class Q> - void ensure_not_equals(const char* msg,const Q& actual,const T& expected) - { - if( expected == actual ) - { - std::stringstream ss; - ss << (msg?msg:"") << (msg?": ":"") << "both equal " << expected; - throw tut::failure(ss.str().c_str()); - } - } - - template <class T,class Q> - void ensure_not_equals(const Q& actual,const T& expected) - { - ensure_not_equals(NULL, actual, expected); - } + inline void ensure_approximately_equals(const char* msg, F64 actual, F64 expected, U32 frac_bits) + { + if(!is_approx_equal_fraction(actual, expected, frac_bits)) + { + std::stringstream ss; + ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected; + throw tut::failure(ss.str().c_str()); + } + } + + inline void ensure_approximately_equals(const char* msg, F32 actual, F32 expected, U32 frac_bits) + { + if(!is_approx_equal_fraction(actual, expected, frac_bits)) + { + std::stringstream ss; + ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected; + throw tut::failure(ss.str().c_str()); + } + } + + inline void ensure_approximately_equals(F32 actual, F32 expected, U32 frac_bits) + { + ensure_approximately_equals(NULL, actual, expected, frac_bits); + } + + inline void ensure_approximately_equals_range(const char *msg, F32 actual, F32 expected, F32 delta) + { + if (fabs(actual-expected)>delta) + { + std::stringstream ss; + ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected << " tolerance: " << delta; + throw tut::failure(ss.str().c_str()); + } + } + + inline void ensure_memory_matches(const char* msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len) + { + if((expected_len != actual_len) || + (std::memcmp(actual, expected, actual_len) != 0)) + { + std::stringstream ss; + ss << (msg?msg:"") << (msg?": ":"") << "not equal"; + throw tut::failure(ss.str().c_str()); + } + } + + inline void ensure_memory_matches(const void* actual, U32 actual_len, const void* expected,U32 expected_len) + { + ensure_memory_matches(NULL, actual, actual_len, expected, expected_len); + } + + template <class T,class Q> + void ensure_not_equals(const char* msg,const Q& actual,const T& expected) + { + if( expected == actual ) + { + std::stringstream ss; + ss << (msg?msg:"") << (msg?": ":"") << "both equal " << expected; + throw tut::failure(ss.str().c_str()); + } + } + + template <class T,class Q> + void ensure_not_equals(const Q& actual,const T& expected) + { + ensure_not_equals(NULL, actual, expected); + } } #endif // LL_LLTUT_H diff --git a/indra/test/lluserrelations_tut.cpp b/indra/test/lluserrelations_tut.cpp index afbcf6e5a8..80a659da65 100644 --- a/indra/test/lluserrelations_tut.cpp +++ b/indra/test/lluserrelations_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lluserrelations_tut.cpp * @author Phoenix * @date 2006-10-12 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,124 +33,124 @@ namespace tut { - struct user_relationship - { - LLRelationship mRelationship; - }; - typedef test_group<user_relationship> user_relationship_t; - typedef user_relationship_t::object user_relationship_object_t; - tut::user_relationship_t tut_user_relationship("relationships"); + struct user_relationship + { + LLRelationship mRelationship; + }; + typedef test_group<user_relationship> user_relationship_t; + typedef user_relationship_t::object user_relationship_object_t; + tut::user_relationship_t tut_user_relationship("relationships"); - template<> template<> - void user_relationship_object_t::test<1>() - { - // Test the default construction - ensure( - "No granted rights to", - !mRelationship.isRightGrantedTo( - LLRelationship::GRANT_ONLINE_STATUS)); - ensure( - "No granted rights from", - !mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_ONLINE_STATUS)); - ensure("No online status",!mRelationship.isOnline()); - } + template<> template<> + void user_relationship_object_t::test<1>() + { + // Test the default construction + ensure( + "No granted rights to", + !mRelationship.isRightGrantedTo( + LLRelationship::GRANT_ONLINE_STATUS)); + ensure( + "No granted rights from", + !mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_ONLINE_STATUS)); + ensure("No online status",!mRelationship.isOnline()); + } - template<> template<> - void user_relationship_object_t::test<2>() - { - // Test some granting - mRelationship.grantRights( - LLRelationship::GRANT_ONLINE_STATUS, - LLRelationship::GRANT_MODIFY_OBJECTS); - ensure( - "Granted rights to has online", - mRelationship.isRightGrantedTo( - LLRelationship::GRANT_ONLINE_STATUS)); - ensure( - "Granted rights from does not have online", - !mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_ONLINE_STATUS)); - ensure( - "Granted rights to does not have modify", - !mRelationship.isRightGrantedTo( - LLRelationship::GRANT_MODIFY_OBJECTS)); - ensure( - "Granted rights from has modify", - mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_MODIFY_OBJECTS)); - } + template<> template<> + void user_relationship_object_t::test<2>() + { + // Test some granting + mRelationship.grantRights( + LLRelationship::GRANT_ONLINE_STATUS, + LLRelationship::GRANT_MODIFY_OBJECTS); + ensure( + "Granted rights to has online", + mRelationship.isRightGrantedTo( + LLRelationship::GRANT_ONLINE_STATUS)); + ensure( + "Granted rights from does not have online", + !mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_ONLINE_STATUS)); + ensure( + "Granted rights to does not have modify", + !mRelationship.isRightGrantedTo( + LLRelationship::GRANT_MODIFY_OBJECTS)); + ensure( + "Granted rights from has modify", + mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_MODIFY_OBJECTS)); + } - template<> template<> - void user_relationship_object_t::test<3>() - { - // Test revoking - mRelationship.grantRights( - LLRelationship::GRANT_ONLINE_STATUS - | LLRelationship::GRANT_MAP_LOCATION, - LLRelationship::GRANT_ONLINE_STATUS); - ensure( - "Granted rights to has online and map", - mRelationship.isRightGrantedTo( - LLRelationship::GRANT_ONLINE_STATUS - | LLRelationship::GRANT_MAP_LOCATION)); - ensure( - "Granted rights from has online", - mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_ONLINE_STATUS)); + template<> template<> + void user_relationship_object_t::test<3>() + { + // Test revoking + mRelationship.grantRights( + LLRelationship::GRANT_ONLINE_STATUS + | LLRelationship::GRANT_MAP_LOCATION, + LLRelationship::GRANT_ONLINE_STATUS); + ensure( + "Granted rights to has online and map", + mRelationship.isRightGrantedTo( + LLRelationship::GRANT_ONLINE_STATUS + | LLRelationship::GRANT_MAP_LOCATION)); + ensure( + "Granted rights from has online", + mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_ONLINE_STATUS)); - mRelationship.revokeRights( - LLRelationship::GRANT_MAP_LOCATION, - LLRelationship::GRANT_NONE); - ensure( - "Granted rights revoked map", - !mRelationship.isRightGrantedTo( - LLRelationship::GRANT_ONLINE_STATUS - | LLRelationship::GRANT_MAP_LOCATION)); - ensure( - "Granted rights revoked still has online", - mRelationship.isRightGrantedTo( - LLRelationship::GRANT_ONLINE_STATUS)); + mRelationship.revokeRights( + LLRelationship::GRANT_MAP_LOCATION, + LLRelationship::GRANT_NONE); + ensure( + "Granted rights revoked map", + !mRelationship.isRightGrantedTo( + LLRelationship::GRANT_ONLINE_STATUS + | LLRelationship::GRANT_MAP_LOCATION)); + ensure( + "Granted rights revoked still has online", + mRelationship.isRightGrantedTo( + LLRelationship::GRANT_ONLINE_STATUS)); - mRelationship.grantRights( - LLRelationship::GRANT_NONE, - LLRelationship::GRANT_MODIFY_OBJECTS); - ensure( - "Granted rights from still has online", - mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_ONLINE_STATUS)); - ensure( - "Granted rights from has full grant", - mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_ONLINE_STATUS - | LLRelationship::GRANT_MODIFY_OBJECTS)); - mRelationship.revokeRights( - LLRelationship::GRANT_NONE, - LLRelationship::GRANT_MODIFY_OBJECTS); - ensure( - "Granted rights from still has online", - mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_ONLINE_STATUS)); - ensure( - "Granted rights from no longer modify", - !mRelationship.isRightGrantedFrom( - LLRelationship::GRANT_MODIFY_OBJECTS)); - } + mRelationship.grantRights( + LLRelationship::GRANT_NONE, + LLRelationship::GRANT_MODIFY_OBJECTS); + ensure( + "Granted rights from still has online", + mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_ONLINE_STATUS)); + ensure( + "Granted rights from has full grant", + mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_ONLINE_STATUS + | LLRelationship::GRANT_MODIFY_OBJECTS)); + mRelationship.revokeRights( + LLRelationship::GRANT_NONE, + LLRelationship::GRANT_MODIFY_OBJECTS); + ensure( + "Granted rights from still has online", + mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_ONLINE_STATUS)); + ensure( + "Granted rights from no longer modify", + !mRelationship.isRightGrantedFrom( + LLRelationship::GRANT_MODIFY_OBJECTS)); + } - template<> template<> - void user_relationship_object_t::test<4>() - { - ensure("No online status", !mRelationship.isOnline()); - mRelationship.online(true); - ensure("Online status", mRelationship.isOnline()); - mRelationship.online(false); - ensure("No online status", !mRelationship.isOnline()); - } + template<> template<> + void user_relationship_object_t::test<4>() + { + ensure("No online status", !mRelationship.isOnline()); + mRelationship.online(true); + ensure("Online status", mRelationship.isOnline()); + mRelationship.online(false); + ensure("No online status", !mRelationship.isOnline()); + } /* - template<> template<> - void user_relationship_object_t::test<>() - { - } + template<> template<> + void user_relationship_object_t::test<>() + { + } */ } diff --git a/indra/test/llxorcipher_tut.cpp b/indra/test/llxorcipher_tut.cpp index 55b3faaa61..9acac53604 100644 --- a/indra/test/llxorcipher_tut.cpp +++ b/indra/test/llxorcipher_tut.cpp @@ -7,25 +7,25 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - + #include "linden_common.h" #include "lltut.h" #include "llxorcipher.h" @@ -33,99 +33,99 @@ namespace tut { - struct cipher - { - }; - typedef test_group<cipher> cipher_t; - typedef cipher_t::object cipher_object_t; - tut::cipher_t tut_cipher("cipher"); + struct cipher + { + }; + typedef test_group<cipher> cipher_t; + typedef cipher_t::object cipher_object_t; + tut::cipher_t tut_cipher("cipher"); + + //encrypt->decrypt + template<> template<> + void cipher_object_t::test<1>() + { + const U32 len = 3; + const U8 pad[] = "abc"; + const char str[] = "SecondLife"; + const S32 str_len = sizeof(str); + U8 encrypted[str_len]; + U8 decrypted[str_len]; + LLXORCipher xorCipher(pad, len); + LLXORCipher xorCipher1(pad, len); + + U32 length = xorCipher.requiredEncryptionSpace(50); + ensure("requiredEncryptionSpace() function failed", (length == 50)); - //encrypt->decrypt - template<> template<> - void cipher_object_t::test<1>() - { - const U32 len = 3; - const U8 pad[] = "abc"; - const char str[] = "SecondLife"; - const S32 str_len = sizeof(str); - U8 encrypted[str_len]; - U8 decrypted[str_len]; - LLXORCipher xorCipher(pad, len); - LLXORCipher xorCipher1(pad, len); + U32 lenEncrypted = xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len); + ensure("Encryption failed", (lenEncrypted == str_len)); + U32 lenDecrypted = xorCipher1.decrypt(encrypted, str_len, decrypted, str_len); + ensure("Decryption failed", (lenDecrypted == str_len)); + ensure_memory_matches("LLXORCipher Encrypt/Decrypt failed", str, str_len, decrypted, lenDecrypted); + } - U32 length = xorCipher.requiredEncryptionSpace(50); - ensure("requiredEncryptionSpace() function failed", (length == 50)); + // operator= + template<> template<> + void cipher_object_t::test<2>() + { + const U8 pad[] = "ABCDEFGHIJKLMNOPQ"; // pad len longer than data to be ciphered + const U32 pad_len = sizeof(pad); + const U8 pad1[] = "SecondLife"; + const U32 pad_len1 = sizeof(pad1); + const char str[] = "To Be Ciphered"; + const S32 str_len = sizeof(str); + U8 encrypted[str_len]; + U8 decrypted[str_len]; - U32 lenEncrypted = xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len); - ensure("Encryption failed", (lenEncrypted == str_len)); - U32 lenDecrypted = xorCipher1.decrypt(encrypted, str_len, decrypted, str_len); - ensure("Decryption failed", (lenDecrypted == str_len)); - ensure_memory_matches("LLXORCipher Encrypt/Decrypt failed", str, str_len, decrypted, lenDecrypted); - } + LLXORCipher xorCipher(pad, pad_len); + LLXORCipher xorCipher1(pad1, pad_len1); - // operator= - template<> template<> - void cipher_object_t::test<2>() - { - const U8 pad[] = "ABCDEFGHIJKLMNOPQ"; // pad len longer than data to be ciphered - const U32 pad_len = sizeof(pad); - const U8 pad1[] = "SecondLife"; - const U32 pad_len1 = sizeof(pad1); - const char str[] = "To Be Ciphered"; - const S32 str_len = sizeof(str); - U8 encrypted[str_len]; - U8 decrypted[str_len]; + xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len); + // make xorCipher1 same as xorCipher..so that xorCipher1 can decrypt what was + // encrypted using xorCipher + xorCipher1 = xorCipher; + U32 lenDecrypted = xorCipher1.decrypt(encrypted, str_len, decrypted, str_len); + ensure_memory_matches("LLXORCipher operator= failed", str, str_len, decrypted, lenDecrypted); + } - LLXORCipher xorCipher(pad, pad_len); - LLXORCipher xorCipher1(pad1, pad_len1); + //in place encrypt->decrypt + template<> template<> + void cipher_object_t::test<3>() + { + U32 padNum = 0x12349087; + const U8* pad = (U8*) &padNum; + const U32 pad_len = sizeof(U32); + char str[] = "To Be Ciphered a long string.........!!!."; + char str1[] = "To Be Ciphered a long string.........!!!."; // same as str + const S32 str_len = sizeof(str); - xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len); - // make xorCipher1 same as xorCipher..so that xorCipher1 can decrypt what was - // encrypted using xorCipher - xorCipher1 = xorCipher; - U32 lenDecrypted = xorCipher1.decrypt(encrypted, str_len, decrypted, str_len); - ensure_memory_matches("LLXORCipher operator= failed", str, str_len, decrypted, lenDecrypted); - } - - //in place encrypt->decrypt - template<> template<> - void cipher_object_t::test<3>() - { - U32 padNum = 0x12349087; - const U8* pad = (U8*) &padNum; - const U32 pad_len = sizeof(U32); - char str[] = "To Be Ciphered a long string.........!!!."; - char str1[] = "To Be Ciphered a long string.........!!!."; // same as str - const S32 str_len = sizeof(str); + LLXORCipher xorCipher(pad, pad_len); + LLXORCipher xorCipher1(pad, pad_len); + xorCipher.encrypt((U8 *) str, str_len); + // it should not be the same as original data! + ensure("LLXORCipher: In Place encrypt failed", memcmp(str, str1, str_len) != 0); + xorCipher1.decrypt((U8 *) str, str_len); + // it should not be the same as original data! + ensure_memory_matches("LLXORCipher: In Place decrypt failed", str, str_len, str1, str_len); + } - LLXORCipher xorCipher(pad, pad_len); - LLXORCipher xorCipher1(pad, pad_len); - xorCipher.encrypt((U8 *) str, str_len); - // it should not be the same as original data! - ensure("LLXORCipher: In Place encrypt failed", memcmp(str, str1, str_len) != 0); - xorCipher1.decrypt((U8 *) str, str_len); - // it should not be the same as original data! - ensure_memory_matches("LLXORCipher: In Place decrypt failed", str, str_len, str1, str_len); - } + //LLNullCipher encrypt->decrypt + template<> template<> + void cipher_object_t::test<4>() + { + const char str[] = "SecondLife"; + const S32 str_len = sizeof(str); + U8 encrypted[str_len]; + U8 decrypted[str_len]; + LLNullCipher nullCipher; + LLNullCipher nullCipher1; - //LLNullCipher encrypt->decrypt - template<> template<> - void cipher_object_t::test<4>() - { - const char str[] = "SecondLife"; - const S32 str_len = sizeof(str); - U8 encrypted[str_len]; - U8 decrypted[str_len]; - LLNullCipher nullCipher; - LLNullCipher nullCipher1; + U32 length = nullCipher.requiredEncryptionSpace(50); + ensure("LLNullCipher::requiredEncryptionSpace() function failed", (length == 50)); - U32 length = nullCipher.requiredEncryptionSpace(50); - ensure("LLNullCipher::requiredEncryptionSpace() function failed", (length == 50)); + U32 len1 = nullCipher.encrypt((U8 *) str, str_len, encrypted, str_len); + ensure_memory_matches("LLNullCipher - Source transformed during encryption.", encrypted, len1, str, str_len); - U32 len1 = nullCipher.encrypt((U8 *) str, str_len, encrypted, str_len); - ensure_memory_matches("LLNullCipher - Source transformed during encryption.", encrypted, len1, str, str_len); - - U32 len2 = nullCipher1.decrypt(encrypted, str_len, decrypted, str_len); - ensure_memory_matches("LLNullCipher - Decryption failed", decrypted, len2, str, str_len); - } + U32 len2 = nullCipher1.decrypt(encrypted, str_len, decrypted, str_len); + ensure_memory_matches("LLNullCipher - Decryption failed", decrypted, len2, str, str_len); + } } diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp index 0a3e6621aa..14ba5884a8 100644 --- a/indra/test/message_tut.cpp +++ b/indra/test/message_tut.cpp @@ -1,147 +1,147 @@ -/** - * @file lldatapacker_tut.cpp - * @date 2007-04 - * @brief LLDataPacker test cases. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include <tut/tut.hpp> -#include "linden_common.h" -#include "lltut.h" -#include "llhttpconstants.h" -#include "llapr.h" -#include "llmessageconfig.h" -#include "llsdserialize.h" -#include "message.h" -#include "message_prehash.h" - -namespace -{ - struct Response : public LLHTTPNode::Response - { - virtual void result(const LLSD&) {} - virtual void status(S32 code, const std::string& message) - { - mStatus = code; - } - virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) { } - virtual void extendedResult(S32 code, const LLSD& result, const LLSD& headers) { } - S32 mStatus; - }; -} - -namespace tut -{ - struct LLMessageSystemTestData - { - std::string mTestConfigDir; - std::string mSep; - - LLMessageSystemTestData() - { - static bool init = false; - if(!init) - { - ll_init_apr(); - //init_prehash_data(); - init = true; - } - const F32 circuit_heartbeat_interval=5; - const F32 circuit_timeout=100; - - - // currently test disconnected message system - start_messaging_system("notafile", 13035, - 1, - 0, - 0, - false, - "notasharedsecret", - NULL, - false, - circuit_heartbeat_interval, - circuit_timeout - ); - // generate temp dir - std::ostringstream ostr; -#if LL_WINDOWS - mSep = "\\"; - ostr << "C:" << mSep; -#else - mSep = "/"; - ostr << mSep << "tmp" << mSep; -#endif - LLUUID random; - random.generate(); - ostr << "message-test-" << random; - mTestConfigDir = ostr.str(); - LLFile::mkdir(mTestConfigDir); - writeConfigFile(LLSD()); - LLMessageConfig::initClass("simulator", ostr.str()); - } - - ~LLMessageSystemTestData() - { - // not end_messaging_system() - delete static_cast<LLMessageSystem*>(gMessageSystem); - gMessageSystem = NULL; - - // rm contents of temp dir - std::ostringstream ostr; - ostr << mTestConfigDir << mSep << "message.xml"; - int rmfile = LLFile::remove(ostr.str()); - ensure_equals("rmfile value", rmfile, 0); - - // rm temp dir - int rmdir = LLFile::rmdir(mTestConfigDir); - ensure_equals("rmdir value", rmdir, 0); - } - - void writeConfigFile(const LLSD& config) - { - std::string ostr(mTestConfigDir + mSep + "message.xml"); - llofstream file(ostr.c_str()); - if (file.is_open()) - { - LLSDSerialize::toPrettyXML(config, file); - } - file.close(); - } - }; - - typedef test_group<LLMessageSystemTestData> LLMessageSystemTestGroup; - typedef LLMessageSystemTestGroup::object LLMessageSystemTestObject; - LLMessageSystemTestGroup messageTestGroup("LLMessageSystem"); - - template<> template<> - void LLMessageSystemTestObject::test<1>() - // dispatch unknown message - { - const char* name = "notamessasge"; - const LLSD message; - const LLPointer<Response> response = new Response(); - gMessageSystem->dispatch(name, message, response); - ensure_equals(response->mStatus, HTTP_NOT_FOUND); - } -} - +/**
+ * @file lldatapacker_tut.cpp
+ * @date 2007-04
+ * @brief LLDataPacker test cases.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include <tut/tut.hpp>
+#include "linden_common.h"
+#include "lltut.h"
+#include "llhttpconstants.h"
+#include "llapr.h"
+#include "llmessageconfig.h"
+#include "llsdserialize.h"
+#include "message.h"
+#include "message_prehash.h"
+
+namespace
+{
+ struct Response : public LLHTTPNode::Response
+ {
+ virtual void result(const LLSD&) {}
+ virtual void status(S32 code, const std::string& message)
+ {
+ mStatus = code;
+ }
+ virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
+ virtual void extendedResult(S32 code, const LLSD& result, const LLSD& headers) { }
+ S32 mStatus;
+ };
+}
+
+namespace tut
+{
+ struct LLMessageSystemTestData
+ {
+ std::string mTestConfigDir;
+ std::string mSep;
+
+ LLMessageSystemTestData()
+ {
+ static bool init = false;
+ if(!init)
+ {
+ ll_init_apr();
+ //init_prehash_data();
+ init = true;
+ }
+ const F32 circuit_heartbeat_interval=5;
+ const F32 circuit_timeout=100;
+
+
+ // currently test disconnected message system
+ start_messaging_system("notafile", 13035,
+ 1,
+ 0,
+ 0,
+ false,
+ "notasharedsecret",
+ NULL,
+ false,
+ circuit_heartbeat_interval,
+ circuit_timeout
+ );
+ // generate temp dir
+ std::ostringstream ostr;
+#if LL_WINDOWS
+ mSep = "\\";
+ ostr << "C:" << mSep;
+#else
+ mSep = "/";
+ ostr << mSep << "tmp" << mSep;
+#endif
+ LLUUID random;
+ random.generate();
+ ostr << "message-test-" << random;
+ mTestConfigDir = ostr.str();
+ LLFile::mkdir(mTestConfigDir);
+ writeConfigFile(LLSD());
+ LLMessageConfig::initClass("simulator", ostr.str());
+ }
+
+ ~LLMessageSystemTestData()
+ {
+ // not end_messaging_system()
+ delete static_cast<LLMessageSystem*>(gMessageSystem);
+ gMessageSystem = NULL;
+
+ // rm contents of temp dir
+ std::ostringstream ostr;
+ ostr << mTestConfigDir << mSep << "message.xml";
+ int rmfile = LLFile::remove(ostr.str());
+ ensure_equals("rmfile value", rmfile, 0);
+
+ // rm temp dir
+ int rmdir = LLFile::rmdir(mTestConfigDir);
+ ensure_equals("rmdir value", rmdir, 0);
+ }
+
+ void writeConfigFile(const LLSD& config)
+ {
+ std::string ostr(mTestConfigDir + mSep + "message.xml");
+ llofstream file(ostr.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(config, file);
+ }
+ file.close();
+ }
+ };
+
+ typedef test_group<LLMessageSystemTestData> LLMessageSystemTestGroup;
+ typedef LLMessageSystemTestGroup::object LLMessageSystemTestObject;
+ LLMessageSystemTestGroup messageTestGroup("LLMessageSystem");
+
+ template<> template<>
+ void LLMessageSystemTestObject::test<1>()
+ // dispatch unknown message
+ {
+ const char* name = "notamessasge";
+ const LLSD message;
+ const LLPointer<Response> response = new Response();
+ gMessageSystem->dispatch(name, message, response);
+ ensure_equals(response->mStatus, HTTP_NOT_FOUND);
+ }
+}
+
diff --git a/indra/test/mock_http_client.cpp b/indra/test/mock_http_client.cpp index e72902bfc2..a97d31c7f4 100644 --- a/indra/test/mock_http_client.cpp +++ b/indra/test/mock_http_client.cpp @@ -1,25 +1,25 @@ -/** +/** * @file mock_http_client.cpp * @brief Framework for testing HTTP requests * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -29,54 +29,54 @@ namespace tut { - class SuccessNode : public LLHTTPNode - { - public: - void get(ResponsePtr r, const LLSD& context) const - { - LLSD result; - result["state"] = "complete"; - result["test"] = "test"; - r->result(result); - } - void post(ResponsePtr r, const LLSD& context, const LLSD& input) const - { - LLSD result; - result["state"] = "complete"; - result["test"] = "test"; - r->result(result); - } - }; + class SuccessNode : public LLHTTPNode + { + public: + void get(ResponsePtr r, const LLSD& context) const + { + LLSD result; + result["state"] = "complete"; + result["test"] = "test"; + r->result(result); + } + void post(ResponsePtr r, const LLSD& context, const LLSD& input) const + { + LLSD result; + result["state"] = "complete"; + result["test"] = "test"; + r->result(result); + } + }; + + class ErrorNode : public LLHTTPNode + { + public: + void get(ResponsePtr r, const LLSD& context) const + { r->status(599, "Intentional error"); } + void post(ResponsePtr r, const LLSD& context, const LLSD& input) const + { r->status(input["status"], input["reason"]); } + }; - class ErrorNode : public LLHTTPNode - { - public: - void get(ResponsePtr r, const LLSD& context) const - { r->status(599, "Intentional error"); } - void post(ResponsePtr r, const LLSD& context, const LLSD& input) const - { r->status(input["status"], input["reason"]); } - }; + class TimeOutNode : public LLHTTPNode + { + public: + void get(ResponsePtr r, const LLSD& context) const + { + /* do nothing, the request will eventually time out */ + } + }; - class TimeOutNode : public LLHTTPNode - { - public: - void get(ResponsePtr r, const LLSD& context) const - { - /* do nothing, the request will eventually time out */ - } - }; + LLSD storage; - LLSD storage; - - class LLSDStorageNode : public LLHTTPNode - { - public: - LLSD get() const{ return storage; } - LLSD put(const LLSD& value) const{ storage = value; return LLSD(); } - }; + class LLSDStorageNode : public LLHTTPNode + { + public: + LLSD get() const{ return storage; } + LLSD put(const LLSD& value) const{ storage = value; return LLSD(); } + }; - LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage"); - LLHTTPRegistration<SuccessNode> gSuccessNode("/test/success"); - LLHTTPRegistration<ErrorNode> gErrorNode("/test/error"); - LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout"); + LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage"); + LLHTTPRegistration<SuccessNode> gSuccessNode("/test/success"); + LLHTTPRegistration<ErrorNode> gErrorNode("/test/error"); + LLHTTPRegistration<TimeOutNode> gTimeOutNode("/test/timeout"); } diff --git a/indra/test/mock_http_client.h b/indra/test/mock_http_client.h index a2b9b435fb..ef268abc6e 100644 --- a/indra/test/mock_http_client.h +++ b/indra/test/mock_http_client.h @@ -1,25 +1,25 @@ -/** +/** * @file mock_http_client.cpp * @brief Framework for testing HTTP requests * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -33,158 +33,158 @@ namespace tut { - struct MockHttpClient - { - public: - MockHttpClient() - { - apr_pool_create(&mPool, NULL); - mServerPump = new LLPumpIO(mPool); - mClientPump = new LLPumpIO(mPool); - - LLHTTPClient::setPump(*mClientPump); - } - - ~MockHttpClient() - { - delete mServerPump; - delete mClientPump; - apr_pool_destroy(mPool); - } - - void setupTheServer() - { - LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888); - - LLHTTPStandardServices::useServices(); - LLHTTPRegistrar::buildAllServices(root); - } - - void runThePump(float timeout = 100.0f) - { - LLTimer timer; - timer.setTimerExpirySec(timeout); - - while(!mSawCompleted && !timer.hasExpired()) - { - if (mServerPump) - { - mServerPump->pump(); - mServerPump->callback(); - } - if (mClientPump) - { - mClientPump->pump(); - mClientPump->callback(); - } - } - } - - void killServer() - { - delete mServerPump; - mServerPump = NULL; - } - - private: - apr_pool_t* mPool; - LLPumpIO* mServerPump; - LLPumpIO* mClientPump; - - - protected: - void ensureStatusOK() - { - if (mSawError) - { - std::string msg = - llformat("httpFailure() called when not expected, status %d", - mStatus); - fail(msg); - } - } - - void ensureStatusError() - { - if (!mSawError) - { - fail("httpFailure() wasn't called"); - } - } - - LLSD getResult() - { - return mResult; - } - - protected: - bool mSawError; - S32 mStatus; - std::string mReason; - bool mSawCompleted; - LLSD mResult; - bool mResultDeleted; - - class Result : public LLHTTPClient::Responder - { - protected: - Result(MockHttpClient& client) - : mClient(client) - { - } - - public: - static boost::intrusive_ptr<Result> build(MockHttpClient& client) - { - return boost::intrusive_ptr<Result>(new Result(client)); - } - - ~Result() - { - mClient.mResultDeleted = true; - } - - protected: - virtual void httpFailure() - { - mClient.mSawError = true; - mClient.mStatus = getStatus(); - mClient.mReason = getReason(); - } - - virtual void httpSuccess() - { - mClient.mResult = getContent(); - } - - virtual void httpCompleted() - { - LLHTTPClient::Responder::httpCompleted(); - - mClient.mSawCompleted = true; - } - - private: - MockHttpClient& mClient; - }; - - friend class Result; - - protected: - - void reset() - { - mSawError = false; - mStatus = 0; - mSawCompleted = false; - mResult.clear(); - mResultDeleted = false; - } - - LLHTTPClient::ResponderPtr newResult() - { - reset(); - return Result::build(*this); - } - }; + struct MockHttpClient + { + public: + MockHttpClient() + { + apr_pool_create(&mPool, NULL); + mServerPump = new LLPumpIO(mPool); + mClientPump = new LLPumpIO(mPool); + + LLHTTPClient::setPump(*mClientPump); + } + + ~MockHttpClient() + { + delete mServerPump; + delete mClientPump; + apr_pool_destroy(mPool); + } + + void setupTheServer() + { + LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888); + + LLHTTPStandardServices::useServices(); + LLHTTPRegistrar::buildAllServices(root); + } + + void runThePump(float timeout = 100.0f) + { + LLTimer timer; + timer.setTimerExpirySec(timeout); + + while(!mSawCompleted && !timer.hasExpired()) + { + if (mServerPump) + { + mServerPump->pump(); + mServerPump->callback(); + } + if (mClientPump) + { + mClientPump->pump(); + mClientPump->callback(); + } + } + } + + void killServer() + { + delete mServerPump; + mServerPump = NULL; + } + + private: + apr_pool_t* mPool; + LLPumpIO* mServerPump; + LLPumpIO* mClientPump; + + + protected: + void ensureStatusOK() + { + if (mSawError) + { + std::string msg = + llformat("httpFailure() called when not expected, status %d", + mStatus); + fail(msg); + } + } + + void ensureStatusError() + { + if (!mSawError) + { + fail("httpFailure() wasn't called"); + } + } + + LLSD getResult() + { + return mResult; + } + + protected: + bool mSawError; + S32 mStatus; + std::string mReason; + bool mSawCompleted; + LLSD mResult; + bool mResultDeleted; + + class Result : public LLHTTPClient::Responder + { + protected: + Result(MockHttpClient& client) + : mClient(client) + { + } + + public: + static boost::intrusive_ptr<Result> build(MockHttpClient& client) + { + return boost::intrusive_ptr<Result>(new Result(client)); + } + + ~Result() + { + mClient.mResultDeleted = true; + } + + protected: + virtual void httpFailure() + { + mClient.mSawError = true; + mClient.mStatus = getStatus(); + mClient.mReason = getReason(); + } + + virtual void httpSuccess() + { + mClient.mResult = getContent(); + } + + virtual void httpCompleted() + { + LLHTTPClient::Responder::httpCompleted(); + + mClient.mSawCompleted = true; + } + + private: + MockHttpClient& mClient; + }; + + friend class Result; + + protected: + + void reset() + { + mSawError = false; + mStatus = 0; + mSawCompleted = false; + mResult.clear(); + mResultDeleted = false; + } + + LLHTTPClient::ResponderPtr newResult() + { + reset(); + return Result::build(*this); + } + }; } diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h index ad14cebbd1..8027f95728 100644 --- a/indra/test/namedtempfile.h +++ b/indra/test/namedtempfile.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2012-01-13 * @brief NamedTempFile class for tests that need disk files as fixtures. - * + * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Copyright (c) 2012, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/prim_linkability_tut.cpp b/indra/test/prim_linkability_tut.cpp index a70912e535..3603b25f18 100644 --- a/indra/test/prim_linkability_tut.cpp +++ b/indra/test/prim_linkability_tut.cpp @@ -1,4 +1,4 @@ -/** +/** * @file linkability.cpp * @author andrew@lindenlab.com * @date 2007-04-23 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -35,461 +35,461 @@ // helper function void randomize_sphere(LLSphere& sphere, F32 center_range, F32 radius_range) { - F32 radius = ll_frand(2.f * radius_range) - radius_range; - LLVector3 center; - for (S32 i=0; i<3; ++i) - { - center.mV[i] = ll_frand(2.f * center_range) - center_range; - } - sphere.setRadius(radius); - sphere.setCenter(center); + F32 radius = ll_frand(2.f * radius_range) - radius_range; + LLVector3 center; + for (S32 i=0; i<3; ++i) + { + center.mV[i] = ll_frand(2.f * center_range) - center_range; + } + sphere.setRadius(radius); + sphere.setCenter(center); } // helper function. Same as above with a min and max radius. void randomize_sphere(LLSphere& sphere, F32 center_range, F32 minimum_radius, F32 maximum_radius) { - F32 radius = ll_frand(maximum_radius - minimum_radius) + minimum_radius; - LLVector3 center; - for (S32 i=0; i<3; ++i) - { - center.mV[i] = ll_frand(2.f * center_range) - center_range; - } - sphere.setRadius(radius); - sphere.setCenter(center); + F32 radius = ll_frand(maximum_radius - minimum_radius) + minimum_radius; + LLVector3 center; + for (S32 i=0; i<3; ++i) + { + center.mV[i] = ll_frand(2.f * center_range) - center_range; + } + sphere.setRadius(radius); + sphere.setCenter(center); } // helper function bool random_sort( const LLPrimLinkInfo< S32 >&, const LLPrimLinkInfo< S32 >& b) { - return (ll_rand(64) < 32); + return (ll_rand(64) < 32); } namespace tut { - struct linkable_data - { - LLPrimLinkInfo<S32> info; - }; - - typedef test_group<linkable_data> linkable_test; - typedef linkable_test::object linkable_object; - tut::linkable_test wtf("prim linkability"); - - template<> template<> - void linkable_object::test<1>() - { - // Here we test the boundary of the LLPrimLinkInfo::canLink() method - // between semi-random middle-sized objects. - - S32 number_of_tests = 100; - for (S32 test = 0; test < number_of_tests; ++test) - { - // compute the radii that would provide the above max link distance - F32 first_radius = 0.f; - F32 second_radius = 0.f; - - // compute a random center for the first sphere - // compute some random max link distance - F32 max_link_span = ll_frand(MAX_OBJECT_SPAN); - if (max_link_span < OBJECT_SPAN_BONUS) - { - max_link_span += OBJECT_SPAN_BONUS; - } - LLVector3 first_center( - ll_frand(2.f * max_link_span) - max_link_span, - ll_frand(2.f * max_link_span) - max_link_span, - ll_frand(2.f * max_link_span) - max_link_span); - - // put the second sphere at the right distance from the origin - // such that it is within the max_link_distance of the first - LLVector3 direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); - direction.normalize(); - F32 half_milimeter = 0.0005f; - LLVector3 second_center; - - // max_span = 3 * (first_radius + second_radius) + OBJECT_SPAN_BONUS - // make sure they link at short distances - { - second_center = first_center + (OBJECT_SPAN_BONUS - half_milimeter) * direction; - LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); - LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); - ensure("these nearby objects should link", first_info.canLink(second_info) ); - } - - // make sure they fail to link if we move them apart just a little bit - { - second_center = first_center + (OBJECT_SPAN_BONUS + half_milimeter) * direction; - LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); - LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); - ensure("these nearby objects should NOT link", !first_info.canLink(second_info) ); - } - - // make sure the objects link or not at medium distances - { - first_radius = 0.3f * ll_frand(max_link_span - OBJECT_SPAN_BONUS); - - // This is the exact second radius that will link at exactly our random max_link_distance - second_radius = ((max_link_span - OBJECT_SPAN_BONUS) / 3.f) - first_radius; - second_center = first_center + (max_link_span - first_radius - second_radius - half_milimeter) * direction; - - LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); - LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); - - ensure("these objects should link", first_info.canLink(second_info) ); - } - - // make sure they fail to link if we move them apart just a little bit - { - // move the second sphere such that it is a little too far from the first - second_center += (2.f * half_milimeter) * direction; - LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); - LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); - - ensure("these objects should NOT link", !first_info.canLink(second_info) ); - } - - // make sure things don't link at far distances - { - second_center = first_center + (MAX_OBJECT_SPAN + 2.f * half_milimeter) * direction; - second_radius = 0.3f * MAX_OBJECT_SPAN; - LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); - LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); - ensure("these objects should NOT link", !first_info.canLink(second_info) ); - } - - } - } - - template<> template<> - void linkable_object::test<2>() - { - - // Consider a row of eight spheres in a row, each 10m in diameter and centered - // at 10m intervals: 01234567. - - F32 radius = 5.f; - F32 spacing = 10.f; - - LLVector3 line_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); - line_direction.normalize(); - - LLVector3 first_center(ll_frand(2.f * spacing) -spacing, ll_frand(2.f * spacing) - spacing, ll_frand(2.f * spacing) - spacing); - - LLPrimLinkInfo<S32> infos[8]; - - for (S32 index = 0; index < 8; ++index) - { - LLVector3 center = first_center + ((F32)(index) * spacing) * line_direction; - infos[index].set(index, LLSphere(center, radius)); - } - - // Max span for 2 spheres of 5m radius is 3 * (5 + 5) + 1 = 31m - // spheres 0&2 have a 30m span (from outside edge to outside edge) and should link - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - info_list.push_back(infos[2]); - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("0&2 prim count should be 2", prim_count, 2); - ensure_equals("0&2 unlinkable list should have length 0", (S32) info_list.size(), 0); - } - - - // spheres 0&3 have a 40 meter span and should NOT link outright - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - info_list.push_back(infos[3]); - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("0&4 prim count should be 1", prim_count, 1); - ensure_equals("0&4 unlinkable list should have length 1", (S32) info_list.size(), 1); - } - - - // spheres 0-4 should link no matter what order : 01234 - // Total span = 50m, 012 link with a r=15.5 giving max span of 3 * (15.5 + 5) + 1 = 62.5, but the cap is 54m - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - for (S32 index = 1; index < 5; ++index) - { - info_list.push_back(infos[index]); - } - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("01234 prim count should be 5", prim_count, 5); - ensure_equals("01234 unlinkable list should have length 0", (S32) info_list.size(), 0); - } - - - // spheres 0-5 should link no matter what order : 04321 - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - for (S32 index = 4; index > 0; --index) - { - info_list.push_back(infos[index]); - } - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("04321 prim count should be 5", prim_count, 5); - ensure_equals("04321 unlinkable list should have length 0", (S32) info_list.size(), 0); - } - - // spheres 0-4 should link no matter what order : 01423 - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - info_list.push_back(infos[1]); - info_list.push_back(infos[4]); - info_list.push_back(infos[2]); - info_list.push_back(infos[3]); - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("01423 prim count should be 5", prim_count, 5); - ensure_equals("01423 unlinkable list should have length 0", (S32) info_list.size(), 0); - } - - // spheres 0-5 should NOT fully link, only 0-4 - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - for (S32 index = 1; index < 6; ++index) - { - info_list.push_back(infos[index]); - } - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("012345 prim count should be 5", prim_count, 5); - ensure_equals("012345 unlinkable list should have length 1", (S32) info_list.size(), 1); - std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin(); - if (info_itr != info_list.end()) - { - // examine the contents of the unlinked info - std::list<S32> unlinked_indecies; - info_itr->getData(unlinked_indecies); - // make sure there is only one index in the unlinked_info - ensure_equals("012345 unlinkable index count should be 1", (S32) unlinked_indecies.size(), 1); - // make sure its value is 6 - std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin(); - S32 unlinkable_index = *unlinked_index_itr; - ensure_equals("012345 unlinkable index should be 5", (S32) unlinkable_index, 5); - } - } - - // spheres 0-7 should NOT fully link, only 0-5 - { - LLPrimLinkInfo<S32> root_info = infos[0]; - std::list< LLPrimLinkInfo<S32> > info_list; - for (S32 index = 1; index < 8; ++index) - { - info_list.push_back(infos[index]); - } - root_info.mergeLinkableSet(info_list); - S32 prim_count = root_info.getPrimCount(); - ensure_equals("01234567 prim count should be 5", prim_count, 5); - // Should be 1 linkinfo on unlinkable that has 2 prims - ensure_equals("01234567 unlinkable list should have length 1", (S32) info_list.size(), 1); - std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin(); - if (info_itr != info_list.end()) - { - // make sure there is only one index in the unlinked_info - std::list<S32> unlinked_indecies; - info_itr->getData(unlinked_indecies); - ensure_equals("0123456 unlinkable index count should be 3", (S32) unlinked_indecies.size(), 3); - - // make sure its values are 6 and 7 - std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin(); - S32 unlinkable_index = *unlinked_index_itr; - ensure_equals("0123456 first unlinkable index should be 5", (S32) unlinkable_index, 5); - ++unlinked_index_itr; - unlinkable_index = *unlinked_index_itr; - ensure_equals("0123456 second unlinkable index should be 6", (S32) unlinkable_index, 6); - ++unlinked_index_itr; - unlinkable_index = *unlinked_index_itr; - ensure_equals("0123456 third unlinkable index should be 7", (S32) unlinkable_index, 7); - - } - } - } - - template<> template<> - void linkable_object::test<3>() - { - // Here we test the link results between an LLPrimLinkInfo and a set of - // randomized LLPrimLinkInfos where the expected results are known. - S32 number_of_tests = 5; - for (S32 test = 0; test < number_of_tests; ++test) - { - // the radii are known - F32 first_radius = 1.f; - F32 second_radius = 2.f; - F32 third_radius = 3.f; - - // compute the distances - F32 half_milimeter = 0.0005f; - F32 max_first_second_span = 3.f * (first_radius + second_radius) + OBJECT_SPAN_BONUS; - F32 linkable_distance = max_first_second_span - first_radius - second_radius - half_milimeter; - - F32 max_full_span = 3.f * (0.5f * max_first_second_span + third_radius) + OBJECT_SPAN_BONUS; - F32 unlinkable_distance = max_full_span - 0.5f * linkable_distance - third_radius + half_milimeter; - - // compute some random directions - LLVector3 first_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); - first_direction.normalize(); - LLVector3 second_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); - second_direction.normalize(); - LLVector3 third_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); - third_direction.normalize(); - - // compute the centers - LLVector3 first_center = ll_frand(10.f) * first_direction; - LLVector3 second_center = first_center + ll_frand(linkable_distance) * second_direction; - LLVector3 first_join_center = 0.5f * (first_center + second_center); - LLVector3 third_center = first_join_center + unlinkable_distance * third_direction; - - // make sure the second info links and the third does not - { - // initialize the infos - S32 index = 0; - LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius)); - LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius)); - LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius)); - - // put the second and third infos in a list - std::list< LLPrimLinkInfo<S32> > info_list; - info_list.push_back(second_info); - info_list.push_back(third_info); - - // merge the list with the first_info - first_info.mergeLinkableSet(info_list); - S32 prim_count = first_info.getPrimCount(); - - ensure_equals("prim count should be 2", prim_count, 2); - ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1); - } - - // reverse the order and make sure we get the same results - { - // initialize the infos - S32 index = 0; - LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius)); - LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius)); - LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius)); - - // build the list in the reverse order - std::list< LLPrimLinkInfo<S32> > info_list; - info_list.push_back(third_info); - info_list.push_back(second_info); - - // merge the list with the first_info - first_info.mergeLinkableSet(info_list); - S32 prim_count = first_info.getPrimCount(); - - ensure_equals("prim count should be 2", prim_count, 2); - ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1); - } - } - } - - template<> template<> - void linkable_object::test<4>() - { - // Here we test whether linkability is invarient under permutations - // of link order. To do this we generate a bunch of random spheres - // and then try to link them in different ways. - // - // NOTE: the linkability will only be invarient if there is only one - // linkable solution. Multiple solutions will exist if the set of - // candidates are larger than the maximum linkable distance, or more - // numerous than a single linked object can contain. This is easily - // understood by considering a very large set of link candidates, - // and first linking preferentially to the left until linking fails, - // then doing the same to the right -- the final solutions will differ. - // Hence for this test we must generate candidate sets that lie within - // the linkability envelope of a single object. - // - // NOTE: a random set of objects will tend to either be totally linkable - // or totally not. That is, the random orientations that - - F32 root_center_range = 0.f; - F32 min_prim_radius = 0.1f; - F32 max_prim_radius = 2.f; - - // Linkability is min(MAX_OBJECT_SPAN,3 *( R1 + R2 ) + BONUS) - // 3 * (min_prim_radius + min_prim_radius) + OBJECT_SPAN_BONUS = 6 * min_prim_radius + OBJECT_SPAN_BONUS; - // Use .45 instead of .5 to gaurantee objects are within the minimum span. - F32 child_center_range = 0.45f * ( (6*min_prim_radius) + OBJECT_SPAN_BONUS ); - - S32 number_of_tests = 100; - S32 number_of_spheres = 10; - S32 number_of_scrambles = 10; - S32 number_of_random_bubble_sorts = 10; - - for (S32 test = 0; test < number_of_tests; ++test) - { - LLSphere sphere; - S32 sphere_index = 0; - - // build the root piece - randomize_sphere(sphere, root_center_range, min_prim_radius, max_prim_radius); - info.set( sphere_index++, sphere ); - - // build the unlinked pieces - std::list< LLPrimLinkInfo<S32> > info_list; - for (; sphere_index < number_of_spheres; ++sphere_index) - { - randomize_sphere(sphere, child_center_range, min_prim_radius, max_prim_radius); - LLPrimLinkInfo<S32> child_info( sphere_index, sphere ); - info_list.push_back(child_info); - } - - // declare the variables used to store the results - std::list<S32> first_linked_list; - - { - // the link attempt will modify our original info's, so we - // have to make copies of the originals for testing - LLPrimLinkInfo<S32> test_info( 0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) ); - std::list< LLPrimLinkInfo<S32> > test_list; - test_list.assign(info_list.begin(), info_list.end()); - - // try to link - test_info.mergeLinkableSet(test_list); - - ensure("All prims should link, but did not.",test_list.empty()); - - // store the results - test_info.getData(first_linked_list); - first_linked_list.sort(); - } - - // try to link the spheres in various random orders - for (S32 scramble = 0; scramble < number_of_scrambles; ++scramble) - { - LLPrimLinkInfo<S32> test_info(0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) ); - - // scramble the order of the info_list - std::list< LLPrimLinkInfo<S32> > test_list; - test_list.assign(info_list.begin(), info_list.end()); - for (S32 i = 0; i < number_of_random_bubble_sorts; i++) - { - test_list.sort(random_sort); - } - - // try to link - test_info.mergeLinkableSet(test_list); - - // get the results - std::list<S32> linked_list; - test_info.getData(linked_list); - linked_list.sort(); - - ensure_equals("linked set size should be order independent",linked_list.size(),first_linked_list.size()); - } - } - } + struct linkable_data + { + LLPrimLinkInfo<S32> info; + }; + + typedef test_group<linkable_data> linkable_test; + typedef linkable_test::object linkable_object; + tut::linkable_test wtf("prim linkability"); + + template<> template<> + void linkable_object::test<1>() + { + // Here we test the boundary of the LLPrimLinkInfo::canLink() method + // between semi-random middle-sized objects. + + S32 number_of_tests = 100; + for (S32 test = 0; test < number_of_tests; ++test) + { + // compute the radii that would provide the above max link distance + F32 first_radius = 0.f; + F32 second_radius = 0.f; + + // compute a random center for the first sphere + // compute some random max link distance + F32 max_link_span = ll_frand(MAX_OBJECT_SPAN); + if (max_link_span < OBJECT_SPAN_BONUS) + { + max_link_span += OBJECT_SPAN_BONUS; + } + LLVector3 first_center( + ll_frand(2.f * max_link_span) - max_link_span, + ll_frand(2.f * max_link_span) - max_link_span, + ll_frand(2.f * max_link_span) - max_link_span); + + // put the second sphere at the right distance from the origin + // such that it is within the max_link_distance of the first + LLVector3 direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + direction.normalize(); + F32 half_milimeter = 0.0005f; + LLVector3 second_center; + + // max_span = 3 * (first_radius + second_radius) + OBJECT_SPAN_BONUS + // make sure they link at short distances + { + second_center = first_center + (OBJECT_SPAN_BONUS - half_milimeter) * direction; + LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); + LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); + ensure("these nearby objects should link", first_info.canLink(second_info) ); + } + + // make sure they fail to link if we move them apart just a little bit + { + second_center = first_center + (OBJECT_SPAN_BONUS + half_milimeter) * direction; + LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); + LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); + ensure("these nearby objects should NOT link", !first_info.canLink(second_info) ); + } + + // make sure the objects link or not at medium distances + { + first_radius = 0.3f * ll_frand(max_link_span - OBJECT_SPAN_BONUS); + + // This is the exact second radius that will link at exactly our random max_link_distance + second_radius = ((max_link_span - OBJECT_SPAN_BONUS) / 3.f) - first_radius; + second_center = first_center + (max_link_span - first_radius - second_radius - half_milimeter) * direction; + + LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); + LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); + + ensure("these objects should link", first_info.canLink(second_info) ); + } + + // make sure they fail to link if we move them apart just a little bit + { + // move the second sphere such that it is a little too far from the first + second_center += (2.f * half_milimeter) * direction; + LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); + LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); + + ensure("these objects should NOT link", !first_info.canLink(second_info) ); + } + + // make sure things don't link at far distances + { + second_center = first_center + (MAX_OBJECT_SPAN + 2.f * half_milimeter) * direction; + second_radius = 0.3f * MAX_OBJECT_SPAN; + LLPrimLinkInfo<S32> first_info(0, LLSphere(first_center, first_radius) ); + LLPrimLinkInfo<S32> second_info(1, LLSphere(second_center, second_radius) ); + ensure("these objects should NOT link", !first_info.canLink(second_info) ); + } + + } + } + + template<> template<> + void linkable_object::test<2>() + { + + // Consider a row of eight spheres in a row, each 10m in diameter and centered + // at 10m intervals: 01234567. + + F32 radius = 5.f; + F32 spacing = 10.f; + + LLVector3 line_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + line_direction.normalize(); + + LLVector3 first_center(ll_frand(2.f * spacing) -spacing, ll_frand(2.f * spacing) - spacing, ll_frand(2.f * spacing) - spacing); + + LLPrimLinkInfo<S32> infos[8]; + + for (S32 index = 0; index < 8; ++index) + { + LLVector3 center = first_center + ((F32)(index) * spacing) * line_direction; + infos[index].set(index, LLSphere(center, radius)); + } + + // Max span for 2 spheres of 5m radius is 3 * (5 + 5) + 1 = 31m + // spheres 0&2 have a 30m span (from outside edge to outside edge) and should link + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + info_list.push_back(infos[2]); + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("0&2 prim count should be 2", prim_count, 2); + ensure_equals("0&2 unlinkable list should have length 0", (S32) info_list.size(), 0); + } + + + // spheres 0&3 have a 40 meter span and should NOT link outright + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + info_list.push_back(infos[3]); + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("0&4 prim count should be 1", prim_count, 1); + ensure_equals("0&4 unlinkable list should have length 1", (S32) info_list.size(), 1); + } + + + // spheres 0-4 should link no matter what order : 01234 + // Total span = 50m, 012 link with a r=15.5 giving max span of 3 * (15.5 + 5) + 1 = 62.5, but the cap is 54m + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + for (S32 index = 1; index < 5; ++index) + { + info_list.push_back(infos[index]); + } + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("01234 prim count should be 5", prim_count, 5); + ensure_equals("01234 unlinkable list should have length 0", (S32) info_list.size(), 0); + } + + + // spheres 0-5 should link no matter what order : 04321 + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + for (S32 index = 4; index > 0; --index) + { + info_list.push_back(infos[index]); + } + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("04321 prim count should be 5", prim_count, 5); + ensure_equals("04321 unlinkable list should have length 0", (S32) info_list.size(), 0); + } + + // spheres 0-4 should link no matter what order : 01423 + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + info_list.push_back(infos[1]); + info_list.push_back(infos[4]); + info_list.push_back(infos[2]); + info_list.push_back(infos[3]); + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("01423 prim count should be 5", prim_count, 5); + ensure_equals("01423 unlinkable list should have length 0", (S32) info_list.size(), 0); + } + + // spheres 0-5 should NOT fully link, only 0-4 + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + for (S32 index = 1; index < 6; ++index) + { + info_list.push_back(infos[index]); + } + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("012345 prim count should be 5", prim_count, 5); + ensure_equals("012345 unlinkable list should have length 1", (S32) info_list.size(), 1); + std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin(); + if (info_itr != info_list.end()) + { + // examine the contents of the unlinked info + std::list<S32> unlinked_indecies; + info_itr->getData(unlinked_indecies); + // make sure there is only one index in the unlinked_info + ensure_equals("012345 unlinkable index count should be 1", (S32) unlinked_indecies.size(), 1); + // make sure its value is 6 + std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin(); + S32 unlinkable_index = *unlinked_index_itr; + ensure_equals("012345 unlinkable index should be 5", (S32) unlinkable_index, 5); + } + } + + // spheres 0-7 should NOT fully link, only 0-5 + { + LLPrimLinkInfo<S32> root_info = infos[0]; + std::list< LLPrimLinkInfo<S32> > info_list; + for (S32 index = 1; index < 8; ++index) + { + info_list.push_back(infos[index]); + } + root_info.mergeLinkableSet(info_list); + S32 prim_count = root_info.getPrimCount(); + ensure_equals("01234567 prim count should be 5", prim_count, 5); + // Should be 1 linkinfo on unlinkable that has 2 prims + ensure_equals("01234567 unlinkable list should have length 1", (S32) info_list.size(), 1); + std::list< LLPrimLinkInfo<S32> >::iterator info_itr = info_list.begin(); + if (info_itr != info_list.end()) + { + // make sure there is only one index in the unlinked_info + std::list<S32> unlinked_indecies; + info_itr->getData(unlinked_indecies); + ensure_equals("0123456 unlinkable index count should be 3", (S32) unlinked_indecies.size(), 3); + + // make sure its values are 6 and 7 + std::list<S32>::iterator unlinked_index_itr = unlinked_indecies.begin(); + S32 unlinkable_index = *unlinked_index_itr; + ensure_equals("0123456 first unlinkable index should be 5", (S32) unlinkable_index, 5); + ++unlinked_index_itr; + unlinkable_index = *unlinked_index_itr; + ensure_equals("0123456 second unlinkable index should be 6", (S32) unlinkable_index, 6); + ++unlinked_index_itr; + unlinkable_index = *unlinked_index_itr; + ensure_equals("0123456 third unlinkable index should be 7", (S32) unlinkable_index, 7); + + } + } + } + + template<> template<> + void linkable_object::test<3>() + { + // Here we test the link results between an LLPrimLinkInfo and a set of + // randomized LLPrimLinkInfos where the expected results are known. + S32 number_of_tests = 5; + for (S32 test = 0; test < number_of_tests; ++test) + { + // the radii are known + F32 first_radius = 1.f; + F32 second_radius = 2.f; + F32 third_radius = 3.f; + + // compute the distances + F32 half_milimeter = 0.0005f; + F32 max_first_second_span = 3.f * (first_radius + second_radius) + OBJECT_SPAN_BONUS; + F32 linkable_distance = max_first_second_span - first_radius - second_radius - half_milimeter; + + F32 max_full_span = 3.f * (0.5f * max_first_second_span + third_radius) + OBJECT_SPAN_BONUS; + F32 unlinkable_distance = max_full_span - 0.5f * linkable_distance - third_radius + half_milimeter; + + // compute some random directions + LLVector3 first_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + first_direction.normalize(); + LLVector3 second_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + second_direction.normalize(); + LLVector3 third_direction(ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + third_direction.normalize(); + + // compute the centers + LLVector3 first_center = ll_frand(10.f) * first_direction; + LLVector3 second_center = first_center + ll_frand(linkable_distance) * second_direction; + LLVector3 first_join_center = 0.5f * (first_center + second_center); + LLVector3 third_center = first_join_center + unlinkable_distance * third_direction; + + // make sure the second info links and the third does not + { + // initialize the infos + S32 index = 0; + LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius)); + LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius)); + LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius)); + + // put the second and third infos in a list + std::list< LLPrimLinkInfo<S32> > info_list; + info_list.push_back(second_info); + info_list.push_back(third_info); + + // merge the list with the first_info + first_info.mergeLinkableSet(info_list); + S32 prim_count = first_info.getPrimCount(); + + ensure_equals("prim count should be 2", prim_count, 2); + ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1); + } + + // reverse the order and make sure we get the same results + { + // initialize the infos + S32 index = 0; + LLPrimLinkInfo<S32> first_info(index++, LLSphere(first_center, first_radius)); + LLPrimLinkInfo<S32> second_info(index++, LLSphere(second_center, second_radius)); + LLPrimLinkInfo<S32> third_info(index++, LLSphere(third_center, third_radius)); + + // build the list in the reverse order + std::list< LLPrimLinkInfo<S32> > info_list; + info_list.push_back(third_info); + info_list.push_back(second_info); + + // merge the list with the first_info + first_info.mergeLinkableSet(info_list); + S32 prim_count = first_info.getPrimCount(); + + ensure_equals("prim count should be 2", prim_count, 2); + ensure_equals("unlinkable list should have length 1", (S32) info_list.size(), 1); + } + } + } + + template<> template<> + void linkable_object::test<4>() + { + // Here we test whether linkability is invarient under permutations + // of link order. To do this we generate a bunch of random spheres + // and then try to link them in different ways. + // + // NOTE: the linkability will only be invarient if there is only one + // linkable solution. Multiple solutions will exist if the set of + // candidates are larger than the maximum linkable distance, or more + // numerous than a single linked object can contain. This is easily + // understood by considering a very large set of link candidates, + // and first linking preferentially to the left until linking fails, + // then doing the same to the right -- the final solutions will differ. + // Hence for this test we must generate candidate sets that lie within + // the linkability envelope of a single object. + // + // NOTE: a random set of objects will tend to either be totally linkable + // or totally not. That is, the random orientations that + + F32 root_center_range = 0.f; + F32 min_prim_radius = 0.1f; + F32 max_prim_radius = 2.f; + + // Linkability is min(MAX_OBJECT_SPAN,3 *( R1 + R2 ) + BONUS) + // 3 * (min_prim_radius + min_prim_radius) + OBJECT_SPAN_BONUS = 6 * min_prim_radius + OBJECT_SPAN_BONUS; + // Use .45 instead of .5 to gaurantee objects are within the minimum span. + F32 child_center_range = 0.45f * ( (6*min_prim_radius) + OBJECT_SPAN_BONUS ); + + S32 number_of_tests = 100; + S32 number_of_spheres = 10; + S32 number_of_scrambles = 10; + S32 number_of_random_bubble_sorts = 10; + + for (S32 test = 0; test < number_of_tests; ++test) + { + LLSphere sphere; + S32 sphere_index = 0; + + // build the root piece + randomize_sphere(sphere, root_center_range, min_prim_radius, max_prim_radius); + info.set( sphere_index++, sphere ); + + // build the unlinked pieces + std::list< LLPrimLinkInfo<S32> > info_list; + for (; sphere_index < number_of_spheres; ++sphere_index) + { + randomize_sphere(sphere, child_center_range, min_prim_radius, max_prim_radius); + LLPrimLinkInfo<S32> child_info( sphere_index, sphere ); + info_list.push_back(child_info); + } + + // declare the variables used to store the results + std::list<S32> first_linked_list; + + { + // the link attempt will modify our original info's, so we + // have to make copies of the originals for testing + LLPrimLinkInfo<S32> test_info( 0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) ); + std::list< LLPrimLinkInfo<S32> > test_list; + test_list.assign(info_list.begin(), info_list.end()); + + // try to link + test_info.mergeLinkableSet(test_list); + + ensure("All prims should link, but did not.",test_list.empty()); + + // store the results + test_info.getData(first_linked_list); + first_linked_list.sort(); + } + + // try to link the spheres in various random orders + for (S32 scramble = 0; scramble < number_of_scrambles; ++scramble) + { + LLPrimLinkInfo<S32> test_info(0, LLSphere(info.getCenter(), 0.5f * info.getDiameter()) ); + + // scramble the order of the info_list + std::list< LLPrimLinkInfo<S32> > test_list; + test_list.assign(info_list.begin(), info_list.end()); + for (S32 i = 0; i < number_of_random_bubble_sorts; i++) + { + test_list.sort(random_sort); + } + + // try to link + test_info.mergeLinkableSet(test_list); + + // get the results + std::list<S32> linked_list; + test_info.getData(linked_list); + linked_list.sort(); + + ensure_equals("linked set size should be order independent",linked_list.size(),first_linked_list.size()); + } + } + } } diff --git a/indra/test/print.h b/indra/test/print.h index 08e36caddf..7577698cc8 100644 --- a/indra/test/print.h +++ b/indra/test/print.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2020-01-02 * @brief print() function for debugging - * + * * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Copyright (c) 2020, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/setenv.h b/indra/test/setenv.h index ed2de9ccca..a691697adb 100644 --- a/indra/test/setenv.h +++ b/indra/test/setenv.h @@ -4,7 +4,7 @@ * @date 2020-04-01 * @brief Provide a way for a particular test program to alter the * environment before entry to main(). - * + * * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Copyright (c) 2020, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/sync.h b/indra/test/sync.h index bd837cb730..82eef1e5f5 100644 --- a/indra/test/sync.h +++ b/indra/test/sync.h @@ -7,7 +7,7 @@ * mechanisms. Such tests usually want to interleave coroutine * executions in strictly stepwise fashion. This class supports that * paradigm. - * + * * $LicenseInfo:firstyear=2019&license=viewerlgpl$ * Copyright (c) 2019, Linden Research, Inc. * $/LicenseInfo$ diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 6b88553cbb..cbd1077306 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file test.cpp * @author Phoenix * @date 2005-09-26 @@ -7,26 +7,26 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -/** +/** * * You can add tests by creating a new cpp file in this directory, and * rebuilding. There are at most 50 tests per testgroup without a @@ -47,10 +47,10 @@ #include "apr_getopt.h" // the CTYPE_WORKAROUND is needed for linux dev stations that don't -// have the broken libc6 packages needed by our out-of-date static +// have the broken libc6 packages needed by our out-of-date static // libs (such as libcrypto and libcurl). -- Leviathan 20060113 #ifdef CTYPE_WORKAROUND -# include "ctype_workaround.h" +# include "ctype_workaround.h" #endif #if LL_MSVC @@ -74,254 +74,254 @@ void wouldHaveCrashed(const std::string& message); namespace tut { - std::string sSourceDir; + std::string sSourceDir; - test_runner_singleton runner; + test_runner_singleton runner; } class LLReplayLog { public: - LLReplayLog() {} - virtual ~LLReplayLog() {} + LLReplayLog() {} + virtual ~LLReplayLog() {} - virtual void reset() {} - virtual void replay(std::ostream&) {} + virtual void reset() {} + virtual void replay(std::ostream&) {} }; class RecordToTempFile : public LLError::Recorder, public boost::noncopyable { public: - RecordToTempFile() - : LLError::Recorder(), - boost::noncopyable(), - mTempFile("log", ""), - mFile(mTempFile.getName().c_str()) - { - } - - virtual ~RecordToTempFile() - { - mFile.close(); - } - - virtual void recordMessage(LLError::ELevel level, const std::string& message) - { + RecordToTempFile() + : LLError::Recorder(), + boost::noncopyable(), + mTempFile("log", ""), + mFile(mTempFile.getName().c_str()) + { + } + + virtual ~RecordToTempFile() + { + mFile.close(); + } + + virtual void recordMessage(LLError::ELevel level, const std::string& message) + { LL_PROFILE_ZONE_SCOPED - mFile << message << std::endl; - } - - void reset() - { - mFile.close(); - mFile.open(mTempFile.getName().c_str()); - } - - void replay(std::ostream& out) - { - mFile.close(); - std::ifstream inf(mTempFile.getName().c_str()); - std::string line; - while (std::getline(inf, line)) - { - out << line << std::endl; - } - } + mFile << message << std::endl; + } + + void reset() + { + mFile.close(); + mFile.open(mTempFile.getName().c_str()); + } + + void replay(std::ostream& out) + { + mFile.close(); + std::ifstream inf(mTempFile.getName().c_str()); + std::string line; + while (std::getline(inf, line)) + { + out << line << std::endl; + } + } private: - NamedTempFile mTempFile; - llofstream mFile; + NamedTempFile mTempFile; + llofstream mFile; }; class LLReplayLogReal: public LLReplayLog, public boost::noncopyable { public: - LLReplayLogReal(LLError::ELevel level) - : LLReplayLog(), - boost::noncopyable(), - mOldSettings(LLError::saveAndResetSettings()), - mRecorder(new RecordToTempFile()) - { - LLError::setFatalFunction(wouldHaveCrashed); - LLError::setDefaultLevel(level); - LLError::addRecorder(mRecorder); - } - - virtual ~LLReplayLogReal() - { - LLError::removeRecorder(mRecorder); - LLError::restoreSettings(mOldSettings); - } - - virtual void reset() - { - std::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->reset(); - } - - virtual void replay(std::ostream& out) - { - std::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->replay(out); - } + LLReplayLogReal(LLError::ELevel level) + : LLReplayLog(), + boost::noncopyable(), + mOldSettings(LLError::saveAndResetSettings()), + mRecorder(new RecordToTempFile()) + { + LLError::setFatalFunction(wouldHaveCrashed); + LLError::setDefaultLevel(level); + LLError::addRecorder(mRecorder); + } + + virtual ~LLReplayLogReal() + { + LLError::removeRecorder(mRecorder); + LLError::restoreSettings(mOldSettings); + } + + virtual void reset() + { + std::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->reset(); + } + + virtual void replay(std::ostream& out) + { + std::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->replay(out); + } private: - LLError::SettingsStoragePtr mOldSettings; - LLError::RecorderPtr mRecorder; + LLError::SettingsStoragePtr mOldSettings; + LLError::RecorderPtr mRecorder; }; class LLTestCallback : public chained_callback { - typedef chained_callback super; + typedef chained_callback super; public: - LLTestCallback(bool verbose_mode, std::ostream *stream, - std::shared_ptr<LLReplayLog> replayer) : - mVerboseMode(verbose_mode), - mTotalTests(0), - mPassedTests(0), - mFailedTests(0), - mSkippedTests(0), - // By default, capture a shared_ptr to std::cout, with a no-op "deleter" - // so that destroying the shared_ptr makes no attempt to delete std::cout. - mStream(std::shared_ptr<std::ostream>(&std::cout, [](std::ostream*){})), - mReplayer(replayer) - { - if (stream) - { - // We want a boost::iostreams::tee_device that will stream to two - // std::ostreams. - typedef boost::iostreams::tee_device<std::ostream, std::ostream> TeeDevice; - // More than that, though, we want an actual stream using that - // device. - typedef boost::iostreams::stream<TeeDevice> TeeStream; - // Allocate and assign in two separate steps, per Herb Sutter. - // (Until we turn on C++11 support, have to wrap *stream with - // boost::ref() due to lack of perfect forwarding.) - std::shared_ptr<std::ostream> pstream(new TeeStream(std::cout, boost::ref(*stream))); - mStream = pstream; - } - } - - ~LLTestCallback() - { - } - - virtual void run_started() - { - //std::cout << "run_started" << std::endl; - LL_INFOS("TestRunner")<<"Test Started"<< LL_ENDL; - super::run_started(); - } - - virtual void group_started(const std::string& name) { - LL_INFOS("TestRunner")<<"Unit test group_started name=" << name << LL_ENDL; - *mStream << "Unit test group_started name=" << name << std::endl; - super::group_started(name); - } - - virtual void group_completed(const std::string& name) { - LL_INFOS("TestRunner")<<"Unit test group_completed name=" << name << LL_ENDL; - *mStream << "Unit test group_completed name=" << name << std::endl; - super::group_completed(name); - } - - virtual void test_completed(const tut::test_result& tr) - { - ++mTotalTests; - - // If this test failed, dump requested log messages BEFORE stating the - // test result. - if (tr.result != tut::test_result::ok && tr.result != tut::test_result::skip) - { - mReplayer->replay(*mStream); - } - // Either way, clear stored messages in preparation for next test. - mReplayer->reset(); - - std::ostringstream out; - out << "[" << tr.group << ", " << tr.test; - if (! tr.name.empty()) - out << ": " << tr.name; - out << "] "; - switch(tr.result) - { - case tut::test_result::ok: - ++mPassedTests; - out << "ok"; - break; - case tut::test_result::fail: - ++mFailedTests; - out << "fail"; - break; - case tut::test_result::ex: - ++mFailedTests; - out << "exception: " << LLError::Log::demangle(tr.exception_typeid.c_str()); - break; - case tut::test_result::warn: - ++mFailedTests; - out << "test destructor throw"; - break; - case tut::test_result::term: - ++mFailedTests; - out << "abnormal termination"; - break; - case tut::test_result::skip: - ++mSkippedTests; - out << "skipped known failure"; - break; - default: - ++mFailedTests; - out << "unknown (tr.result == " << tr.result << ")"; - } - if(mVerboseMode || (tr.result != tut::test_result::ok)) - { - *mStream << out.str(); - if(!tr.message.empty()) - { - *mStream << ": '" << tr.message << "'"; - LL_WARNS("TestRunner") << "not ok : "<<tr.message << LL_ENDL; - } - *mStream << std::endl; - } - LL_INFOS("TestRunner")<<out.str()<<LL_ENDL; - super::test_completed(tr); - } - - virtual int getFailedTests() const { return mFailedTests; } - - virtual void run_completed() - { - *mStream << "\tTotal Tests:\t" << mTotalTests << std::endl; - *mStream << "\tPassed Tests:\t" << mPassedTests; - if (mPassedTests == mTotalTests) - { - *mStream << "\tYAY!! \\o/"; - } - *mStream << std::endl; - - if (mSkippedTests > 0) - { - *mStream << "\tSkipped known failures:\t" << mSkippedTests - << std::endl; - } - - if(mFailedTests > 0) - { - *mStream << "*********************************" << std::endl; - *mStream << "Failed Tests:\t" << mFailedTests << std::endl; - *mStream << "Please report or fix the problem." << std::endl; - *mStream << "*********************************" << std::endl; - } - super::run_completed(); - } + LLTestCallback(bool verbose_mode, std::ostream *stream, + std::shared_ptr<LLReplayLog> replayer) : + mVerboseMode(verbose_mode), + mTotalTests(0), + mPassedTests(0), + mFailedTests(0), + mSkippedTests(0), + // By default, capture a shared_ptr to std::cout, with a no-op "deleter" + // so that destroying the shared_ptr makes no attempt to delete std::cout. + mStream(std::shared_ptr<std::ostream>(&std::cout, [](std::ostream*){})), + mReplayer(replayer) + { + if (stream) + { + // We want a boost::iostreams::tee_device that will stream to two + // std::ostreams. + typedef boost::iostreams::tee_device<std::ostream, std::ostream> TeeDevice; + // More than that, though, we want an actual stream using that + // device. + typedef boost::iostreams::stream<TeeDevice> TeeStream; + // Allocate and assign in two separate steps, per Herb Sutter. + // (Until we turn on C++11 support, have to wrap *stream with + // boost::ref() due to lack of perfect forwarding.) + std::shared_ptr<std::ostream> pstream(new TeeStream(std::cout, boost::ref(*stream))); + mStream = pstream; + } + } + + ~LLTestCallback() + { + } + + virtual void run_started() + { + //std::cout << "run_started" << std::endl; + LL_INFOS("TestRunner")<<"Test Started"<< LL_ENDL; + super::run_started(); + } + + virtual void group_started(const std::string& name) { + LL_INFOS("TestRunner")<<"Unit test group_started name=" << name << LL_ENDL; + *mStream << "Unit test group_started name=" << name << std::endl; + super::group_started(name); + } + + virtual void group_completed(const std::string& name) { + LL_INFOS("TestRunner")<<"Unit test group_completed name=" << name << LL_ENDL; + *mStream << "Unit test group_completed name=" << name << std::endl; + super::group_completed(name); + } + + virtual void test_completed(const tut::test_result& tr) + { + ++mTotalTests; + + // If this test failed, dump requested log messages BEFORE stating the + // test result. + if (tr.result != tut::test_result::ok && tr.result != tut::test_result::skip) + { + mReplayer->replay(*mStream); + } + // Either way, clear stored messages in preparation for next test. + mReplayer->reset(); + + std::ostringstream out; + out << "[" << tr.group << ", " << tr.test; + if (! tr.name.empty()) + out << ": " << tr.name; + out << "] "; + switch(tr.result) + { + case tut::test_result::ok: + ++mPassedTests; + out << "ok"; + break; + case tut::test_result::fail: + ++mFailedTests; + out << "fail"; + break; + case tut::test_result::ex: + ++mFailedTests; + out << "exception: " << LLError::Log::demangle(tr.exception_typeid.c_str()); + break; + case tut::test_result::warn: + ++mFailedTests; + out << "test destructor throw"; + break; + case tut::test_result::term: + ++mFailedTests; + out << "abnormal termination"; + break; + case tut::test_result::skip: + ++mSkippedTests; + out << "skipped known failure"; + break; + default: + ++mFailedTests; + out << "unknown (tr.result == " << tr.result << ")"; + } + if(mVerboseMode || (tr.result != tut::test_result::ok)) + { + *mStream << out.str(); + if(!tr.message.empty()) + { + *mStream << ": '" << tr.message << "'"; + LL_WARNS("TestRunner") << "not ok : "<<tr.message << LL_ENDL; + } + *mStream << std::endl; + } + LL_INFOS("TestRunner")<<out.str()<<LL_ENDL; + super::test_completed(tr); + } + + virtual int getFailedTests() const { return mFailedTests; } + + virtual void run_completed() + { + *mStream << "\tTotal Tests:\t" << mTotalTests << std::endl; + *mStream << "\tPassed Tests:\t" << mPassedTests; + if (mPassedTests == mTotalTests) + { + *mStream << "\tYAY!! \\o/"; + } + *mStream << std::endl; + + if (mSkippedTests > 0) + { + *mStream << "\tSkipped known failures:\t" << mSkippedTests + << std::endl; + } + + if(mFailedTests > 0) + { + *mStream << "*********************************" << std::endl; + *mStream << "Failed Tests:\t" << mFailedTests << std::endl; + *mStream << "Please report or fix the problem." << std::endl; + *mStream << "*********************************" << std::endl; + } + super::run_completed(); + } protected: - bool mVerboseMode; - int mTotalTests; - int mPassedTests; - int mFailedTests; - int mSkippedTests; - std::shared_ptr<std::ostream> mStream; - std::shared_ptr<LLReplayLog> mReplayer; + bool mVerboseMode; + int mTotalTests; + int mPassedTests; + int mFailedTests; + int mSkippedTests; + std::shared_ptr<std::ostream> mStream; + std::shared_ptr<LLReplayLog> mReplayer; }; // TeamCity specific class which emits service messages @@ -330,352 +330,352 @@ protected: class LLTCTestCallback : public LLTestCallback { public: - LLTCTestCallback(bool verbose_mode, std::ostream *stream, - std::shared_ptr<LLReplayLog> replayer) : - LLTestCallback(verbose_mode, stream, replayer) - { - } - - ~LLTCTestCallback() - { - } - - virtual void group_started(const std::string& name) { - LLTestCallback::group_started(name); - std::cout << "\n##teamcity[testSuiteStarted name='" << escape(name) << "']" << std::endl; - } - - virtual void group_completed(const std::string& name) { - LLTestCallback::group_completed(name); - std::cout << "##teamcity[testSuiteFinished name='" << escape(name) << "']" << std::endl; - } - - virtual void test_completed(const tut::test_result& tr) - { - std::string testname(STRINGIZE(tr.group << "." << tr.test)); - if (! tr.name.empty()) - { - testname.append(":"); - testname.append(tr.name); - } - testname = escape(testname); - - // Sadly, tut::callback doesn't give us control at test start; have to - // backfill start message into TC output. - std::cout << "##teamcity[testStarted name='" << testname << "']" << std::endl; - - // now forward call to base class so any output produced there is in - // the right TC context - LLTestCallback::test_completed(tr); - - switch(tr.result) - { - case tut::test_result::ok: - break; - - case tut::test_result::fail: - case tut::test_result::ex: - case tut::test_result::warn: - case tut::test_result::term: - std::cout << "##teamcity[testFailed name='" << testname - << "' message='" << escape(tr.message) << "']" << std::endl; - break; - - case tut::test_result::skip: - std::cout << "##teamcity[testIgnored name='" << testname << "']" << std::endl; - break; - - default: - break; - } - - std::cout << "##teamcity[testFinished name='" << testname << "']" << std::endl; - } - - static std::string escape(const std::string& str) - { - // Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages - std::string result; - for (char c : str) - { - switch (c) - { - case '\'': - result.append("|'"); - break; - case '\n': - result.append("|n"); - break; - case '\r': - result.append("|r"); - break; + LLTCTestCallback(bool verbose_mode, std::ostream *stream, + std::shared_ptr<LLReplayLog> replayer) : + LLTestCallback(verbose_mode, stream, replayer) + { + } + + ~LLTCTestCallback() + { + } + + virtual void group_started(const std::string& name) { + LLTestCallback::group_started(name); + std::cout << "\n##teamcity[testSuiteStarted name='" << escape(name) << "']" << std::endl; + } + + virtual void group_completed(const std::string& name) { + LLTestCallback::group_completed(name); + std::cout << "##teamcity[testSuiteFinished name='" << escape(name) << "']" << std::endl; + } + + virtual void test_completed(const tut::test_result& tr) + { + std::string testname(STRINGIZE(tr.group << "." << tr.test)); + if (! tr.name.empty()) + { + testname.append(":"); + testname.append(tr.name); + } + testname = escape(testname); + + // Sadly, tut::callback doesn't give us control at test start; have to + // backfill start message into TC output. + std::cout << "##teamcity[testStarted name='" << testname << "']" << std::endl; + + // now forward call to base class so any output produced there is in + // the right TC context + LLTestCallback::test_completed(tr); + + switch(tr.result) + { + case tut::test_result::ok: + break; + + case tut::test_result::fail: + case tut::test_result::ex: + case tut::test_result::warn: + case tut::test_result::term: + std::cout << "##teamcity[testFailed name='" << testname + << "' message='" << escape(tr.message) << "']" << std::endl; + break; + + case tut::test_result::skip: + std::cout << "##teamcity[testIgnored name='" << testname << "']" << std::endl; + break; + + default: + break; + } + + std::cout << "##teamcity[testFinished name='" << testname << "']" << std::endl; + } + + static std::string escape(const std::string& str) + { + // Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages + std::string result; + for (char c : str) + { + switch (c) + { + case '\'': + result.append("|'"); + break; + case '\n': + result.append("|n"); + break; + case '\r': + result.append("|r"); + break; /*==========================================================================*| - // These are not possible 'char' values from a std::string. - case '\u0085': // next line - result.append("|x"); - break; - case '\u2028': // line separator - result.append("|l"); - break; - case '\u2029': // paragraph separator - result.append("|p"); - break; + // These are not possible 'char' values from a std::string. + case '\u0085': // next line + result.append("|x"); + break; + case '\u2028': // line separator + result.append("|l"); + break; + case '\u2029': // paragraph separator + result.append("|p"); + break; |*==========================================================================*/ - case '|': - result.append("||"); - break; - case '[': - result.append("|["); - break; - case ']': - result.append("|]"); - break; - default: - result.push_back(c); - break; - } - } - return result; - } + case '|': + result.append("||"); + break; + case '[': + result.append("|["); + break; + case ']': + result.append("|]"); + break; + default: + result.push_back(c); + break; + } + } + return result; + } }; static const apr_getopt_option_t TEST_CL_OPTIONS[] = { - {"help", 'h', 0, "Print the help message."}, - {"list", 'l', 0, "List available test groups."}, - {"verbose", 'v', 0, "Verbose output."}, - {"group", 'g', 1, "Run test group specified by option argument."}, - {"output", 'o', 1, "Write output to the named file."}, - {"sourcedir", 's', 1, "Project source file directory from CMake."}, - {"touch", 't', 1, "Touch the given file if all tests succeed"}, - {"wait", 'w', 0, "Wait for input before exit."}, - {"debug", 'd', 0, "Emit full debug logs."}, - {"suitename", 'x', 1, "Run tests using this suitename"}, - {0, 0, 0, 0} + {"help", 'h', 0, "Print the help message."}, + {"list", 'l', 0, "List available test groups."}, + {"verbose", 'v', 0, "Verbose output."}, + {"group", 'g', 1, "Run test group specified by option argument."}, + {"output", 'o', 1, "Write output to the named file."}, + {"sourcedir", 's', 1, "Project source file directory from CMake."}, + {"touch", 't', 1, "Touch the given file if all tests succeed"}, + {"wait", 'w', 0, "Wait for input before exit."}, + {"debug", 'd', 0, "Emit full debug logs."}, + {"suitename", 'x', 1, "Run tests using this suitename"}, + {0, 0, 0, 0} }; void stream_usage(std::ostream& s, const char* app) { - s << "Usage: " << app << " [OPTIONS]" << std::endl - << std::endl; - - s << "This application runs the unit tests." << std::endl << std::endl; - - s << "Options: " << std::endl; - const apr_getopt_option_t* option = &TEST_CL_OPTIONS[0]; - while(option->name) - { - s << " "; - s << " -" << (char)option->optch << ", --" << option->name - << std::endl; - s << "\t" << option->description << std::endl << std::endl; - ++option; - } - - s << app << " is also sensitive to environment variables:\n" - << "LOGTEST=level : for all tests, emit log messages at level 'level'\n" - << "LOGFAIL=level : only for failed tests, emit log messages at level 'level'\n" - << "where 'level' is one of ALL, DEBUG, INFO, WARN, ERROR, NONE.\n" - << "--debug is like LOGTEST=DEBUG, but --debug overrides LOGTEST,\n" - << "while LOGTEST overrides LOGFAIL.\n\n"; - - s << "Examples:" << std::endl; - s << " " << app << " --verbose" << std::endl; - s << "\tRun all the tests and report all results." << std::endl; - s << " " << app << " --list" << std::endl; - s << "\tList all available test groups." << std::endl; - s << " " << app << " --group=uuid" << std::endl; - s << "\tRun the test group 'uuid'." << std::endl; - - s << "\n\n" - << "In any event, logs are recorded in the build directory by appending\n" - << "the suffix '.log' to the full path name of this application.\n" - << "If no level is specified as described above, these log files are at\n" - << "DEBUG level.\n" - ; + s << "Usage: " << app << " [OPTIONS]" << std::endl + << std::endl; + + s << "This application runs the unit tests." << std::endl << std::endl; + + s << "Options: " << std::endl; + const apr_getopt_option_t* option = &TEST_CL_OPTIONS[0]; + while(option->name) + { + s << " "; + s << " -" << (char)option->optch << ", --" << option->name + << std::endl; + s << "\t" << option->description << std::endl << std::endl; + ++option; + } + + s << app << " is also sensitive to environment variables:\n" + << "LOGTEST=level : for all tests, emit log messages at level 'level'\n" + << "LOGFAIL=level : only for failed tests, emit log messages at level 'level'\n" + << "where 'level' is one of ALL, DEBUG, INFO, WARN, ERROR, NONE.\n" + << "--debug is like LOGTEST=DEBUG, but --debug overrides LOGTEST,\n" + << "while LOGTEST overrides LOGFAIL.\n\n"; + + s << "Examples:" << std::endl; + s << " " << app << " --verbose" << std::endl; + s << "\tRun all the tests and report all results." << std::endl; + s << " " << app << " --list" << std::endl; + s << "\tList all available test groups." << std::endl; + s << " " << app << " --group=uuid" << std::endl; + s << "\tRun the test group 'uuid'." << std::endl; + + s << "\n\n" + << "In any event, logs are recorded in the build directory by appending\n" + << "the suffix '.log' to the full path name of this application.\n" + << "If no level is specified as described above, these log files are at\n" + << "DEBUG level.\n" + ; } void stream_groups(std::ostream& s, const char* app) { - s << "Registered test groups:" << std::endl; - tut::groupnames gl = tut::runner.get().list_groups(); - tut::groupnames::const_iterator it = gl.begin(); - tut::groupnames::const_iterator end = gl.end(); - for(; it != end; ++it) - { - s << " " << *(it) << std::endl; - } + s << "Registered test groups:" << std::endl; + tut::groupnames gl = tut::runner.get().list_groups(); + tut::groupnames::const_iterator it = gl.begin(); + tut::groupnames::const_iterator end = gl.end(); + for(; it != end; ++it) + { + s << " " << *(it) << std::endl; + } } void wouldHaveCrashed(const std::string& message) { - tut::fail("llerrs message: " + message); + tut::fail("llerrs message: " + message); } static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL; int main(int argc, char **argv) { - ll_init_apr(); - apr_getopt_t* os = NULL; - if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv)) - { - std::cerr << "apr_getopt_init() failed" << std::endl; - return 1; - } - - // values used for controlling application - bool verbose_mode = false; - bool wait_at_exit = false; - std::string test_group; - std::string suite_name; - - // LOGTEST overrides default, but can be overridden by --debug. - const char* LOGTEST = getenv("LOGTEST"); - - // values used for options parsing - apr_status_t apr_err; - const char* opt_arg = NULL; - int opt_id = 0; - std::unique_ptr<llofstream> output; - const char *touch = NULL; - - while(true) - { - apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg); - if(APR_STATUS_IS_EOF(apr_err)) break; - if(apr_err) - { - char buf[255]; /* Flawfinder: ignore */ - std::cerr << "Error parsing options: " - << apr_strerror(apr_err, buf, 255) << std::endl; - return 1; - } - switch (opt_id) - { - case 'g': - test_group.assign(opt_arg); - break; - case 'h': - stream_usage(std::cout, argv[0]); - return 0; - break; - case 'l': - stream_groups(std::cout, argv[0]); - return 0; - case 'v': - verbose_mode = true; - break; - case 'o': - output.reset(new llofstream); - output->open(opt_arg); - break; - case 's': // --sourcedir - tut::sSourceDir = opt_arg; - // For convenience, so you can use tut::sSourceDir + "myfile" - tut::sSourceDir += '/'; - break; - case 't': - touch = opt_arg; - break; - case 'w': - wait_at_exit = true; - break; - case 'd': - LOGTEST = "DEBUG"; - break; - case 'x': - suite_name.assign(opt_arg); - break; - default: - stream_usage(std::cerr, argv[0]); - return 1; - break; - } - } - - // set up logging - const char* LOGFAIL = getenv("LOGFAIL"); - std::shared_ptr<LLReplayLog> replayer{std::make_shared<LLReplayLog>()}; - - // Testing environment variables for both 'set' and 'not empty' allows a - // user to suppress a pre-existing environment variable by forcing empty. - if (LOGTEST && *LOGTEST) - { - LLError::initForApplication(".", ".", true /* log to stderr */); - LLError::setDefaultLevel(LLError::decodeLevel(LOGTEST)); - } - else - { - LLError::initForApplication(".", ".", false /* do not log to stderr */); - LLError::setDefaultLevel(LLError::LEVEL_DEBUG); - if (LOGFAIL && *LOGFAIL) - { - LLError::ELevel level = LLError::decodeLevel(LOGFAIL); - replayer.reset(new LLReplayLogReal(level)); - } - } - LLError::setFatalFunction(wouldHaveCrashed); - std::string test_app_name(argv[0]); - std::string test_log = test_app_name + ".log"; - LLFile::remove(test_log); - LLError::logToFile(test_log); + ll_init_apr(); + apr_getopt_t* os = NULL; + if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv)) + { + std::cerr << "apr_getopt_init() failed" << std::endl; + return 1; + } + + // values used for controlling application + bool verbose_mode = false; + bool wait_at_exit = false; + std::string test_group; + std::string suite_name; + + // LOGTEST overrides default, but can be overridden by --debug. + const char* LOGTEST = getenv("LOGTEST"); + + // values used for options parsing + apr_status_t apr_err; + const char* opt_arg = NULL; + int opt_id = 0; + std::unique_ptr<llofstream> output; + const char *touch = NULL; + + while(true) + { + apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg); + if(APR_STATUS_IS_EOF(apr_err)) break; + if(apr_err) + { + char buf[255]; /* Flawfinder: ignore */ + std::cerr << "Error parsing options: " + << apr_strerror(apr_err, buf, 255) << std::endl; + return 1; + } + switch (opt_id) + { + case 'g': + test_group.assign(opt_arg); + break; + case 'h': + stream_usage(std::cout, argv[0]); + return 0; + break; + case 'l': + stream_groups(std::cout, argv[0]); + return 0; + case 'v': + verbose_mode = true; + break; + case 'o': + output.reset(new llofstream); + output->open(opt_arg); + break; + case 's': // --sourcedir + tut::sSourceDir = opt_arg; + // For convenience, so you can use tut::sSourceDir + "myfile" + tut::sSourceDir += '/'; + break; + case 't': + touch = opt_arg; + break; + case 'w': + wait_at_exit = true; + break; + case 'd': + LOGTEST = "DEBUG"; + break; + case 'x': + suite_name.assign(opt_arg); + break; + default: + stream_usage(std::cerr, argv[0]); + return 1; + break; + } + } + + // set up logging + const char* LOGFAIL = getenv("LOGFAIL"); + std::shared_ptr<LLReplayLog> replayer{std::make_shared<LLReplayLog>()}; + + // Testing environment variables for both 'set' and 'not empty' allows a + // user to suppress a pre-existing environment variable by forcing empty. + if (LOGTEST && *LOGTEST) + { + LLError::initForApplication(".", ".", true /* log to stderr */); + LLError::setDefaultLevel(LLError::decodeLevel(LOGTEST)); + } + else + { + LLError::initForApplication(".", ".", false /* do not log to stderr */); + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + if (LOGFAIL && *LOGFAIL) + { + LLError::ELevel level = LLError::decodeLevel(LOGFAIL); + replayer.reset(new LLReplayLogReal(level)); + } + } + LLError::setFatalFunction(wouldHaveCrashed); + std::string test_app_name(argv[0]); + std::string test_log = test_app_name + ".log"; + LLFile::remove(test_log); + LLError::logToFile(test_log); #ifdef CTYPE_WORKAROUND - ctype_workaround(); + ctype_workaround(); #endif - if (!sMasterThreadRecorder) - { - sMasterThreadRecorder = new LLTrace::ThreadRecorder(); - LLTrace::set_master_thread_recorder(sMasterThreadRecorder); - } - - // run the tests - - LLTestCallback* mycallback; - if (getenv("TEAMCITY_PROJECT_NAME")) - { - mycallback = new LLTCTestCallback(verbose_mode, output.get(), replayer); - } - else - { - mycallback = new LLTestCallback(verbose_mode, output.get(), replayer); - } - - // a chained_callback subclass must be linked with previous - mycallback->link(); - - if(test_group.empty()) - { - tut::runner.get().run_tests(); - } - else - { - tut::runner.get().run_tests(test_group); - } - - bool success = (mycallback->getFailedTests() == 0); - - if (wait_at_exit) - { - std::cerr << "Press return to exit..." << std::endl; - std::cin.get(); - } - - if (touch && success) - { - llofstream s; - s.open(touch); - s << "ok" << std::endl; - s.close(); - } - - ll_cleanup_apr(); - - int retval = (success ? 0 : 1); - return retval; - - //delete mycallback; + if (!sMasterThreadRecorder) + { + sMasterThreadRecorder = new LLTrace::ThreadRecorder(); + LLTrace::set_master_thread_recorder(sMasterThreadRecorder); + } + + // run the tests + + LLTestCallback* mycallback; + if (getenv("TEAMCITY_PROJECT_NAME")) + { + mycallback = new LLTCTestCallback(verbose_mode, output.get(), replayer); + } + else + { + mycallback = new LLTestCallback(verbose_mode, output.get(), replayer); + } + + // a chained_callback subclass must be linked with previous + mycallback->link(); + + if(test_group.empty()) + { + tut::runner.get().run_tests(); + } + else + { + tut::runner.get().run_tests(test_group); + } + + bool success = (mycallback->getFailedTests() == 0); + + if (wait_at_exit) + { + std::cerr << "Press return to exit..." << std::endl; + std::cin.get(); + } + + if (touch && success) + { + llofstream s; + s.open(touch); + s << "ok" << std::endl; + s.close(); + } + + ll_cleanup_apr(); + + int retval = (success ? 0 : 1); + return retval; + + //delete mycallback; } diff --git a/indra/test/test.h b/indra/test/test.h index 40c94283ec..3db33e85f7 100644 --- a/indra/test/test.h +++ b/indra/test/test.h @@ -1,4 +1,4 @@ -/** +/** * @file test.h * @author James * @date 2009-01-12 @@ -6,21 +6,21 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -31,14 +31,14 @@ namespace tut { - // Source code directory from CMake, used for loading test data and - // configuration. For example: - // - // loadMyConfig( sSourceDir + "config.dat" ); - // - // Use sparingly, as hitting the file system slows down test execution - // and hence every compile. JC - extern std::string sSourceDir; + // Source code directory from CMake, used for loading test data and + // configuration. For example: + // + // loadMyConfig( sSourceDir + "config.dat" ); + // + // Use sparingly, as hitting the file system slows down test execution + // and hence every compile. JC + extern std::string sSourceDir; } #endif |