diff --git a/indra/cmake/ALAddTestBinary.cmake b/indra/cmake/ALAddTestBinary.cmake index 02c82263b3..15cd931401 100644 --- a/indra/cmake/ALAddTestBinary.cmake +++ b/indra/cmake/ALAddTestBinary.cmake @@ -12,7 +12,8 @@ endif() # al_add_test_binary( PROJECT SOURCES ... [UNIT ...] # [LIBRARIES ...] [SUPPORT ...] # [INCLUDES ...] [DEFINES ...] [ENVIRONMENT ...] -# [GL] [PYTHON] [ISA_TIER ] [RESOURCE_LOCK ...] [COMBINED]) +# [GL] [PYTHON] [ISA_TIER ] [RESOURCE_LOCK ...] [LAUNCHER ...] +# [COMBINED]) # # Builds the test files into one Catch2 executable, , with the harness # (al_test_support: the main, the listeners and the matchers) and SUPPORT's @@ -56,14 +57,17 @@ endif() # ISA_TIER binary is built at that x86-64 tier, named _, labelled # isa, and skips on a host below it -- or below the tree's own tier, since it # links the tree's libraries, built at that one. RESOURCE_LOCK names what the binary's -# entries hold that no two may hold at once, such as a fixed port. +# entries hold that no two may hold at once, such as a fixed port. LAUNCHER is +# a command each entry runs the binary through, its path and arguments after +# the command's own: llcorehttp's tests run under the Python peer that serves +# their requests. A per-case entry, and its discovery, go through it too. function(al_add_test_binary name) cmake_parse_arguments( PARSE_ARGV 1 arg "GL;PYTHON;COMBINED" "PROJECT;ISA_TIER" - "SOURCES;UNIT;LIBRARIES;SUPPORT;INCLUDES;DEFINES;ENVIRONMENT;RESOURCE_LOCK" + "SOURCES;UNIT;LIBRARIES;SUPPORT;INCLUDES;DEFINES;ENVIRONMENT;RESOURCE_LOCK;LAUNCHER" ) if(NOT arg_PROJECT) message(FATAL_ERROR "al_add_test_binary(${name}): PROJECT is required") @@ -119,6 +123,9 @@ function(al_add_test_binary name) add_executable(${target} ${arg_SOURCES} ${arg_UNIT}) target_link_libraries(${target} PRIVATE al::flags al_test_support ${arg_SUPPORT} ${arg_LIBRARIES}) target_include_directories(${target} PRIVATE ${arg_INCLUDES} ${INDRA_SOURCE_DIR}/test) + # For the helpers in test/ that TUT tests still share, so each fails a + # test the way its framework does. + target_compile_definitions(${target} PRIVATE AL_TEST_CATCH2=1) if(arg_UNIT) target_include_directories( ${target} @@ -190,6 +197,11 @@ function(al_add_test_binary name) DISABLED ${disabled} ) + # Catch.cmake runs the discovery and each case through the target's + # emulator, which CMake's own add_test leaves alone in a native build. + if(arg_LAUNCHER) + set_target_properties(${target} PROPERTIES CROSSCOMPILING_EMULATOR "${arg_LAUNCHER}") + endif() # The main makes Catch2's "all skipped" CTest's 125, so a skip is not # left to the discovery's own code for it. catch_discover_tests( @@ -235,7 +247,7 @@ function(al_add_test_binary name) foreach(stem IN LISTS stems) add_test( NAME ${target}/${stem} - COMMAND $ --filenames-as-tags "[#${stem}]~[.]" ${arguments} + COMMAND ${arg_LAUNCHER} $ --filenames-as-tags "[#${stem}]~[.]" ${arguments} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) set_tests_properties( @@ -287,7 +299,7 @@ function(al_add_test_binary name) endif() add_test( NAME ${target}/combined - COMMAND $ ${arguments} + COMMAND ${arg_LAUNCHER} $ ${arguments} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) set_tests_properties( diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index b0d5370b7d..6c58c81d5b 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -76,26 +76,33 @@ target_precompile_headers(llcorehttp REUSE_FROM llprecompiled) # tests if(AL_BUILD_TESTS) - # The suite runs under a Python peer that serves the requests it makes. + # The state guard's checks on what llcorehttp keeps for the process, for + # every test binary that links it. + add_library(llcorehttp_test_checks OBJECT tests/llcorehttp_test_checks.cpp) + target_link_libraries(llcorehttp_test_checks PRIVATE al::flags al_test_support llcorehttp llmessage) + set_target_properties(llcorehttp_test_checks PROPERTIES FOLDER "Tests/llcorehttp") + + # The suites run under a Python peer that serves the requests they make. # An http_proxy in the environment would put a proxy between the two, so # the run clears it. - al_add_test( - llcorehttp + al_add_test_binary( + llcorehttp_tests PROJECT llcorehttp SOURCES - tests/test_httpstatus.hpp - tests/test_refcounted.hpp - tests/test_httpoperation.hpp - tests/test_httprequest.hpp - tests/test_httprequestqueue.hpp - tests/test_httpheaders.hpp - tests/test_bufferarray.hpp - tests/test_bufferstream.hpp - tests/test_jsonrpcws.hpp - tests/test_websocketmgr.hpp + tests/bufferarray_test.cpp + tests/bufferstream_test.cpp + tests/httpheaders_test.cpp + tests/httpoperation_test.cpp + tests/httprequest_test.cpp + tests/httprequestqueue_test.cpp + tests/httpstatus_test.cpp + tests/jsonrpcws_test.cpp + tests/refcounted_test.cpp + tests/websocketmgr_test.cpp LIBRARIES llcorehttp llmessage llcommon + SUPPORT llcorehttp_test_checks PYTHON - COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py" + LAUNCHER ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py" ENVIRONMENT "http_proxy=" ) diff --git a/indra/llcorehttp/tests/bufferarray_test.cpp b/indra/llcorehttp/tests/bufferarray_test.cpp new file mode 100644 index 0000000000..65691b3779 --- /dev/null +++ b/indra/llcorehttp/tests/bufferarray_test.cpp @@ -0,0 +1,365 @@ +/** + * @file bufferarray_test.cpp + * @brief unit tests for the LLCore::BufferArray class + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 + +#include "bufferarray.h" + +#include + + +using namespace LLCore; + + + +namespace +{ +TEST_CASE("BufferArray Tests: a new BufferArray holds one reference and no data", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + CHECK(ba->getRefCount() == 1); + CHECK(ba->size() == 0); + + // Try to read + char buffer[20]; + size_t read_len(ba->read(0, buffer, sizeof(buffer))); + CHECK(read_len == 0); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +TEST_CASE("BufferArray Tests: BufferArray single write", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + char buffer[256]; + + size_t len = ba->write(0, str1, strlen(str1)); + CHECK(strlen(str1) == len); + CHECK(strlen(str1) == ba->size()); + + // read some data back + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(2, buffer, 2); + CHECK(len == 2); + CHECK(buffer[0] == 'c'); + CHECK(buffer[1] == 'd'); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[2] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + + +TEST_CASE("BufferArray Tests: BufferArray multiple writes", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + CHECK(str1_len == len); + CHECK(str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, strlen(str1)); + CHECK(str1_len == len); + CHECK((2 * str1_len) == ba->size()); + + // read some data back + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(8, buffer, 4); + CHECK(len == 4); + CHECK(buffer[0] == 'i'); + CHECK(buffer[1] == 'j'); + CHECK(buffer[2] == 'a'); + CHECK(buffer[3] == 'b'); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[4] == 'X'); + + // Read whole thing + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(0, buffer, sizeof(buffer)); + CHECK((2 * str1_len) == len); + CHECK(strncmp(buffer, str1, str1_len) == 0); + CHECK(strncmp(&buffer[str1_len], str1, str1_len) == 0); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[2 * str1_len] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +TEST_CASE("BufferArray Tests: BufferArray overwriting", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJ"; + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + CHECK(str1_len == len); + CHECK(str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, strlen(str1)); + CHECK(str1_len == len); + CHECK((2 * str1_len) == ba->size()); + + // reposition and overwrite + len = ba->write(8, str2, 4); + CHECK(len == 4); + + // Leave position and read verifying content (stale really from seek() days) + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(12, buffer, 4); + CHECK(len == 4); + CHECK(buffer[0] == 'c'); + CHECK(buffer[1] == 'd'); + CHECK(buffer[2] == 'e'); + CHECK(buffer[3] == 'f'); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[4] == 'X'); + + // reposition and check + len = ba->read(6, buffer, 8); + CHECK(len == 8); + CHECK(buffer[0] == 'g'); + CHECK(buffer[1] == 'h'); + CHECK(buffer[2] == 'A'); + CHECK(buffer[3] == 'B'); + CHECK(buffer[4] == 'C'); + CHECK(buffer[5] == 'D'); + CHECK(buffer[6] == 'c'); + CHECK(buffer[7] == 'd'); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[8] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +TEST_CASE("BufferArray Tests: BufferArray multiple writes - sequential reads", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + CHECK(str1_len == len); + CHECK(str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, str1_len); + CHECK(str1_len == len); + CHECK((2 * str1_len) == ba->size()); + + // read some data back + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(8, buffer, 4); + CHECK(len == 4); + CHECK(buffer[0] == 'i'); + CHECK(buffer[1] == 'j'); + CHECK(buffer[2] == 'a'); + CHECK(buffer[3] == 'b'); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[4] == 'X'); + + // Read some more without repositioning + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(12, buffer, sizeof(buffer)); + CHECK((str1_len - 2) == len); + CHECK(strncmp(buffer, str1+2, str1_len-2) == 0); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[str1_len-1] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +TEST_CASE("BufferArray Tests: BufferArray overwrite spanning blocks and appending", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJKLMNOPQRST"; + size_t str2_len(strlen(str2)); + char buffer[256]; + + size_t len = ba->write(0, str1, str1_len); + CHECK(str1_len == len); + CHECK(str1_len == ba->size()); + + // again... + len = ba->write(str1_len, str1, strlen(str1)); + CHECK(str1_len == len); + CHECK((2 * str1_len) == ba->size()); + + // reposition and overwrite + len = ba->write(8, str2, str2_len); + CHECK(str2_len == len); + + // Leave position and read verifying content + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(8 + str2_len, buffer, 0); + CHECK(len == 0); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[0] == 'X'); + + // reposition and check + len = ba->read(0, buffer, sizeof(buffer)); + CHECK((str1_len + str2_len - 2) == len); + CHECK(strncmp(buffer, str1, str1_len-2) == 0); + CHECK(strncmp(buffer+str1_len-2, str2, str2_len) == 0); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[str1_len + str2_len - 2] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +TEST_CASE("BufferArray Tests: BufferArray overwrite spanning blocks and sequential writes", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJKLMNOPQRST"; + size_t str2_len(strlen(str2)); + char buffer[256]; + + // 2x str1 + size_t len = ba->write(0, str1, str1_len); + len = ba->write(str1_len, str1, str1_len); + + // reposition and overwrite + len = ba->write(6, str2, 2); + CHECK(len == 2); + + len = ba->write(8, str2, 2); + CHECK(len == 2); + + len = ba->write(10, str2, 2); + CHECK(len == 2); + + // append some data + len = ba->append(str2, str2_len); + CHECK(str2_len == len); + + // append some more + void * out_buf(ba->appendBufferAlloc(str1_len)); + memcpy(out_buf, str1, str1_len); + + // And some final writes + len = ba->write(3 * str1_len + str2_len, str2, 2); + CHECK(len == 2); + + // Check contents + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(0, buffer, sizeof(buffer)); + CHECK((3 * str1_len + str2_len + 2) == len); + CHECK(strncmp(buffer, str1, 6) == 0); + CHECK(strncmp(buffer + 6, str2, 2) == 0); + CHECK(strncmp(buffer + 8, str2, 2) == 0); + CHECK(strncmp(buffer + 10, str2, 2) == 0); + CHECK(strncmp(buffer + str1_len + 2, str1 + 2, str1_len - 2) == 0); + CHECK(strncmp(buffer + str1_len + str1_len, str2, str2_len) == 0); + CHECK(strncmp(buffer + str1_len + str1_len + str2_len, str1, str1_len) == 0); + CHECK(strncmp(buffer + str1_len + str1_len + str2_len + str1_len, str2, 2) == 0); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[str1_len + str1_len + str2_len + str1_len + 2] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +TEST_CASE("BufferArray Tests: BufferArray zero-length appendBufferAlloc", "[BufferArray_Tests]") +{ + // create a new ref counted object with an implicit reference + BufferArray * ba = new BufferArray(); + + // write some data to the buffer + char str1[] = "abcdefghij"; + size_t str1_len(strlen(str1)); + char str2[] = "ABCDEFGHIJKLMNOPQRST"; + size_t str2_len(strlen(str2)); + char buffer[256]; + + // 2x str1 + size_t len = ba->write(0, str1, str1_len); + len = ba->write(str1_len, str1, str1_len); + + // zero-length allocate (we allow this with a valid pointer returned) + void * out_buf(ba->appendBufferAlloc(0)); + REQUIRE(NULL != out_buf); + + // Do it again + void * out_buf2(ba->appendBufferAlloc(0)); + REQUIRE(NULL != out_buf2); + CHECK(out_buf != out_buf2); + + // And some final writes + len = ba->write(2 * str1_len, str2, str2_len); + + // Check contents + memset(buffer, 'X', sizeof(buffer)); + len = ba->read(0, buffer, sizeof(buffer)); + CHECK((2 * str1_len + str2_len) == len); + CHECK(strncmp(buffer, str1, str1_len) == 0); + CHECK(strncmp(buffer + str1_len, str1, str1_len) == 0); + CHECK(strncmp(buffer + str1_len + str1_len, str2, str2_len) == 0); + UNSCOPED_INFO("nothing written past what was read"); + CHECK(buffer[str1_len + str1_len + str2_len] == 'X'); + + // release the implicit reference, causing the object to be released + ba->release(); +} + +} // anonymous namespace diff --git a/indra/llcorehttp/tests/test_bufferstream.hpp b/indra/llcorehttp/tests/bufferstream_test.cpp similarity index 54% rename from indra/llcorehttp/tests/test_bufferstream.hpp rename to indra/llcorehttp/tests/bufferstream_test.cpp index 4bd4cba38a..ca2b81afc0 100644 --- a/indra/llcorehttp/tests/test_bufferstream.hpp +++ b/indra/llcorehttp/tests/bufferstream_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_bufferstream.hpp + * @file bufferstream_test.cpp * @brief unit tests for the LLCore::BufferArrayStreamBuf/BufferArrayStream classes * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -23,8 +23,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef TEST_LLCORE_BUFFER_STREAM_H_ -#define TEST_LLCORE_BUFFER_STREAM_H_ +#include "linden_common.h" + +#include #include "bufferstream.h" @@ -37,40 +38,25 @@ using namespace LLCore; -namespace tut -{ namespace { -struct BufferStreamTestData -{ - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. -}; - -typedef test_group BufferStreamTestGroupType; -typedef BufferStreamTestGroupType::object BufferStreamTestObjectType; -BufferStreamTestGroupType BufferStreamTestGroup("BufferStream Tests"); typedef BufferArrayStreamBuf::traits_type tst_traits_t; -} -template <> template <> -void BufferStreamTestObjectType::test<1>() +TEST_CASE("BufferStream Tests: BufferArrayStreamBuf over a NULL BufferArray fails every call", "[BufferStream_Tests]") { - set_test_name("BufferArrayStreamBuf construction with NULL BufferArray"); - // create a new ref counted object with an implicit reference BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(NULL); // Not much will work with a NULL - ensure("underflow() on NULL fails", tst_traits_t::eof() == bsb->underflow()); - ensure("uflow() on NULL fails", tst_traits_t::eof() == bsb->uflow()); - ensure("pbackfail() on NULL fails", tst_traits_t::eof() == bsb->pbackfail('c')); - ensure("showmanyc() on NULL fails", bsb->showmanyc() == -1); - ensure("overflow() on NULL fails", tst_traits_t::eof() == bsb->overflow('c')); - ensure("xsputn() on NULL fails", bsb->xsputn("blah", 4) == 0); - ensure("seekoff() on NULL fails", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1)); + CHECK(tst_traits_t::eof() == bsb->underflow()); + CHECK(tst_traits_t::eof() == bsb->uflow()); + CHECK(tst_traits_t::eof() == bsb->pbackfail('c')); + CHECK(bsb->showmanyc() == -1); + CHECK(tst_traits_t::eof() == bsb->overflow('c')); + CHECK(bsb->xsputn("blah", 4) == 0); + CHECK(bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1)); // release the implicit reference, causing the object to be released delete bsb; @@ -78,18 +64,15 @@ void BufferStreamTestObjectType::test<1>() } -template <> template <> -void BufferStreamTestObjectType::test<2>() +TEST_CASE("BufferStream Tests: BufferArrayStream over a NULL BufferArray starts out good", "[BufferStream_Tests]") { - set_test_name("BufferArrayStream construction with NULL BufferArray"); - // create a new ref counted object with an implicit reference BufferArrayStream * bas = new BufferArrayStream(NULL); // Not much will work with a NULL here - ensure("eof() is false on NULL", ! bas->eof()); - ensure("fail() is false on NULL", ! bas->fail()); - ensure("good() on NULL", bas->good()); + CHECK_FALSE(bas->eof()); + CHECK_FALSE(bas->fail()); + CHECK(bas->good()); // release the implicit reference, causing the object to be released delete bas; @@ -97,11 +80,8 @@ void BufferStreamTestObjectType::test<2>() } -template <> template <> -void BufferStreamTestObjectType::test<3>() +TEST_CASE("BufferStream Tests: BufferArrayStreamBuf construction with empty BufferArray", "[BufferStream_Tests]") { - set_test_name("BufferArrayStreamBuf construction with empty BufferArray"); - // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); @@ -116,11 +96,8 @@ void BufferStreamTestObjectType::test<3>() } -template <> template <> -void BufferStreamTestObjectType::test<4>() +TEST_CASE("BufferStream Tests: BufferArrayStream construction with empty BufferArray", "[BufferStream_Tests]") { - set_test_name("BufferArrayStream construction with empty BufferArray"); - // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; @@ -135,11 +112,8 @@ void BufferStreamTestObjectType::test<4>() } -template <> template <> -void BufferStreamTestObjectType::test<5>() +TEST_CASE("BufferStream Tests: BufferArrayStreamBuf reads and appends and seeks a BufferArray", "[BufferStream_Tests]") { - set_test_name("BufferArrayStreamBuf construction with real BufferArray"); - // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; const char * content("This is a string. A fragment."); @@ -154,23 +128,30 @@ void BufferStreamTestObjectType::test<5>() ba = NULL; // Various static state - ensure("underflow() returns 'T'", bsb->underflow() == 'T'); - ensure("underflow() returns 'T' again", bsb->underflow() == 'T'); - ensure("uflow() returns 'T'", bsb->uflow() == 'T'); - ensure("uflow() returns 'h'", bsb->uflow() == 'h'); - ensure("pbackfail('i') fails", tst_traits_t::eof() == bsb->pbackfail('i')); - ensure("pbackfail('T') fails", tst_traits_t::eof() == bsb->pbackfail('T')); - ensure("pbackfail('h') succeeds", bsb->pbackfail('h') == 'h'); - ensure("showmanyc() is everything but the 'T'", bsb->showmanyc() == (c_len - 1)); - ensure("overflow() appends", bsb->overflow('c') == 'c'); - ensure("showmanyc() reflects append", bsb->showmanyc() == (c_len - 1 + 1)); - ensure("xsputn() appends some more", bsb->xsputn("bla!", 4) == 4); - ensure("showmanyc() reflects 2nd append", bsb->showmanyc() == (c_len - 1 + 5)); - ensure("seekoff() succeeds", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0)); - ensure("seekoff() succeeds 2", bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4)); - ensure("showmanyc() picks up seekoff", bsb->showmanyc() == (c_len + 5 - 4)); - ensure("seekoff() succeeds 3", bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4)); - ensure("pbackfail('!') succeeds", tst_traits_t::eof() == bsb->pbackfail('!')); + CHECK(bsb->underflow() == 'T'); + UNSCOPED_INFO("underflow() does not advance"); + CHECK(bsb->underflow() == 'T'); + CHECK(bsb->uflow() == 'T'); + CHECK(bsb->uflow() == 'h'); + CHECK(tst_traits_t::eof() == bsb->pbackfail('i')); + CHECK(tst_traits_t::eof() == bsb->pbackfail('T')); + CHECK(bsb->pbackfail('h') == 'h'); + UNSCOPED_INFO("showmanyc() is everything but the 'T'"); + CHECK(bsb->showmanyc() == (c_len - 1)); + UNSCOPED_INFO("overflow() appends"); + CHECK(bsb->overflow('c') == 'c'); + UNSCOPED_INFO("showmanyc() reflects append"); + CHECK(bsb->showmanyc() == (c_len - 1 + 1)); + UNSCOPED_INFO("xsputn() appends"); + CHECK(bsb->xsputn("bla!", 4) == 4); + UNSCOPED_INFO("showmanyc() reflects 2nd append"); + CHECK(bsb->showmanyc() == (c_len - 1 + 5)); + CHECK(bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0)); + CHECK(bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4)); + UNSCOPED_INFO("showmanyc() picks up seekoff"); + CHECK(bsb->showmanyc() == (c_len + 5 - 4)); + CHECK(bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4)); + CHECK(tst_traits_t::eof() == bsb->pbackfail('!')); // release the implicit reference, causing the object to be released delete bsb; @@ -178,11 +159,8 @@ void BufferStreamTestObjectType::test<5>() } -template <> template <> -void BufferStreamTestObjectType::test<6>() +TEST_CASE("BufferStream Tests: BufferArrayStream writes to and reads back a BufferArray", "[BufferStream_Tests]") { - set_test_name("BufferArrayStream construction with real BufferArray"); - // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; //const char * content("This is a string. A fragment."); @@ -195,11 +173,11 @@ void BufferStreamTestObjectType::test<6>() // Basic operations bas << "Hello" << 27 << "."; - ensure("BA length 8", ba->size() == 8); + CHECK(ba->size() == 8); std::string str; bas >> str; - ensure("reads correctly", str == "Hello27."); + CHECK(str == "Hello27."); } // release the implicit reference, causing the object to be released @@ -208,11 +186,8 @@ void BufferStreamTestObjectType::test<6>() } -template <> template <> -void BufferStreamTestObjectType::test<7>() +TEST_CASE("BufferStream Tests: BufferArrayStream with LLSD serialization", "[BufferStream_Tests]") { - set_test_name("BufferArrayStream with LLSD serialization"); - // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; @@ -240,7 +215,7 @@ void BufferStreamTestObjectType::test<7>() std::string str; bas >> str; // std::cout << "SERIALIZED LLSD: " << str << std::endl; - ensure("Extracted string has reasonable length", str.size() > 60); + CHECK(str.size() > 60); } // release the implicit reference, causing the object to be released @@ -249,7 +224,4 @@ void BufferStreamTestObjectType::test<7>() } -} // end namespace tut - - -#endif // TEST_LLCORE_BUFFER_STREAM_H_ +} // anonymous namespace diff --git a/indra/llcorehttp/tests/test_httpheaders.hpp b/indra/llcorehttp/tests/httpheaders_test.cpp similarity index 64% rename from indra/llcorehttp/tests/test_httpheaders.hpp rename to indra/llcorehttp/tests/httpheaders_test.cpp index d2d76aa281..932cf1ab6d 100644 --- a/indra/llcorehttp/tests/test_httpheaders.hpp +++ b/indra/llcorehttp/tests/httpheaders_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_httpheaders.hpp + * @file httpheaders_test.cpp * @brief unit tests for the LLCore::HttpHeaders class * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -23,51 +23,33 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef TEST_LLCORE_HTTP_HEADERS_H_ -#define TEST_LLCORE_HTTP_HEADERS_H_ +#include "linden_common.h" + +#include #include "httpheaders.h" #include +using namespace LLCore; using namespace LLCoreInt; -namespace tut -{ namespace { - -struct HttpHeadersTestData -{ - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. -}; - -typedef test_group HttpHeadersTestGroupType; -typedef HttpHeadersTestGroupType::object HttpHeadersTestObjectType; -HttpHeadersTestGroupType HttpHeadersTestGroup("HttpHeaders Tests"); -} - -template <> template <> -void HttpHeadersTestObjectType::test<1>() +TEST_CASE("HttpHeaders Tests: a new HttpHeaders is empty", "[HttpHeaders_Tests]") { - set_test_name("HttpHeaders construction"); - // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); - ensure("Nothing in headers", 0 == headers->size()); + CHECK(headers->size() == 0); // release the implicit reference, causing the object to be released headers.reset(); } -template <> template <> -void HttpHeadersTestObjectType::test<2>() +TEST_CASE("HttpHeaders Tests: append keeps names and values in order", "[HttpHeaders_Tests]") { - set_test_name("HttpHeaders construction"); - // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); @@ -80,24 +62,21 @@ void HttpHeadersTestObjectType::test<2>() std::string str2v("application/json"); headers->append(str2n, str2v); - ensure("Headers retained", 2 == headers->size()); + REQUIRE(headers->size() == 2); HttpHeaders::container_t & c(headers->getContainerTESTONLY()); - ensure("First name is first name", c[0].first == str1n); - ensure("First value is first value", c[0].second == str1v); - ensure("Second name is second name", c[1].first == str2n); - ensure("Second value is second value", c[1].second == str2v); + CHECK(c[0].first == str1n); + CHECK(c[0].second == str1v); + CHECK(c[1].first == str2n); + CHECK(c[1].second == str2v); } // release the implicit reference, causing the object to be released headers.reset(); } -template <> template <> -void HttpHeadersTestObjectType::test<3>() +TEST_CASE("HttpHeaders Tests: find matches whole names case-sensitively", "[HttpHeaders_Tests]") { - set_test_name("HttpHeaders basic find"); - // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); @@ -113,35 +92,35 @@ void HttpHeadersTestObjectType::test<3>() std::string str3v("trois gymnopedie"); headers->append(str3n, str3v); - ensure("Headers retained", 3 == headers->size()); + CHECK(headers->size() == 3); const std::string * result(NULL); // Find a header result = headers->find("TRES"); - ensure("Found the last item", result != NULL); - ensure("Last item is a nice", result != NULL && str3v == *result); + REQUIRE(result != NULL); + CHECK((result != NULL && str3v == *result)); // appends above are raw and find is case sensitive result = headers->find("TReS"); - ensure("Last item not found due to case", result == NULL); + UNSCOPED_INFO("the case differs"); + CHECK(result == NULL); result = headers->find("TRE"); - ensure("Last item not found due to prefixing (1)", result == NULL); + UNSCOPED_INFO("a prefix of the name"); + CHECK(result == NULL); result = headers->find("TRESS"); - ensure("Last item not found due to prefixing (2)", result == NULL); + UNSCOPED_INFO("the name and more"); + CHECK(result == NULL); } // release the implicit reference, causing the object to be released headers.reset(); } -template <> template <> -void HttpHeadersTestObjectType::test<4>() +TEST_CASE("HttpHeaders Tests: appendNormal splits and cleans raw header lines", "[HttpHeaders_Tests]") { - set_test_name("HttpHeaders normalized header entry"); - // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); @@ -150,80 +129,82 @@ void HttpHeadersTestObjectType::test<4>() static char line1v[] = "image/yourfacehere"; headers->appendNormal(line1, sizeof(line1) - 1); - ensure("First append worked in some fashion", 1 == headers->size()); + CHECK(headers->size() == 1); const std::string * result(NULL); // Find a header result = headers->find("accept"); - ensure("Found 'accept'", result != NULL); - ensure("accept value has face", result != NULL && *result == line1v); + REQUIRE(result != NULL); + CHECK((result != NULL && *result == line1v)); // Left-clean on value static char line2[] = " next : \t\tlinejunk \t"; headers->appendNormal(line2, sizeof(line2) - 1); - ensure("Second append worked", 2 == headers->size()); + CHECK(headers->size() == 2); result = headers->find("next"); - ensure("Found 'next'", result != NULL); - ensure("next value is left-clean", result != NULL && - *result == "linejunk \t"); + REQUIRE(result != NULL); + UNSCOPED_INFO("the value is trimmed on the left only"); + CHECK((result != NULL && + *result == "linejunk \t")); // First value unmolested result = headers->find("accept"); - ensure("Found 'accept' again", result != NULL); - ensure("accept value has face", result != NULL && *result == line1v); + REQUIRE(result != NULL); + CHECK((result != NULL && *result == line1v)); // Colons in value are okay static char line3[] = "FancY-PANTs::plop:-neuf-=vleem="; static char line3v[] = ":plop:-neuf-=vleem="; headers->appendNormal(line3, sizeof(line3) - 1); - ensure("Third append worked", 3 == headers->size()); + CHECK(headers->size() == 3); result = headers->find("fancy-pants"); - ensure("Found 'fancy-pants'", result != NULL); - ensure("fancy-pants value has colons", result != NULL && *result == line3v); + REQUIRE(result != NULL); + UNSCOPED_INFO("colons in the value are kept"); + CHECK((result != NULL && *result == line3v)); // Zero-length value static char line4[] = "all-talk-no-walk:"; headers->appendNormal(line4, sizeof(line4) - 1); - ensure("Fourth append worked", 4 == headers->size()); + CHECK(headers->size() == 4); result = headers->find("all-talk-no-walk"); - ensure("Found 'all-talk'", result != NULL); - ensure("al-talk value is zero-length", result != NULL && result->size() == 0); + REQUIRE(result != NULL); + CHECK((result != NULL && result->size() == 0)); // Zero-length name static char line5[] = ":all-talk-no-walk"; static char line5v[] = "all-talk-no-walk"; headers->appendNormal(line5, sizeof(line5) - 1); - ensure("Fifth append worked", 5 == headers->size()); + CHECK(headers->size() == 5); result = headers->find(""); - ensure("Found no-name", result != NULL); - ensure("no-name value is something", result != NULL && *result == line5v); + REQUIRE(result != NULL); + CHECK((result != NULL && *result == line5v)); // Lone colon is still something headers->clear(); static char line6[] = " :"; headers->appendNormal(line6, sizeof(line6) - 1); - ensure("Sixth append worked", 1 == headers->size()); + CHECK(headers->size() == 1); result = headers->find(""); - ensure("Found 2nd no-name", result != NULL); - ensure("2nd no-name value is nothing", result != NULL && result->size() == 0); + REQUIRE(result != NULL); + CHECK((result != NULL && result->size() == 0)); // Line without colons is taken as-is and unstripped in name static char line7[] = " \toskdgioasdghaosdghoowg28342908tg8902hg0hwedfhqew890v7qh0wdebv78q0wdevbhq>?M>BNM?NZ? \t"; headers->appendNormal(line7, sizeof(line7) - 1); - ensure("Seventh append worked", 2 == headers->size()); + CHECK(headers->size() == 2); result = headers->find(line7); - ensure("Found whatsit line", result != NULL); - ensure("Whatsit line has no value", result != NULL && result->size() == 0); + REQUIRE(result != NULL); + CHECK((result != NULL && result->size() == 0)); // Normaling interface heeds the byte count, doesn't look for NUL-terminator static char line8[] = "binary:ignorestuffontheendofthis"; headers->appendNormal(line8, 13); - ensure("Eighth append worked", 3 == headers->size()); + CHECK(headers->size() == 3); result = headers->find("binary"); - ensure("Found 'binary'", result != NULL); - ensure("binary value was limited to 'ignore'", result != NULL && - *result == "ignore"); + REQUIRE(result != NULL); + CHECK((result != NULL && + *result == "ignore")); } @@ -232,20 +213,17 @@ void HttpHeadersTestObjectType::test<4>() } // Verify forward iterator finds everything as expected -template <> template <> -void HttpHeadersTestObjectType::test<5>() +TEST_CASE("HttpHeaders Tests: iterators visit every entry in order", "[HttpHeaders_Tests]") { - set_test_name("HttpHeaders iterator tests"); - // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); HttpHeaders::iterator end(headers->end()), begin(headers->begin()); - ensure("Empty container has equal begin/end const iterators", end == begin); + CHECK(end == begin); HttpHeaders::const_iterator cend(headers->end()), cbegin(headers->begin()); - ensure("Empty container has equal rbegin/rend const iterators", cend == cbegin); + CHECK(cend == cbegin); - ensure("Empty container has equal begin/end iterators", headers->end() == headers->begin()); + CHECK(headers->end() == headers->begin()); { static char line1[] = " AcCePT : image/yourfacehere"; @@ -272,7 +250,7 @@ void HttpHeadersTestObjectType::test<5>() static char line6v[] = ""; headers->appendNormal(line6, sizeof(line6) - 1); - ensure("All entries accounted for", 6 == headers->size()); + REQUIRE(headers->size() == 6); static char * values[] = { line1v, @@ -289,9 +267,8 @@ void HttpHeadersTestObjectType::test<5>() cend != it; ++it, ++i) { - std::ostringstream str; - str << "Const Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); + CAPTURE(i); + REQUIRE((*it).second == values[i]); } // Rewind, do non-consts @@ -301,9 +278,8 @@ void HttpHeadersTestObjectType::test<5>() end != it; ++it, ++i) { - std::ostringstream str; - str << "Const Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); + CAPTURE(i); + REQUIRE((*it).second == values[i]); } } @@ -312,18 +288,15 @@ void HttpHeadersTestObjectType::test<5>() } // Reverse iterators find everything as expected -template <> template <> -void HttpHeadersTestObjectType::test<6>() +TEST_CASE("HttpHeaders Tests: reverse iterators visit every entry in reverse order", "[HttpHeaders_Tests]") { - set_test_name("HttpHeaders reverse iterator tests"); - // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); HttpHeaders::reverse_iterator rend(headers->rend()), rbegin(headers->rbegin()); - ensure("Empty container has equal rbegin/rend const iterators", rend == rbegin); + CHECK(rend == rbegin); HttpHeaders::const_reverse_iterator crend(headers->rend()), crbegin(headers->rbegin()); - ensure("Empty container has equal rbegin/rend const iterators", crend == crbegin); + CHECK(crend == crbegin); { static char line1[] = " AcCePT : image/yourfacehere"; @@ -350,7 +323,7 @@ void HttpHeadersTestObjectType::test<6>() static char line6v[] = ""; headers->appendNormal(line6, sizeof(line6) - 1); - ensure("All entries accounted for", 6 == headers->size()); + REQUIRE(headers->size() == 6); static char * values[] = { line6v, @@ -367,9 +340,8 @@ void HttpHeadersTestObjectType::test<6>() cend != it; ++it, ++i) { - std::ostringstream str; - str << "Const Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); + CAPTURE(i); + REQUIRE((*it).second == values[i]); } // Rewind, do non-consts @@ -379,9 +351,8 @@ void HttpHeadersTestObjectType::test<6>() end != it; ++it, ++i) { - std::ostringstream str; - str << "Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); + CAPTURE(i); + REQUIRE((*it).second == values[i]); } } @@ -389,7 +360,4 @@ void HttpHeadersTestObjectType::test<6>() headers.reset(); } -} // end namespace tut - - -#endif // TEST_LLCORE_HTTP_HEADERS_H_ +} // anonymous namespace diff --git a/indra/llcorehttp/tests/test_httpoperation.hpp b/indra/llcorehttp/tests/httpoperation_test.cpp similarity index 69% rename from indra/llcorehttp/tests/test_httpoperation.hpp rename to indra/llcorehttp/tests/httpoperation_test.cpp index 2d17d00eab..eaebf146c2 100644 --- a/indra/llcorehttp/tests/test_httpoperation.hpp +++ b/indra/llcorehttp/tests/httpoperation_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_httpoperation.hpp + * @file httpoperation_test.cpp * @brief unit tests for the LLCore::HttpOperation-derived classes * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -23,8 +23,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef TEST_LLCORE_HTTP_OPERATION_H_ -#define TEST_LLCORE_HTTP_OPERATION_H_ +#include "linden_common.h" + +#include #include "_httpoperation.h" #include "httphandler.h" @@ -32,6 +33,7 @@ #include +using namespace LLCore; using namespace LLCoreInt; @@ -52,39 +54,20 @@ class TestHandler : public LLCore::HttpHandler } // end namespace anonymous -namespace tut -{ namespace { - struct HttpOperationTestData + TEST_CASE("HttpOperation Tests: a new HttpOpNull has one reference", "[HttpOperation_Tests]") { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. - }; - - typedef test_group HttpOperationTestGroupType; - typedef HttpOperationTestGroupType::object HttpOperationTestObjectType; - HttpOperationTestGroupType HttpOperationTestGroup("HttpOperation Tests"); -} - - template <> template <> - void HttpOperationTestObjectType::test<1>() - { - set_test_name("HttpOpNull construction"); - // create a new ref counted object with an implicit reference HttpOperation::ptr_t op (new HttpOpNull()); - ensure(op.use_count() == 1); + CHECK(op.use_count() == 1); // release the implicit reference, causing the object to be released op.reset(); } - template <> template <> - void HttpOperationTestObjectType::test<2>() + TEST_CASE("HttpOperation Tests: setting a reply handler adds no reference to the op", "[HttpOperation_Tests]") { - set_test_name("HttpOpNull construction with handlers"); - // Get some handlers LLCore::HttpHandler::ptr_t h1 (new TestHandler()); @@ -95,7 +78,7 @@ namespace op->setReplyPath(LLCore::HttpOperation::HttpReplyQueuePtr_t(), h1); // Check ref count - ensure(op.use_count() == 1); + CHECK(op.use_count() == 1); // release the reference, releasing the operation but // not the handlers. @@ -106,5 +89,3 @@ namespace } } - -#endif // TEST_LLCORE_HTTP_OPERATION_H_ diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/httprequest_test.cpp similarity index 83% rename from indra/llcorehttp/tests/test_httprequest.hpp rename to indra/llcorehttp/tests/httprequest_test.cpp index 6d5b8ab0a3..bb66f439e1 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/httprequest_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_httprequest.hpp + * @file httprequest_test.cpp * @brief unit tests for the LLCore::HttpRequest class * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -23,8 +23,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef TEST_LLCORE_HTTP_REQUEST_H_ -#define TEST_LLCORE_HTTP_REQUEST_H_ +#include "linden_common.h" + +#include #include "httprequest.h" #include "bufferarray.h" @@ -39,9 +40,13 @@ #include "alregex.h" #include -#include "llcorehttp_test.h" +#include "llcleanup.h" +#include "llproxy.h" + +#include +using namespace LLCore; using namespace LLCoreInt; // spin/sleep waiting times for client/server exchange tests @@ -56,17 +61,82 @@ static const int LOOP_COUNT_LONG(3000); // 30-second dwell time namespace { - #if defined(WIN32) void usleep(unsigned long usec); #endif +// Initialization and cleanup for libcurl: curl's global state and the +// LLProxy singleton, for the length of a test. +void init_curl() +{ + curl_global_init(CURL_GLOBAL_ALL); + + LLProxy::getInstance(); } -namespace tut + +void term_curl() { + SUBSYSTEM_CLEANUP(LLProxy); +} + + +class ScopedCurlInit +{ +public: + ScopedCurlInit() + { + init_curl(); + } + + ~ScopedCurlInit() + { + term_curl(); + } +}; + + +// The peer's address, which test_llcorehttp_peer.py, the program this test +// runs under, puts in LL_TEST_PORT. +std::string get_base_url() +{ + const char * env(getenv("LL_TEST_PORT")); + + if (! env) + { + std::cerr << "LL_TEST_PORT environment variable missing." << std::endl; + std::cerr << "Test expects to run in test_llcorehttp_peer.py script." << std::endl; + INFO("LL_TEST_PORT set in environment"); + REQUIRE(env != NULL); + } + + int port(atoi(env)); + std::ostringstream out; + out << "http://localhost:" << port << "/"; + return out.str(); +} + + +void stop_thread(LLCore::HttpRequest * req) +{ + if (req) + { + req->requestStopThread(LLCore::HttpHandler::ptr_t()); + + int count = 0; + int limit = 10; + while (count++ < limit && ! HttpService::isStopped()) + { + req->update(1000); + usleep(100000); + } + } +} + +} + namespace { @@ -94,16 +164,14 @@ class TestHandler2 : public LLCore::HttpHandler { if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle) { - ensure("Expected handle received in handler", mExpectHandle == handle); + REQUIRE(mExpectHandle == handle); } - ensure("Handler got a response", NULL != response); + REQUIRE(response != NULL); if (response && mState) { const HttpStatus actual_status(response->getStatus()); - std::ostringstream test; - test << "Expected HttpStatus received in response. Wanted: " - << mState->mStatus.toHex() << " Received: " << actual_status.toHex(); - ensure(test.str().c_str(), actual_status == mState->mStatus); + INFO("wanted status " << mState->mStatus.toHex() << ", received " << actual_status.toHex()); + REQUIRE(actual_status == mState->mStatus); } if (mState) { @@ -111,9 +179,9 @@ class TestHandler2 : public LLCore::HttpHandler } if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty()) { - ensure("Response required with header check", response != NULL); + REQUIRE(response != NULL); HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this - ensure("Some quantity of headers returned", header != NULL); + REQUIRE(header != NULL); if (! mHeadersRequired.empty()) { @@ -134,11 +202,8 @@ class TestHandler2 : public LLCore::HttpHandler break; } } - std::ostringstream str; - str << "Required header #" << i << " " - << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second - << " not found in response"; - ensure(str.str(), found); + INFO("required header " << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second); + REQUIRE(found); } } @@ -153,11 +218,8 @@ class TestHandler2 : public LLCore::HttpHandler if (mHeadersDisallowed[i].first.match((*iter).first) && mHeadersDisallowed[i].second.match((*iter).second)) { - std::ostringstream str; - str << "Disallowed header #" << i << " " - << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second - << " found in response"; - ensure(str.str(), false); + FAIL("disallowed header " << mHeadersDisallowed[i].first << "=" + << mHeadersDisallowed[i].second << " found in response"); } } } @@ -166,10 +228,9 @@ class TestHandler2 : public LLCore::HttpHandler if (! mCheckContentType.empty()) { - ensure("Response required with content type check", response != NULL); + REQUIRE(response != NULL); std::string con_type(response->getContentType()); - ensure("Content-Type as expected (" + mCheckContentType + ")", - mCheckContentType == con_type); + REQUIRE(mCheckContentType == con_type); } // std::cout << "TestHandler2::onCompleted() invoked" << std::endl; @@ -183,18 +244,11 @@ class TestHandler2 : public LLCore::HttpHandler regex_container_t mHeadersDisallowed; }; -typedef test_group HttpRequestTestGroupType; -typedef HttpRequestTestGroupType::object HttpRequestTestObjectType; -HttpRequestTestGroupType HttpRequestTestGroup("HttpRequest Tests"); -} -template <> template <> -void HttpRequestTestObjectType::test<1>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: an HttpRequest is constructed and deleted with the service up", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("HttpRequest construction"); - HttpRequest * req = NULL; try @@ -219,13 +273,10 @@ void HttpRequestTestObjectType::test<1>() } } -template <> template <> -void HttpRequestTestObjectType::test<2>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a NoOp queued with no thread running leaves two queue references", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("HttpRequest and Null Op queued"); - HttpRequest * req = NULL; try @@ -238,14 +289,14 @@ void HttpRequestTestObjectType::test<2>() // Issue a NoOp HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t()); - ensure("Request issued", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // release the request object delete req; req = NULL; // Request queue should have two references: global singleton & service object - ensure("Two references to request queue", 2 == HttpRequestQueue::instanceOf()->getRefCount()); + CHECK(HttpRequestQueue::instanceOf()->getRefCount() == 2); // Okay, tear it down HttpRequest::destroyService(); @@ -259,18 +310,12 @@ void HttpRequestTestObjectType::test<2>() } } -namespace -{ void NoOpDeletor(LLCore::HttpHandler *) { } -} -template <> template <> -void HttpRequestTestObjectType::test<3>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a NoOp is answered and a stop request stops the worker thread", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("HttpRequest NoOp + Stop execution"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -294,7 +339,7 @@ void HttpRequestTestObjectType::test<3>() // Issue a NoOp HttpHandle handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -304,12 +349,13 @@ void HttpRequestTestObjectType::test<3>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -319,8 +365,9 @@ void HttpRequestTestObjectType::test<3>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -329,7 +376,7 @@ void HttpRequestTestObjectType::test<3>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req; @@ -338,7 +385,7 @@ void HttpRequestTestObjectType::test<3>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -349,13 +396,10 @@ void HttpRequestTestObjectType::test<3>() } } -template <> template <> -void HttpRequestTestObjectType::test<4>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: two HttpRequest instances are served by one worker thread", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("2 HttpRequest instances, one thread"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. TestHandler2 handler1(this, "handler1"); @@ -384,11 +428,11 @@ void HttpRequestTestObjectType::test<4>() // Issue some NoOps HttpHandle handle = req1->requestNoOp(handler1p); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); handler1.mExpectHandle = handle; handle = req2->requestNoOp(handler2p); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); handler2.mExpectHandle = handle; // Run the notification pump. @@ -400,12 +444,13 @@ void HttpRequestTestObjectType::test<4>() req2->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 2); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // Okay, request a shutdown of the servicing thread handle = req2->requestStopThread(handler2p); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); handler2.mExpectHandle = handle; // Run the notification pump again @@ -417,8 +462,9 @@ void HttpRequestTestObjectType::test<4>() req2->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 3); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 3); // See that we actually shutdown the thread count = 0; @@ -427,7 +473,7 @@ void HttpRequestTestObjectType::test<4>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req1; @@ -438,7 +484,7 @@ void HttpRequestTestObjectType::test<4>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 3 == mHandlerCalls); + CHECK(mHandlerCalls == 3); } catch (...) { @@ -450,17 +496,14 @@ void HttpRequestTestObjectType::test<4>() } } -template <> template <> -void HttpRequestTestObjectType::test<5>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a NoOp is answered behind a soft spin before hard termination", "[HttpRequest_Tests]") { #ifndef LL_WINDOWS - skip("Skip due to issues with testing pthread cancellation"); + SKIP("Skip due to issues with testing pthread cancellation"); #endif ScopedCurlInit ready; - set_test_name("HttpRequest Spin (soft) + NoOp + hard termination"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -484,11 +527,11 @@ void HttpRequestTestObjectType::test<5>() // Issue a Spin HttpHandle handle = req->requestSpin(1); - ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Issue a NoOp handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -498,7 +541,7 @@ void HttpRequestTestObjectType::test<5>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("NoOp notification received", mHandlerCalls == 1); + CHECK(mHandlerCalls == 1); // release the request object delete req; @@ -517,16 +560,13 @@ void HttpRequestTestObjectType::test<5>() } -template <> template <> -void HttpRequestTestObjectType::test<6>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a hard spin keeps a NoOp unanswered until hard termination", "[HttpRequest_Tests]") { #ifndef LL_WINDOWS - skip("Skip due to issues with testing pthread cancellation"); + SKIP("Skip due to issues with testing pthread cancellation"); #endif ScopedCurlInit ready; - set_test_name("HttpRequest Spin + NoOp + hard termination"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -551,11 +591,11 @@ void HttpRequestTestObjectType::test<6>() // Issue a Spin HttpHandle handle = req->requestSpin(0); // Hard spin - ensure("Valid handle returned for spin request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Issue a NoOp handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for no-op request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -565,7 +605,7 @@ void HttpRequestTestObjectType::test<6>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("No notifications received", mHandlerCalls == 0); + CHECK(mHandlerCalls == 0); // release the request object delete req; @@ -584,13 +624,10 @@ void HttpRequestTestObjectType::test<6>() } -template <> template <> -void HttpRequestTestObjectType::test<7>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET to a dead port fails with CURLE_COULDNT_CONNECT", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("HttpRequest GET to dead port + Stop execution"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -626,7 +663,7 @@ void HttpRequestTestObjectType::test<7>() opts, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -636,13 +673,14 @@ void HttpRequestTestObjectType::test<7>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -652,8 +690,9 @@ void HttpRequestTestObjectType::test<7>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -662,7 +701,7 @@ void HttpRequestTestObjectType::test<7>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options opts.reset(); @@ -674,7 +713,7 @@ void HttpRequestTestObjectType::test<7>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -687,16 +726,13 @@ void HttpRequestTestObjectType::test<7>() } -template <> template <> -void HttpRequestTestObjectType::test<8>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET to the peer is answered 200", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest GET to real service"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -725,7 +761,7 @@ void HttpRequestTestObjectType::test<8>() HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -735,13 +771,14 @@ void HttpRequestTestObjectType::test<8>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -751,8 +788,9 @@ void HttpRequestTestObjectType::test<8>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -761,7 +799,7 @@ void HttpRequestTestObjectType::test<8>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req; @@ -770,7 +808,7 @@ void HttpRequestTestObjectType::test<8>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -782,16 +820,13 @@ void HttpRequestTestObjectType::test<8>() } -template <> template <> -void HttpRequestTestObjectType::test<9>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: requestGetByteRange with a zero range is answered 200", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest GET with Range: header to real service"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -822,7 +857,7 @@ void HttpRequestTestObjectType::test<9>() HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -832,13 +867,14 @@ void HttpRequestTestObjectType::test<9>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -848,8 +884,9 @@ void HttpRequestTestObjectType::test<9>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -858,7 +895,7 @@ void HttpRequestTestObjectType::test<9>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req; @@ -867,7 +904,7 @@ void HttpRequestTestObjectType::test<9>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -879,16 +916,13 @@ void HttpRequestTestObjectType::test<9>() } -template <> template <> -void HttpRequestTestObjectType::test<10>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a PUT with a body to the peer is answered 200", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest PUT to real service"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -921,7 +955,7 @@ void HttpRequestTestObjectType::test<10>() HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -931,13 +965,14 @@ void HttpRequestTestObjectType::test<10>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -947,8 +982,9 @@ void HttpRequestTestObjectType::test<10>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -957,7 +993,7 @@ void HttpRequestTestObjectType::test<10>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // Lose the request body body->release(); @@ -970,7 +1006,7 @@ void HttpRequestTestObjectType::test<10>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -985,16 +1021,13 @@ void HttpRequestTestObjectType::test<10>() } } -template <> template <> -void HttpRequestTestObjectType::test<11>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a POST with a body to the peer is answered 200", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest POST to real service"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1027,7 +1060,7 @@ void HttpRequestTestObjectType::test<11>() HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -1037,13 +1070,14 @@ void HttpRequestTestObjectType::test<11>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1053,8 +1087,9 @@ void HttpRequestTestObjectType::test<11>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -1063,7 +1098,7 @@ void HttpRequestTestObjectType::test<11>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // Lose the request body body->release(); @@ -1076,7 +1111,7 @@ void HttpRequestTestObjectType::test<11>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -1091,16 +1126,13 @@ void HttpRequestTestObjectType::test<11>() } } -template <> template <> -void HttpRequestTestObjectType::test<12>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET with tracing on is answered 200", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest GET with some tracing"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1134,7 +1166,7 @@ void HttpRequestTestObjectType::test<12>() HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -1144,13 +1176,14 @@ void HttpRequestTestObjectType::test<12>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1160,8 +1193,9 @@ void HttpRequestTestObjectType::test<12>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -1170,7 +1204,7 @@ void HttpRequestTestObjectType::test<12>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req; @@ -1179,7 +1213,7 @@ void HttpRequestTestObjectType::test<12>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -1191,8 +1225,7 @@ void HttpRequestTestObjectType::test<12>() } -template <> template <> -void HttpRequestTestObjectType::test<13>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET that wants headers gets the peer's X-LL-Special header", "[HttpRequest_Tests]") { ScopedCurlInit ready; @@ -1203,8 +1236,6 @@ void HttpRequestTestObjectType::test<13>() std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest GET with returned headers"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1246,7 +1277,7 @@ void HttpRequestTestObjectType::test<13>() opts, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // release options opts.reset(); @@ -1259,14 +1290,15 @@ void HttpRequestTestObjectType::test<13>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1276,8 +1308,9 @@ void HttpRequestTestObjectType::test<13>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -1286,7 +1319,7 @@ void HttpRequestTestObjectType::test<13>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req; @@ -1295,7 +1328,7 @@ void HttpRequestTestObjectType::test<13>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -1308,13 +1341,10 @@ void HttpRequestTestObjectType::test<13>() } -template <> template <> -void HttpRequestTestObjectType::test<14>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET to a peer that sleeps times out after two seconds", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("HttpRequest GET timeout"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1351,7 +1381,7 @@ void HttpRequestTestObjectType::test<14>() opts, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -1361,13 +1391,14 @@ void HttpRequestTestObjectType::test<14>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1377,8 +1408,9 @@ void HttpRequestTestObjectType::test<14>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -1387,7 +1419,7 @@ void HttpRequestTestObjectType::test<14>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options opts.reset(); @@ -1399,7 +1431,7 @@ void HttpRequestTestObjectType::test<14>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -1412,16 +1444,13 @@ void HttpRequestTestObjectType::test<14>() } // Test retrieval of Content-Type/Content-Encoding headers -template <> template <> -void HttpRequestTestObjectType::test<15>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET reports the response's Content-Type", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("HttpRequest GET with Content-Type"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1456,7 +1485,7 @@ void HttpRequestTestObjectType::test<15>() HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -1466,14 +1495,15 @@ void HttpRequestTestObjectType::test<15>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handler.mCheckContentType.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1483,8 +1513,9 @@ void HttpRequestTestObjectType::test<15>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -1493,7 +1524,7 @@ void HttpRequestTestObjectType::test<15>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release the request object delete req; @@ -1502,7 +1533,7 @@ void HttpRequestTestObjectType::test<15>() // Shut down service HttpRequest::destroyService(); - ensure("Two handler calls on the way out", 2 == mHandlerCalls); + CHECK(mHandlerCalls == 2); } catch (...) { @@ -1515,8 +1546,7 @@ void HttpRequestTestObjectType::test<15>() // Test header generation on GET requests -template <> template <> -void HttpRequestTestObjectType::test<16>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a GET sends default headers and a texture fetch adds Range and Accept", "[HttpRequest_Tests]") { ScopedCurlInit ready; @@ -1526,8 +1556,6 @@ void HttpRequestTestObjectType::test<16>() std::string url_base(get_base_url()); - set_test_name("Header generation for HttpRequest GET"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1610,7 +1638,7 @@ void HttpRequestTestObjectType::test<16>() options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -1620,8 +1648,9 @@ void HttpRequestTestObjectType::test<16>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Do a texture-style fetch headers = HttpHeaders::ptr_t(new HttpHeaders); @@ -1686,7 +1715,7 @@ void HttpRequestTestObjectType::test<16>() options, headers, handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. count = 0; @@ -1696,8 +1725,9 @@ void HttpRequestTestObjectType::test<16>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 2); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // Okay, request a shutdown of the servicing thread @@ -1705,7 +1735,7 @@ void HttpRequestTestObjectType::test<16>() handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1715,8 +1745,9 @@ void HttpRequestTestObjectType::test<16>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 3); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 3); // See that we actually shutdown the thread count = 0; @@ -1725,7 +1756,7 @@ void HttpRequestTestObjectType::test<16>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options & headers options.reset(); @@ -1752,8 +1783,7 @@ void HttpRequestTestObjectType::test<16>() // Test header generation on POST requests -template <> template <> -void HttpRequestTestObjectType::test<17>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a POST sends default headers and a form-urlencoded Content-Type", "[HttpRequest_Tests]") { ScopedCurlInit ready; @@ -1763,8 +1793,6 @@ void HttpRequestTestObjectType::test<17>() std::string url_base(get_base_url()); - set_test_name("Header generation for HttpRequest POST"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -1863,7 +1891,7 @@ void HttpRequestTestObjectType::test<17>() options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -1875,8 +1903,9 @@ void HttpRequestTestObjectType::test<17>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread @@ -1884,7 +1913,7 @@ void HttpRequestTestObjectType::test<17>() handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -1894,8 +1923,9 @@ void HttpRequestTestObjectType::test<17>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -1904,7 +1934,7 @@ void HttpRequestTestObjectType::test<17>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options & headers options.reset(); @@ -1936,8 +1966,7 @@ void HttpRequestTestObjectType::test<17>() // Test header generation on PUT requests -template <> template <> -void HttpRequestTestObjectType::test<18>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: a PUT sends default headers with a length and no Content-Type", "[HttpRequest_Tests]") { ScopedCurlInit ready; @@ -1947,8 +1976,6 @@ void HttpRequestTestObjectType::test<18>() std::string url_base(get_base_url()); - set_test_name("Header generation for HttpRequest PUT"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2048,7 +2075,7 @@ void HttpRequestTestObjectType::test<18>() options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2060,8 +2087,9 @@ void HttpRequestTestObjectType::test<18>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread @@ -2069,7 +2097,7 @@ void HttpRequestTestObjectType::test<18>() handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -2079,8 +2107,9 @@ void HttpRequestTestObjectType::test<18>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -2089,7 +2118,7 @@ void HttpRequestTestObjectType::test<18>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options & headers options.reset(); @@ -2121,8 +2150,7 @@ void HttpRequestTestObjectType::test<18>() // Test header generation on GET requests with overrides -template <> template <> -void HttpRequestTestObjectType::test<19>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: headers given to a GET replace its defaults", "[HttpRequest_Tests]") { // It appears that HttpRequest is fully capable of sending duplicate header values in violation of // this test's expectations. Something needs to budge: is sending duplicate header values desired? @@ -2133,7 +2161,7 @@ void HttpRequestTestObjectType::test<19>() // X-Reflect-content-type: text/html // X-Reflect-content-type: application/llsd+xml // - skip("FIXME: Bad assertions or broken functionality."); + SKIP("FIXME: Bad assertions or broken functionality."); ScopedCurlInit ready; @@ -2143,8 +2171,6 @@ void HttpRequestTestObjectType::test<19>() std::string url_base(get_base_url()); - set_test_name("Header generation for HttpRequest GET with header overrides"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2246,7 +2272,7 @@ void HttpRequestTestObjectType::test<19>() options, headers, handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump. int count(0); @@ -2256,15 +2282,16 @@ void HttpRequestTestObjectType::test<19>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -2274,8 +2301,9 @@ void HttpRequestTestObjectType::test<19>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -2284,7 +2312,7 @@ void HttpRequestTestObjectType::test<19>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options & headers options.reset(); @@ -2311,8 +2339,7 @@ void HttpRequestTestObjectType::test<19>() // Test header generation on POST requests with overrides -template <> template <> -void HttpRequestTestObjectType::test<20>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: headers given to a POST replace its defaults", "[HttpRequest_Tests]") { // It appears that HttpRequest is fully capable of sending duplicate header values in violation of // this test's expectations. Something needs to budge: is sending duplicate header values desired? @@ -2323,7 +2350,7 @@ void HttpRequestTestObjectType::test<20>() // X-Reflect-content-type: text/html // X-Reflect-content-type: application/llsd+xml // - skip("FIXME: Bad assertions or broken functionality."); + SKIP("FIXME: Bad assertions or broken functionality."); ScopedCurlInit ready; @@ -2333,8 +2360,6 @@ void HttpRequestTestObjectType::test<20>() std::string url_base(get_base_url()); - set_test_name("Header generation for HttpRequest POST with header overrides"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2454,7 +2479,7 @@ void HttpRequestTestObjectType::test<20>() options, headers, handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2466,8 +2491,9 @@ void HttpRequestTestObjectType::test<20>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread @@ -2475,7 +2501,7 @@ void HttpRequestTestObjectType::test<20>() handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -2485,8 +2511,9 @@ void HttpRequestTestObjectType::test<20>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -2495,7 +2522,7 @@ void HttpRequestTestObjectType::test<20>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options & headers options.reset(); @@ -2526,8 +2553,7 @@ void HttpRequestTestObjectType::test<20>() // Test header generation on PUT requests with overrides -template <> template <> -void HttpRequestTestObjectType::test<21>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: the last of several Content-Types given to a PUT is the one sent", "[HttpRequest_Tests]") { // It appears that HttpRequest is fully capable of sending duplicate header values in violation of // this test's expectations. Something needs to budge: is sending duplicate header values desired? @@ -2538,7 +2564,7 @@ void HttpRequestTestObjectType::test<21>() // X-Reflect-content-type: text/html // X-Reflect-content-type: application/llsd+xml // - skip("FIXME: Bad assertions or broken functionality."); + SKIP("FIXME: Bad assertions or broken functionality."); ScopedCurlInit ready; @@ -2548,8 +2574,6 @@ void HttpRequestTestObjectType::test<21>() std::string url_base(get_base_url()); - set_test_name("Header generation for HttpRequest PUT with header overrides"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2662,7 +2686,7 @@ void HttpRequestTestObjectType::test<21>() options, headers, handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); ba->release(); ba = NULL; @@ -2674,8 +2698,9 @@ void HttpRequestTestObjectType::test<21>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // Okay, request a shutdown of the servicing thread @@ -2683,7 +2708,7 @@ void HttpRequestTestObjectType::test<21>() handler.mHeadersRequired.clear(); handler.mHeadersDisallowed.clear(); handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -2693,8 +2718,9 @@ void HttpRequestTestObjectType::test<21>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 2); // See that we actually shutdown the thread count = 0; @@ -2703,7 +2729,7 @@ void HttpRequestTestObjectType::test<21>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options & headers options.reset(); @@ -2733,16 +2759,13 @@ void HttpRequestTestObjectType::test<21>() } // BUG-2295 Tests - Content-Range header received but no body -template <> template <> -void HttpRequestTestObjectType::test<22>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: BUG-2295 a 206 with a missing or short body gets the right status", "[HttpRequest_Tests]") { ScopedCurlInit ready; std::string url_base(get_base_url()); // std::cerr << "Base: " << url_base << std::endl; - set_test_name("BUG-2295"); - // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2786,7 +2809,7 @@ void HttpRequestTestObjectType::test<22>() options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); } // Run the notification pump. @@ -2797,8 +2820,9 @@ void HttpRequestTestObjectType::test<22>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time - ms1", count < limit); - ensure("One handler invocation for each request - ms1", mHandlerCalls == test_count); + UNSCOPED_INFO("Request executed in reasonable time - ms1"); + CHECK(count < limit); + CHECK(mHandlerCalls == test_count); // ====================================== // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE) @@ -2817,7 +2841,7 @@ void HttpRequestTestObjectType::test<22>() options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); } // Run the notification pump. @@ -2828,8 +2852,9 @@ void HttpRequestTestObjectType::test<22>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time - ms2", count < limit); - ensure("One handler invocation for each request - ms2", mHandlerCalls == test2_count); + UNSCOPED_INFO("Request executed in reasonable time - ms2"); + CHECK(count < limit); + CHECK(mHandlerCalls == test2_count); // ====================================== // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status @@ -2848,7 +2873,7 @@ void HttpRequestTestObjectType::test<22>() options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); } // Run the notification pump. @@ -2859,8 +2884,9 @@ void HttpRequestTestObjectType::test<22>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time - ms3", count < limit); - ensure("One handler invocation for each request - ms3", mHandlerCalls == test3_count); + UNSCOPED_INFO("Request executed in reasonable time - ms3"); + CHECK(count < limit); + CHECK(mHandlerCalls == test3_count); // ====================================== // Okay, request a shutdown of the servicing thread @@ -2868,7 +2894,7 @@ void HttpRequestTestObjectType::test<22>() mStatus = HttpStatus(); mHandlerCalls = 0; HttpHandle handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -2878,8 +2904,9 @@ void HttpRequestTestObjectType::test<22>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Shutdown request executed in reasonable time", count < limit); - ensure("Shutdown handler invocation", mHandlerCalls == 1); + UNSCOPED_INFO("Shutdown request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // See that we actually shutdown the thread count = 0; @@ -2888,7 +2915,7 @@ void HttpRequestTestObjectType::test<22>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options options.reset(); @@ -2909,13 +2936,10 @@ void HttpRequestTestObjectType::test<22>() } } -template <> template <> -void HttpRequestTestObjectType::test<23>() +TEST_CASE_METHOD(HttpRequestTestData, "HttpRequest Tests: GETs answered 503 with good and bad Retry-After headers complete", "[HttpRequest_Tests]") { ScopedCurlInit ready; - set_test_name("HttpRequest GET 503s with 'Retry-After'"); - // This tests mainly that the code doesn't fall over if // various well- and mis-formed Retry-After headers are // sent along with the response. Direct inspection of @@ -2963,9 +2987,8 @@ void HttpRequestTestObjectType::test<23>() HttpHeaders::ptr_t(), handlerp); - std::ostringstream testtag; - testtag << "Valid handle returned for 503 request #" << i; - ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID); + CAPTURE(i); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); } @@ -2977,14 +3000,15 @@ void HttpRequestTestObjectType::test<23>() req->update(0); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == url_limit); + UNSCOPED_INFO("Request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == url_limit); // Okay, request a shutdown of the servicing thread mStatus = HttpStatus(); mHandlerCalls = 0; HttpHandle handle = req->requestStopThread(handlerp); - ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID); + REQUIRE(handle != LLCORE_HTTP_HANDLE_INVALID); // Run the notification pump again count = 0; @@ -2994,8 +3018,9 @@ void HttpRequestTestObjectType::test<23>() req->update(1000000); usleep(LOOP_SLEEP_INTERVAL); } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 1); + UNSCOPED_INFO("Second request executed in reasonable time"); + CHECK(count < limit); + CHECK(mHandlerCalls == 1); // See that we actually shutdown the thread count = 0; @@ -3004,7 +3029,7 @@ void HttpRequestTestObjectType::test<23>() { usleep(LOOP_SLEEP_INTERVAL); } - ensure("Thread actually stopped running", HttpService::isStopped()); + CHECK(HttpService::isStopped()); // release options opts.reset(); @@ -3027,7 +3052,7 @@ void HttpRequestTestObjectType::test<23>() } -} // end namespace tut +} // anonymous namespace namespace { @@ -3042,5 +3067,3 @@ void usleep(unsigned long usec) #endif } - -#endif // TEST_LLCORE_HTTP_REQUEST_H_ diff --git a/indra/llcorehttp/tests/test_httprequestqueue.hpp b/indra/llcorehttp/tests/httprequestqueue_test.cpp similarity index 66% rename from indra/llcorehttp/tests/test_httprequestqueue.hpp rename to indra/llcorehttp/tests/httprequestqueue_test.cpp index 11a0016912..40b98610d7 100644 --- a/indra/llcorehttp/tests/test_httprequestqueue.hpp +++ b/indra/llcorehttp/tests/httprequestqueue_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_httprequestqueue.hpp + * @file httprequestqueue_test.cpp * @brief unit tests for the LLCore::HttpRequestQueue class * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -23,8 +23,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef TEST_LLCORE_HTTP_REQUESTQUEUE_H_ -#define TEST_LLCORE_HTTP_REQUESTQUEUE_H_ +#include "linden_common.h" + +#include #include "_httprequestqueue.h" @@ -33,45 +34,26 @@ #include "_httpoperation.h" +using namespace LLCore; using namespace LLCoreInt; -namespace tut -{ namespace { - -struct HttpRequestqueueTestData -{ - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. -}; - -typedef test_group HttpRequestqueueTestGroupType; -typedef HttpRequestqueueTestGroupType::object HttpRequestqueueTestObjectType; -HttpRequestqueueTestGroupType HttpRequestqueueTestGroup("HttpRequestqueue Tests"); -} - -template <> template <> -void HttpRequestqueueTestObjectType::test<1>() +TEST_CASE("HttpRequestqueue Tests: init makes a queue holding one reference", "[HttpRequestqueue_Tests]") { - set_test_name("HttpRequestQueue construction"); - // create a new ref counted object with an implicit reference HttpRequestQueue::init(); - ensure("One ref on construction of HttpRequestQueue", HttpRequestQueue::instanceOf()->getRefCount() == 1); + CHECK(HttpRequestQueue::instanceOf()->getRefCount() == 1); // release the implicit reference, causing the object to be released HttpRequestQueue::term(); } -template <> template <> -void HttpRequestqueueTestObjectType::test<2>() +TEST_CASE("HttpRequestqueue Tests: term drops only the reference init made", "[HttpRequestqueue_Tests]") { - set_test_name("HttpRequestQueue refcount works"); - // create a new ref counted object with an implicit reference HttpRequestQueue::init(); @@ -81,17 +63,14 @@ void HttpRequestqueueTestObjectType::test<2>() // release the singleton, hold on to the object HttpRequestQueue::term(); - ensure("One ref after term() called", rq->getRefCount() == 1); + CHECK(rq->getRefCount() == 1); // Drop ref rq->release(); } -template <> template <> -void HttpRequestqueueTestObjectType::test<3>() +TEST_CASE("HttpRequestqueue Tests: fetchOp returns an added op once", "[HttpRequestqueue_Tests]") { - set_test_name("HttpRequestQueue addOp/fetchOp work"); - // create a new ref counted object with an implicit reference HttpRequestQueue::init(); @@ -102,21 +81,18 @@ void HttpRequestqueueTestObjectType::test<3>() rq->addOp(op); // transfer my refcount op = rq->fetchOp(true); // Potentially hangs the test on failure - ensure("One goes in, one comes out", static_cast(op)); + CHECK(static_cast(op)); op.reset(); op = rq->fetchOp(false); - ensure("Better not be two of them", !op); + CHECK_FALSE(op); // release the singleton, hold on to the object HttpRequestQueue::term(); } -template <> template <> -void HttpRequestqueueTestObjectType::test<4>() +TEST_CASE("HttpRequestqueue Tests: fetchAll returns every added op", "[HttpRequestqueue_Tests]") { - set_test_name("HttpRequestQueue addOp/fetchAll work"); - // create a new ref counted object with an implicit reference HttpRequestQueue::init(); @@ -134,10 +110,10 @@ void HttpRequestqueueTestObjectType::test<4>() { HttpRequestQueue::OpContainer ops; rq->fetchAll(true, ops); // Potentially hangs the test on failure - ensure("Three go in, three come out", 3 == ops.size()); + CHECK(ops.size() == 3); op = rq->fetchOp(false); - ensure("Better not be any more of them", !op); + CHECK_FALSE(op); op.reset(); // release the singleton, hold on to the object @@ -154,7 +130,4 @@ void HttpRequestqueueTestObjectType::test<4>() } } -} // end namespace tut - - -#endif // TEST_LLCORE_HTTP_REQUESTQUEUE_H_ +} // anonymous namespace diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/httpstatus_test.cpp similarity index 65% rename from indra/llcorehttp/tests/test_httpstatus.hpp rename to indra/llcorehttp/tests/httpstatus_test.cpp index 3a0ff04370..41add478d7 100644 --- a/indra/llcorehttp/tests/test_httpstatus.hpp +++ b/indra/llcorehttp/tests/httpstatus_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_llrefcounted + * @file httpstatus_test.cpp * @brief unit tests for HttpStatus struct * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -24,8 +24,9 @@ * $/LicenseInfo$ */ -#ifndef TEST_HTTP_STATUS_H_ -#define TEST_HTTP_STATUS_H_ +#include "linden_common.h" + +#include #include "httpcommon.h" @@ -34,8 +35,6 @@ using namespace LLCore; -namespace tut -{ namespace { @@ -45,44 +44,37 @@ struct HttpStatusTestData {} }; -typedef test_group HttpStatusTestGroupType; -typedef HttpStatusTestGroupType::object HttpStatusTestObjectType; - -HttpStatusTestGroupType HttpStatusTestGroup("HttpStatus Tests"); -} -template <> template <> -void HttpStatusTestObjectType::test<1>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: success converts to true and errors to false", "[HttpStatus_Tests]") { - set_test_name("HttpStatus construction"); - // auto allocation fine for this HttpStatus status; status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0); - ensure(bool(status)); - ensure(false == !(status)); + // operator! is a function of its own, so each status checks it as well as operator bool + CHECK(bool(status)); + CHECK_FALSE(!status); status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0); - ensure(bool(status)); - ensure(false == !(status)); + CHECK(bool(status)); + CHECK_FALSE(!status); status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS); - ensure(bool(status)); - ensure(false == !(status)); + CHECK(bool(status)); + CHECK_FALSE(!status); status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1); - ensure(false == bool(status)); - ensure(!(status)); + CHECK_FALSE(bool(status)); + CHECK(!status); status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME); - ensure(false == bool(status)); - ensure(!(status)); + CHECK_FALSE(bool(status)); + CHECK(!status); } @@ -99,205 +91,187 @@ void HttpStatusTestObjectType::test<1>() // } -template <> template <> -void HttpStatusTestObjectType::test<2>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: toString is empty on success and says what an error is", "[HttpStatus_Tests]") { - set_test_name("HttpStatus valid status string conversion"); - HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0); std::string msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(msg.empty()); + CHECK(msg.empty()); status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT); msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + CHECK_FALSE(msg.empty()); status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY); msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + CHECK_FALSE(msg.empty()); status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + CHECK_FALSE(msg.empty()); } -template <> template <> -void HttpStatusTestObjectType::test<3>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: toString says something for an unknown code", "[HttpStatus_Tests]") { - set_test_name("HttpStatus invalid status string conversion"); - HttpStatus status = HttpStatus(HttpStatus::EXT_CURL_EASY, 32726); std::string msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + CHECK_FALSE(msg.empty()); status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470); msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + CHECK_FALSE(msg.empty()); status = HttpStatus(HttpStatus::LLCORE, 923); msg = status.toString(); // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + CHECK_FALSE(msg.empty()); } -template <> template <> -void HttpStatusTestObjectType::test<4>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: statuses of different types compare unequal", "[HttpStatus_Tests]") { - set_test_name("HttpStatus equality/inequality testing"); - // Make certain equality/inequality tests do not pass // through the bool conversion. Distinct successful // and error statuses should compare unequal. HttpStatus status1(HttpStatus::LLCORE, HE_SUCCESS); HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS); - ensure(status1 != status2); + CHECK(status1 != status2); status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR); status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); - ensure(status1 != status2); + CHECK(status1 != status2); } -template <> template <> -void HttpStatusTestObjectType::test<5>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: an HTTP status carries its own success or failure", "[HttpStatus_Tests]") { - set_test_name("HttpStatus basic HTTP status encoding"); - HttpStatus status; status = HttpStatus(200, HE_SUCCESS); std::string msg = status.toString(); - ensure(msg.empty()); - ensure(bool(status)); + CHECK(msg.empty()); + CHECK(bool(status)); // Normally a success but application says error status = HttpStatus(200, HE_REPLY_ERROR); msg = status.toString(); - ensure(! msg.empty()); - ensure(! bool(status)); - ensure(status.toULong() > 1UL); // Biggish number, not a bool-to-ulong + CHECK_FALSE(msg.empty()); + CHECK_FALSE(bool(status)); + CHECK(status.toULong() > 1UL); // Biggish number, not a bool-to-ulong // Same statuses with distinct success/fail are distinct status = HttpStatus(200, HE_SUCCESS); HttpStatus status2(200, HE_REPLY_ERROR); - ensure(status != status2); + CHECK(status != status2); // Normally an error but application says okay status = HttpStatus(406, HE_SUCCESS); msg = status.toString(); - ensure(msg.empty()); - ensure(bool(status)); + CHECK(msg.empty()); + CHECK(bool(status)); // Different statuses but both successful are distinct status = HttpStatus(200, HE_SUCCESS); status2 = HttpStatus(201, HE_SUCCESS); - ensure(status != status2); + CHECK(status != status2); // Different statuses but both failed are distinct status = HttpStatus(200, HE_REPLY_ERROR); status2 = HttpStatus(201, HE_REPLY_ERROR); - ensure(status != status2); + CHECK(status != status2); } -template <> template <> -void HttpStatusTestObjectType::test<6>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: toString gives the HTTP reason phrase", "[HttpStatus_Tests]") { - set_test_name("HttpStatus HTTP status text strings"); - HttpStatus status(100, HE_REPLY_ERROR); std::string msg(status.toString()); - ensure(! msg.empty()); // Should be something - ensure(msg == "Continue"); + CHECK_FALSE(msg.empty()); // Should be something + CHECK(msg == "Continue"); status = HttpStatus(200, HE_SUCCESS); msg = status.toString(); - ensure(msg.empty()); // Success is empty + CHECK(msg.empty()); // Success is empty status = HttpStatus(199, HE_REPLY_ERROR); msg = status.toString(); - ensure(msg == "Unknown error"); + CHECK(msg == "Unknown error"); status = HttpStatus(505, HE_REPLY_ERROR); msg = status.toString(); - ensure(msg == "HTTP Version not supported"); + CHECK(msg == "HTTP Version not supported"); status = HttpStatus(506, HE_REPLY_ERROR); msg = status.toString(); - ensure(msg == "Unknown error"); + CHECK(msg == "Unknown error"); status = HttpStatus(999, HE_REPLY_ERROR); msg = status.toString(); - ensure(msg == "Unknown error"); + CHECK(msg == "Unknown error"); } -template <> template <> -void HttpStatusTestObjectType::test<7>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: toHex packs the type and the status", "[HttpStatus_Tests]") { - set_test_name("HttpStatus toHex() nominal function"); - HttpStatus status(404); std::string msg = status.toHex(); // std::cout << "Result: " << msg << std::endl; - ensure_equals(msg, "01940001"); + CHECK(msg == "01940001"); } -template <> template <> -void HttpStatusTestObjectType::test<8>() +TEST_CASE_METHOD(HttpStatusTestData, "HttpStatus Tests: toTerseString names the type and the code", "[HttpStatus_Tests]") { - set_test_name("HttpStatus toTerseString() nominal function"); - HttpStatus status(404); std::string msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Normal HTTP 404", msg == "Http_404"); + CHECK(msg == "Http_404"); status = HttpStatus(200); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Normal HTTP 200", msg == "Http_200"); + CHECK(msg == "Http_200"); status = HttpStatus(200, HE_REPLY_ERROR); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Unsuccessful HTTP 200", msg == "Http_200"); // No distinction for error + UNSCOPED_INFO("Unsuccessful HTTP 200"); + CHECK(msg == "Http_200"); // No distinction for error status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Easy couldn't connect error", msg == "Easy_7"); + UNSCOPED_INFO("Easy couldn't connect error"); + CHECK(msg == "Easy_7"); status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Multi out-of-memory error", msg == "Multi_3"); + UNSCOPED_INFO("Multi out-of-memory error"); + CHECK(msg == "Multi_3"); status = HttpStatus(HttpStatus::LLCORE, HE_OPT_NOT_SET); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Core option not set error", msg == "Core_7"); + UNSCOPED_INFO("Core option not set error"); + CHECK(msg == "Core_7"); status = HttpStatus(22000, 1); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Undecodable error", msg == "Unknown_1"); + UNSCOPED_INFO("Undecodable error"); + CHECK(msg == "Unknown_1"); status = HttpStatus(22000, -1); msg = status.toTerseString(); // std::cout << "Result: " << msg << std::endl; - ensure("Undecodable error 65535", msg == "Unknown_65535"); + UNSCOPED_INFO("Undecodable error 65535"); + CHECK(msg == "Unknown_65535"); } -} // end namespace tut - -#endif // TEST_HTTP_STATUS_H - +} // anonymous namespace diff --git a/indra/llcorehttp/tests/test_jsonrpcws.hpp b/indra/llcorehttp/tests/jsonrpcws_test.cpp similarity index 50% rename from indra/llcorehttp/tests/test_jsonrpcws.hpp rename to indra/llcorehttp/tests/jsonrpcws_test.cpp index 5ae24a3181..ed501fcc25 100644 --- a/indra/llcorehttp/tests/test_jsonrpcws.hpp +++ b/indra/llcorehttp/tests/jsonrpcws_test.cpp @@ -1,10 +1,11 @@ /** - * @file test_jsonrpcws.hpp + * @file jsonrpcws_test.cpp * @brief unit tests for LLJSONRPCConnection helpers and dispatch behavior */ -#ifndef TEST_LLCORE_JSONRPCWS_H_ -#define TEST_LLCORE_JSONRPCWS_H_ +#include "linden_common.h" + +#include #include "lljsonrpcws.h" #include "lltimer.h" @@ -28,52 +29,32 @@ class TestJSONRPCConnection : public LLJSONRPCConnection }; } -namespace tut -{ namespace { - struct JSONRPCWSTestData - { - }; - - typedef test_group JSONRPCWSTestGroupType; - typedef JSONRPCWSTestGroupType::object JSONRPCWSTestObjectType; - JSONRPCWSTestGroupType JSONRPCWSTestGroup("LLJSONRPCConnection Tests"); -} - - template<> template<> - void JSONRPCWSTestObjectType::test<1>() + TEST_CASE("LLJSONRPCConnection Tests: makeEnvelope notification omits id", "[LLJSONRPCConnection_Tests]") { - set_test_name("makeEnvelope notification omits id"); - LLSD params; params["value"] = 42; LLSD env = LLJSONRPCConnection::makeEnvelope(LLSD(), "runtime.debug", params, LLSD(), LLSD()); - ensure("jsonrpc field should exist", env.has("jsonrpc")); - ensure_equals("jsonrpc version", env["jsonrpc"].asString(), "2.0"); - ensure("notification should omit id", !env.has("id")); - ensure_equals("method", env["method"].asString(), "runtime.debug"); - ensure_equals("param round trip", env["params"]["value"].asInteger(), 42); + CHECK(env.has("jsonrpc")); + CHECK(env["jsonrpc"].asString() == "2.0"); + CHECK_FALSE(env.has("id")); + CHECK(env["method"].asString() == "runtime.debug"); + CHECK(env["params"]["value"].asInteger() == 42); } - template<> template<> - void JSONRPCWSTestObjectType::test<2>() + TEST_CASE("LLJSONRPCConnection Tests: makeEnvelope response keeps id slot", "[LLJSONRPCConnection_Tests]") { - set_test_name("makeEnvelope response keeps id slot"); - LLSD env = LLJSONRPCConnection::makeEnvelope(LLSD(), std::string(), LLSD(), LLSD("ok"), LLSD()); - ensure("response should include id", env.has("id")); - ensure("response should not include method", !env.has("method")); - ensure_equals("result", env["result"].asString(), "ok"); + CHECK(env.has("id")); + CHECK_FALSE(env.has("method")); + CHECK(env["result"].asString() == "ok"); } - template<> template<> - void JSONRPCWSTestObjectType::test<3>() + TEST_CASE("LLJSONRPCConnection Tests: validateMessage accepts valid request and rejects invalid params", "[LLJSONRPCConnection_Tests]") { - set_test_name("validateMessage accepts valid request and rejects invalid params"); - TestJSONRPCConnection conn; LLSD valid; @@ -82,18 +63,15 @@ namespace LLSD params = LLSD::emptyMap(); params["timestamp"] = 123; valid["params"] = params; - ensure("valid request should pass", conn.validateMessage(valid, true)); + CHECK(conn.validateMessage(valid, true)); LLSD invalid = valid; invalid["params"] = "not-an-array-or-object"; - ensure("invalid params type should fail", !conn.validateMessage(invalid, true)); + CHECK_FALSE(conn.validateMessage(invalid, true)); } - template<> template<> - void JSONRPCWSTestObjectType::test<4>() + TEST_CASE("LLJSONRPCConnection Tests: processMessage dispatches a notification to its handler", "[LLJSONRPCConnection_Tests]") { - set_test_name("processMessage dispatches notification handler"); - TestJSONRPCConnection conn; bool called = false; @@ -103,7 +81,7 @@ namespace [&](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { called = true; - ensure_equals("method propagated", method, "runtime.debug"); + REQUIRE(method == "runtime.debug"); seen_id = id; seen_params = params; return LLSD(); @@ -114,16 +92,13 @@ namespace LLSD notification = LLJSONRPCConnection::makeEnvelope(LLSD(), "runtime.debug", params, LLSD(), LLSD()); conn.processMessage(notification); - ensure("handler should be called", called); - ensure("notification id should be undefined", seen_id.isUndefined()); - ensure_equals("payload should be forwarded", seen_params["message"].asString(), "hello"); + CHECK(called); + CHECK(seen_id.isUndefined()); + CHECK(seen_params["message"].asString() == "hello"); } - template<> template<> - void JSONRPCWSTestObjectType::test<5>() + TEST_CASE("LLJSONRPCConnection Tests: sweepTimeouts expires overdue callbacks", "[LLJSONRPCConnection_Tests]") { - set_test_name("sweepTimeouts expires overdue callbacks"); - TestJSONRPCConnection conn; bool callback_called = false; @@ -133,26 +108,22 @@ namespace [&](const LLSD& result, const LLSD& error) { callback_called = true; - ensure("timed out result should be undefined", result.isUndefined()); - ensure_equals( - "timeout code", - error["code"].asInteger(), + REQUIRE(result.isUndefined()); + REQUIRE(error["code"].asInteger() == LLJSONRPCConnection::RPCError::REQUEST_TIMEOUT); }); - ensure_equals("pending request should be tracked", conn.testPendingRequestCount(), (size_t)1); + CHECK(conn.testPendingRequestCount() == (size_t)1); conn.testSweepTimeouts(); - ensure("timeout callback should be called", callback_called); - ensure_equals("pending request should be removed", conn.testPendingRequestCount(), (size_t)0); + CHECK(callback_called); + CHECK(conn.testPendingRequestCount() == (size_t)0); } - template<> template<> - void JSONRPCWSTestObjectType::test<6>() + TEST_CASE("LLJSONRPCConnection Tests: an unauthenticated connection dispatches nothing until authenticated", "[LLJSONRPCConnection_Tests]") { - set_test_name("a connection not yet authenticated dispatches nothing, and everything once it is"); - TestJSONRPCConnection conn; - ensure("authenticated unless it says otherwise", conn.isAuthenticated()); + UNSCOPED_INFO("authenticated by default"); + CHECK(conn.isAuthenticated()); int calls = 0; conn.registerMethod("object.list", @@ -163,23 +134,20 @@ namespace }); conn.setAuthenticated(false); - ensure("not authenticated", !conn.isAuthenticated()); + CHECK_FALSE(conn.isAuthenticated()); const LLSD request = LLJSONRPCConnection::makeEnvelope(LLSD("req_1"), "object.list", LLSD::emptyMap(), LLSD(), LLSD()); conn.processMessage(request); const LLSD notification = LLJSONRPCConnection::makeEnvelope(LLSD(), "object.list", LLSD::emptyMap(), LLSD(), LLSD()); conn.processMessage(notification); - ensure_equals("neither a request nor a notification reaches the handler", calls, 0); + CHECK(calls == 0); conn.setAuthenticated(true); conn.processMessage(request); - ensure_equals("dispatched once authenticated", calls, 1); + CHECK(calls == 1); } - template<> template<> - void JSONRPCWSTestObjectType::test<7>() + TEST_CASE("LLJSONRPCConnection Tests: an unauthenticated connection still takes answers to its own calls", "[LLJSONRPCConnection_Tests]") { - set_test_name("a connection not yet authenticated still takes the answers to its own calls"); - TestJSONRPCConnection conn; conn.setAuthenticated(false); @@ -189,22 +157,19 @@ namespace LLTimer::getTotalSeconds() + 60.0, [&](const LLSD& result, const LLSD& error) { - ensure("no error", error.isUndefined()); + REQUIRE(error.isUndefined()); answer = result; }); LLSD result; result["challenge_response"] = "secret"; conn.processMessage(LLJSONRPCConnection::makeEnvelope(LLSD("rpc_1"), std::string(), LLSD(), result, LLSD())); - ensure_equals("the answer reached the caller", answer["challenge_response"].asString(), std::string("secret")); - ensure("and it is answered", conn.testPendingRequestCount() == 0); + CHECK(answer["challenge_response"].asString() == std::string("secret")); + CHECK(conn.testPendingRequestCount() == 0); } - template<> template<> - void JSONRPCWSTestObjectType::test<8>() + TEST_CASE("LLJSONRPCConnection Tests: a closed connection tells its waiting calls and refuses new ones", "[LLJSONRPCConnection_Tests]") { - set_test_name("a closed connection tells whatever waits on it, and takes no call that would wait for good"); - TestJSONRPCConnection conn; LLSD told; conn.testInjectPendingRequest( @@ -213,16 +178,16 @@ namespace [&](const LLSD&, const LLSD& error) { told = error; }); conn.onClose(); - ensure("closed", conn.isClosed()); - ensure_equals("the waiting call told it closed", told["code"].asInteger(), LLJSONRPCConnection::RPCError::CONNECTION_CLOSED); + CHECK(conn.isClosed()); + CHECK(told["code"].asInteger() == LLJSONRPCConnection::RPCError::CONNECTION_CLOSED); bool called = false; const LLSD id = conn.call("session.handshake", LLSD(), [&](const LLSD&, const LLSD&) { called = true; }, 30.0); - ensure("not sent", id.isUndefined()); - ensure_equals("and nothing waiting", conn.testPendingRequestCount(), (size_t)0); + UNSCOPED_INFO("the call was not sent"); + CHECK(id.isUndefined()); + CHECK(conn.testPendingRequestCount() == (size_t)0); conn.testSweepTimeouts(); - ensure("so nothing is ever told", !called); + UNSCOPED_INFO("a refused call is never told"); + CHECK_FALSE(called); } } - -#endif \ No newline at end of file diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp deleted file mode 100644 index a503555602..0000000000 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @file llcorehttp_test - * @brief Main test runner - * - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, 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 "llcorehttp_test.h" - -#include -#include - -// These are not the right way in viewer for some reason: -// #include -// #include -// This works: -#include "../test/lltut.h" - -// Pull in each of the test sets -#include "test_bufferarray.hpp" -#include "test_bufferstream.hpp" -#include "test_httpstatus.hpp" -#include "test_refcounted.hpp" -#include "test_httpoperation.hpp" -#include "test_httprequest.hpp" -#include "test_httpheaders.hpp" -#include "test_httprequestqueue.hpp" -#include "test_jsonrpcws.hpp" -#include "test_websocketmgr.hpp" -#include "_httpservice.h" - -#include "llproxy.h" -#include "llcleanup.h" - -#if 0 // lltut provides main and runner - -namespace tut -{ - test_runner_singleton runner; -} - -int main() -{ - curl_global_init(CURL_GLOBAL_ALL); - - // *FIXME: Need threaded/SSL curl setup here. - - tut::reporter reporter; - - tut::runner.get().set_callback(&reporter); - tut::runner.get().run_tests(); - return !reporter.all_ok(); - - curl_global_cleanup(); -} - -#endif // 0 - -namespace -{ - -void init_curl() -{ - curl_global_init(CURL_GLOBAL_ALL); - - LLProxy::getInstance(); -} - - -void term_curl() -{ - SUBSYSTEM_CLEANUP(LLProxy); -} - - -std::string get_base_url() -{ - const char * env(getenv("LL_TEST_PORT")); - - if (! env) - { - std::cerr << "LL_TEST_PORT environment variable missing." << std::endl; - std::cerr << "Test expects to run in test_llcorehttp_peer.py script." << std::endl; - tut::ensure("LL_TEST_PORT set in environment", NULL != env); - } - - int port(atoi(env)); - std::ostringstream out; - out << "http://localhost:" << port << "/"; - return out.str(); -} - - -void stop_thread(LLCore::HttpRequest * req) -{ - if (req) - { - req->requestStopThread(LLCore::HttpHandler::ptr_t()); - - int count = 0; - int limit = 10; - while (count++ < limit && ! HttpService::isStopped()) - { - req->update(1000); - usleep(100000); - } - } -} - -} diff --git a/indra/llcorehttp/tests/llcorehttp_test.h b/indra/llcorehttp/tests/llcorehttp_test.h deleted file mode 100644 index c0b575d1a5..0000000000 --- a/indra/llcorehttp/tests/llcorehttp_test.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file llcorehttp_test.h - * @brief Main test runner - * - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, 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$ - */ - - -#ifndef _LLCOREHTTP_TEST_H_ -#define _LLCOREHTTP_TEST_H_ - -#include "linden_common.h" // Modifies curl interfaces - -#include -#include -#include - -#include "httprequest.h" - -// The suites and these helpers are one translation unit, -// llcorehttp_test.cpp, so the helpers have internal linkage. -namespace -{ - -// Initialization and cleanup for libcurl. Mainly provides -// a mutex callback for SSL and a thread ID hash for libcurl. -// If you don't use these (or equivalent) and do use libcurl, -// you'll see stalls and other anomalies when performing curl -// operations. -void init_curl(); -void term_curl(); -std::string get_base_url(); -void stop_thread(LLCore::HttpRequest * req); - -class ScopedCurlInit -{ -public: - ScopedCurlInit() - { - init_curl(); - } - - ~ScopedCurlInit() - { - term_curl(); - } -}; - -} - - -#endif // _LLCOREHTTP_TEST_H_ diff --git a/indra/llcorehttp/tests/llcorehttp_test_checks.cpp b/indra/llcorehttp/tests/llcorehttp_test_checks.cpp new file mode 100644 index 0000000000..8ce3413aaf --- /dev/null +++ b/indra/llcorehttp/tests/llcorehttp_test_checks.cpp @@ -0,0 +1,65 @@ +/** + * @file llcorehttp_test_checks.cpp + * @brief The state guard's checks on what llcorehttp keeps for the process. + * + * $LicenseInfo:firstyear=2026&license=viewerlgpl$ + * Alchemy Viewer Source Code + * Copyright (C) 2026, Rye + * + * 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 + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "_httpservice.h" +#include "alteststateguard.h" +#include "llwebsocketmgr.h" + +#include +#include + +#include +#include + +namespace +{ + class LLCoreHttpChecks : public Catch::EventListenerBase + { + public: + using Catch::EventListenerBase::EventListenerBase; + + void testRunStarting(Catch::TestRunInfo const&) override + { + // The service and its worker thread are the process's: a case + // that makes them destroys them, or the next case's + // createService finds them made. + ll_test::StateGuard::add("the HTTP service", + [] + { + std::ostringstream out; + out << static_cast(LLCore::HttpService::instanceOf()) + << ", state " << LLCore::HttpService::getState(); + return out.str(); + }); + // Each server runs a thread of its own, which a case that leaves + // the manager alive leaves running. + ll_test::StateGuard::add("the websocket manager", + [] { return std::string(LLWebsocketMgr::instanceExists() ? "made" : "none"); }); + } + }; +} + +CATCH_REGISTER_LISTENER(LLCoreHttpChecks) diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/refcounted_test.cpp similarity index 59% rename from indra/llcorehttp/tests/test_refcounted.hpp rename to indra/llcorehttp/tests/refcounted_test.cpp index 9b1a48b8c7..d93a901576 100644 --- a/indra/llcorehttp/tests/test_refcounted.hpp +++ b/indra/llcorehttp/tests/refcounted_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_refcounted.hpp + * @file refcounted_test.cpp * @brief unit tests for the LLCoreInt::RefCounted class * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -23,63 +23,42 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef TEST_LLCOREINT_REF_COUNTED_H_ -#define TEST_LLCOREINT_REF_COUNTED_H_ +#include "linden_common.h" + +#include #include "_refcounted.h" using namespace LLCoreInt; -namespace tut -{ namespace { - struct RefCountedTestData - { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. - }; - - typedef test_group RefCountedTestGroupType; - typedef RefCountedTestGroupType::object RefCountedTestObjectType; - RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests"); -} - - template <> template <> - void RefCountedTestObjectType::test<1>() + TEST_CASE("RefCounted Tests: construction with an implicit count holds one reference", "[RefCounted_Tests]") { - set_test_name("RefCounted construction with implicit count"); - // create a new ref counted object with an implicit reference RefCounted * rc = new RefCounted(true); - ensure(rc->getRefCount() == 1); + CHECK(rc->getRefCount() == 1); // release the implicit reference, causing the object to be released rc->release(); } - template <> template <> - void RefCountedTestObjectType::test<2>() + TEST_CASE("RefCounted Tests: construction without an implicit count holds none", "[RefCounted_Tests]") { - set_test_name("RefCounted construction without implicit count"); - // create a new ref counted object with an implicit reference RefCounted * rc = new RefCounted(false); - ensure(rc->getRefCount() == 0); + CHECK(rc->getRefCount() == 0); // add a reference rc->addRef(); - ensure(rc->getRefCount() == 1); + CHECK(rc->getRefCount() == 1); // release the implicit reference, causing the object to be released rc->release(); } - template <> template <> - void RefCountedTestObjectType::test<3>() + TEST_CASE("RefCounted Tests: addRef counts every reference", "[RefCounted_Tests]") { - set_test_name("RefCounted addRef and release"); - RefCounted * rc = new RefCounted(false); for (int i = 0; i < 1024; ++i) @@ -87,7 +66,7 @@ namespace rc->addRef(); } - ensure(rc->getRefCount() == 1024); + CHECK(rc->getRefCount() == 1024); for (int i = 0; i < 1024; ++i) { @@ -95,32 +74,25 @@ namespace } } - template <> template <> - void RefCountedTestObjectType::test<4>() + TEST_CASE("RefCounted Tests: isLastRef is true with one reference", "[RefCounted_Tests]") { - set_test_name("RefCounted isLastRef check"); - RefCounted * rc = new RefCounted(true); // with only one reference, isLastRef should be true - ensure(rc->isLastRef()); + CHECK(rc->isLastRef()); // release it to clean up memory rc->release(); } - template <> template <> - void RefCountedTestObjectType::test<5>() + TEST_CASE("RefCounted Tests: noRef marks the object not ref counted", "[RefCounted_Tests]") { - set_test_name("RefCounted noRef check"); - RefCounted * rc = new RefCounted(false); // set the noRef rc->noRef(); // with only one reference, isLastRef should be true - ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); + CHECK(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); } } -#endif // TEST_LLCOREINT_REF_COUNTED_H_ diff --git a/indra/llcorehttp/tests/test_bufferarray.hpp b/indra/llcorehttp/tests/test_bufferarray.hpp deleted file mode 100644 index da2b742350..0000000000 --- a/indra/llcorehttp/tests/test_bufferarray.hpp +++ /dev/null @@ -1,383 +0,0 @@ -/** - * @file test_bufferarray.hpp - * @brief unit tests for the LLCore::BufferArray class - * - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, 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$ - */ -#ifndef TEST_LLCORE_BUFFER_ARRAY_H_ -#define TEST_LLCORE_BUFFER_ARRAY_H_ - -#include "bufferarray.h" - -#include - - -using namespace LLCore; - - - -namespace tut -{ -namespace -{ - -struct BufferArrayTestData -{ - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. -}; - -typedef test_group BufferArrayTestGroupType; -typedef BufferArrayTestGroupType::object BufferArrayTestObjectType; -BufferArrayTestGroupType BufferArrayTestGroup("BufferArray Tests"); -} - -template <> template <> -void BufferArrayTestObjectType::test<1>() -{ - set_test_name("BufferArray construction"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - ensure("One ref on construction of BufferArray", ba->getRefCount() == 1); - ensure("Nothing in BA", 0 == ba->size()); - - // Try to read - char buffer[20]; - size_t read_len(ba->read(0, buffer, sizeof(buffer))); - ensure("Read returns empty", 0 == read_len); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -template <> template <> -void BufferArrayTestObjectType::test<2>() -{ - set_test_name("BufferArray single write"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - char buffer[256]; - - size_t len = ba->write(0, str1, strlen(str1)); - ensure("Wrote length correct", strlen(str1) == len); - ensure("Recorded size correct", strlen(str1) == ba->size()); - - // read some data back - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(2, buffer, 2); - ensure("Read length correct", 2 == len); - ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]); - ensure("Read didn't overwrite", 'X' == buffer[2]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - - -template <> template <> -void BufferArrayTestObjectType::test<3>() -{ - set_test_name("BufferArray multiple writes"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - size_t str1_len(strlen(str1)); - char buffer[256]; - - size_t len = ba->write(0, str1, str1_len); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", str1_len == ba->size()); - - // again... - len = ba->write(str1_len, str1, strlen(str1)); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", (2 * str1_len) == ba->size()); - - // read some data back - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(8, buffer, 4); - ensure("Read length correct", 4 == len); - ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]); - ensure("Read content correct", 'a' == buffer[2] && 'b' == buffer[3]); - ensure("Read didn't overwrite", 'X' == buffer[4]); - - // Read whole thing - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(0, buffer, sizeof(buffer)); - ensure("Read length correct", (2 * str1_len) == len); - ensure("Read content correct (3)", 0 == strncmp(buffer, str1, str1_len)); - ensure("Read content correct (4)", 0 == strncmp(&buffer[str1_len], str1, str1_len)); - ensure("Read didn't overwrite (5)", 'X' == buffer[2 * str1_len]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -template <> template <> -void BufferArrayTestObjectType::test<4>() -{ - set_test_name("BufferArray overwriting"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - size_t str1_len(strlen(str1)); - char str2[] = "ABCDEFGHIJ"; - char buffer[256]; - - size_t len = ba->write(0, str1, str1_len); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", str1_len == ba->size()); - - // again... - len = ba->write(str1_len, str1, strlen(str1)); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", (2 * str1_len) == ba->size()); - - // reposition and overwrite - len = ba->write(8, str2, 4); - ensure("Overwrite length correct", 4 == len); - - // Leave position and read verifying content (stale really from seek() days) - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(12, buffer, 4); - ensure("Read length correct", 4 == len); - ensure("Read content correct", 'c' == buffer[0] && 'd' == buffer[1]); - ensure("Read content correct.2", 'e' == buffer[2] && 'f' == buffer[3]); - ensure("Read didn't overwrite", 'X' == buffer[4]); - - // reposition and check - len = ba->read(6, buffer, 8); - ensure("Read length correct.2", 8 == len); - ensure("Read content correct.3", 'g' == buffer[0] && 'h' == buffer[1]); - ensure("Read content correct.4", 'A' == buffer[2] && 'B' == buffer[3]); - ensure("Read content correct.5", 'C' == buffer[4] && 'D' == buffer[5]); - ensure("Read content correct.6", 'c' == buffer[6] && 'd' == buffer[7]); - ensure("Read didn't overwrite.7", 'X' == buffer[8]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -template <> template <> -void BufferArrayTestObjectType::test<5>() -{ - set_test_name("BufferArray multiple writes - sequential reads"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - size_t str1_len(strlen(str1)); - char buffer[256]; - - size_t len = ba->write(0, str1, str1_len); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", str1_len == ba->size()); - - // again... - len = ba->write(str1_len, str1, str1_len); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", (2 * str1_len) == ba->size()); - - // read some data back - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(8, buffer, 4); - ensure("Read length correct", 4 == len); - ensure("Read content correct", 'i' == buffer[0] && 'j' == buffer[1]); - ensure("Read content correct.2", 'a' == buffer[2] && 'b' == buffer[3]); - ensure("Read didn't overwrite", 'X' == buffer[4]); - - // Read some more without repositioning - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(12, buffer, sizeof(buffer)); - ensure("Read length correct", (str1_len - 2) == len); - ensure("Read content correct.3", 0 == strncmp(buffer, str1+2, str1_len-2)); - ensure("Read didn't overwrite.2", 'X' == buffer[str1_len-1]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -template <> template <> -void BufferArrayTestObjectType::test<6>() -{ - set_test_name("BufferArray overwrite spanning blocks and appending"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - size_t str1_len(strlen(str1)); - char str2[] = "ABCDEFGHIJKLMNOPQRST"; - size_t str2_len(strlen(str2)); - char buffer[256]; - - size_t len = ba->write(0, str1, str1_len); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", str1_len == ba->size()); - - // again... - len = ba->write(str1_len, str1, strlen(str1)); - ensure("Wrote length correct", str1_len == len); - ensure("Recorded size correct", (2 * str1_len) == ba->size()); - - // reposition and overwrite - len = ba->write(8, str2, str2_len); - ensure("Overwrite length correct", str2_len == len); - - // Leave position and read verifying content - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(8 + str2_len, buffer, 0); - ensure("Read length correct", 0 == len); - ensure("Read didn't overwrite", 'X' == buffer[0]); - - // reposition and check - len = ba->read(0, buffer, sizeof(buffer)); - ensure("Read length correct.2", (str1_len + str2_len - 2) == len); - ensure("Read content correct", 0 == strncmp(buffer, str1, str1_len-2)); - ensure("Read content correct.2", 0 == strncmp(buffer+str1_len-2, str2, str2_len)); - ensure("Read didn't overwrite.2", 'X' == buffer[str1_len + str2_len - 2]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -template <> template <> -void BufferArrayTestObjectType::test<7>() -{ - set_test_name("BufferArray overwrite spanning blocks and sequential writes"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - size_t str1_len(strlen(str1)); - char str2[] = "ABCDEFGHIJKLMNOPQRST"; - size_t str2_len(strlen(str2)); - char buffer[256]; - - // 2x str1 - size_t len = ba->write(0, str1, str1_len); - len = ba->write(str1_len, str1, str1_len); - - // reposition and overwrite - len = ba->write(6, str2, 2); - ensure("Overwrite length correct", 2 == len); - - len = ba->write(8, str2, 2); - ensure("Overwrite length correct.2", 2 == len); - - len = ba->write(10, str2, 2); - ensure("Overwrite length correct.3", 2 == len); - - // append some data - len = ba->append(str2, str2_len); - ensure("Append length correct", str2_len == len); - - // append some more - void * out_buf(ba->appendBufferAlloc(str1_len)); - memcpy(out_buf, str1, str1_len); - - // And some final writes - len = ba->write(3 * str1_len + str2_len, str2, 2); - ensure("Write length correct.2", 2 == len); - - // Check contents - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(0, buffer, sizeof(buffer)); - ensure("Final buffer length correct", (3 * str1_len + str2_len + 2) == len); - ensure("Read content correct", 0 == strncmp(buffer, str1, 6)); - ensure("Read content correct.2", 0 == strncmp(buffer + 6, str2, 2)); - ensure("Read content correct.3", 0 == strncmp(buffer + 8, str2, 2)); - ensure("Read content correct.4", 0 == strncmp(buffer + 10, str2, 2)); - ensure("Read content correct.5", 0 == strncmp(buffer + str1_len + 2, str1 + 2, str1_len - 2)); - ensure("Read content correct.6", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len)); - ensure("Read content correct.7", 0 == strncmp(buffer + str1_len + str1_len + str2_len, str1, str1_len)); - ensure("Read content correct.8", 0 == strncmp(buffer + str1_len + str1_len + str2_len + str1_len, str2, 2)); - ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len + str1_len + 2]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -template <> template <> -void BufferArrayTestObjectType::test<8>() -{ - set_test_name("BufferArray zero-length appendBufferAlloc"); - - // create a new ref counted object with an implicit reference - BufferArray * ba = new BufferArray(); - - // write some data to the buffer - char str1[] = "abcdefghij"; - size_t str1_len(strlen(str1)); - char str2[] = "ABCDEFGHIJKLMNOPQRST"; - size_t str2_len(strlen(str2)); - char buffer[256]; - - // 2x str1 - size_t len = ba->write(0, str1, str1_len); - len = ba->write(str1_len, str1, str1_len); - - // zero-length allocate (we allow this with a valid pointer returned) - void * out_buf(ba->appendBufferAlloc(0)); - ensure("Buffer from zero-length appendBufferAlloc non-NULL", NULL != out_buf); - - // Do it again - void * out_buf2(ba->appendBufferAlloc(0)); - ensure("Buffer from zero-length appendBufferAlloc non-NULL.2", NULL != out_buf2); - ensure("Two zero-length appendBufferAlloc buffers distinct", out_buf != out_buf2); - - // And some final writes - len = ba->write(2 * str1_len, str2, str2_len); - - // Check contents - memset(buffer, 'X', sizeof(buffer)); - len = ba->read(0, buffer, sizeof(buffer)); - ensure("Final buffer length correct", (2 * str1_len + str2_len) == len); - ensure("Read content correct.1", 0 == strncmp(buffer, str1, str1_len)); - ensure("Read content correct.2", 0 == strncmp(buffer + str1_len, str1, str1_len)); - ensure("Read content correct.3", 0 == strncmp(buffer + str1_len + str1_len, str2, str2_len)); - ensure("Read didn't overwrite", 'X' == buffer[str1_len + str1_len + str2_len]); - - // release the implicit reference, causing the object to be released - ba->release(); -} - -} // end namespace tut - - -#endif // TEST_LLCORE_BUFFER_ARRAY_H_ diff --git a/indra/llcorehttp/tests/test_websocketmgr.hpp b/indra/llcorehttp/tests/websocketmgr_test.cpp similarity index 75% rename from indra/llcorehttp/tests/test_websocketmgr.hpp rename to indra/llcorehttp/tests/websocketmgr_test.cpp index 0f46d0fe99..e2111a0f28 100644 --- a/indra/llcorehttp/tests/test_websocketmgr.hpp +++ b/indra/llcorehttp/tests/websocketmgr_test.cpp @@ -1,5 +1,5 @@ /** - * @file test_websocketmgr.hpp + * @file websocketmgr_test.cpp * @brief A WebSocket server lets programs in and turns pages away. * * $LicenseInfo:firstyear=2026&license=viewerlgpl$ @@ -22,8 +22,10 @@ * $/LicenseInfo$ */ -#ifndef TEST_LLCORE_WEBSOCKETMGR_H_ -#define TEST_LLCORE_WEBSOCKETMGR_H_ +#include "linden_common.h" + +#include +#include #include "llwebsocketmgr.h" #include "lljsonrpcws.h" @@ -423,8 +425,6 @@ namespace }; } -namespace tut -{ namespace { struct WebsocketMgrTestData @@ -439,25 +439,18 @@ namespace } }; - typedef test_group WebsocketMgrTestGroupType; - typedef WebsocketMgrTestGroupType::object WebsocketMgrTestObjectType; - WebsocketMgrTestGroupType WebsocketMgrTestGroup("LLWebsocketMgr Tests"); -} - template<> template<> - void WebsocketMgrTestObjectType::test<1>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a program sending no origin is let in and a page sending one refused", "[LLWebsocketMgr_Tests]") { - set_test_name("a program, which sends no origin, is let in; a page, which always does, is refused"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "origin_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); - ensure("added", manager.addServer(std::make_shared(name, port, true))); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(std::make_shared(name, port, true))); + CHECK(manager.startServer(name)); const int program = TestClient().open(port); const int page = TestClient().open(port, "https://example.com"); @@ -465,29 +458,30 @@ namespace const int local = TestClient().open(port, "http://127.0.0.1:8080"); manager.removeServer(name); - ensure_equals("no origin: in", program, 101); - ensure_equals("a web page: refused", page, 403); - ensure_equals("a page with an opaque origin, a sandboxed frame or a file: refused", opaque, 403); - ensure_equals("a page served from this machine: refused", local, 403); + UNSCOPED_INFO("no origin: in"); + CHECK(program == 101); + UNSCOPED_INFO("a web page: refused"); + CHECK(page == 403); + UNSCOPED_INFO("a page with an opaque origin, a sandboxed frame or a file: refused"); + CHECK(opaque == 403); + UNSCOPED_INFO("a page served from this machine: refused"); + CHECK(local == 403); } - template<> template<> - void WebsocketMgrTestObjectType::test<2>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a request is answered from a main loop the server thread never waits on", "[LLWebsocketMgr_Tests]") { - set_test_name("a request read on the server's thread is answered from the main loop, which that thread does not wait on"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } // The main loop, drained here by hand: a server's thread that // waited on it would wait until the answer's own time ran out. LL::WorkQueue mainloop("mainloop"); const std::string name = "rpc_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); - ensure("added", manager.addServer(std::make_shared(name, port, true))); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(std::make_shared(name, port, true))); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101; @@ -506,52 +500,53 @@ namespace std::ostringstream here; here << std::this_thread::get_id(); LLSD answer; - ensure("opened", opened); - ensure("sent", sent); - ensure("closed by the client", closed); - ensure("answered", LlsdFromJsonString(reply, answer)); - ensure_equals("to the request", answer["id"].asString(), std::string("req_1")); - ensure_equals("run on the thread that drains the main loop", answer["result"]["thread"].asString(), here.str()); - ensure_equals("with its params", answer["result"]["item_id"].asString(), params["item_id"].asString()); - ensure_equals("all of them", answer["result"]["lines"][0].asString(), std::string("default {}")); + CHECK(opened); + CHECK(sent); + UNSCOPED_INFO("closed by the client"); + CHECK(closed); + UNSCOPED_INFO("answered"); + REQUIRE(LlsdFromJsonString(reply, answer)); + UNSCOPED_INFO("to the request"); + CHECK(answer["id"].asString() == std::string("req_1")); + UNSCOPED_INFO("run on the thread that drains the main loop"); + CHECK(answer["result"]["thread"].asString() == here.str()); + UNSCOPED_INFO("with its params"); + CHECK(answer["result"]["item_id"].asString() == params["item_id"].asString()); + UNSCOPED_INFO("all of them"); + CHECK(answer["result"]["lines"][0].asString() == std::string("default {}")); } - template<> template<> - void WebsocketMgrTestObjectType::test<3>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a request asking for no upgrade is told to ask for one", "[LLWebsocketMgr_Tests]") { - set_test_name("a request asking for no upgrade is told to ask for one"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "http_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); - ensure("added", manager.addServer(std::make_shared(name, port, true))); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(std::make_shared(name, port, true))); + CHECK(manager.startServer(name)); const int status = TestClient().get(port); manager.removeServer(name); - ensure_equals("426 Upgrade Required", status, 426); + UNSCOPED_INFO("426 Upgrade Required"); + CHECK(status == 426); } - template<> template<> - void WebsocketMgrTestObjectType::test<4>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: messages go before the close with its code and reason and none after", "[LLWebsocketMgr_Tests]") { - set_test_name("messages sent just before a close go first, the close carries its code and reason, and nothing goes after it"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "close_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101 && waitFor([&]() { return server->opened() != nullptr; }); @@ -578,31 +573,32 @@ namespace const bool told = waitFor([&]() { return server->closed() == 1; }); manager.removeServer(name); - ensure("opened", opened); - ensure("sent", sent); - ensure("the messages first, in order", in_order); - ensure("then the close", last.closed); - ensure_equals("with its code", last.code, U16(1000)); - ensure_equals("and its reason", last.reason, std::string("done")); - ensure("a send after the close refused", !after_close); - ensure("the server told it closed", told); + CHECK(opened); + CHECK(sent); + UNSCOPED_INFO("the messages first, in order"); + CHECK(in_order); + UNSCOPED_INFO("then the close"); + CHECK(last.closed); + CHECK(last.code == U16(1000)); + CHECK(last.reason == std::string("done")); + UNSCOPED_INFO("a send after the close refused"); + CHECK_FALSE(after_close); + UNSCOPED_INFO("the server told it closed"); + CHECK(told); } - template<> template<> - void WebsocketMgrTestObjectType::test<5>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: sends from two threads at once arrive whole and in each thread's order", "[LLWebsocketMgr_Tests]") { - set_test_name("messages sent from two threads at once each arrive whole, and each thread's in its order"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "threads_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101 && waitFor([&]() { return server->opened() != nullptr; }); @@ -647,28 +643,29 @@ namespace const bool closed = opened && client.close(); manager.removeServer(name); - ensure("opened", opened); - ensure("closed by the client", closed); - ensure("each whole, and in its thread's order", whole); - ensure_equals("all of the first thread's", next_a, count); - ensure_equals("all of the second's", next_b, count); + CHECK(opened); + UNSCOPED_INFO("closed by the client"); + CHECK(closed); + UNSCOPED_INFO("each whole, and in its thread's order"); + CHECK(whole); + UNSCOPED_INFO("all of the first thread's"); + CHECK(next_a == count); + UNSCOPED_INFO("all of the second's"); + CHECK(next_b == count); } - template<> template<> - void WebsocketMgrTestObjectType::test<6>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: stopping closes clients as going away and tells the server at once", "[LLWebsocketMgr_Tests]") { - set_test_name("stopping closes each client as going away, and says so to the server without waiting out the deadline"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "stop_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101 && waitFor([&]() { return server->opened() != nullptr; }); @@ -684,29 +681,29 @@ namespace const bool running = server->isRunning(); manager.removeServer(name); - ensure("opened", opened); - ensure("the client closed", received.closed); - ensure_equals("as going away", received.code, U16(1001)); - ensure_equals("the server told, once", closed, 1); - ensure("stopped", !running); - ensure("without waiting out the deadline", took < std::chrono::milliseconds(900)); + CHECK(opened); + CHECK(received.closed); + UNSCOPED_INFO("as going away"); + CHECK(received.code == U16(1001)); + UNSCOPED_INFO("the server told, once"); + CHECK(closed == 1); + CHECK_FALSE(running); + UNSCOPED_INFO("without waiting out the deadline"); + CHECK(took < std::chrono::milliseconds(900)); } - template<> template<> - void WebsocketMgrTestObjectType::test<7>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: stopping waits little on a client that never answers yet says it closed", "[LLWebsocketMgr_Tests]") { - set_test_name("stopping waits little on a client that never answers the close, and still says it closed"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "deadline_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); // Opened, and then never read again. TestClient client; @@ -717,20 +714,19 @@ namespace const int closed = server->closed(); manager.removeServer(name); - ensure("opened", opened); - ensure_equals("the server told, once", closed, 1); - ensure("within about the deadline", took < std::chrono::milliseconds(2500)); + CHECK(opened); + UNSCOPED_INFO("the server told, once"); + CHECK(closed == 1); + UNSCOPED_INFO("within about the deadline"); + CHECK(took < std::chrono::milliseconds(2500)); } - template<> template<> - void WebsocketMgrTestObjectType::test<8>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a port another socket listens on fails the start", "[LLWebsocketMgr_Tests]") { - set_test_name("a port another socket listens on fails the start"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } boost::asio::io_context io; boost::asio::ip::tcp::acceptor holder(io); @@ -746,36 +742,33 @@ namespace } if (ec) { - skip("could not hold the port"); + SKIP("could not hold the port"); } const std::string name = "busy_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); + CHECK(manager.addServer(server)); const bool started = manager.startServer(name); const bool running = server->isRunning(); manager.removeServer(name); - ensure("not started", !started); - ensure("not running", !running); + CHECK_FALSE(started); + CHECK_FALSE(running); } - template<> template<> - void WebsocketMgrTestObjectType::test<9>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a server stopped with a client connected starts again on the same port", "[LLWebsocketMgr_Tests]") { - set_test_name("a server stopped with a client connected starts again on the same port"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "restart_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient first; const bool opened = first.open(port) == 101 && waitFor([&]() { return server->opened() != nullptr; }); @@ -787,26 +780,24 @@ namespace const int second = TestClient().open(port); manager.removeServer(name); - ensure("opened", opened); - ensure("started again", restarted); - ensure_equals("and opens a connection", second, 101); + CHECK(opened); + CHECK(restarted); + UNSCOPED_INFO("a new connection opens after the restart"); + CHECK(second == 101); } - template<> template<> - void WebsocketMgrTestObjectType::test<10>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a client that stops reading is dropped once too much waits unsent to it", "[LLWebsocketMgr_Tests]") { - set_test_name("a client that stops reading is dropped once what waits unsent to it passes the most it may"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "backlog_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); // Opened, and then never read. TestClient client; @@ -824,26 +815,24 @@ namespace const bool dropped = waitFor([&]() { return server->closed() == 1; }); manager.removeServer(name); - ensure("opened", opened); - ensure("dropped", dropped); - ensure("before all 128 MB were taken", sent < 128); + CHECK(opened); + CHECK(dropped); + UNSCOPED_INFO("before all 128 MB were taken"); + CHECK(sent < 128); } - template<> template<> - void WebsocketMgrTestObjectType::test<11>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a close stuck behind unread messages drops the connection at its deadline", "[LLWebsocketMgr_Tests]") { - set_test_name("a close stuck behind messages the client will not read drops the connection after its deadline"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "stuck_close_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101 && waitFor([&]() { return server->opened() != nullptr; }); @@ -865,27 +854,25 @@ namespace const auto took = std::chrono::steady_clock::now() - began; manager.removeServer(name); - ensure("opened", opened); - ensure("dropped", dropped); - ensure("at the deadline, not before", took > std::chrono::seconds(3)); + CHECK(opened); + CHECK(dropped); + UNSCOPED_INFO("at the deadline, not before"); + CHECK(took > std::chrono::seconds(3)); } - template<> template<> - void WebsocketMgrTestObjectType::test<12>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a message within a connection's limit is taken and one past it closes it", "[LLWebsocketMgr_Tests]") { - set_test_name("a message within a connection's limit is taken, and one past it closes the connection"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "limit_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); server->mLimit = 1024; - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101; @@ -902,27 +889,28 @@ namespace const bool closed = taken && waitFor([&]() { return server->closed() == 1; }); manager.removeServer(name); - ensure("opened", opened); - ensure("the small one taken", taken); - ensure("the connection closed by the large one", closed); - ensure_equals("with only the small one taken", server->messages(), 1); - ensure("a close the client read says too big", !seen.closed || seen.code == 1009); + CHECK(opened); + UNSCOPED_INFO("the small one taken"); + CHECK(taken); + UNSCOPED_INFO("the connection closed by the large one"); + CHECK(closed); + UNSCOPED_INFO("with only the small one taken"); + CHECK(server->messages() == 1); + UNSCOPED_INFO("a close the client read says too big"); + CHECK((!seen.closed || seen.code == 1009)); } - template<> template<> - void WebsocketMgrTestObjectType::test<13>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a connection past the most at once goes unanswered until there is room", "[LLWebsocketMgr_Tests]") { - set_test_name("past the most connections at once, one more is closed unanswered, and taken once there is room"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "crowd_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); - ensure("added", manager.addServer(std::make_shared(name, port, true))); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(std::make_shared(name, port, true))); + CHECK(manager.startServer(name)); // Thirty-two connections that never ask for anything: each holds // a place while its request is waited on. @@ -945,25 +933,24 @@ namespace const bool taken = waitFor([&]() { return (later = TestClient().open(port)) == 101; }); manager.removeServer(name); - ensure_equals("one more is not answered", refused, -1); - ensure("once they have gone, one is", taken); + UNSCOPED_INFO("one more is not answered"); + CHECK(refused == -1); + UNSCOPED_INFO("once they have gone, one is"); + CHECK(taken); } - template<> template<> - void WebsocketMgrTestObjectType::test<14>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a malformed request is answered -32600 and a notification not at all", "[LLWebsocketMgr_Tests]") { - set_test_name("a malformed request is answered -32600 with its id; a method needing an id, called without one, is neither run nor answered"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } LL::WorkQueue mainloop("mainloop"); const std::string name = "malformed_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); - ensure("added", manager.addServer(std::make_shared(name, port, true))); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(std::make_shared(name, port, true))); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101; @@ -984,31 +971,32 @@ namespace manager.removeServer(name); mainloop.close(); - ensure("opened", opened); - ensure("the malformed one answered", read_malformed); - ensure_equals("as an invalid request", malformed["error"]["code"].asInteger(), LLSD::Integer(-32600)); - ensure_equals("with its id", malformed["id"].asString(), std::string("bad")); - ensure("the notification sent", sent_notification); - ensure("something answered after it", read_next); - ensure_equals("the ping, not the notification", next["id"].asString(), std::string("ping")); + CHECK(opened); + CHECK(read_malformed); + UNSCOPED_INFO("as an invalid request"); + CHECK(malformed["error"]["code"].asInteger() == LLSD::Integer(-32600)); + UNSCOPED_INFO("with its id"); + CHECK(malformed["id"].asString() == std::string("bad")); + CHECK(sent_notification); + UNSCOPED_INFO("something answered after it"); + CHECK(read_next); + UNSCOPED_INFO("the ping, not the notification"); + CHECK(next["id"].asString() == std::string("ping")); } - template<> template<> - void WebsocketMgrTestObjectType::test<15>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: an unauthenticated connection is refused calls and reads 64 KB at most", "[LLWebsocketMgr_Tests]") { - set_test_name("a connection not yet authenticated is refused what it asks, reads a message within 64 KB, and is closed by one past it"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } LL::WorkQueue mainloop("mainloop"); const std::string name = "gated_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101; @@ -1032,30 +1020,31 @@ namespace manager.removeServer(name); mainloop.close(); - ensure("opened", opened); - ensure("answered", read); - ensure_equals("as unauthorized", refusal["error"]["code"].asInteger(), LLSD::Integer(-32002)); - ensure("the one within the limit read", read_within); - ensure_equals("and answered as not JSON", parse_error["error"]["code"].asInteger(), LLSD::Integer(-32700)); - ensure("the connection open after it", open_after); - ensure("and closed by the one past it", closed); + CHECK(opened); + UNSCOPED_INFO("answered"); + CHECK(read); + UNSCOPED_INFO("as unauthorized"); + CHECK(refusal["error"]["code"].asInteger() == LLSD::Integer(-32002)); + CHECK(read_within); + UNSCOPED_INFO("and answered as not JSON"); + CHECK(parse_error["error"]["code"].asInteger() == LLSD::Integer(-32700)); + CHECK(open_after); + UNSCOPED_INFO("and closed by the one past it"); + CHECK(closed); } - template<> template<> - void WebsocketMgrTestObjectType::test<16>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: a throw is answered as a bare internal error and a refusal says why", "[LLWebsocketMgr_Tests]") { - set_test_name("a handler that throws is answered as an internal error saying nothing of what it threw; one that refuses says why"); - const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } LL::WorkQueue mainloop("mainloop"); const std::string name = "throw_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); - ensure("added", manager.addServer(std::make_shared(name, port, true))); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(std::make_shared(name, port, true))); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101; @@ -1073,24 +1062,26 @@ namespace manager.removeServer(name); mainloop.close(); - ensure("opened", opened); + CHECK(opened); for (const auto& [what, read, answer] : { std::tuple{ "run where it came in", read_sync, sync_answer }, std::tuple{ "run on the main thread", read_async, async_answer } }) { - ensure(std::string(what) + ": answered", read); - ensure_equals(std::string(what) + ": as an internal error", answer["error"]["code"].asInteger(), LLSD::Integer(-32603)); - ensure_equals(std::string(what) + ": and nothing more", answer["error"]["message"].asString(), std::string("Internal error")); + INFO(what); + UNSCOPED_INFO("answered"); + REQUIRE(read); + UNSCOPED_INFO("as an internal error"); + REQUIRE(answer["error"]["code"].asInteger() == LLSD::Integer(-32603)); + UNSCOPED_INFO("and nothing more"); + REQUIRE(answer["error"]["message"].asString() == std::string("Internal error")); } - ensure("the refusal answered", read_refusal); - ensure_equals("as invalid params", refusal["error"]["code"].asInteger(), LLSD::Integer(-32602)); - ensure_contains("saying why", refusal["error"]["message"].asString(), "no such script"); + CHECK(read_refusal); + UNSCOPED_INFO("as invalid params"); + CHECK(refusal["error"]["code"].asInteger() == LLSD::Integer(-32602)); + CHECK_THAT(refusal["error"]["message"].asString(), Catch::Matchers::ContainsSubstring("no such script")); } - template<> template<> - void WebsocketMgrTestObjectType::test<17>() + TEST_CASE_METHOD(WebsocketMgrTestData, "LLWebsocketMgr Tests: sends while the server thread is busy count against the 32 MB limit", "[LLWebsocketMgr_Tests]") { - set_test_name("sends taken while the server thread is busy count against the most a connection may hold"); - // Holds the server thread as the connection opens, so that nothing // sent meanwhile is queued, let alone written, until it is let go. class HeldServer : public LLWebsocketMgr::WSServer @@ -1121,13 +1112,13 @@ namespace const U16 port = unusedPort(); if (!port) { - skip("no port free to listen on"); + SKIP("no port free to listen on"); } const std::string name = "held_test"; LLWebsocketMgr& manager = LLWebsocketMgr::instance(); auto server = std::make_shared(name, port, true); - ensure("added", manager.addServer(server)); - ensure("started", manager.startServer(name)); + CHECK(manager.addServer(server)); + CHECK(manager.startServer(name)); TestClient client; const bool opened = client.open(port) == 101 && waitFor([&]() { return server->mOpened.load(); }); @@ -1145,11 +1136,10 @@ namespace const bool dropped = waitFor([&]() { return server->mClosed == 1; }); manager.removeServer(name); - ensure("opened", opened); - ensure_equals("taken up to the most it may hold", sent, 31); - ensure("and refused after", refused); - ensure("dropped", dropped); + CHECK(opened); + UNSCOPED_INFO("taken up to the most it may hold"); + CHECK(sent == 31); + CHECK(refused); + CHECK(dropped); } } - -#endif diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 018693a921..5c00b968db 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -173,38 +173,49 @@ if(AL_BUILD_TESTS) # These three stand in for parts of llmessage and llcorehttp with stubs of # their own, so they build their one file and do not link llmessage. foreach(test llcoproceduremanager lltrustedmessageservice lltemplatemessagedispatcher) - al_add_test(${test} UNIT PROJECT llmessage LIBRARIES llmath llcorehttp) + al_add_test_binary( + ${test}_test + PROJECT llmessage + SOURCES tests/${test}_test.cpp + UNIT ${test}.cpp + LIBRARIES llmath llcorehttp llcommon + ) endforeach() - set( - test_libs - llfilesystem - llmath - llcorehttp - llmessage - llcommon - ) - al_add_test(io PROJECT llmessage SOURCES tests/llpipeutil.cpp LIBRARIES ${test_libs}) - foreach( - test - alnetimpairment - llavatarnamecache - llbuffer - lldatapacker - llhost - llhttpnode - llsdmessagebuilder - llsdmessagereader - llmessageconfig - llmessagetemplateparser - llnamevalue - llpartdata - lltemplatemessagebuilder - llxfer_file - llxorcipher - llzerocode - message + # The state guard's checks on what llmessage keeps for the process, for + # every test binary that links it. + add_library(llmessage_test_checks OBJECT tests/llmessage_test_checks.cpp) + target_link_libraries(llmessage_test_checks PRIVATE al::flags al_test_support llmessage) + set_target_properties(llmessage_test_checks PROPERTIES FOLDER "Tests/llmessage") + + # io_test's pipes, which are not tests of their own. + add_library(llmessage_test_pipes OBJECT tests/llpipeutil.cpp) + target_link_libraries(llmessage_test_pipes PRIVATE al::flags llmessage) + set_target_properties(llmessage_test_pipes PROPERTIES FOLDER "Tests/llmessage") + + al_add_test_binary( + llmessage_tests + PROJECT llmessage + SOURCES + tests/alnetimpairment_test.cpp + tests/io_test.cpp + tests/llavatarnamecache_test.cpp + tests/llbuffer_test.cpp + tests/lldatapacker_test.cpp + tests/llhost_test.cpp + tests/llhttpnode_test.cpp + tests/llmessageconfig_test.cpp + tests/llmessagetemplateparser_test.cpp + tests/llnamevalue_test.cpp + tests/llpartdata_test.cpp + tests/llsdmessagebuilder_test.cpp + tests/llsdmessagereader_test.cpp + tests/lltemplatemessagebuilder_test.cpp + tests/llxfer_file_test.cpp + tests/llxorcipher_test.cpp + tests/llzerocode_test.cpp + tests/message_test.cpp + LIBRARIES llfilesystem llmath llcorehttp llmessage llcommon + SUPPORT llmessage_test_checks llmessage_test_pipes ) - al_add_test(${test} PROJECT llmessage LIBRARIES ${test_libs}) - endforeach() endif() diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp index 3c028fdcf3..0f5fe99e75 100644 --- a/indra/llmessage/llmessageconfig.cpp +++ b/indra/llmessage/llmessageconfig.cpp @@ -34,6 +34,20 @@ #include "llsdserialize.h" #include "message.h" +#include + +namespace +{ + std::string sServerName; + std::string sConfigDir; + + // The file of the directory initClass last named. An LLLiveFile watches + // the one path it was made with, so another directory gets another + // file: one that kept watching the first directory's file would reload + // only when that changed, and then read the new directory's. + std::unique_ptr sConfigFile; +} + std::string LLMessageConfigFile::filename() { std::ostringstream ostr; @@ -44,9 +58,12 @@ std::string LLMessageConfigFile::filename() LLMessageConfigFile& LLMessageConfigFile::instance() { - static LLMessageConfigFile the_file; - the_file.checkAndReload(); - return the_file; + if (!sConfigFile) + { + sConfigFile = std::make_unique(); + } + sConfigFile->checkAndReload(); + return *sConfigFile; } // virtual @@ -153,7 +170,11 @@ void LLMessageConfig::initClass(const std::string& server_name, const std::string& config_dir) { sServerName = server_name; - sConfigDir = config_dir; + if (config_dir != sConfigDir) + { + sConfigDir = config_dir; + sConfigFile.reset(); + } (void) LLMessageConfigFile::instance(); LL_DEBUGS("AppInit") << "LLMessageConfig::initClass config file " << config_dir << "/" << messageConfigFileName << LL_ENDL; diff --git a/indra/llmessage/llmessageconfig.h b/indra/llmessage/llmessageconfig.h index d45a54386a..88d2eaa75e 100644 --- a/indra/llmessage/llmessageconfig.h +++ b/indra/llmessage/llmessageconfig.h @@ -34,12 +34,6 @@ static constexpr char messageConfigFileName[] = "message.xml"; static constexpr F32 messageConfigRefreshRate = 5.f; // seconds -static std::string sServerName; -static std::string sConfigDir; - -static std::string sServerDefault; -static LLSD sMessages; - class LLSD; class LLMessageConfig @@ -78,7 +72,7 @@ class LLMessageConfigFile : public LLLiveFile std::string mServerDefault; static LLMessageConfigFile& instance(); - // return the singleton configuration file + // return the configuration file of the directory initClass last named /* virtual */ bool loadFile(); void loadServerDefaults(const LLSD& data); diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index f350fc7112..8597651766 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -243,8 +243,9 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers); mLLSDMessageReader = new LLSDMessageReader(); - // initialize various bits of net info - mSocket = 0; + // initialize various bits of net info. No socket is -1: 0 is a + // descriptor, stdin's. + mSocket = -1; mPort = port; S32 error = start_net(mSocket, mPort); @@ -336,11 +337,9 @@ LLMessageSystem::~LLMessageSystem() for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer()); mMessageNumbers.clear(); - if (!mbError) - { - end_net(mSocket); - } - mSocket = 0; + // Closed whatever else failed: the template loads before the socket + // opens, so a system without one still has a socket. + end_net(mSocket); delete mTemplateMessageReader; mTemplateMessageReader = NULL; diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index 0df38d040a..a4a32bb551 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -243,6 +243,8 @@ S32 start_net(S32& socket_out, int& nPort) if (nRet == SOCKET_ERROR) { LL_WARNS("AppInit") << "startNet() : Couldn't find available network port." << LL_ENDL; + closesocket(hSocket); + WSACleanup(); // Fail gracefully here in release return 3; } @@ -251,6 +253,8 @@ S32 start_net(S32& socket_out, int& nPort) // Some other socket error { LL_WARNS("AppInit") << llformat("bind() port: %d failed, Err: %d\n", nPort, WSAGetLastError()) << LL_ENDL; + closesocket(hSocket); + WSACleanup(); // Fail gracefully in release. return 4; } @@ -301,14 +305,17 @@ S32 start_net(S32& socket_out, int& nPort) return 0; } +// Undoes a start_net that succeeded: the socket, and WSAStartup. The socket +// is -1 after, so a second call does nothing. void end_net(S32& socket_out) { if (socket_out >= 0) { shutdown(socket_out, SD_BOTH); closesocket(socket_out); + WSACleanup(); + socket_out = -1; } - WSACleanup(); } S32 receive_packet(int hSocket, char * receiveBuffer) @@ -449,6 +456,7 @@ S32 start_net(S32& socket_out, int& nPort) if (nRet < 0) { LL_WARNS() << "startNet() : Couldn't find available network port." << LL_ENDL; + close(hSocket); // Fail gracefully in release. return 3; } @@ -457,6 +465,7 @@ S32 start_net(S32& socket_out, int& nPort) else { LL_WARNS() << llformat ("bind() port: %d failed, Err: %s\n", nPort, strerror(errno)) << LL_ENDL; + close(hSocket); // Fail gracefully in release. return 4; } @@ -508,11 +517,14 @@ S32 start_net(S32& socket_out, int& nPort) return 0; } +// Undoes a start_net that succeeded. The socket is -1 after, so a second +// call does nothing. void end_net(S32& socket_out) { if (socket_out >= 0) { close(socket_out); + socket_out = -1; } } diff --git a/indra/llmessage/tests/alnetimpairment_test.cpp b/indra/llmessage/tests/alnetimpairment_test.cpp index 9dc0c39356..2560a80cd9 100644 --- a/indra/llmessage/tests/alnetimpairment_test.cpp +++ b/indra/llmessage/tests/alnetimpairment_test.cpp @@ -14,7 +14,7 @@ #include "linden_common.h" -#include "../test/lltut.h" +#include #include "../alnetimpairment.h" @@ -24,8 +24,6 @@ #include -namespace tut -{ namespace { struct impairment_data @@ -73,33 +71,25 @@ namespace } }; - typedef test_group impairment_group_t; - typedef impairment_group_t::object impairment_object_t; - tut::impairment_group_t impairment_group("ALNetImpairment"); -} - template<> template<> - void impairment_object_t::test<1>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: idle by default and lets everything through while off", "[ALNetImpairment]") { - set_test_name("idle by default, and off means untouched"); - - ensure("not active until configured", !mImpairment.isActive()); + CHECK_FALSE(mImpairment.isActive()); S32 dropped = 0; F32 run = 0.f; measureLoss(5000, dropped, run); - ensure_equals("nothing is dropped when loss is zero", dropped, 0); + UNSCOPED_INFO("nothing is dropped when loss is zero"); + CHECK(dropped == 0); std::vector released; - ensure("nothing is held when reordering is zero", !mImpairment.hold(numbered(1))); + UNSCOPED_INFO("nothing is held when reordering is zero"); + CHECK_FALSE(mImpairment.hold(numbered(1))); mImpairment.advance(released); - ensure("and nothing comes back", released.empty()); + CHECK(released.empty()); } - template<> template<> - void impairment_object_t::test<2>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: loss rate follows the setting", "[ALNetImpairment]") { - set_test_name("loss rate follows the setting"); - for (F32 target : { 1.f, 5.f, 20.f, 50.f }) { ALNetImpairment fresh; @@ -111,16 +101,13 @@ namespace measureLoss(count, dropped, run); const F32 realised = 100.f * (F32)dropped / (F32)count; - ensure(llformat("loss near %.0f%%, got %.2f%%", target, realised).c_str(), - fabsf(realised - target) < llmax(0.5f, target * 0.1f)); + CAPTURE(target, realised); + REQUIRE(fabsf(realised - target) < llmax(0.5f, target * 0.1f)); } } - template<> template<> - void impairment_object_t::test<3>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: burst length is independent of loss rate", "[ALNetImpairment]") { - set_test_name("burst length is independent of loss rate"); - // Real loss arrives in runs, and the whole point of the burst control is to lengthen // those runs without also losing more traffic -- a burst of ten consecutive updates is // what strands a moving object, where the same average spread thinly does not. @@ -136,18 +123,15 @@ namespace measureLoss(count, dropped, run); const F32 realised = 100.f * (F32)dropped / (F32)count; - ensure(llformat("burst %.0f still loses ~10%%, got %.2f%%", burst, realised).c_str(), - fabsf(realised - 10.f) < 1.5f); - ensure(llformat("run length near %.0f, got %.2f", burst, run).c_str(), - fabsf(run - burst) < llmax(0.35f, burst * 0.15f)); + CAPTURE(burst, realised); + REQUIRE(fabsf(realised - 10.f) < 1.5f); + CAPTURE(run); + REQUIRE(fabsf(run - burst) < llmax(0.35f, burst * 0.15f)); } } - template<> template<> - void impairment_object_t::test<4>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: a held packet returns behind the ones that overtook it", "[ALNetImpairment]") { - set_test_name("a held packet returns behind the ones that overtook it"); - mImpairment.setReorderPercent(100.f); // hold everything eligible mImpairment.setReorderDelay(3); @@ -162,7 +146,7 @@ namespace if (i == 0) { - ensure("first packet is held", mImpairment.hold(numbered(i))); + REQUIRE(mImpairment.hold(numbered(i))); } else { @@ -177,47 +161,43 @@ namespace } } - ensure_equals("everything arrived", (S32)delivered.size(), 6); + REQUIRE((S32)delivered.size() == 6); // 1, 2, 3, then the held 0, then 4, 5. - ensure_equals("overtaken by 1", delivered[0], 1); - ensure_equals("overtaken by 2", delivered[1], 2); - ensure_equals("overtaken by 3", delivered[2], 3); - ensure_equals("held packet lands out of sequence", delivered[3], 0); - ensure_equals("stream continues", delivered[4], 4); - ensure_equals("stream continues", delivered[5], 5); + CHECK(delivered[0] == 1); + CHECK(delivered[1] == 2); + CHECK(delivered[2] == 3); + CHECK(delivered[3] == 0); + CHECK(delivered[4] == 4); + CHECK(delivered[5] == 5); } - template<> template<> - void impairment_object_t::test<5>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: nothing is stranded when reordering is switched off", "[ALNetImpairment]") { - set_test_name("nothing is stranded when reordering is switched off"); - mImpairment.setReorderPercent(100.f); mImpairment.setReorderDelay(50); for (S32 i = 0; i < 10; ++i) { - ensure("held", mImpairment.hold(numbered(i))); + REQUIRE(mImpairment.hold(numbered(i))); } std::vector released; mImpairment.flush(released); - ensure_equals("every held packet comes back", (S32)released.size(), 10); + REQUIRE((S32)released.size() == 10); for (S32 i = 0; i < 10; ++i) { - ensure_equals("in the order they were held", numberOf(released[i]), i); + UNSCOPED_INFO("in the order they were held"); + REQUIRE(numberOf(released[i]) == i); } released.clear(); mImpairment.advance(released); - ensure("and the queue is empty afterwards", released.empty()); + UNSCOPED_INFO("flush left nothing queued"); + CHECK(released.empty()); } - template<> template<> - void impairment_object_t::test<6>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: the hold queue has a ceiling", "[ALNetImpairment]") { - set_test_name("the hold queue has a ceiling"); - mImpairment.setReorderPercent(100.f); mImpairment.setReorderDelay(1000000); // never due on its own @@ -227,7 +207,7 @@ namespace if (mImpairment.hold(numbered((S32)i))) { ++held; } } - ensure_equals("stops holding at the ceiling", (size_t)held, ALNetImpairment::MAX_HELD_PACKETS); + CHECK((size_t)held == ALNetImpairment::MAX_HELD_PACKETS); } } @@ -235,20 +215,13 @@ namespace // Nothing to test in a build the impairment is compiled out of, but the test binary still has to // link and report success. -namespace tut -{ namespace { struct impairment_data {}; - typedef test_group impairment_group_t; - tut::impairment_group_t impairment_group("ALNetImpairment"); -} - template<> template<> - void impairment_group_t::object::test<1>() + TEST_CASE_METHOD(impairment_data, "ALNetImpairment: compiled out of release builds", "[ALNetImpairment]") { - set_test_name("compiled out of release builds"); - ensure("nothing to check", true); + CHECK(true); } } diff --git a/indra/llmessage/tests/io_test.cpp b/indra/llmessage/tests/io_test.cpp index 683142d18c..c726fe1ecd 100644 --- a/indra/llmessage/tests/io_test.cpp +++ b/indra/llmessage/tests/io_test.cpp @@ -27,7 +27,7 @@ */ #include "linden_common.h" -#include "lltut.h" +#include #include @@ -47,8 +47,6 @@ #include "lluuid.h" #include "llinstantmessage.h" -namespace tut -{ namespace { struct heap_buffer_data @@ -57,124 +55,31 @@ namespace ~heap_buffer_data() { if(mBuffer) delete mBuffer; } LLHeapBuffer* mBuffer; }; - typedef test_group 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 -{ namespace { struct buffer_data { LLBufferArray mBuffer; }; - typedef test_group buffer_test; - typedef buffer_test::object buffer_object; - tut::buffer_test tba("buffer_array"); -} - template<> template<> - void buffer_object::test<1>() + TEST_CASE_METHOD(buffer_data, "buffer_array: countAfter counts the whole channel or what follows an address", "[buffer_array]") { const char HELLO_WORLD[] = "hello world"; const S32 str_len = static_cast(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); + CHECK(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); + CHECK(count == str_len - 1); } - template<> template<> - void buffer_object::test<2>() + TEST_CASE_METHOD(buffer_data, "buffer_array: countAfter counts across two appended segments", "[buffer_array]") { const char HELLO_WORLD[] = "hello world"; const S32 str_len = static_cast(strlen(HELLO_WORLD)); /* Flawfinder: ignore */ @@ -182,15 +87,14 @@ namespace 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); + CHECK(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); + CHECK(count == (2 * str_len) - 1); } - template<> template<> - void buffer_object::test<3>() + TEST_CASE_METHOD(buffer_data, "buffer_array: readAfter reads two appends in order", "[buffer_array]") { const char ONE[] = "one"; const char TWO[] = "two"; @@ -202,14 +106,13 @@ namespace char buffer[255]; /* Flawfinder: ignore */ S32 len = 6; mBuffer.readAfter(ch.in(), NULL, (U8*)buffer, len); - ensure_equals(len, 6); + CHECK(len == 6); buffer[len] = '\0'; std::string actual(buffer); - ensure_equals("read", actual, expected); + CHECK(actual == expected); } - template<> template<> - void buffer_object::test<4>() + TEST_CASE_METHOD(buffer_data, "buffer_array: readAfter reads a prepend before an append", "[buffer_array]") { const char ONE[] = "one"; const char TWO[] = "two"; @@ -221,14 +124,13 @@ namespace char buffer[255]; /* Flawfinder: ignore */ S32 len = 6; mBuffer.readAfter(ch.in(), NULL, (U8*)buffer, len); - ensure_equals(len, 6); + CHECK(len == 6); buffer[len] = '\0'; std::string actual(buffer); - ensure_equals("read", actual, expected); + CHECK(actual == expected); } - template<> template<> - void buffer_object::test<5>() + TEST_CASE_METHOD(buffer_data, "buffer_array: readAfter from an address starts after that byte", "[buffer_array]") { const char ONE[] = "one"; const char TWO[] = "two"; @@ -241,14 +143,13 @@ namespace LLBufferArray::segment_iterator_t it = mBuffer.beginSegment(); U8* addr = (*it).data(); mBuffer.readAfter(ch.in(), addr, (U8*)buffer, len); - ensure_equals(len, 5); + CHECK(len == 5); buffer[len] = '\0'; std::string actual(buffer); - ensure_equals("read", actual, expected); + CHECK(actual == expected); } - template<> template<> - void buffer_object::test<6>() + TEST_CASE_METHOD(buffer_data, "buffer_array: a header prepended to the out channel reads back first", "[buffer_array]") { std::string request("The early bird catches the worm."); std::string response("If you're a worm, sleep late."); @@ -265,15 +166,14 @@ namespace mBuffer.prepend(ch.out(), (U8*)head.c_str(), static_cast(head.length())); char buffer[1024]; /* Flawfinder: ignore */ S32 len = static_cast(response.size() + head.length()); - ensure_equals("same length", len, (S32)expected.str().length()); + CHECK(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()); + CHECK(actual == expected.str()); } - template<> template<> - void buffer_object::test<7>() + TEST_CASE_METHOD(buffer_data, "buffer_array: readAfter and seek step through the buffer a line at a time", "[buffer_array]") { const S32 LINE_COUNT = 3; std::string lines[LINE_COUNT] = @@ -304,15 +204,13 @@ namespace ++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]); + CAPTURE(i); + REQUIRE(last_line == lines[i]); last = mBuffer.seek(ch.in(), last, offset); } } - template<> template<> - void buffer_object::test<8>() + TEST_CASE_METHOD(buffer_data, "buffer_array: takeContents splices another array between appends", "[buffer_array]") { LLChannelDescriptors ch = mBuffer.nextChannel(); mBuffer.append(ch.in(), (U8*)"1", 1); @@ -321,26 +219,26 @@ namespace mBuffer.takeContents(buffer); mBuffer.append(ch.in(), (U8*)"3", 1); S32 count = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("buffer size", count, 3); + REQUIRE(count == 3); U8* temp = new U8[count]; mBuffer.readAfter(ch.in(), NULL, temp, count); - ensure("buffer content", (0 == memcmp(temp, (void*)"123", 3))); + CHECK(memcmp(temp, (void*)"123", 3) == 0); delete[] temp; } - template<> template<> - void buffer_object::test<9>() + TEST_CASE_METHOD(buffer_data, "buffer_array: capacity holds as segments are erased and refilled", "[buffer_array]") { LLChannelDescriptors ch = mBuffer.nextChannel(); mBuffer.append(ch.in(), (U8*)"1", 1); S32 capacity = mBuffer.capacity(); - ensure("has capacity", capacity > 0); + CHECK(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); + UNSCOPED_INFO("has capacity when full"); + CHECK(capacity > 0); S32 used = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("used equals capacity", used, capacity); + CHECK(used == capacity); LLBufferArray::segment_iterator_t iter = mBuffer.beginSegment(); while(iter != mBuffer.endSegment()) @@ -349,12 +247,14 @@ namespace } used = mBuffer.countAfter(ch.in(), NULL); - ensure_equals("used is zero", used, 0); + CHECK(used == 0); S32 capacity2 = mBuffer.capacity(); - ensure_equals("capacity the same after erase", capacity2, capacity); + UNSCOPED_INFO("capacity the same after erase"); + CHECK(capacity2 == capacity); mBuffer.append(ch.in(), temp, capacity - 1); capacity2 = mBuffer.capacity(); - ensure_equals("capacity the same after append", capacity2, capacity); + UNSCOPED_INFO("capacity the same after append"); + CHECK(capacity2 == capacity); delete[] temp; } @@ -404,21 +304,14 @@ namespace */ } -namespace tut -{ namespace { struct buffer_and_stream_data { LLBufferArray mBuffer; }; - typedef test_group bas_test; - typedef bas_test::object bas_object; - tut::bas_test tbs("buffer_stream"); -} - template<> template<> - void bas_object::test<1>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: operator>> reads words appended to the in channel", "[buffer_stream]") { const char HELLO_WORLD[] = "hello world"; const S32 str_len = static_cast(strlen(HELLO_WORLD)); /* Flawfinder: ignore */ @@ -428,12 +321,11 @@ namespace 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")); + CHECK(hello == std::string("hello")); + CHECK(world == std::string("world")); } - template<> template<> - void bas_object::test<2>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: operator>> reads across segments and ignores the out channel", "[buffer_stream]") { std::string part1("Eat my shor"); std::string part2("ts ho"); @@ -450,14 +342,13 @@ namespace 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")); + CHECK(eat == std::string("Eat")); + CHECK(my == std::string("my")); + CHECK(shorts == std::string("shorts")); + CHECK(homer == std::string("homer")); } - template<> template<> - void bas_object::test<3>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: seek back from a read and read across segments", "[buffer_stream]") { std::string part1("junk in "); std::string part2("the trunk"); @@ -471,17 +362,16 @@ namespace 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")); + CHECK(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")); + CHECK(actual == std::string("in the trunk")); } - template<> template<> - void bas_object::test<4>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: splitAfter splits a segment in two after a read", "[buffer_stream]") { std::string phrase("zippity do da!"); const S32 CHANNEL = 0; @@ -494,16 +384,15 @@ namespace 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")); + CHECK(first == std::string("zippity")); ++it; std::string second((char*)((*it).data()), (*it).size()); - ensure_equals("second part", second, std::string(" do da!")); + CHECK(second == std::string(" do da!")); ++it; - ensure("iterators equal", (it == end)); + CHECK(it == end); } - template<> template<> - void bas_object::test<5>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: operator<< writes to the out channel", "[buffer_stream]") { LLChannelDescriptors ch = mBuffer.nextChannel(); LLBufferStream str(ch, &mBuffer); @@ -518,14 +407,13 @@ namespace S32 actual_len = BUF_LEN; S32 expected_len = static_cast(h1.size() + h2.size()); (void) mBuffer.readAfter(ch.out(), NULL, (U8*)buf, actual_len); - ensure_equals("streamed size", actual_len, expected_len); + REQUIRE(actual_len == expected_len); buf[actual_len] = '\0'; std::string actual(buf); - ensure_equals("streamed to buf", actual, expected); + CHECK(actual == expected); } - template<> template<> - void bas_object::test<6>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: seekp on the stream matches seekp on an ostringstream", "[buffer_stream]") { LLChannelDescriptors ch = mBuffer.nextChannel(); LLBufferStream bstr(ch, &mBuffer); @@ -565,36 +453,34 @@ namespace 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); + CHECK(actual.size() == expected.size()); + CHECK(actual == expected); } - template<> template<> - void bas_object::test<7>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: takeContents splices between flushed stream writes", "[buffer_stream]") { 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); + CHECK(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); + CHECK(count == 2); bstr << "3"; bstr.flush(); count = mBuffer.countAfter(ch.out(), NULL); - ensure_equals("buffer size 3", count, 3); + REQUIRE(count == 3); U8* temp = new U8[count]; mBuffer.readAfter(ch.out(), NULL, temp, count); - ensure("buffer content", (0 == memcmp(temp, (void*)"123", 3))); + CHECK(memcmp(temp, (void*)"123", 3) == 0); delete[] temp; } - template<> template<> - void bas_object::test<8>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: binary blobs in a notation array parse back intact", "[buffer_stream]") { LLChannelDescriptors ch = mBuffer.nextChannel(); LLBufferStream ostr(ch, &mBuffer); @@ -635,32 +521,24 @@ namespace // 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); + CHECK(count == total_size); LLBufferStream istr(ch, &mBuffer); LLSD data; count = LLSDSerialize::fromNotation(data, istr, total_size); - ensure("sd parsed", data.isDefined()); + REQUIRE(data.isDefined()); for(S32 j = 0; j < 3; ++j) { - std::ostringstream name; + CAPTURE(j); LLSD child(data[j]); - name << "found buffer " << j; - ensure(name.str(), child.isDefined()); + REQUIRE(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()))); + REQUIRE(source.size() == actual[j].size()); + REQUIRE(memcmp(&source[0], &actual[j][0], source.size()) == 0); } } - template<> template<> - void bas_object::test<9>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: a notation map of 2000 binary blobs parses", "[buffer_stream]") { LLChannelDescriptors ch = mBuffer.nextChannel(); LLBufferStream ostr(ch, &mBuffer); @@ -700,15 +578,14 @@ namespace // 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); + CHECK(count == total_size); LLBufferStream istr(ch, &mBuffer); LLSD data; count = LLSDSerialize::fromNotation(data, istr, total_size); - ensure("sd parsed", data.isDefined()); + CHECK(data.isDefined()); } - template<> template<> - void bas_object::test<10>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: a notation login request parses from the stream", "[buffer_stream]") { //#if LL_WINDOWS && _MSC_VER >= 1400 // skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); @@ -746,57 +623,62 @@ namespace 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")); + CHECK(count > 0); + REQUIRE(data.isDefined()); + CHECK(data.type() == LLSD::TypeMap); + CHECK(data.has("method")); + REQUIRE(data.has("parameter")); LLSD parameter = data["parameter"]; - ensure_equals("parameter is array", parameter.type(), LLSD::TypeArray); + CHECK(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")); + UNSCOPED_INFO("last name"); + CHECK(s_value == std::string("Linden")); s_value = agent_params["first_name"].asString(); - ensure_equals("first name", s_value, std::string("Kelly")); + UNSCOPED_INFO("first name"); + CHECK(s_value == std::string("Kelly")); s_value = agent_params["agent_access"].asString(); - ensure_equals("agent access", s_value, std::string("M")); + UNSCOPED_INFO("agent access"); + CHECK(s_value == std::string("M")); s_value = agent_params["group_name"].asString(); - ensure_equals("group name", s_value, std::string("test!")); + UNSCOPED_INFO("group name"); + CHECK(s_value == std::string("test!")); s_value = agent_params["group_title"].asString(); - ensure_equals("group title", s_value, std::string("-> !BLING! <-")); + UNSCOPED_INFO("group title"); + CHECK(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); + CHECK(id == agent_id); LLUUID session_id("324cfa9f-fe5d-4d1c-a317-35f20a86a4d1"); id = agent_params["session_id"]; - ensure_equals("session id", id, session_id); + CHECK(id == session_id); LLUUID group_id ("8615c885-9cf0-bf0a-6e40-0c11462aa652"); id = agent_params["group_id"]; - ensure_equals("group id", id, group_id); + CHECK(id == group_id); S32 i_val = agent_params["limited_to_estate"]; - ensure_equals("limited to estate", i_val, 1); + UNSCOPED_INFO("limited to estate"); + CHECK(i_val == 1); i_val = agent_params["circuit_code"]; - ensure_equals("circuit code", i_val, 124); + UNSCOPED_INFO("circuit code"); + CHECK(i_val == 124); } - template<> template<> - void bas_object::test<11>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: fromNotation fails on garbage in a map", "[buffer_stream]") { 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()); + CHECK(count == -1); + CHECK(sd.isUndefined()); } - template<> template<> - void bas_object::test<12>() + TEST_CASE_METHOD(buffer_and_stream_data, "buffer_stream: fromNotation fails on garbage nested in arrays and maps", "[buffer_stream]") { //#if LL_WINDOWS && _MSC_VER >= 1400 // skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); @@ -806,8 +688,95 @@ namespace 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()); + CHECK(count == -1); + CHECK(sd.isUndefined()); + } + + TEST_CASE_METHOD(heap_buffer_data, "heap_buffer: capacity does not change when a segment is made", "[heap_buffer]") + { + const S32 BUF_SIZE = 100; + mBuffer = new LLHeapBuffer(BUF_SIZE); + UNSCOPED_INFO("before any segment"); + CHECK(mBuffer->capacity() == BUF_SIZE); + const S32 SEGMENT_SIZE = 50; + LLSegment segment; + mBuffer->createSegment(0, SEGMENT_SIZE, segment); + UNSCOPED_INFO("after a segment"); + CHECK(mBuffer->capacity() == BUF_SIZE); + } + + TEST_CASE_METHOD(heap_buffer_data, "heap_buffer: a full buffer refuses new segments", "[heap_buffer]") + { + const S32 BUF_SIZE = 10; + mBuffer = new LLHeapBuffer(BUF_SIZE); + LLSegment segment; + mBuffer->createSegment(0, BUF_SIZE, segment); + CHECK(mBuffer->containsSegment(segment)); + CHECK(mBuffer->bytesLeft() == 0); + bool created; + created = mBuffer->createSegment(0, 0, segment); + UNSCOPED_INFO("zero size segment"); + CHECK_FALSE(created); + created = mBuffer->createSegment(0, BUF_SIZE, segment); + UNSCOPED_INFO("segment in a full buffer"); + CHECK_FALSE(created); + } + + TEST_CASE_METHOD(heap_buffer_data, "heap_buffer: reclaiming the only segment frees the whole buffer", "[heap_buffer]") + { + const S32 BUF_SIZE = 10; + mBuffer = new LLHeapBuffer(BUF_SIZE); + LLSegment segment; + mBuffer->createSegment(0, BUF_SIZE, segment); + CHECK(mBuffer->containsSegment(segment)); + CHECK(mBuffer->bytesLeft() == 0); + bool reclaimed = mBuffer->reclaimSegment(segment); + CHECK(reclaimed); + CHECK(mBuffer->bytesLeft() == BUF_SIZE); + bool created; + created = mBuffer->createSegment(0, 0, segment); + UNSCOPED_INFO("zero size segment"); + CHECK_FALSE(created); + created = mBuffer->createSegment(0, BUF_SIZE, segment); + UNSCOPED_INFO("full size segment after the reclaim"); + CHECK(created); + } + + TEST_CASE_METHOD(heap_buffer_data, "heap_buffer: space comes back only once every segment is reclaimed", "[heap_buffer]") + { + const S32 BUF_SIZE = 10; + const S32 SEGMENT_SIZE = 4; + mBuffer = new LLHeapBuffer(BUF_SIZE); + LLSegment seg1; + mBuffer->createSegment(0, SEGMENT_SIZE, seg1); + CHECK(mBuffer->containsSegment(seg1)); + LLSegment seg2; + mBuffer->createSegment(0, SEGMENT_SIZE, seg2); + CHECK(mBuffer->containsSegment(seg2)); + LLSegment seg3; + mBuffer->createSegment(0, SEGMENT_SIZE, seg3); + CHECK(mBuffer->containsSegment(seg3)); + UNSCOPED_INFO("segment is truncated"); + CHECK(seg3.size() == 2); + LLSegment seg4; + bool created; + created = mBuffer->createSegment(0, SEGMENT_SIZE, seg4); + UNSCOPED_INFO("fourth segment in a full buffer"); + CHECK_FALSE(created); + bool reclaimed; + reclaimed = mBuffer->reclaimSegment(seg1); + CHECK(reclaimed); + CHECK(mBuffer->bytesLeft() == 0); + reclaimed = mBuffer->reclaimSegment(seg2); + CHECK(reclaimed); + CHECK(mBuffer->bytesLeft() == 0); + reclaimed = mBuffer->reclaimSegment(seg3); + CHECK(reclaimed); + CHECK(mBuffer->bytesLeft() == BUF_SIZE); + created = mBuffer->createSegment(0, SEGMENT_SIZE, seg1); + CHECK(mBuffer->containsSegment(seg1)); + UNSCOPED_INFO("segment after every reclaim"); + CHECK(created); } /* @@ -827,8 +796,6 @@ namespace } -namespace tut -{ namespace { class PumpAndChainTestData @@ -852,32 +819,7 @@ namespace apr_pool_destroy(mPool); } }; - typedef test_group 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(), ""); - } } /* @@ -906,8 +848,6 @@ namespace tut } */ -namespace tut -{ namespace { /** @@ -964,13 +904,8 @@ namespace LLSocket::ptr_t mSocket; U16 mServerPort = 0; }; - typedef test_group 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>() + TEST_CASE_METHOD(pipe_and_pump_fitness, "pipe and pump fitness: a reply the client never reads does not stall the pump", "[pipe_and_pump_fitness]") { LL_DEBUGS() << "fitness_test_object::test<1>()" << LL_ENDL; @@ -1001,7 +936,7 @@ namespace LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); LLHost server_host("127.0.0.1", mServerPort); bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); + CHECK(connected); LL_DEBUGS() << "connected" << LL_ENDL; // We have connected, since the socket reader does not block, @@ -1016,11 +951,10 @@ namespace // 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)); + CHECK(elapsed < 3.0f); } - template<> template<> - void fitness_test_object::test<2>() + TEST_CASE_METHOD(pipe_and_pump_fitness, "pipe and pump fitness: a fuzz flood does not stall when the client expires first", "[pipe_and_pump_fitness]") { LL_DEBUGS() << "fitness_test_object::test<2>()" << LL_ENDL; @@ -1044,7 +978,7 @@ namespace LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); LLHost server_host("127.0.0.1", mServerPort); bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); + CHECK(connected); LL_DEBUGS() << "connected" << LL_ENDL; // We have connected, since the socket reader does not block, @@ -1059,11 +993,10 @@ namespace // 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)); + CHECK(elapsed < 3.0f); } - template<> template<> - void fitness_test_object::test<3>() + TEST_CASE_METHOD(pipe_and_pump_fitness, "pipe and pump fitness: a fuzz flood does not stall when the server times out first", "[pipe_and_pump_fitness]") { LL_DEBUGS() << "fitness_test_object::test<3>()" << LL_ENDL; @@ -1087,7 +1020,7 @@ namespace LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); LLHost server_host("127.0.0.1", mServerPort); bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); + CHECK(connected); LL_DEBUGS() << "connected" << LL_ENDL; // We have connected, since the socket reader does not block, @@ -1102,11 +1035,10 @@ namespace // 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)); + CHECK(elapsed < 4.0f); } - template<> template<> - void fitness_test_object::test<4>() + TEST_CASE_METHOD(pipe_and_pump_fitness, "pipe and pump fitness: a fuzz flood does not stall a client that never expires", "[pipe_and_pump_fitness]") { LL_DEBUGS() << "fitness_test_object::test<4>()" << LL_ENDL; @@ -1130,7 +1062,7 @@ namespace LLSocket::ptr_t client = LLSocket::create(mPool, LLSocket::STREAM_TCP); LLHost server_host("127.0.0.1", mServerPort); bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); + CHECK(connected); LL_DEBUGS() << "connected" << LL_ENDL; // We have connected, since the socket reader does not block, @@ -1145,11 +1077,10 @@ namespace // 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)); + CHECK(elapsed < DEFAULT_CHAIN_EXPIRY_SECS); } - template<> template<> - void fitness_test_object::test<5>() + TEST_CASE_METHOD(pipe_and_pump_fitness, "pipe and pump fitness: client and accepted socket chains time out in turn", "[pipe_and_pump_fitness]") { // Set up the server LLPumpIO::chain_t chain; @@ -1166,18 +1097,20 @@ namespace // We need to tickle the pump a little to set up the listen() pump_loop(mPump, 0.1f); auto count = mPump->runningChains(); - ensure_equals("server chain onboard", count, 1); + UNSCOPED_INFO("server chain onboard"); + CHECK(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", mServerPort); bool connected = client->blockingConnect(server_host); - ensure("Connected to server", connected); + CHECK(connected); LL_DEBUGS() << "connected" << LL_ENDL; pump_loop(mPump,0.1f); count = mPump->runningChains(); - ensure_equals("server chain onboard", count, 2); + UNSCOPED_INFO("accepted socket chain onboard"); + CHECK(count == 2); LL_DEBUGS() << "** Client is connected." << LL_ENDL; // We have connected, since the socket reader does not block, @@ -1200,15 +1133,38 @@ namespace // server socket should not be closed yet. pump_loop(mPump,0.2f); count = mPump->runningChains(); - ensure_equals("client chain timed out ", count, 2); + UNSCOPED_INFO("client chain timed out"); + CHECK(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); + UNSCOPED_INFO("accepted socket closed"); + CHECK(count == 1); LL_DEBUGS() << "** Sleeper should have timed out.." << LL_ENDL; } + + TEST_CASE_METHOD(PumpAndChainTestData, "pump_and_chain: a flushed chain hands the extractor an empty string", "[pump_and_chain]") + { + 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(); + } + + CHECK(extractor->done()); + CHECK(extractor->string() == ""); + } } /* diff --git a/indra/llmessage/tests/llavatarnamecache_test.cpp b/indra/llmessage/tests/llavatarnamecache_test.cpp index c45c9067c4..52019dcc1a 100644 --- a/indra/llmessage/tests/llavatarnamecache_test.cpp +++ b/indra/llmessage/tests/llavatarnamecache_test.cpp @@ -29,77 +29,78 @@ #include "../llavatarnamecache.h" -#include "../test/lltut.h" +#include -namespace tut -{ namespace { - struct avatarnamecache_data - { - }; - typedef test_group avatarnamecache_test; - typedef avatarnamecache_test::object avatarnamecache_object; - tut::avatarnamecache_test avatarnamecache_testcase("LLAvatarNameCache"); -} - - template<> template<> - void avatarnamecache_object::test<1>() + TEST_CASE("LLAvatarNameCache: max_age_from_cache_control parses a well-formed max-age", "[LLAvatarNameCache]") { bool valid = false; S32 max_age = 0; valid = max_age_from_cache_control("max-age=3600", &max_age); - ensure("typical input valid", valid); - ensure_equals("typical input parsed", max_age, 3600); + UNSCOPED_INFO("typical input valid"); + CHECK(valid); + CHECK(max_age == 3600); valid = max_age_from_cache_control( " max-age=600 , no-cache,private=\"stuff\" ", &max_age); - ensure("complex input valid", valid); - ensure_equals("complex input parsed", max_age, 600); + UNSCOPED_INFO("complex input valid"); + CHECK(valid); + CHECK(max_age == 600); valid = max_age_from_cache_control( "no-cache, max-age = 123 ", &max_age); - ensure("complex input 2 valid", valid); - ensure_equals("complex input 2 parsed", max_age, 123); + UNSCOPED_INFO("complex input 2 valid"); + CHECK(valid); + CHECK(max_age == 123); } - template<> template<> - void avatarnamecache_object::test<2>() + TEST_CASE("LLAvatarNameCache: max_age_from_cache_control rejects malformed input but accepts zero", "[LLAvatarNameCache]") { bool valid = false; S32 max_age = -1; valid = max_age_from_cache_control("", &max_age); - ensure("empty input returns invalid", !valid); - ensure_equals("empty input doesn't change val", max_age, -1); + UNSCOPED_INFO("empty input returns invalid"); + CHECK_FALSE(valid); + UNSCOPED_INFO("empty input doesn't change val"); + CHECK(max_age == -1); valid = max_age_from_cache_control("no-cache", &max_age); - ensure("no max-age field returns invalid", !valid); + UNSCOPED_INFO("no max-age field returns invalid"); + CHECK_FALSE(valid); valid = max_age_from_cache_control("max", &max_age); - ensure("just 'max' returns invalid", !valid); + UNSCOPED_INFO("just 'max' returns invalid"); + CHECK_FALSE(valid); valid = max_age_from_cache_control("max-age", &max_age); - ensure("partial max-age is invalid", !valid); + UNSCOPED_INFO("partial max-age is invalid"); + CHECK_FALSE(valid); valid = max_age_from_cache_control("max-age=", &max_age); - ensure("longer partial max-age is invalid", !valid); + UNSCOPED_INFO("longer partial max-age is invalid"); + CHECK_FALSE(valid); valid = max_age_from_cache_control("max-age=FOO", &max_age); - ensure("invalid integer max-age is invalid", !valid); + UNSCOPED_INFO("invalid integer max-age is invalid"); + CHECK_FALSE(valid); valid = max_age_from_cache_control("max-age 234", &max_age); - ensure("space separated max-age is invalid", !valid); + UNSCOPED_INFO("space separated max-age is invalid"); + CHECK_FALSE(valid); valid = max_age_from_cache_control("max-age=0", &max_age); - ensure("zero max-age is valid", valid); + UNSCOPED_INFO("zero max-age is valid"); + CHECK(valid); // *TODO: Handle "0000" as zero //valid = max_age_from_cache_control("max-age=0000", &max_age); //ensure("multi-zero max-age is valid", valid); valid = max_age_from_cache_control("max-age=-123", &max_age); - ensure("less than zero max-age is invalid", !valid); + UNSCOPED_INFO("less than zero max-age is invalid"); + CHECK_FALSE(valid); } } diff --git a/indra/llmessage/tests/llbuffer_test.cpp b/indra/llmessage/tests/llbuffer_test.cpp index 26a00fb491..b4de019d73 100644 --- a/indra/llmessage/tests/llbuffer_test.cpp +++ b/indra/llmessage/tests/llbuffer_test.cpp @@ -26,62 +26,52 @@ * $/LicenseInfo$ */ -#include +#include +#include "altestmatchers.h" #include "linden_common.h" -#include "lltut.h" #include "llbuffer.h" #include "llerror.h" -namespace tut -{ namespace { - struct buffer - { - }; - - typedef test_group buffer_t; - typedef buffer_t::object buffer_object_t; - tut::buffer_t tut_buffer("buffer"); -} - - template<> template<> - void buffer_object_t::test<1>() + TEST_CASE("buffer: LLChannelDescriptors in() is the base channel and out() the next", "[buffer]") { LLChannelDescriptors channelDescriptors; - ensure("in() and out() functions Failed", (0 == channelDescriptors.in() && 1 == channelDescriptors.out())); + CHECK(channelDescriptors.in() == 0); + CHECK(channelDescriptors.out() == 1); S32 val = 50; LLChannelDescriptors channelDescriptors1(val); - ensure("LLChannelDescriptors in() and out() functions Failed", (50 == channelDescriptors1.in() && 51 == channelDescriptors1.out())); + CHECK(channelDescriptors1.in() == 50); + CHECK(channelDescriptors1.out() == 51); } - template<> template<> - void buffer_object_t::test<2>() + TEST_CASE("buffer: a default LLSegment is empty and setChannel sets its channel", "[buffer]") { LLSegment segment; - ensure("LLSegment get functions failed", (0 == segment.getChannel() && NULL == segment.data() && 0 == segment.size())); + CHECK((segment.getChannel() == 0 && segment.data() == NULL)); + CHECK(segment.size() == 0); segment.setChannel(50); - ensure_equals("LLSegment setChannel() function failed", segment.getChannel(), 50); - ensure("LLSegment isOnChannel() function failed", (true == segment.isOnChannel(50))); + CHECK(segment.getChannel() == 50); + CHECK(segment.isOnChannel(50)); } - template<> template<> - void buffer_object_t::test<3>() + TEST_CASE("buffer: an LLSegment over data keeps its channel and data", "[buffer]") { 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))); + CHECK(segment.getChannel() == 30); + REQUIRE(segment.size() == len); + CHECK(segment.data() == (U8*)str); + CHECK_THAT(ll_test::Memory(segment.data(), segment.size()), ll_test::MemoryMatches((U8*)str, len)); + CHECK(segment.isOnChannel(channel)); } - template<> template<> - void buffer_object_t::test<4>() + TEST_CASE("buffer: LLHeapBuffer createSegment succeeds until the buffer is full", "[buffer]") { S32 channel = 50; S32 bigSize = 16384*2; @@ -94,40 +84,42 @@ namespace S32 requestSize; requestSize = 16384-1; - ensure("1. LLHeapBuffer createSegment failed", (true == buf.createSegment(channel, requestSize, segment)) && segment.size() == requestSize); + CHECK(buf.createSegment(channel, requestSize, segment)); + CHECK(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); + CHECK(buf.createSegment(channel, requestSize, segment)); + CHECK(segment.size() == requestSize); // it should fail now. requestSize = 1; - ensure("3. LLHeapBuffer createSegment failed", (false == buf.createSegment(channel, requestSize, segment))); + CHECK_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); + CHECK(buf1.createSegment(channel, requestSize, segment)); + CHECK(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); + CHECK(buf2.createSegment(channel, requestSize, segment)); + REQUIRE(segment.size() == requestSize); + CHECK(memcmp(segment.data(), (U8*) str, requestSize) == 0); requestSize = smallSize+1; - ensure("6. LLHeapBuffer createSegment failed", (false == buf2.createSegment(channel, requestSize, segment))); + CHECK_FALSE(buf2.createSegment(channel, requestSize, segment)); } - //makeChannelConsumer() - template<> template<> - void buffer_object_t::test<5>() + TEST_CASE("buffer: makeChannelConsumer reads the out channel of its producer", "[buffer]") { LLChannelDescriptors inchannelDescriptors(20); LLChannelDescriptors outchannelDescriptors = LLBufferArray::makeChannelConsumer(inchannelDescriptors); - ensure("LLBufferArray::makeChannelConsumer() function Failed", (21 == outchannelDescriptors.in())); + CHECK(outchannelDescriptors.in() == 21); } - template<> template<> - void buffer_object_t::test<6>() + TEST_CASE("buffer: countAfter counts the bytes appended to a channel", "[buffer]") { LLBufferArray bufferArray; const char array[] = "SecondLife"; @@ -135,12 +127,10 @@ namespace 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); + CHECK(count == len); } - //append() and prepend() - template<> template<> - void buffer_object_t::test<7>() + TEST_CASE("buffer: readAfter reads prepended data before appended data", "[buffer]") { LLBufferArray bufferArray; const char array[] = "SecondLife"; @@ -157,15 +147,13 @@ namespace char buf[100]; S32 len2 = 20; bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2); - ensure_equals("readAfter length failed", len2, 20); + CHECK(len2 == 20); buf[len2] = '\0'; - ensure_equals("readAfter/prepend/append failed", buf, str); + CHECK(buf == str); } - //append() - template<> template<> - void buffer_object_t::test<8>() + TEST_CASE("buffer: readAfter reads two appends in order", "[buffer]") { LLBufferArray bufferArray; const char array[] = "SecondLife"; @@ -182,14 +170,13 @@ namespace char buf[100]; S32 len2 = 20; bufferArray.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2); - ensure_equals("readAfter length failed", len2, 20); + CHECK(len2 == 20); buf[len2] = '\0'; - ensure_equals("readAfter/append/append failed", buf, str); + CHECK(buf == str); } - template<> template<> - void buffer_object_t::test<9>() + TEST_CASE("buffer: takeContents moves the data of another array", "[buffer]") { LLBufferArray bufferArray; const char array[] = "SecondLife"; @@ -198,17 +185,15 @@ namespace 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))); + REQUIRE(bufferArray1.takeContents(bufferArray) == 1); char buf[100]; S32 len2 = len; bufferArray1.readAfter(channelDescriptors.in(), NULL, (U8*)buf, len2); - ensure_equals("takeContents failed to copy", buf, str); + CHECK(buf == str); } - //seek() - template<> template<> - void buffer_object_t::test<10>() + TEST_CASE("buffer: seek moves back from where a read ended", "[buffer]") { const char array[] = "SecondLife is a Virtual World"; S32 len = static_cast(strlen(array)); @@ -225,11 +210,10 @@ namespace 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")); + CHECK(str == std::string("a Virtual World")); } - template<> template<> - void buffer_object_t::test<11>() + TEST_CASE("buffer: splitAfter starts a new segment after the address", "[buffer]") { const char array[] = "SecondLife is a Virtual World"; S32 len = static_cast(strlen(array)); @@ -243,32 +227,28 @@ namespace 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")); + CHECK(str == std::string(" is a Virtual World")); } - //makeSegment()->eraseSegment() - template<> template<> - void buffer_object_t::test<12>() + TEST_CASE("buffer: eraseSegment removes the segment makeSegment made", "[buffer]") { 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()); + REQUIRE(it != bufferArray.endSegment()); + CHECK(bufferArray.eraseSegment(it)); + CHECK(bufferArray.beginSegment() == bufferArray.endSegment()); } - // constructSegmentAfter() - template<> template<> - void buffer_object_t::test<13>() + TEST_CASE("buffer: constructSegmentAfter on an empty array returns endSegment", "[buffer]") { 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)); + CHECK(it == end); } } diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index d17f7730c4..9325d0ef28 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -39,7 +39,7 @@ #include #include -#include "../test/lltut.h" +#include #include "../test/sync.h" @@ -69,8 +69,6 @@ LLCore::HttpRequest::~HttpRequest() { } -namespace tut -{ namespace { struct coproceduremanager_test @@ -84,14 +82,9 @@ namespace LLCoprocedureManager::instance().close(); } }; - typedef test_group coproceduremanager_t; - typedef coproceduremanager_t::object coproceduremanager_object_t; - tut::coproceduremanager_t tut_coproceduremanager("LLCoprocedureManager"); -} - template<> template<> - void coproceduremanager_object_t::test<1>() + TEST_CASE_METHOD(coproceduremanager_test, "LLCoprocedureManager: an enqueued coprocedure runs in its pool", "[LLCoprocedureManager]") { Sync sync; int foo = 0; @@ -103,13 +96,12 @@ namespace }); sync.yield(); - ensure_equals("coprocedure failed to update foo", foo, 1); + CHECK(foo == 1); LLCoprocedureManager::instance().close("PoolName"); } - template<> template<> - void coproceduremanager_object_t::test<2>() + TEST_CASE_METHOD(coproceduremanager_test, "LLCoprocedureManager: a buffered channel hands a function to a fiber", "[LLCoprocedureManager]") { const size_t capacity = 2; boost::fibers::buffered_channel> chan(capacity); @@ -125,8 +117,7 @@ namespace worker.join(); } - template<> template<> - void coproceduremanager_object_t::test<3>() + TEST_CASE_METHOD(coproceduremanager_test, "LLCoprocedureManager: an unbuffered channel hands a function to a fiber", "[LLCoprocedureManager]") { boost::fibers::unbuffered_channel> chan; @@ -141,8 +132,7 @@ namespace worker.join(); } - template<> template<> - void coproceduremanager_object_t::test<4>() + TEST_CASE_METHOD(coproceduremanager_test, "LLCoprocedureManager: a worker fiber runs every function until its channel closes", "[LLCoprocedureManager]") { boost::fibers::buffered_channel> chan(4); @@ -178,6 +168,6 @@ namespace worker.join(); LL_INFOS("CoMain") << "checking count" << LL_ENDL; - ensure_equals("coprocedure failed to update counter", counter, 5); + CHECK(counter == 5); } -} // namespace tut +} // anonymous namespace diff --git a/indra/llmessage/tests/lldatapacker_test.cpp b/indra/llmessage/tests/lldatapacker_test.cpp index 2caeeb3fc8..cb8a508616 100644 --- a/indra/llmessage/tests/lldatapacker_test.cpp +++ b/indra/llmessage/tests/lldatapacker_test.cpp @@ -28,7 +28,9 @@ #include "linden_common.h" -#include "lltut.h" +#include +#include +#include "altestmatchers.h" #include "lldatapacker.h" #include "v4color.h" @@ -40,21 +42,10 @@ #include "../test/namedtempfile.h" -namespace tut -{ namespace { - struct datapacker_test - { - }; - typedef test_group 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>() + TEST_CASE("datapacker_test: LLDataPackerBinaryBuffer packFixed round-trips at three widths", "[datapacker_test]") { U8 packbuf[128]; F32 f_val1 = 44.44f, f_unpkval1; @@ -69,13 +60,15 @@ namespace 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); + UNSCOPED_INFO("8 fraction bits"); + CHECK_THAT(f_val1, ll_test::WithinBits(f_unpkval1, 8)); + UNSCOPED_INFO("16 fraction bits"); + CHECK_THAT(f_val2, ll_test::WithinBits(f_unpkval2, 16)); + UNSCOPED_INFO("23 fraction bits"); + CHECK_THAT(f_val3, ll_test::WithinBits(f_unpkval3, 31)); } - template<> template<> - void datapacker_test_object_t::test<2>() + TEST_CASE("datapacker_test: LLDataPackerBinaryBuffer round-trips every packed type", "[datapacker_test]") { U8 packbuf[1024]; @@ -146,24 +139,23 @@ namespace 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); + CHECK(std::string_view(str) == std::string_view(unpkstr.c_str())); + CHECK(std::string_view(strBinary) == std::string_view(unpkstrBinary)); + CHECK(std::string_view(strBinaryFixed) == std::string_view(unpkstrBinaryFixed)); + CHECK(valU8 == unpkvalU8); + CHECK(valU16 == unpkvalU16); + CHECK(valU32 == unpkvalU32); + CHECK(valS32 == unpkvalS32); + CHECK(is_approx_equal(valF32, unpkvalF32)); + CHECK(llcol4 == unpkllcol4); + CHECK(llcol4u == unpkllcol4u); + CHECK(llvec2 == unpkllvec2); + CHECK(llvec3 == unpkllvec3); + CHECK(llvec4 == unpkllvec4); + CHECK(uuid == unpkuuid); } - template<> template<> - void datapacker_test_object_t::test<3>() + TEST_CASE("datapacker_test: LLDataPackerBinaryBuffer sizes after packString and reset", "[datapacker_test]") { U8 packbuf[128]; char str[] = "SecondLife is virtual World"; @@ -171,27 +163,25 @@ namespace 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()); + CHECK(strSize == lldp.getCurrentSize()); + CHECK(lldp.getBufferSize() == 128); lldp.reset(); - ensure("LLDataPackerBinaryBuffer::reset failed",0 == lldp.getCurrentSize()); + CHECK(lldp.getCurrentSize() == 0); } - template<> template<> - void datapacker_test_object_t::test<4>() + TEST_CASE("datapacker_test: LLDataPackerBinaryBuffer freeBuffer leaves a zero buffer size", "[datapacker_test]") { 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()); + CHECK(lldp.getBufferSize() == 0); } - template<> template<> - void datapacker_test_object_t::test<5>() + TEST_CASE("datapacker_test: LLDataPackerBinaryBuffer assignBuffer takes the new size and rewinds", "[datapacker_test]") { U8* buf = new U8[]("SecondLife is virtual World"); S32 size = sizeof(buf); @@ -199,11 +189,11 @@ namespace U8* new_buf = new U8[]("Its Amazing"); size = sizeof(new_buf)-1; lldp.assignBuffer(new_buf, size); - ensure("LLDataPackerBinaryBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (0 == lldp.getCurrentSize()))) ; + CHECK(lldp.getBufferSize() == size); + CHECK(lldp.getCurrentSize() == 0); } - template<> template<> - void datapacker_test_object_t::test<6>() + TEST_CASE("datapacker_test: LLDataPackerBinaryBuffer operator= copies the packed buffer", "[datapacker_test]") { U8 packbuf[128]; char str[] = "SecondLife is virtual World"; @@ -214,14 +204,13 @@ namespace 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); + CHECK(lldp1.getBufferSize() == lldp.getBufferSize()); + CHECK(str == unpkbuf); } //*********LLDataPackerAsciiBuffer - template<> template<> - void datapacker_test_object_t::test<7>() + TEST_CASE("datapacker_test: LLDataPackerAsciiBuffer packFixed round-trips", "[datapacker_test]") { char packbuf[128]; F32 f_val = 44.44f, f_unpkval; @@ -230,11 +219,10 @@ namespace 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); + CHECK_THAT(f_val, ll_test::WithinBits(f_unpkval, 8)); } - template<> template<> - void datapacker_test_object_t::test<8>() + TEST_CASE("datapacker_test: LLDataPackerAsciiBuffer round-trips every packed type", "[datapacker_test]") { char packbuf[1024]; @@ -305,35 +293,33 @@ namespace 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); + CHECK(std::string_view(str) == std::string_view(unpkstr.c_str())); + CHECK(std::string_view(strBinary) == std::string_view(unpkstrBinary)); + CHECK(std::string_view(strBinaryFixed) == std::string_view(unpkstrBinaryFixed)); + CHECK(valU8 == unpkvalU8); + CHECK(valU16 == unpkvalU16); + CHECK(valU32 == unpkvalU32); + CHECK(valS32 == unpkvalS32); + CHECK(is_approx_equal(valF32, unpkvalF32)); + CHECK(llcol4 == unpkllcol4); + CHECK(llcol4u == unpkllcol4u); + CHECK(llvec2 == unpkllvec2); + CHECK(llvec3 == unpkllvec3); + CHECK(llvec4 == unpkllvec4); + CHECK(uuid == unpkuuid); } - template<> template<> - void datapacker_test_object_t::test<9>() + TEST_CASE("datapacker_test: LLDataPackerAsciiBuffer freeBuffer leaves a zero buffer size", "[datapacker_test]") { 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()); + CHECK(lldp.getBufferSize() == 0); } - template<> template<> - void datapacker_test_object_t::test<10>() + TEST_CASE("datapacker_test: LLDataPackerAsciiBuffer assignBuffer takes the new size and rewinds", "[datapacker_test]") { char buf[] = "SecondLife is virtual World"; S32 size = sizeof(buf); @@ -341,13 +327,13 @@ namespace char new_buf[] = "Its Amazing"; size = sizeof(new_buf); lldp.assignBuffer(new_buf, size); - ensure("LLDataPackerAsciiBuffer::assignBuffer failed" , ((lldp.getBufferSize() == size) && (1 == lldp.getCurrentSize()))) ; + CHECK(lldp.getBufferSize() == size); + CHECK(lldp.getCurrentSize() == 1); } //*********LLDataPackerAsciiFile - template<> template<> - void datapacker_test_object_t::test<11>() + TEST_CASE("datapacker_test: LLDataPackerAsciiFile packFixed round-trips through a file", "[datapacker_test]") { F32 f_val = 44.44f, f_unpkval; @@ -371,11 +357,10 @@ namespace lldp1.unpackFixed(f_unpkval, "linden_lab", false, 8, 8); fclose(fp); - ensure_approximately_equals("LLDataPackerAsciiFile::packFixed failed", f_val, f_unpkval, 8); + CHECK_THAT(f_val, ll_test::WithinBits(f_unpkval, 8)); } - template<> template<> - void datapacker_test_object_t::test<12>() + TEST_CASE("datapacker_test: LLDataPackerAsciiFile round-trips every packed type through a file", "[datapacker_test]") { char str[] = "SecondLife is virtual World\0"; char strBinary[] = "SecondLife is virtual World"; @@ -458,24 +443,23 @@ namespace 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); + CHECK(std::string_view(str) == std::string_view(unpkstr.c_str())); + CHECK(std::string_view(strBinary) == std::string_view(unpkstrBinary)); + CHECK(std::string_view(strBinaryFixed) == std::string_view(unpkstrBinaryFixed)); + CHECK(valU8 == unpkvalU8); + CHECK(valU16 == unpkvalU16); + CHECK(valU32 == unpkvalU32); + CHECK(valS32 == unpkvalS32); + CHECK(is_approx_equal(valF32, unpkvalF32)); + CHECK(llcol4 == unpkllcol4); + CHECK(llcol4u == unpkllcol4u); + CHECK(llvec2 == unpkllvec2); + CHECK(llvec3 == unpkllvec3); + CHECK(llvec4 == unpkllvec4); + CHECK(uuid == unpkuuid); } - template<> template<> - void datapacker_test_object_t::test<13>() + TEST_CASE("datapacker_test: LLDataPackerAsciiFile packFixed round-trips through string streams", "[datapacker_test]") { F32 f_val = 44.44f, f_unpkval; @@ -488,11 +472,10 @@ namespace lldp1.unpackFixed(f_unpkval, "linden_lab", false, 8, 8); - ensure_approximately_equals("LLDataPackerAsciiFile::packFixed (iostring) failed", f_unpkval, f_val, 8); + CHECK_THAT(f_unpkval, ll_test::WithinBits(f_val, 8)); } - template<> template<> - void datapacker_test_object_t::test<14>() + TEST_CASE("datapacker_test: LLDataPackerAsciiFile round-trips every type through string streams", "[datapacker_test]") { const char str[] = "SecondLife is virtual World"; const char strBinary[] = "SecondLife is virtual World"; @@ -563,24 +546,23 @@ namespace 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); + CHECK(std::string_view(str) == std::string_view(unpkstr.c_str())); + CHECK(std::string_view(strBinary) == std::string_view(unpkstrBinary)); + CHECK(std::string_view(strBinaryFixed) == std::string_view(unpkstrBinaryFixed)); + CHECK(valU8 == unpkvalU8); + CHECK(valU16 == unpkvalU16); + CHECK(valU32 == unpkvalU32); + CHECK(valS32 == unpkvalS32); + CHECK(is_approx_equal(valF32, unpkvalF32)); + CHECK(llcol4 == unpkllcol4); + CHECK(llcol4u == unpkllcol4u); + CHECK(llvec2 == unpkllvec2); + CHECK(llvec3 == unpkllvec3); + CHECK(llvec4 == unpkllvec4); + CHECK(uuid == unpkuuid); } - template<> template<> - void datapacker_test_object_t::test<15>() + TEST_CASE("datapacker_test: LLDataPackerAsciiBuffer refuses every read past the end", "[datapacker_test]") { // An ascii buffer that has run out says so. Every unpack in that class // comes through one place, and each one moves the cursor on by what it @@ -588,30 +570,33 @@ namespace // told yes while the cursor walked off the buffer. char buffer[128]; LLDataPackerAsciiBuffer writer(buffer, sizeof(buffer)); - ensure("packS32", writer.packS32(42, "first")); - ensure("packString", writer.packString("second", "second")); + CHECK(writer.packS32(42, "first")); + CHECK(writer.packString("second", "second")); const S32 written = writer.getCurrentSize(); LLDataPackerAsciiBuffer reader(buffer, written); S32 first = 0; std::string second; - ensure("the first field reads back", reader.unpackS32(first, "first")); - ensure_equals("and is what was written", first, 42); - ensure("the second field reads back", reader.unpackString(second, "second")); - ensure_equals("and is what was written", second, std::string("second")); + CHECK(reader.unpackS32(first, "first")); + CHECK(first == 42); + REQUIRE(reader.unpackString(second, "second")); + CHECK(second == std::string("second")); S32 past_the_end = 7; - ensure("a read past the end is refused", !reader.unpackS32(past_the_end, "third")); - ensure_equals("and leaves what it was handed alone", past_the_end, 7); + UNSCOPED_INFO("a read past the end is refused"); + CHECK_FALSE(reader.unpackS32(past_the_end, "third")); + UNSCOPED_INFO("and leaves its argument alone"); + CHECK(past_the_end == 7); std::string also_past = "untouched"; - ensure("and stays refused", !reader.unpackString(also_past, "fourth")); - ensure_equals("however many times it is asked", also_past, std::string("untouched")); + UNSCOPED_INFO("a second read past the end is refused too"); + CHECK_FALSE(reader.unpackString(also_past, "fourth")); + UNSCOPED_INFO("and leaves its argument alone too"); + CHECK(also_past == std::string("untouched")); } - template<> template<> - void datapacker_test_object_t::test<16>() + TEST_CASE("datapacker_test: LLDataPackerAsciiBuffer refuses the first read of an empty buffer", "[datapacker_test]") { // An empty buffer is refused from the first read rather than from the // second. @@ -619,7 +604,8 @@ namespace LLDataPackerAsciiBuffer reader(buffer, 0); S32 value = 11; - ensure("nothing to read", !reader.unpackS32(value, "anything")); - ensure_equals("and nothing was written", value, 11); + CHECK_FALSE(reader.unpackS32(value, "anything")); + UNSCOPED_INFO("the refused read leaves its argument alone"); + CHECK(value == 11); } } diff --git a/indra/llmessage/tests/llhost_test.cpp b/indra/llmessage/tests/llhost_test.cpp index 8f4214e8bb..805a096864 100644 --- a/indra/llmessage/tests/llhost_test.cpp +++ b/indra/llmessage/tests/llhost_test.cpp @@ -30,112 +30,96 @@ #include "../llhost.h" -#include "../test/lltut.h" +#include -namespace tut -{ namespace { - struct host_data - { - }; - typedef test_group host_test; - typedef host_test::object host_object; - tut::host_test host_testcase("LLHost"); -} - - template<> template<> - void host_object::test<1>() + TEST_CASE("LLHost: a default host is zero and not ok", "[LLHost]") { LLHost host; - ensure("IP address is not NULL", (0 == host.getAddress()) && (0 == host.getPort()) && !host.isOk()); + CHECK(host.getAddress() == 0); + CHECK(host.getPort() == 0); + CHECK_FALSE(host.isOk()); } - template<> template<> - void host_object::test<2>() + TEST_CASE("LLHost: constructing from an address and port sets both and is ok", "[LLHost]") { U32 ip_addr = 0xc098017d; U32 port = 8080; LLHost host(ip_addr, port); - ensure("IP address is invalid", ip_addr == host.getAddress()); - ensure("Port Number is invalid", port == host.getPort()); - ensure("IP address and port number both should be ok", host.isOk()); + CHECK(ip_addr == host.getAddress()); + CHECK(port == host.getPort()); + CHECK(host.isOk()); } - template<> template<> - void host_object::test<3>() + TEST_CASE("LLHost: constructing from a dotted string and port", "[LLHost]") { const char* str = "192.168.1.1"; U32 port = 8080; LLHost host(str, port); - ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str))); - ensure("Port Number is invalid", (port == host.getPort())); + CHECK(host.getAddress() == ip_string_to_u32(str)); + CHECK(port == host.getPort()); } - template<> template<> - void host_object::test<4>() + TEST_CASE("LLHost: constructing from a U64 packing address and port", "[LLHost]") { U32 ip = ip_string_to_u32("192.168.1.1"); U32 port = 22; U64 ip_port = (((U64) ip) << 32) | port; LLHost host(ip_port); - ensure("IP address is invalid", ip == host.getAddress()); - ensure("Port Number is invalid", port == host.getPort()); + CHECK(ip == host.getAddress()); + CHECK(port == host.getPort()); } - template<> template<> - void host_object::test<5>() + TEST_CASE("LLHost: constructing from an IP:port string", "[LLHost]") { std::string ip_port_string = "192.168.1.1:8080"; U32 ip = ip_string_to_u32("192.168.1.1"); U32 port = 8080; LLHost host(ip_port_string); - ensure("IP address from IP:port is invalid", ip == host.getAddress()); - ensure("Port Number from from IP:port is invalid", port == host.getPort()); + CHECK(ip == host.getAddress()); + CHECK(port == host.getPort()); } - template<> template<> - void host_object::test<6>() + TEST_CASE("LLHost: set takes an address and port", "[LLHost]") { U32 ip = 0xc098017d, port = 8080; LLHost host; host.set(ip,port); - ensure("IP address is invalid", (ip == host.getAddress())); - ensure("Port Number is invalid", (port == host.getPort())); + CHECK(ip == host.getAddress()); + CHECK(port == host.getPort()); } - template<> template<> - void host_object::test<7>() + TEST_CASE("LLHost: setAddress and setPort each change only their own part", "[LLHost]") { const char* str = "192.168.1.1"; U32 port = 8080, ip; LLHost host; host.set(str,port); ip = ip_string_to_u32(str); - ensure("IP address is invalid", (ip == host.getAddress())); - ensure("Port Number is invalid", (port == host.getPort())); + CHECK(ip == host.getAddress()); + CHECK(port == host.getPort()); str = "64.233.187.99"; ip = ip_string_to_u32(str); host.setAddress(str); - ensure("IP address is invalid", (ip == host.getAddress())); + CHECK(ip == host.getAddress()); ip = 0xc098017b; host.setAddress(ip); - ensure("IP address is invalid", (ip == host.getAddress())); + CHECK(ip == host.getAddress()); // should still use the old port - ensure("Port Number is invalid", (port == host.getPort())); + CHECK(port == host.getPort()); port = 8084; host.setPort(port); - ensure("Port Number is invalid", (port == host.getPort())); + CHECK(port == host.getPort()); // should still use the old address - ensure("IP address is invalid", (ip == host.getAddress())); + CHECK(ip == host.getAddress()); } - template<> template<> - void host_object::test<8>() + TEST_CASE("LLHost: getIPString and getIPandPort format the address", "[LLHost]") { const std::string str("192.168.1.1"); U32 port = 8080; @@ -143,18 +127,17 @@ namespace host.set(str,port); std::string ip_string = host.getIPString(); - ensure("Function Failed", (ip_string == str)); + CHECK(ip_string == str); std::string ip_string_port = host.getIPandPort(); - ensure("Function Failed", (ip_string_port == "192.168.1.1:8080")); + CHECK(ip_string_port == "192.168.1.1:8080"); } // getHostName() and setHostByName - template<> template<> - void host_object::test<9>() + TEST_CASE("LLHost: getHostName reports the name given to setHostByName", "[LLHost]") { - skip("this test is irreparably flaky"); + SKIP("this test is irreparably flaky"); // skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\""); // nat: is it reasonable to expect LLHost::getHostName() to echo // back something resembling the string passed to setHostByName()? @@ -187,7 +170,8 @@ namespace std::string hostname = host.getHostName(); try { - ensure("getHostName failed", hostname.find(hostStr) != std::string::npos); + UNSCOPED_INFO("getHostName failed"); + REQUIRE(hostname.find(hostStr) != std::string::npos); } catch (const std::exception&) { @@ -197,32 +181,29 @@ namespace } // setHostByName for dotted IP - template<> template<> - void host_object::test<10>() + TEST_CASE("LLHost: setHostByName takes a dotted IP address", "[LLHost]") { std::string hostStr = "64.233.167.99"; LLHost host; host.setHostByName(hostStr); - ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str())); + CHECK(host.getAddress() == ip_string_to_u32(hostStr.c_str())); } - template<> template<> - void host_object::test<11>() + TEST_CASE("LLHost: a copy keeps address and port", "[LLHost]") { LLHost host1(0xc098017d, 8080); LLHost host2 = host1; - ensure("Both IP addresses are not same", (host1.getAddress() == host2.getAddress())); - ensure("Both port numbers are not same", (host1.getPort() == host2.getPort())); + CHECK(host1.getAddress() == host2.getAddress()); + CHECK(host1.getPort() == host2.getPort()); } - template<> template<> - void host_object::test<12>() + TEST_CASE("LLHost: operator<< writes IP:port", "[LLHost]") { LLHost host1("192.168.1.1", 8080); std::string str1 = "192.168.1.1:8080"; std::ostringstream stream; stream << host1; - ensure("Operator << failed", ( stream.str()== str1)); + CHECK(stream.str()== str1); // There is no istream >> llhost operator. //std::istringstream is(stream.str()); @@ -232,43 +213,44 @@ namespace } // operators ==, !=, < - template<> template<> - void host_object::test<13>() + TEST_CASE("LLHost: == and != and < compare address and port", "[LLHost]") { U32 ip_addr = 0xc098017d; U32 port = 8080; LLHost host1(ip_addr, port); LLHost host2(ip_addr, port); - ensure("operator== failed", host1 == host2); + CHECK(host1 == host2); // change port host2.setPort(7070); - ensure("operator!= failed", host1 != host2); + CHECK(host1 != host2); // set port back to 8080 and change IP address now host2.setPort(8080); host2.setAddress(ip_addr+10); - ensure("operator!= failed", host1 != host2); + CHECK(host1 != host2); - ensure("operator< failed", host1 < host2); + CHECK(host1 < host2); // set IP address back to same value and change port host2.setAddress(ip_addr); host2.setPort(host1.getPort() + 10); - ensure("operator< failed", host1 < host2); + CHECK(host1 < host2); } // invalid ip address string - template<> template<> - void host_object::test<14>() + TEST_CASE("LLHost: isOk tells valid address strings from invalid ones", "[LLHost]") { LLHost host1("10.0.1.2", 6143); - ensure("10.0.1.2 should be a valid address", host1.isOk()); + UNSCOPED_INFO("10.0.1.2 is a valid address"); + CHECK(host1.isOk()); LLHost host2("booger-brains", 6143); - ensure("booger-brains should be an invalid ip addess", !host2.isOk()); + UNSCOPED_INFO("booger-brains is not an address"); + CHECK_FALSE(host2.isOk()); LLHost host3("255.255.255.255", 6143); - ensure("255.255.255.255 should be valid broadcast address", host3.isOk()); + UNSCOPED_INFO("255.255.255.255 is the valid broadcast address"); + CHECK(host3.isOk()); } } diff --git a/indra/llmessage/tests/llhttpnode_test.cpp b/indra/llmessage/tests/llhttpnode_test.cpp index a6c0f3da63..b38192eb22 100644 --- a/indra/llmessage/tests/llhttpnode_test.cpp +++ b/indra/llmessage/tests/llhttpnode_test.cpp @@ -26,12 +26,12 @@ */ #include "linden_common.h" -#include "lltut.h" +#include +#include +#include "altestmatchers.h" #include "llhttpnode.h" #include "llsdhttpserver.h" -namespace tut -{ namespace { struct HTTPNodeTestData @@ -59,7 +59,7 @@ namespace return pathOutput.str(); } - void ensureRootTraversal(const std::string& path, + void require_root_traversal(const std::string& path, const LLHTTPNode* expectedNode, const char* expectedRemainder) { @@ -67,10 +67,9 @@ namespace const LLHTTPNode* actualNode = mRoot.traverse(path, mContext); - ensure_equals("traverse " + path + " node", - actualNode, expectedNode); - ensure_equals("traverse " + path + " remainder", - remainderPath(), expectedRemainder); + INFO("traverse " << path); + REQUIRE(actualNode == expectedNode); + REQUIRE(remainderPath() == expectedRemainder); } class Response : public LLHTTPNode::Response @@ -95,7 +94,8 @@ namespace { mContext.clear(); const LLHTTPNode* node = mRoot.traverse(path, mContext); - ensure(path + " found", node != NULL); + CAPTURE(path); + REQUIRE(node != NULL); ResponsePtr response = Response::create(); node->get(LLHTTPNode::ResponsePtr(response), mContext); @@ -106,23 +106,24 @@ namespace { mContext.clear(); const LLHTTPNode* node = mRoot.traverse(path, mContext); - ensure(path + " found", node != NULL); + CAPTURE(path); + REQUIRE(node != NULL); ResponsePtr response = Response::create(); node->post(LLHTTPNode::ResponsePtr(response), mContext, input); return response->mResult; } - void ensureMemberString(const std::string& name, + void require_member_string(const std::string& name, const LLSD& actualMap, const std::string& member, const std::string& expectedValue) { - ensure_equals(name + " " + member, - actualMap[member].asString(), expectedValue); + CAPTURE(name, member); + REQUIRE(actualMap[member].asString() == expectedValue); } - void ensureInArray(const LLSD& actualArray, + void require_in_array(const LLSD& actualArray, const std::string& expectedValue) { LLSD::array_const_iterator i = actualArray.beginArray(); @@ -138,49 +139,42 @@ namespace } } - fail("didn't find " + expectedValue); + FAIL("didn't find " + expectedValue); } }; - typedef test_group HTTPNodeTestGroup; - typedef HTTPNodeTestGroup::object HTTPNodeTestObject; - HTTPNodeTestGroup httpNodeTestGroup("http node"); -} - template<> template<> - void HTTPNodeTestObject::test<1>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: a lone root matches only an empty path and is its own root", "[http_node]") { // traversal of the lone node - ensureRootTraversal("", &mRoot, ""); - ensureRootTraversal("/", &mRoot, ""); - ensureRootTraversal("foo", NULL, "foo"); - ensureRootTraversal("foo/bar", NULL, "foo/bar"); + require_root_traversal("", &mRoot, ""); + require_root_traversal("/", &mRoot, ""); + require_root_traversal("foo", NULL, "foo"); + require_root_traversal("foo/bar", NULL, "foo/bar"); - ensure_equals("root of root", mRoot.rootNode(), &mRoot); + CHECK(mRoot.rootNode() == &mRoot); } - template<> template<> - void HTTPNodeTestObject::test<2>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: a child node matches its name with or without slashes", "[http_node]") { // 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, ""); + require_root_traversal("hello", helloNode, ""); + require_root_traversal("/hello", helloNode, ""); + require_root_traversal("hello/", helloNode, ""); + require_root_traversal("/hello/", helloNode, ""); - ensureRootTraversal("hello/there", NULL, "there"); + require_root_traversal("hello/there", NULL, "there"); - ensure_equals("root of hello", helloNode->rootNode(), &mRoot); + CHECK(helloNode->rootNode() == &mRoot); } - template<> template<> - void HTTPNodeTestObject::test<3>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: traversal finds each leaf of a multi-branched tree", "[http_node]") { // traversal of mutli-branched tree @@ -200,22 +194,21 @@ namespace 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); + require_root_traversal("greek/alpha", alphaNode, ""); + require_root_traversal("greek/beta", betaNode, ""); + require_root_traversal("greek/delta", NULL, "delta"); + require_root_traversal("greek/gamma", gammaNode, ""); + require_root_traversal("hebrew/aleph", alephNode, ""); + + CHECK(greekNode->rootNode() == &mRoot); + CHECK(alphaNode->rootNode() == &mRoot); + CHECK(betaNode->rootNode() == &mRoot); + CHECK(gammaNode->rootNode() == &mRoot); + CHECK(hebrewNode->rootNode() == &mRoot); + CHECK(alephNode->rootNode() == &mRoot); } - template<> template<> - void HTTPNodeTestObject::test<4>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: addNode creates parents and keeps an existing node", "[http_node]") { // automatic creation of parent nodes and not overriding existing nodes @@ -234,20 +227,18 @@ namespace 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, ""); + require_root_traversal("greek/alpha", alphaNode, ""); + require_root_traversal("greek/beta", betaNode, ""); + require_root_traversal("greek/delta", NULL, "delta"); + require_root_traversal("greek/gamma", gammaNode, ""); + require_root_traversal("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); + CHECK(alphaNode->rootNode() == &mRoot); + CHECK(betaNode->rootNode() == &mRoot); + CHECK(gammaNode->rootNode() == &mRoot); + CHECK(alephNode->rootNode() == &mRoot); } -namespace -{ class IntegerNode : public LLHTTPNode { public: @@ -289,10 +280,8 @@ namespace response->result(n*n); } }; -} - template<> template<> - void HTTPNodeTestObject::test<5>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: a wildcard node validates its path element and stores it", "[http_node]") { // wildcard nodes @@ -304,22 +293,18 @@ namespace mRoot.addNode("test/", iNode); mRoot.addNode("test//square", sqNode); - ensureRootTraversal("test/42", iNode, ""); - ensure_equals("stored integer", - context()["extra"]["value"].asInteger(), 42); + require_root_traversal("test/42", iNode, ""); + CHECK(context()["extra"]["value"].asInteger() == 42); - ensureRootTraversal("test/bob", NULL, "bob"); - ensure("nothing stored", - context()["extra"]["value"].isUndefined()); + require_root_traversal("test/bob", NULL, "bob"); + CHECK(context()["extra"]["value"].isUndefined()); - ensureRootTraversal("test/3/square", sqNode, ""); + require_root_traversal("test/3/square", sqNode, ""); ResponsePtr response = Response::create(); sqNode->get(LLHTTPNode::ResponsePtr(response), context()); - ensure_equals("square result", response->mResult.asInteger(), 9); + CHECK(response->mResult.asInteger() == 9); } -namespace -{ class AlphaNode : public LLHTTPNode { public: @@ -340,10 +325,8 @@ namespace return true; } }; -} - template<> template<> - void HTTPNodeTestObject::test<6>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: a node that handles remainders takes the paths it accepts", "[http_node]") { // nodes that handle remainders @@ -355,16 +338,15 @@ namespace 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, ""); + require_root_traversal("test/alpha", aNode, ""); + require_root_traversal("test/alpha/abe", aNode, "abe"); + require_root_traversal("test/alpha/abe/amy", aNode, "abe/amy"); + require_root_traversal("test/alpha/abe/bea", NULL, "abe/bea"); + require_root_traversal("test/alpha/bob", NULL, "bob"); + require_root_traversal("test/alpha/zebra", zNode, ""); } - template<> template<> - void HTTPNodeTestObject::test<7>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: standard services answer web/hello and web/echo", "[http_node]") { // test auto registration @@ -373,17 +355,16 @@ namespace { LLSD result = get("web/hello"); - ensure_equals("hello result", result.asString(), "hello"); + CHECK(result.asString() == "hello"); } { LLSD stuff = 3.14159; LLSD result = post("web/echo", stuff); - ensure_equals("echo result", result, stuff); + CHECK_THAT(result, ll_test::LLSDEquals(stuff)); } } - template<> template<> - void HTTPNodeTestObject::test<8>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: web/server/api lists the registered paths", "[http_node]") { // test introspection @@ -395,18 +376,17 @@ namespace const LLSD result = get("web/server/api"); - ensure("result is array", result.isArray()); - ensure("result size", result.size() >= 2); + REQUIRE(result.isArray()); + REQUIRE(result.size() >= 2); - ensureInArray(result, "web/echo"); - ensureInArray(result, "web/hello"); - ensureInArray(result, "test/misc"); - ensureInArray(result, "test/"); - ensureInArray(result, "test//square"); + require_in_array(result, "web/echo"); + require_in_array(result, "web/hello"); + require_in_array(result, "test/misc"); + require_in_array(result, "test/"); + require_in_array(result, "test//square"); } - template<> template<> - void HTTPNodeTestObject::test<9>() + TEST_CASE_METHOD(HTTPNodeTestData, "http node: web/server/api describes web/hello and web/echo", "[http_node]") { // test introspection details @@ -414,24 +394,20 @@ namespace 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()); + CHECK_THAT(helloDetails["description"].asString(), Catch::Matchers::ContainsSubstring("hello")); + CHECK(helloDetails["api"][0].asString() == std::string("GET")); + require_member_string("hello", helloDetails, "output", "\"hello\""); + CHECK_THAT(helloDetails["__file__"].asString(), Catch::Matchers::ContainsSubstring("llsdhttpserver.cpp")); + CHECK(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", ""); - ensureMemberString("echo", echoDetails, "output", ""); - ensure_contains("echo __file__", - echoDetails["__file__"].asString(), "llsdhttpserver.cpp"); - ensure("echo", echoDetails["__line__"].isInteger()); + CHECK_THAT(echoDetails["description"].asString(), Catch::Matchers::ContainsSubstring("echo")); + CHECK(echoDetails["api"][0].asString() == std::string("POST")); + require_member_string("echo", echoDetails, "input", ""); + require_member_string("echo", echoDetails, "output", ""); + CHECK_THAT(echoDetails["__file__"].asString(), Catch::Matchers::ContainsSubstring("llsdhttpserver.cpp")); + CHECK(echoDetails["__line__"].isInteger()); } } diff --git a/indra/llmessage/tests/llmessage_test_checks.cpp b/indra/llmessage/tests/llmessage_test_checks.cpp new file mode 100644 index 0000000000..3e5d0ef3ed --- /dev/null +++ b/indra/llmessage/tests/llmessage_test_checks.cpp @@ -0,0 +1,63 @@ +/** + * @file llmessage_test_checks.cpp + * @brief The state guard's checks on what llmessage keeps for the process. + * + * $LicenseInfo:firstyear=2026&license=viewerlgpl$ + * Alchemy Viewer Source Code + * Copyright (C) 2026, Rye + * + * 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 + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "alteststateguard.h" +#include "llproxy.h" +#include "message.h" + +#include +#include + +#include +#include + +namespace +{ + class LLMessageChecks : public Catch::EventListenerBase + { + public: + using Catch::EventListenerBase::EventListenerBase; + + void testRunStarting(Catch::TestRunInfo const&) override + { + // A case that makes a message system of its own puts the one + // before it back: one left in place is what every later case + // sends through. + ll_test::StateGuard::add("gMessageSystem", + [] + { + std::ostringstream out; + out << static_cast(static_cast(gMessageSystem)); + return out.str(); + }); + // A case that sets curl up ends with the proxy cleaned up. + ll_test::StateGuard::add("the LLProxy", + [] { return std::string(LLProxy::instanceExists() ? "made" : "none"); }); + } + }; +} + +CATCH_REGISTER_LISTENER(LLMessageChecks) diff --git a/indra/llmessage/tests/llmessageconfig_test.cpp b/indra/llmessage/tests/llmessageconfig_test.cpp index d886d248a4..639bb07720 100644 --- a/indra/llmessage/tests/llmessageconfig_test.cpp +++ b/indra/llmessage/tests/llmessageconfig_test.cpp @@ -27,15 +27,13 @@ #include "linden_common.h" #include "llmessageconfig.h" -#include "lltut.h" +#include #include "llsdserialize.h" #include "llfile.h" #include "lltimer.h" #include "llframetimer.h" #include "llsdutil.h" -namespace tut -{ namespace { struct LLMessageConfigTestData { @@ -85,25 +83,17 @@ namespace } }; - typedef test_group LLMessageConfigTestGroup; - typedef LLMessageConfigTestGroup::object LLMessageConfigTestObject; - LLMessageConfigTestGroup llMessageConfigTestGroup("LLMessageConfig"); -} - template<> template<> - void LLMessageConfigTestObject::test<1>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: serverDefaults sets the server default flavor", "[LLMessageConfig]") // 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); + CHECK(LLMessageConfig::getServerDefaultFlavor() == LLMessageConfig::TEMPLATE_FLAVOR); } - template<> template<> - void LLMessageConfigTestObject::test<2>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: each message takes the flavor its entry names", "[LLMessageConfig]") // tests message flavors { LLSD config; @@ -111,35 +101,11 @@ namespace 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); + CHECK(LLMessageConfig::getMessageFlavor("msg1") == LLMessageConfig::TEMPLATE_FLAVOR); + CHECK(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>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: trusted-sender sets a message's sender trustedness", "[LLMessageConfig]") // tests trusted/untrusted senders { LLSD config; @@ -149,50 +115,48 @@ namespace 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); + CHECK(LLMessageConfig::getSenderTrustedness("msg1") == LLMessageConfig::UNTRUSTED); + CHECK(LLMessageConfig::getSenderTrustedness("msg2") == LLMessageConfig::TRUSTED); + UNSCOPED_INFO("a message not in the config"); + CHECK(LLMessageConfig::getSenderTrustedness("msg3") == LLMessageConfig::NOT_SET); + } + + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: a message with no flavor entry has NO_FLAVOR", "[LLMessageConfig]") + // tests message flavor defaults + { + LLSD config; + config["serverDefaults"]["simulator"] = "llsd"; + config["messages"]["msg1"]["trusted-sender"] = true; + LLMessageConfig::useConfig(config); + UNSCOPED_INFO("a message not in the config"); + CHECK(LLMessageConfig::getMessageFlavor("Test") == LLMessageConfig::NO_FLAVOR); + UNSCOPED_INFO("a message with only its sender trustedness set"); + CHECK(LLMessageConfig::getMessageFlavor("msg1") == LLMessageConfig::NO_FLAVOR); + CHECK(LLMessageConfig::getServerDefaultFlavor() == LLMessageConfig::LLSD_FLAVOR); } - template<> template<> - void LLMessageConfigTestObject::test<5>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: a message with only a flavor has trustedness NOT_SET", "[LLMessageConfig]") // 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); + CHECK(LLMessageConfig::getMessageFlavor("msg1") == LLMessageConfig::LLSD_FLAVOR); + CHECK(LLMessageConfig::getSenderTrustedness("msg1") == LLMessageConfig::NOT_SET); } - template<> template<> - void LLMessageConfigTestObject::test<6>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: capBans says which caps are banned", "[LLMessageConfig]") { 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); + CHECK(LLMessageConfig::isCapBanned("MapLayer")); + CHECK_FALSE(LLMessageConfig::isCapBanned("MapLayerGod")); } - template<> template<> - void LLMessageConfigTestObject::test<7>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: a changed config file is reloaded after a wait", "[LLMessageConfig]") // tests that config changes are picked up/refreshed periodically { LLSD config; @@ -202,13 +166,10 @@ namespace // 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); + CHECK(LLMessageConfig::getServerDefaultFlavor() == LLMessageConfig::LLSD_FLAVOR); } - template<> template<> - void LLMessageConfigTestObject::test<8>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: only-send-latest sets onlySendLatest per message", "[LLMessageConfig]") // tests that config changes are picked up/refreshed periodically { LLSD config; @@ -218,28 +179,39 @@ namespace 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); + CHECK(LLMessageConfig::onlySendLatest("msg1")); + CHECK_FALSE(LLMessageConfig::onlySendLatest("msg2")); } - template<> template<> - void LLMessageConfigTestObject::test<9>() + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: maxQueuedEvents is read from the config and defaults to 100", "[LLMessageConfig]") // tests that event queue max is reloaded { LLSD config; config["maxQueuedEvents"] = 200; LLMessageConfig::useConfig(config); - ensure_equals("Ensure setting maxQueuedEvents", - LLMessageConfig::getMaxQueuedEvents(), - 200); + CHECK(LLMessageConfig::getMaxQueuedEvents() == 200); LLMessageConfig::useConfig(LLSD()); - ensure_equals("Ensure default of event queue max 100", - LLMessageConfig::getMaxQueuedEvents(), - 100); + CHECK(LLMessageConfig::getMaxQueuedEvents() == 100); + } + + TEST_CASE_METHOD(LLMessageConfigTestData, "LLMessageConfig: initClass with another directory reads that directory's file", "[LLMessageConfig]") + // initClass with another directory reads that directory's file + { + const std::string other_dir = mTestConfigDir + "-other"; + LLFile::mkdir(other_dir); + LLSD config; + config["serverDefaults"]["simulator"] = "llsd"; + { + llofstream file((other_dir + "/message.xml").c_str()); + LLSDSerialize::toPrettyXML(config, file); + } + + // The fixture named its own directory, whose file holds nothing. + LLMessageConfig::initClass("simulator", other_dir); + const LLMessageConfig::Flavor flavor = LLMessageConfig::getServerDefaultFlavor(); + LLFile::remove(other_dir + "/message.xml"); + LLFile::remove(other_dir); + CHECK(flavor == LLMessageConfig::LLSD_FLAVOR); } } diff --git a/indra/llmessage/tests/llmessagesystem_fixture.h b/indra/llmessage/tests/llmessagesystem_fixture.h index 6e2b589290..2c50241d07 100644 --- a/indra/llmessage/tests/llmessagesystem_fixture.h +++ b/indra/llmessage/tests/llmessagesystem_fixture.h @@ -56,17 +56,10 @@ namespace ll_test ~MessageSystemScope() { - LLMessageSystem* system = gMessageSystem; - // Without its template the system is not OK, and a system that is - // not OK leaves its socket open when it is deleted, so the scope - // closes it. A socket that never opened is still 0. - if (system && !system->isOK() && system->mSocket > 0) - { - end_net(system->mSocket); - } - // Not end_messaging_system(): a system that is not OK never - // started the transfer manager that would end. - delete system; + // Not end_messaging_system(): a system that is not OK, as one + // without its template is, never started the transfer manager + // that would end. Deleting it closes its socket. + delete gMessageSystem; gMessageSystem = mPrior; } diff --git a/indra/llmessage/tests/llmessagetemplateparser_test.cpp b/indra/llmessage/tests/llmessagetemplateparser_test.cpp index 3c963955d4..082c30b1f4 100644 --- a/indra/llmessage/tests/llmessagetemplateparser_test.cpp +++ b/indra/llmessage/tests/llmessagetemplateparser_test.cpp @@ -27,14 +27,12 @@ #include "linden_common.h" #include "llmessagetemplateparser.h" -#include "lltut.h" +#include -namespace tut -{ namespace { struct LLMessageTemplateParserTestData { - LLMessageTemplateParserTestData() : mMessage("unset message") + LLMessageTemplateParserTestData() { } @@ -42,13 +40,14 @@ namespace { } - void ensure_next(LLTemplateTokenizer & tokens, - std::string value, - U32 line) + void require_next(LLTemplateTokenizer & tokens, + std::string value, + U32 line) { + CAPTURE(value); std::string next = tokens.next(); - ensure_equals(mMessage + " token matches", next, value); - ensure_equals(mMessage + " line matches", tokens.line(), line); + REQUIRE(next == value); + REQUIRE(tokens.line() == line); } char * prehash(const char * name) @@ -56,110 +55,99 @@ namespace 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) + void require_block_attributes(const 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); + INFO(identifier << ":" << message->mName << ":" << name << " block"); + REQUIRE(block != NULL); + REQUIRE(block->mName == prehash(name)); + REQUIRE(block->mType == type); + REQUIRE(block->mNumber == number); + REQUIRE(block->mTotalSize == total_size); } - void ensure_variable_attributes(std::string identifier, - const LLMessageBlock * block, - const char * name, - EMsgVariableType type, - S32 size) + void require_variable_attributes(const 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); + INFO(identifier << ":" << block->mName << ":" << name << " variable"); + REQUIRE(var != NULL); + REQUIRE(var->getName() == prehash(name)); + REQUIRE(var->getType() == type); + REQUIRE(var->getSize() == size); } - std::string mMessage; - }; - typedef test_group LLMessageTemplateParserTestGroup; - typedef LLMessageTemplateParserTestGroup::object LLMessageTemplateParserTestObject; - LLMessageTemplateParserTestGroup llMessageTemplateParserTestGroup("LLMessageTemplateParser"); -} - template<> template<> - void LLMessageTemplateParserTestObject::test<1>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: tokenizer next walks the tokens and counts lines", "[LLMessageTemplateParser]") // 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); + require_next(tokens, "first", 1); + require_next(tokens, "line", 1); + require_next(tokens, "next", 2); + require_next(tokens, "line", 2); + require_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("}")); + CHECK(tokens.want("{")); + require_next(tokens, "Test1", 2); + require_next(tokens, "Fixed", 2); + require_next(tokens, "523", 3); + CHECK(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")); + CHECK(tokens.want("first")); + require_next(tokens, "line", 1); + require_next(tokens, "next", 2); + require_next(tokens, "line", 2); + CHECK(tokens.want("fourth")); } - template<> template<> - void LLMessageTemplateParserTestObject::test<2>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: tokenizer want consumes only a matching token", "[LLMessageTemplateParser]") // 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); + CHECK(tokens.want("first")); + CHECK_FALSE(tokens.want("blar")); + CHECK(tokens.want("line")); } - template<> template<> - void LLMessageTemplateParserTestObject::test<3>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: tokenizer is at EOF only once wantEOF steps past the end", "[LLMessageTemplateParser]") // 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); + UNSCOPED_INFO("at the start"); + CHECK_FALSE(tokens.atEOF()); + CHECK_FALSE(tokens.wantEOF()); + UNSCOPED_INFO("wants the first token just to consume it"); + CHECK(tokens.want("single")); + UNSCOPED_INFO("on the last token"); + CHECK_FALSE(tokens.atEOF()); + CHECK(tokens.wantEOF()); + CHECK(tokens.atEOF()); } - template<> template<> - void LLMessageTemplateParserTestObject::test<4>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: parseVariable reads the name and type and size", "[LLMessageTemplateParser]") // 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); + REQUIRE(var != 0); + CHECK(std::string(var->getName()) == std::string("Test0")); + CHECK(var->getType() == MVT_U32); + CHECK(var->getSize() == 4); delete var; @@ -167,10 +155,10 @@ namespace 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); + REQUIRE(var != 0); + CHECK(std::string(var->getName()) == std::string("Test1")); + CHECK(var->getType() == MVT_FIXED); + CHECK(var->getSize() == 523); delete var; @@ -178,58 +166,52 @@ namespace // test that :-( } - template<> template<> - void LLMessageTemplateParserTestObject::test<5>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: parseBlock reads Single and Variable and Multiple blocks", "[LLMessageTemplateParser]") // 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); + REQUIRE(block != 0); + CHECK(std::string(block->mName) == std::string("BlockA")); + CHECK(block->mType == MBT_SINGLE); + CHECK(block->mTotalSize == 4); + UNSCOPED_INFO("the number defaults to 1"); + CHECK(block->mNumber == 1); + CHECK(block->getVariableType(prehash("VarX")) == MVT_F32); + CHECK(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); + REQUIRE(block != 0); + CHECK(std::string(block->mName) == std::string("Stuff")); + CHECK(block->mType == MBT_VARIABLE); + CHECK(block->mTotalSize == 16); + UNSCOPED_INFO("the number defaults to 1"); + CHECK(block->mNumber == 1); + CHECK(block->getVariableType(prehash("Id")) == MVT_LLUUID); + CHECK(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); + REQUIRE(block != 0); + CHECK(std::string(block->mName) == std::string("Stuff2")); + CHECK(block->mType == MBT_MULTIPLE); + CHECK(block->mTotalSize == 24); + CHECK(block->mNumber == 45); + CHECK(block->getVariableType(prehash("Shid")) == MVT_LLVector3d); + CHECK(block->getVariableSize(prehash("Shid")) == 24); delete block; } - template<> template<> - void LLMessageTemplateParserTestObject::test<6>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: parseMessage reads the header of a simple message", "[LLMessageTemplateParser]") // tests message parsing method on a simple message { std::string message_skel( @@ -250,22 +232,21 @@ namespace 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); + REQUIRE(message != 0); + CHECK(std::string(message->mName) == std::string("TestMessage")); + CHECK(message->mFrequency == MFT_LOW); + CHECK(message->mTrust == MT_NOTRUST); + CHECK(message->mMessageNumber == (U32)((255 << 24) | (255 << 16) | 1)); + CHECK(message->mEncoding == ME_ZEROCODED); + CHECK(message->mDeprecation == MD_NOTDEPRECATED); LLMessageBlock * block = message->getBlock(prehash("NonexistantBlock")); - ensure("Nonexistant block does not exist", block == 0); + CHECK(block == 0); delete message; } - template<> template<> - void LLMessageTemplateParserTestObject::test<7>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: parseMessage reads a deprecated message", "[LLMessageTemplateParser]") // tests message parsing method on a deprecated message { std::string message_skel( @@ -279,18 +260,18 @@ namespace 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); + REQUIRE(message != 0); + CHECK(std::string(message->mName) == std::string("TestMessageDeprecated")); + CHECK(message->mFrequency == MFT_HIGH); + CHECK(message->mTrust == MT_TRUST); + CHECK(message->mMessageNumber == (U32)34); + CHECK(message->mEncoding == ME_UNENCODED); + CHECK(message->mDeprecation == MD_DEPRECATED); delete message; } - template<> template<> void LLMessageTemplateParserTestObject::test<8>() + TEST_CASE_METHOD(LLMessageTemplateParserTestData, "LLMessageTemplateParser: parseMessage reads RezMultipleAttachmentsFromInv in full", "[LLMessageTemplateParser]") // tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message { std::string message_skel( @@ -324,44 +305,44 @@ namespace 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); + REQUIRE(message != 0); + CHECK(message->mName == prehash("RezMultipleAttachmentsFromInv")); + CHECK(message->mFrequency == MFT_LOW); + CHECK(message->mTrust == MT_NOTRUST); + CHECK(message->mMessageNumber == (U32)((255 << 24) | (255 << 16) | 452)); + CHECK(message->mEncoding == ME_ZEROCODED); - ensure_block_attributes( + require_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); + require_variable_attributes("RMAFI", + block, "AgentID", MVT_LLUUID, 16); + require_variable_attributes("RMAFI", + block, "SessionID", MVT_LLUUID, 16); - ensure_block_attributes( + require_block_attributes( "RMAFI", message, "HeaderData", MBT_SINGLE, 1, 16+1+1); block = message->getBlock(prehash("HeaderData")); - ensure_variable_attributes( + require_variable_attributes( "RMAFI", block, "CompoundMsgID", MVT_LLUUID, 16); - ensure_variable_attributes( + require_variable_attributes( "RMAFI", block, "TotalObjects", MVT_U8, 1); - ensure_variable_attributes( + require_variable_attributes( "RMAFI", block, "FirstDetachAll", MVT_BOOL, 1); - ensure_block_attributes( + require_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); + require_variable_attributes("RMAFI", block, "ItemID", MVT_LLUUID, 16); + require_variable_attributes("RMAFI", block, "OwnerID", MVT_LLUUID, 16); + require_variable_attributes("RMAFI", block, "AttachmentPt", MVT_U8, 1); + require_variable_attributes("RMAFI", block, "ItemFlags", MVT_U32, 4); + require_variable_attributes("RMAFI", block, "GroupMask", MVT_U32, 4); + require_variable_attributes("RMAFI", block, "EveryoneMask", MVT_U32, 4); + require_variable_attributes("RMAFI", block, "NextOwnerMask", MVT_U32, 4); + require_variable_attributes("RMAFI", block, "Name", MVT_VARIABLE, 1); + require_variable_attributes("RMAFI", block, "Description", MVT_VARIABLE, 1); delete message; } diff --git a/indra/llmessage/tests/llnamevalue_test.cpp b/indra/llmessage/tests/llnamevalue_test.cpp index c06abd41c9..d031585ee9 100644 --- a/indra/llmessage/tests/llnamevalue_test.cpp +++ b/indra/llmessage/tests/llnamevalue_test.cpp @@ -31,7 +31,8 @@ #include "../llnamevalue.h" -#include "../test/lltut.h" +#include +#include #if LL_WINDOWS @@ -39,8 +40,6 @@ #pragma warning(disable: 4702) #endif -namespace tut -{ namespace { struct namevalue_test @@ -49,21 +48,16 @@ namespace { } }; - typedef test_group namevalue_t; - typedef namevalue_t::object namevalue_object_t; - tut::namevalue_t tut_namevalue("LLNameValue"); -} - template<> template<> - void namevalue_object_t::test<1>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: the default constructor leaves the name and enums null", "[LLNameValue]") { // LLNameValue() LLNameValue nValue; - ensure("mName should have been NULL", nValue.mName == NULL); - ensure("getTypeEnum failed",nValue.getTypeEnum() == NVT_NULL); - ensure("getClassEnum failed",nValue.getClassEnum() == NVC_NULL); - ensure("getSendtoEnum failed",nValue.getSendtoEnum() == NVS_NULL); + CHECK(nValue.mName == NULL); + CHECK(nValue.getTypeEnum() == NVT_NULL); + CHECK(nValue.getClassEnum() == NVC_NULL); + CHECK(nValue.getSendtoEnum() == NVS_NULL); LLNameValue nValue1(" SecondLife ASSET RW SIM 232324343"); @@ -72,298 +66,299 @@ namespace // LLNameValue(const char* data); // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, const char* nvsendto, // TNameValueCallback nvcb = NULL, void** user_data = NULL); - template<> template<> - void namevalue_object_t::test<2>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: string and five-argument constructors set every field", "[LLNameValue]") { LLNameValue nValue(" SecondLife ASSET RW S 232324343"); - ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); - ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); - ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); - ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); - ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); - ensure("sendToData or sendToViewer failed", !nValue.sendToData() && !nValue.sendToViewer()); + CHECK(std::string_view(nValue.mName) == "SecondLife"); + CHECK(nValue.getTypeEnum() == NVT_ASSET); + CHECK(nValue.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue.getSendtoEnum() == NVS_SIM); + CHECK(std::string_view(nValue.getAsset()) == "232324343"); + CHECK_FALSE(nValue.sendToData()); + CHECK_FALSE(nValue.sendToViewer()); LLNameValue nValue1("\n\r SecondLife_1 STRING READ_WRITE SIM 232324343"); - ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife_1"))); - ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); - ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); - ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); - ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); - ensure("1. sendToData or sendToViewer failed", !nValue1.sendToData() && !nValue1.sendToViewer()); + CHECK(std::string_view(nValue1.mName) == "SecondLife_1"); + CHECK(nValue1.getTypeEnum() == NVT_STRING); + CHECK(nValue1.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue1.getSendtoEnum() == NVS_SIM); + CHECK(std::string_view(nValue1.getString()) == "232324343"); + CHECK_FALSE(nValue1.sendToData()); + CHECK_FALSE(nValue1.sendToViewer()); LLNameValue nValue2("SecondLife", "23.5", "F32", "R", "DS"); - ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); - ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); - ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_DATA_SIM); - ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); - ensure("2. sendToData or sendToViewer failed", nValue2.sendToData() && !nValue2.sendToViewer()); + CHECK(nValue2.getTypeEnum() == NVT_F32); + CHECK(nValue2.getClassEnum() == NVC_READ_ONLY); + CHECK(nValue2.getSendtoEnum() == NVS_DATA_SIM); + CHECK(*nValue2.getF32() == 23.5f); + CHECK(nValue2.sendToData()); + CHECK_FALSE(nValue2.sendToViewer()); LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY", "SIM_SPACE"); - ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); - ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); - ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_DATA_SIM); - ensure("3. getS32 failed", *nValue3.getS32() == -43456787); - ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); + CHECK(nValue3.getTypeEnum() == NVT_S32); + CHECK(nValue3.getClassEnum() == NVC_READ_ONLY); + CHECK(nValue3.getSendtoEnum() == NVS_DATA_SIM); + CHECK(*nValue3.getS32() == -43456787); + CHECK(nValue3.sendToData()); + CHECK_FALSE(nValue3.sendToViewer()); LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV"); LLVector3 llvec4(1.0, 2.0, 3.0); - ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); - ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); - ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); - ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); - ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); + CHECK(nValue4.getTypeEnum() == NVT_VEC3); + CHECK(nValue4.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue4.getSendtoEnum() == NVS_SIM_VIEWER); + CHECK(*nValue4.getVec3() == llvec4); + CHECK_FALSE(nValue4.sendToData()); + CHECK(nValue4.sendToViewer()); LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER"); LLVector3 llvec5(-1.0f, 2.4f, 3); - ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); - ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); - ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); - ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); - ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); + CHECK(nValue5.getTypeEnum() == NVT_VEC3); + CHECK(nValue5.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue5.getSendtoEnum() == NVS_SIM_VIEWER); + CHECK(*nValue5.getVec3() == llvec5); + CHECK_FALSE(nValue5.sendToData()); + CHECK(nValue5.sendToViewer()); LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV"); - ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); - ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); - ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); - ensure("6. getU32 failed", *nValue6.getU32() == 89764323); - ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); + CHECK(nValue6.getTypeEnum() == NVT_U32); + CHECK(nValue6.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + CHECK(*nValue6.getU32() == 89764323); + CHECK(nValue6.sendToData()); + CHECK(nValue6.sendToViewer()); LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER"); U64 u64_7 = U64L(89764323323232); - ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); - ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); - ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); - ensure("7. getU32 failed", *nValue7.getU64() == u64_7); - ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); + CHECK(nValue7.getTypeEnum() == NVT_U64); + CHECK(nValue7.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + CHECK(*nValue7.getU64() == u64_7); + CHECK(nValue7.sendToData()); + CHECK(nValue7.sendToViewer()); } // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, // TNameValueCallback nvcb = NULL, void** user_data = NULL); - template<> template<> - void namevalue_object_t::test<3>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: the four-argument constructor parses each type and sends to SIM", "[LLNameValue]") { LLNameValue nValue("SecondLife", "232324343", "ASSET", "READ_WRITE"); - ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); - ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); - ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); - ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); - ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + CHECK(std::string_view(nValue.mName) == "SecondLife"); + CHECK(nValue.getTypeEnum() == NVT_ASSET); + CHECK(nValue.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue.getSendtoEnum() == NVS_SIM); + CHECK(std::string_view(nValue.getAsset()) == "232324343"); LLNameValue nValue1("SecondLife", "232324343", "STRING", "READ_WRITE"); - ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); - ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); - ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); - ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); - ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + CHECK(std::string_view(nValue1.mName) == "SecondLife"); + CHECK(nValue1.getTypeEnum() == NVT_STRING); + CHECK(nValue1.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue1.getSendtoEnum() == NVS_SIM); + CHECK(std::string_view(nValue1.getString()) == "232324343"); LLNameValue nValue2("SecondLife", "23.5", "F32", "R"); - ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); - ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); - ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); - ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + CHECK(nValue2.getTypeEnum() == NVT_F32); + CHECK(nValue2.getClassEnum() == NVC_READ_ONLY); + CHECK(nValue2.getSendtoEnum() == NVS_SIM); + CHECK(*nValue2.getF32() == 23.5f); LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY"); - ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); - ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); - ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); - ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + CHECK(nValue3.getTypeEnum() == NVT_S32); + CHECK(nValue3.getClassEnum() == NVC_READ_ONLY); + CHECK(nValue3.getSendtoEnum() == NVS_SIM); + CHECK(*nValue3.getS32() == -43456787); LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW"); LLVector3 llvec4(1.0, 2.0, 3.0); - ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); - ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); - ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); - ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + CHECK(nValue4.getTypeEnum() == NVT_VEC3); + CHECK(nValue4.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue4.getSendtoEnum() == NVS_SIM); + CHECK(*nValue4.getVec3() == llvec4); LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW"); LLVector3 llvec5(-1.0f, 2.4f, 3); - ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); - ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); - ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); - ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + CHECK(nValue5.getTypeEnum() == NVT_VEC3); + CHECK(nValue5.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue5.getSendtoEnum() == NVS_SIM); + CHECK(*nValue5.getVec3() == llvec5); LLNameValue nValue6("SecondLife", "89764323", "U32", "RW"); - ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); - ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); - ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); - ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + CHECK(nValue6.getTypeEnum() == NVT_U32); + CHECK(nValue6.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue6.getSendtoEnum() == NVS_SIM); + CHECK(*nValue6.getU32() == 89764323); LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW"); U64 u64_7 = U64L(89764323323232); - ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); - ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); - ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); - ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + CHECK(nValue7.getTypeEnum() == NVT_U64); + CHECK(nValue7.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue7.getSendtoEnum() == NVS_SIM); + CHECK(*nValue7.getU64() == u64_7); } // LLNameValue(const char* name, const char* type, const char* nvclass, // TNameValueCallback nvcb = NULL, void** user_data = NULL); - template<> template<> - void namevalue_object_t::test<4>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: the three-argument constructor sets type and class and sends to SIM", "[LLNameValue]") { LLNameValue nValue("SecondLife", "STRING", "READ_WRITE"); - ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); - ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_STRING); - ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); - ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + CHECK(std::string_view(nValue.mName) == "SecondLife"); + CHECK(nValue.getTypeEnum() == NVT_STRING); + CHECK(nValue.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue.getSendtoEnum() == NVS_SIM); LLNameValue nValue1("SecondLife", "ASSET", "READ_WRITE"); - ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); - ensure("1. getTypeEnum for RW failed", nValue1.getTypeEnum() == NVT_ASSET); - ensure("1. getClassEnum for RW failed", nValue1.getClassEnum() == NVC_READ_WRITE); - ensure("1. getSendtoEnum for RW failed", nValue1.getSendtoEnum() == NVS_SIM); + CHECK(std::string_view(nValue1.mName) == "SecondLife"); + CHECK(nValue1.getTypeEnum() == NVT_ASSET); + CHECK(nValue1.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue1.getSendtoEnum() == NVS_SIM); LLNameValue nValue2("SecondLife", "F32", "READ_ONLY"); - ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); - ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); - ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + CHECK(nValue2.getTypeEnum() == NVT_F32); + CHECK(nValue2.getClassEnum() == NVC_READ_ONLY); + CHECK(nValue2.getSendtoEnum() == NVS_SIM); LLNameValue nValue3("SecondLife", "S32", "READ_ONLY"); - ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); - ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); - ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + CHECK(nValue3.getTypeEnum() == NVT_S32); + CHECK(nValue3.getClassEnum() == NVC_READ_ONLY); + CHECK(nValue3.getSendtoEnum() == NVS_SIM); LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE"); - ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); - ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); - ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + CHECK(nValue4.getTypeEnum() == NVT_VEC3); + CHECK(nValue4.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue4.getSendtoEnum() == NVS_SIM); LLNameValue nValue6("SecondLife", "U32", "READ_WRITE"); - ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); - ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); - ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + CHECK(nValue6.getTypeEnum() == NVT_U32); + CHECK(nValue6.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue6.getSendtoEnum() == NVS_SIM); LLNameValue nValue7("SecondLife", "U64", "READ_WRITE"); - ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); - ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); - ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + CHECK(nValue7.getTypeEnum() == NVT_U64); + CHECK(nValue7.getClassEnum() == NVC_READ_WRITE); + CHECK(nValue7.getSendtoEnum() == NVS_SIM); } - template<> template<> - void namevalue_object_t::test<5>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: getString returns a STRING value", "[LLNameValue]") { LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM"); - ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); + CHECK(std::string_view(nValue.getString()) == "This is a test"); } - template<> template<> - void namevalue_object_t::test<6>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: getAsset returns an ASSET value", "[LLNameValue]") { LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S"); - ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + CHECK(std::string_view(nValue.getAsset()) == "This is a test"); } - template<> template<> - void namevalue_object_t::test<7>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: getF32 returns an F32 value", "[LLNameValue]") { LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM"); - ensure("getF32 failed",*nValue.getF32() == 555555.f); + CHECK(*nValue.getF32() == 555555.f); } - template<> template<> - void namevalue_object_t::test<8>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: setS32 and getS32 across the S32 range", "[LLNameValue]") { LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM"); - ensure("getS32 failed", *nValue.getS32() == -5555); + CHECK(*nValue.getS32() == -5555); S32 sVal = 0x7FFFFFFF; nValue.setS32(sVal); - ensure("getS32 failed", *nValue.getS32() == sVal); + CHECK(*nValue.getS32() == sVal); sVal = -0x7FFFFFFF; nValue.setS32(sVal); - ensure("getS32 failed", *nValue.getS32() == sVal); + CHECK(*nValue.getS32() == sVal); sVal = 0; nValue.setS32(sVal); - ensure("getS32 failed", *nValue.getS32() == sVal); + CHECK(*nValue.getS32() == sVal); } - template<> template<> - void namevalue_object_t::test<9>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: getVec3 fills a vector", "[LLNameValue]") { LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM"); LLVector3 vecExpected(-3, 2, 1); LLVector3 vec; nValue.getVec3(vec); - ensure("getVec3 failed", vec == vecExpected); + CHECK(vec == vecExpected); } - template<> template<> - void namevalue_object_t::test<10>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: setU32 and getU32 at the U32 limits", "[LLNameValue]") { LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM"); - ensure("getU32 failed",*nValue.getU32() == 12345678); + CHECK(*nValue.getU32() == 12345678); U32 val = 0xFFFFFFFF; nValue.setU32(val); - ensure("U32 max", *nValue.getU32() == val); + UNSCOPED_INFO("U32 max"); + CHECK(*nValue.getU32() == val); val = 0; nValue.setU32(val); - ensure("U32 min", *nValue.getU32() == val); + UNSCOPED_INFO("U32 min"); + CHECK(*nValue.getU32() == val); } - template<> template<> - void namevalue_object_t::test<11>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: getU64 returns a U64 value", "[LLNameValue]") { //skip_fail("incomplete support for U64."); LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM"); - ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); + CHECK(*nValue.getU64() == U64L(44444444444)); // there is no LLNameValue::setU64() } - template<> template<> - void namevalue_object_t::test<12>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: printNameValue round-trips a U64 value", "[LLNameValue]") { //skip_fail("incomplete support for U64."); LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); std::string ret_str = nValue.printNameValue(); - ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); + CHECK(ret_str == "SecondLife U64 RW DSV 44444444444"); LLNameValue nValue1(ret_str.c_str()); - ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64()); + CHECK(*nValue.getU64() == *nValue1.getU64()); } - template<> template<> - void namevalue_object_t::test<13>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: printData prints only the data", "[LLNameValue]") { LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); std::string ret_str = nValue.printData(); - ensure_equals("1:printData failed",ret_str,"44444444444"); + CHECK(ret_str == "44444444444"); LLNameValue nValue1("SecondLife S32 RW DSV 44444"); ret_str = nValue1.printData(); - ensure_equals("2:printData failed",ret_str,"44444"); + CHECK(ret_str == "44444"); } - template<> template<> - void namevalue_object_t::test<14>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: operator<< prints the data of each type", "[LLNameValue]") { LLNameValue nValue("SecodLife STRING RW SIM 22222"); std::ostringstream stream1,stream2,stream3, stream4, stream5; stream1 << nValue; - ensure_equals("STRING << failed",stream1.str(),"22222"); + UNSCOPED_INFO("STRING type"); + CHECK(stream1.str() == "22222"); LLNameValue nValue1("SecodLife F32 RW SIM 22222"); stream2 << nValue1; - ensure_equals("F32 << failed",stream2.str(),"22222"); + UNSCOPED_INFO("F32 type"); + CHECK(stream2.str() == "22222"); LLNameValue nValue2("SecodLife S32 RW SIM 22222"); stream3<< nValue2; - ensure_equals("S32 << failed",stream3.str(),"22222"); + UNSCOPED_INFO("S32 type"); + CHECK(stream3.str() == "22222"); LLNameValue nValue3("SecodLife U32 RW SIM 122222"); stream4<< nValue3; - ensure_equals("U32 << failed",stream4.str(),"122222"); + UNSCOPED_INFO("U32 type"); + CHECK(stream4.str() == "122222"); // I don't think we use U64 name value pairs. JC //skip_fail("incomplete support for U64."); @@ -372,37 +367,36 @@ namespace //ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); } - template<> template<> - void namevalue_object_t::test<15>() + TEST_CASE_METHOD(namevalue_test, "LLNameValue: setters leave a read-only value unchanged", "[LLNameValue]") { LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S"); - ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + CHECK(std::string_view(nValue.getAsset()) == "This is a test"); // this should not have updated as it is read only. nValue.setAsset("New Value should not be updated"); - ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + CHECK(std::string_view(nValue.getAsset()) == "This is a test"); LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S"); // this should not have updated as it is read only. nValue1.setU32(4567); - ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); + CHECK(*nValue1.getU32() == 1234); LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S"); // this should not have updated as it is read only. nValue2.setS32(4567); - ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); + CHECK(*nValue2.getS32() == 1234); LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S"); // this should not have updated as it is read only. nValue3.setF32(4567); - ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); + CHECK(*nValue3.getF32() == 1234); LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S"); // this should not have updated as it is read only. LLVector3 vec(4,5,6); nValue3.setVec3(vec); LLVector3 vec1(1,2,3); - ensure("setVec3 on ReadOnly failed", *nValue4.getVec3() == vec1); + CHECK(*nValue4.getVec3() == vec1); // cant test for U64 as no set64 exists nor any operators support U64 type } diff --git a/indra/llmessage/tests/llpartdata_test.cpp b/indra/llmessage/tests/llpartdata_test.cpp index 017fbbd0c4..10130c1652 100644 --- a/indra/llmessage/tests/llpartdata_test.cpp +++ b/indra/llmessage/tests/llpartdata_test.cpp @@ -34,10 +34,9 @@ #include "../llpartdata.h" -#include "../test/lltut.h" +#include +#include "altestmatchers.h" -namespace tut -{ namespace { @@ -64,94 +63,85 @@ namespace 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x95, 0x7a, 0x22, 0x7f, 0x3f, 0xd0, 0x98, 0xa3, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00 }; - struct partdata_test - { - }; - - typedef test_group partdata_test_t; - typedef partdata_test_t::object partdata_test_object_t; - tut::partdata_test_t tut_partdata_test("LLPartData"); -} - template<> template<> - void partdata_test_object_t::test<1>() + TEST_CASE("LLPartData: LLPartSysData unpacks every field of a sniffed system", "[LLPartData]") { LLPartSysData llpsysdata; LLDataPackerBinaryBuffer dp1(msg, sizeof(msg)); - ensure("LLPartSysData::unpack failed.", llpsysdata.unpack(dp1)); + REQUIRE(llpsysdata.unpack(dp1)); //mCRC 1 unsigned int - ensure("mCRC different after unpacking", llpsysdata.mCRC == (U32) 1); + CHECK(llpsysdata.mCRC == (U32) 1); //mFlags 0 unsigned int - ensure ("mFlags different after unpacking", llpsysdata.mFlags == (U32) 0); + CHECK(llpsysdata.mFlags == (U32) 0); //mPattern 1 '' unsigned char - ensure ("mPattern different after unpacking", llpsysdata.mPattern == (U8) 1); + CHECK(llpsysdata.mPattern == (U8) 1); //mInnerAngle 0.00000000 float - ensure_approximately_equals("mInnerAngle different after unpacking", llpsysdata.mInnerAngle, 0.f, 8); + CHECK_THAT(llpsysdata.mInnerAngle, ll_test::WithinBits(0.f, 8)); //mOuterAngle 0.00000000 float - ensure_approximately_equals("mOuterAngle different after unpacking", llpsysdata.mOuterAngle, 0.f, 8); + CHECK_THAT(llpsysdata.mOuterAngle, ll_test::WithinBits(0.f, 8)); //mAngularVelocity 0,0,0 - ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[0], 0.f, 8); - ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[1], 0.f, 8); - ensure_approximately_equals("mAngularVelocity.mV[0] different after unpacking", llpsysdata.mAngularVelocity.mV[2], 0.f, 8); + CHECK_THAT(llpsysdata.mAngularVelocity.mV[0], ll_test::WithinBits(0.f, 8)); + CHECK_THAT(llpsysdata.mAngularVelocity.mV[1], ll_test::WithinBits(0.f, 8)); + CHECK_THAT(llpsysdata.mAngularVelocity.mV[2], ll_test::WithinBits(0.f, 8)); //mBurstRate 0.097656250 float - ensure_approximately_equals("mBurstRate different after unpacking", llpsysdata.mBurstRate, 0.097656250f, 8); + CHECK_THAT(llpsysdata.mBurstRate, ll_test::WithinBits(0.097656250f, 8)); //mBurstPartCount 1 '' unsigned char - ensure("mBurstPartCount different after unpacking", llpsysdata.mBurstPartCount == (U8) 1); + CHECK(llpsysdata.mBurstPartCount == (U8) 1); //mBurstRadius 0.00000000 float - ensure_approximately_equals("mBurstRadius different after unpacking", llpsysdata.mBurstRadius, 0.f, 8); + CHECK_THAT(llpsysdata.mBurstRadius, ll_test::WithinBits(0.f, 8)); //mBurstSpeedMin 1.0000000 float - ensure_approximately_equals("mBurstSpeedMin different after unpacking", llpsysdata.mBurstSpeedMin, 1.f, 8); + CHECK_THAT(llpsysdata.mBurstSpeedMin, ll_test::WithinBits(1.f, 8)); //mBurstSpeedMax 1.0000000 float - ensure_approximately_equals("mBurstSpeedMax different after unpacking", llpsysdata.mBurstSpeedMax, 1.f, 8); + CHECK_THAT(llpsysdata.mBurstSpeedMax, ll_test::WithinBits(1.f, 8)); //mMaxAge 0.00000000 float - ensure_approximately_equals("mMaxAge different after unpacking", llpsysdata.mMaxAge, 0.f, 8); + CHECK_THAT(llpsysdata.mMaxAge, ll_test::WithinBits(0.f, 8)); //mStartAge 0.00000000 float - ensure_approximately_equals("mStartAge different after unpacking", llpsysdata.mStartAge, 0.f, 8); + CHECK_THAT(llpsysdata.mStartAge, ll_test::WithinBits(0.f, 8)); //mPartAccel <0,0,0> - ensure_approximately_equals("mPartAccel.mV[0] different after unpacking", llpsysdata.mPartAccel.mV[0], 0.f, 7); - ensure_approximately_equals("mPartAccel.mV[1] different after unpacking", llpsysdata.mPartAccel.mV[1], 0.f, 7); - ensure_approximately_equals("mPartAccel.mV[2] different after unpacking", llpsysdata.mPartAccel.mV[2], 0.f, 7); + CHECK_THAT(llpsysdata.mPartAccel.mV[0], ll_test::WithinBits(0.f, 7)); + CHECK_THAT(llpsysdata.mPartAccel.mV[1], ll_test::WithinBits(0.f, 7)); + CHECK_THAT(llpsysdata.mPartAccel.mV[2], ll_test::WithinBits(0.f, 7)); //mPartData LLPartData& data = llpsysdata.mPartData; //mFlags 132354 unsigned int - ensure ("mPartData.mFlags different after unpacking", data.mFlags == (U32) 132354); + CHECK(data.mFlags == (U32) 132354); //mMaxAge 10.000000 float - ensure_approximately_equals("mPartData.mMaxAge different after unpacking", data.mMaxAge, 10.f, 8); + CHECK_THAT(data.mMaxAge, ll_test::WithinBits(10.f, 8)); //mStartColor <1,1,1,1> - ensure_approximately_equals("mPartData.mStartColor.mV[0] different after unpacking", data.mStartColor.mV[0], 1.f, 8); - ensure_approximately_equals("mPartData.mStartColor.mV[1] different after unpacking", data.mStartColor.mV[1], 1.f, 8); - ensure_approximately_equals("mPartData.mStartColor.mV[2] different after unpacking", data.mStartColor.mV[2], 1.f, 8); - ensure_approximately_equals("mPartData.mStartColor.mV[3] different after unpacking", data.mStartColor.mV[3], 1.f, 8); + CHECK_THAT(data.mStartColor.mV[0], ll_test::WithinBits(1.f, 8)); + CHECK_THAT(data.mStartColor.mV[1], ll_test::WithinBits(1.f, 8)); + CHECK_THAT(data.mStartColor.mV[2], ll_test::WithinBits(1.f, 8)); + CHECK_THAT(data.mStartColor.mV[3], ll_test::WithinBits(1.f, 8)); //mEndColor <1,1,0,0> - ensure_approximately_equals("mPartData.mEndColor.mV[0] different after unpacking", data.mEndColor.mV[0], 1.f, 8); - ensure_approximately_equals("mPartData.mEndColor.mV[1] different after unpacking", data.mEndColor.mV[1], 1.f, 8); - ensure_approximately_equals("mPartData.mEndColor.mV[2] different after unpacking", data.mEndColor.mV[2], 0.f, 8); - ensure_approximately_equals("mPartData.mEndColor.mV[3] different after unpacking", data.mEndColor.mV[3], 0.f, 8); + CHECK_THAT(data.mEndColor.mV[0], ll_test::WithinBits(1.f, 8)); + CHECK_THAT(data.mEndColor.mV[1], ll_test::WithinBits(1.f, 8)); + CHECK_THAT(data.mEndColor.mV[2], ll_test::WithinBits(0.f, 8)); + CHECK_THAT(data.mEndColor.mV[3], ll_test::WithinBits(0.f, 8)); //mStartScale <1,1> - ensure_approximately_equals("mPartData.mStartScale.mV[0] different after unpacking", data.mStartScale.mV[0], 1.f, 8); - ensure_approximately_equals("mPartData.mStartScale.mV[1] different after unpacking", data.mStartScale.mV[1], 1.f, 8); + CHECK_THAT(data.mStartScale.mV[0], ll_test::WithinBits(1.f, 8)); + CHECK_THAT(data.mStartScale.mV[1], ll_test::WithinBits(1.f, 8)); //mEndScale <0,0> - ensure_approximately_equals("mPartData.mEndScale.mV[0] different after unpacking", data.mEndScale.mV[0], 0.f, 8); - ensure_approximately_equals("mPartData.mEndScale.mV[1] different after unpacking", data.mEndScale.mV[1], 0.f, 8); + CHECK_THAT(data.mEndScale.mV[0], ll_test::WithinBits(0.f, 8)); + CHECK_THAT(data.mEndScale.mV[1], ll_test::WithinBits(0.f, 8)); //mPosOffset <0,0,0> - ensure_approximately_equals("mPartData.mPosOffset.mV[0] different after unpacking", data.mPosOffset.mV[0], 0.f, 8); - ensure_approximately_equals("mPartData.mPosOffset.mV[1] different after unpacking", data.mPosOffset.mV[1], 0.f, 8); - ensure_approximately_equals("mPartData.mPosOffset.mV[2] different after unpacking", data.mPosOffset.mV[2], 0.f, 8); + CHECK_THAT(data.mPosOffset.mV[0], ll_test::WithinBits(0.f, 8)); + CHECK_THAT(data.mPosOffset.mV[1], ll_test::WithinBits(0.f, 8)); + CHECK_THAT(data.mPosOffset.mV[2], ll_test::WithinBits(0.f, 8)); //mParameter 0.00000000 float - ensure_approximately_equals("mPartData.mParameter different after unpacking", data.mParameter, 0.f, 8); + CHECK_THAT(data.mParameter, ll_test::WithinBits(0.f, 8)); //mStartGlow 0.00000000 float - ensure_approximately_equals("mPartData.mStartGlow different after unpacking", data.mStartGlow, 0.f, 8); + CHECK_THAT(data.mStartGlow, ll_test::WithinBits(0.f, 8)); //mEndGlow 0.00000000 float - ensure_approximately_equals("mPartData.mEndGlow different after unpacking", data.mEndGlow, 0.f, 8); + CHECK_THAT(data.mEndGlow, ll_test::WithinBits(0.f, 8)); //mBlendFuncSource 2 '' unsigned char - ensure("mPartData.mBlendFuncSource different after unpacking", data.mBlendFuncSource == (U8) 2); + CHECK(data.mBlendFuncSource == (U8) 2); //mBlendFuncDest 1 '' unsigned char - ensure("mPartData.mBlendFuncDest different after unpacking", data.mBlendFuncDest == (U8) 1); + CHECK(data.mBlendFuncDest == (U8) 1); } } diff --git a/indra/llmessage/tests/llsdmessagebuilder_test.cpp b/indra/llmessage/tests/llsdmessagebuilder_test.cpp index 9e7bee3758..9f8aeb0e30 100644 --- a/indra/llmessage/tests/llsdmessagebuilder_test.cpp +++ b/indra/llmessage/tests/llsdmessagebuilder_test.cpp @@ -25,10 +25,10 @@ * $/LicenseInfo$ */ -#include +#include +#include "altestmatchers.h" #include "linden_common.h" -#include "lltut.h" #include "llmessagetemplate.h" #include "llsdmessagebuilder.h" #include "llsdmessagereader.h" @@ -43,8 +43,6 @@ #include "llsdutil_math.h" #include "lltemplatemessagebuilder.h" -namespace tut -{ namespace { static LLTemplateMessageBuilder::message_template_name_map_t templateNameMap; @@ -113,178 +111,145 @@ namespace } }; - typedef test_group LLSDMessageBuilderTestGroup; - typedef LLSDMessageBuilderTestGroup::object LLSDMessageBuilderTestObject; - LLSDMessageBuilderTestGroup llsdMessageBuilderTestGroup("LLSDMessageBuilder"); -} - template<> template<> - void LLSDMessageBuilderTestObject::test<1>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: a builder with a message and a block makes a reader", "[LLSDMessageBuilder]") // construction and test of undefined { LLSDMessageBuilder builder = defaultBuilder(); LLSDMessageReader reader = setReader(builder); } - template<> template<> - void LLSDMessageBuilderTestObject::test<2>() - // bool + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addBOOL round trips a bool through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<3>() - // U8 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addU8 round trips a U8 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<4>() - // S16 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addS16 round trips an S16 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<5>() - // U16 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addU16 round trips a U16 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<6>() - // S32 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addS32 round trips an S32 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<7>() - // F32 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addF32 round trips an F32 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<8>() - // U32 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addU32 round trips a U32 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<9>() - // U64 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addU64 round trips a U64 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<10>() - // F64 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addF64 round trips an F64 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<11>() - // Vector3 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addVector3 round trips an LLVector3 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<12>() - // Vector4 + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addVector4 round trips an LLVector4 through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<13>() - // Vector3d + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addVector3d round trips an LLVector3d through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<14>() - // Quaternion + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addQuat round trips an LLQuaternion through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<15>() - // UUID + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addUUID round trips a generated UUID through the reader", "[LLSDMessageBuilder]") { LLUUID outValue, inValue; inValue.generate(); @@ -292,35 +257,30 @@ namespace builder.addUUID("var", inValue); LLSDMessageReader reader = setReader(builder); reader.getUUID("block", "var", outValue); - ensure_equals("Ensure UUID", inValue, outValue); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<16>() - // IPAddr + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addIPAddr round trips an address through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<17>() - // IPPort + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addIPPort round trips a port through the reader", "[LLSDMessageBuilder]") { 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); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<18>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: addString round trips a string through the reader", "[LLSDMessageBuilder]") { std::string outValue, inValue = "testing"; LLSDMessageBuilder builder = defaultBuilder(); @@ -329,11 +289,10 @@ namespace char buffer[MAX_STRING]; reader.getString("block", "var", MAX_STRING, buffer); outValue = buffer; - ensure_equals("Ensure String", inValue, outValue); + CHECK(inValue == outValue); } - template<> template<> - void LLSDMessageBuilderTestObject::test<19>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData creates the blocks of a legacy message", "[LLSDMessageBuilder]") { LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); LLMsgData* md = new LLMsgData("testMessage"); @@ -343,12 +302,10 @@ namespace builder.copyFromMessageData(*md); LLSD output = builder.getMessage(); - ensure("Ensure message block created when copied from legacy message to llsd", output["testBlock"].isDefined()); + CHECK(output["testBlock"].isDefined()); } - // MVT_FIXED - template<> template<> - void LLSDMessageBuilderTestObject::test<20>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_FIXED as binary", "[LLSDMessageBuilder]") { char binData[] = "abcdefghijklmnop"; @@ -360,15 +317,12 @@ namespace LLSD output = builder.getMessage(); std::vector v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + REQUIRE(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)); + CHECK_THAT(ll_test::Memory(&v[0], sizeof(binData)), ll_test::MemoryMatches(binData, sizeof(binData))); } - // MVT_VARIABLE data_size 1 (U8's) - template<> template<> - void LLSDMessageBuilderTestObject::test<21>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData of MVT_VARIABLE data_size 1 is commented out", "[LLSDMessageBuilder]") { /* U8 binData[] = "abcdefghijklmnop"; @@ -386,9 +340,7 @@ namespace &v[0], sizeof(binData), binData, sizeof(binData));*/ } - // MVT_VARIABLE data_size 2 (U16's) - template<> template<> - void LLSDMessageBuilderTestObject::test<22>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_VARIABLE data_size 2 U16s as binary", "[LLSDMessageBuilder]") { U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts @@ -400,15 +352,12 @@ namespace LLSD output = builder.getMessage(); std::vector v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + REQUIRE(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); + CHECK_THAT(ll_test::Memory(&v[0], sizeof(binData) >> 1), ll_test::MemoryMatches(binData, sizeof(binData) >> 1)); } - // MVT_VARIABLE data_size 4 (S32's) - template<> template<> - void LLSDMessageBuilderTestObject::test<23>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_VARIABLE data_size 4 U32s as binary", "[LLSDMessageBuilder]") { U32 binData[] = {9,8,7,6,5,4,3,2,1}; @@ -420,15 +369,12 @@ namespace LLSD output = builder.getMessage(); std::vector v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + REQUIRE(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); + CHECK_THAT(ll_test::Memory(&v[0], sizeof(binData) >> 2), ll_test::MemoryMatches(binData, sizeof(binData) >> 2)); } - // MVT_U8 - template<> template<> - void LLSDMessageBuilderTestObject::test<24>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_U8 as an integer", "[LLSDMessageBuilder]") { U8 data = 0xa5; @@ -439,13 +385,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asInteger() == data); } - // MVT_U16 - template<> template<> - void LLSDMessageBuilderTestObject::test<25>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_U16 as an integer", "[LLSDMessageBuilder]") { U16 data = 0xa55a; @@ -456,13 +399,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asInteger() == data); } - // MVT_U32 - template<> template<> - void LLSDMessageBuilderTestObject::test<26>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_U32 for ll_U32_from_sd", "[LLSDMessageBuilder]") { U32 data = 0xa55a7117; @@ -473,13 +413,11 @@ namespace 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); + CHECK(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>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData keeps all 64 bits of MVT_U64 for ll_U64_from_sd", "[LLSDMessageBuilder]") { U64 data = U64L(0xa55a711711223344); addValue(messageBlockData, (char *)"testBinData", &data, MVT_U64, sizeof(data)); @@ -489,13 +427,10 @@ namespace 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); + CHECK(ll_U64_from_sd(output["testBlock"][0]["testBinData"]) == data); } - // MVT_S8 - template<> template<> - void LLSDMessageBuilderTestObject::test<28>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_S8 as an integer", "[LLSDMessageBuilder]") { S8 data = -31; @@ -506,13 +441,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asInteger() == data); } - // MVT_S16 - template<> template<> - void LLSDMessageBuilderTestObject::test<29>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_S16 as an integer", "[LLSDMessageBuilder]") { S16 data = -31; @@ -523,13 +455,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asInteger() == data); } - // MVT_S32 - template<> template<> - void LLSDMessageBuilderTestObject::test<30>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_S32 as an integer", "[LLSDMessageBuilder]") { S32 data = -3100; @@ -540,13 +469,11 @@ namespace 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); + CHECK(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>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData truncates MVT_S64 to an S32", "[LLSDMessageBuilder]") { S64 data = -31003100; @@ -557,13 +484,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asInteger() == (S32)data); } - // MVT_F32 - template<> template<> - void LLSDMessageBuilderTestObject::test<32>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_F32 as a real", "[LLSDMessageBuilder]") { F32 data = 1234.1234f; @@ -574,13 +498,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asReal() == data); } - // MVT_F64 - template<> template<> - void LLSDMessageBuilderTestObject::test<33>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_F64 as a real", "[LLSDMessageBuilder]") { F64 data = 1234.1234; @@ -591,13 +512,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asReal() == data); } - // MVT_LLVector3 - template<> template<> - void LLSDMessageBuilderTestObject::test<34>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_LLVector3 for ll_vector3_from_sd", "[LLSDMessageBuilder]") { LLVector3 data(1,2,3); @@ -608,13 +526,10 @@ namespace 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); + CHECK(ll_vector3_from_sd(output["testBlock"][0]["testBinData"]) == data); } - // MVT_LLVector3d - template<> template<> - void LLSDMessageBuilderTestObject::test<35>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_LLVector3d for ll_vector3d_from_sd", "[LLSDMessageBuilder]") { LLVector3d data(1,2,3); @@ -625,13 +540,10 @@ namespace 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); + CHECK(ll_vector3d_from_sd(output["testBlock"][0]["testBinData"]) == data); } - // MVT_LLVector4 - template<> template<> - void LLSDMessageBuilderTestObject::test<36>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_LLVector4 as ll_sd_from_vector4 does", "[LLSDMessageBuilder]") { LLVector4 data(1,2,3,4); LLSD v = ll_sd_from_vector4(data); @@ -643,13 +555,10 @@ namespace 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); + CHECK_THAT(output["testBlock"][0]["testBinData"], ll_test::LLSDEquals(v)); } - // MVT_LLQuaternion - template<> template<> - void LLSDMessageBuilderTestObject::test<37>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData unpacks MVT_LLQuaternion from a packed vector", "[LLSDMessageBuilder]") { LLQuaternion data(0.3713907f, 0.5570861f, 0.7427813f,0.0f); @@ -663,13 +572,10 @@ namespace 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); + CHECK(ll_quaternion_from_sd(output["testBlock"][0]["testBinData"]) == data); } - // MVT_LLUUID - template<> template<> - void LLSDMessageBuilderTestObject::test<38>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_LLUUID as a UUID", "[LLSDMessageBuilder]") { LLUUID data("01234567-0123-0123-0123-234567abcdef"); @@ -682,13 +588,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asUUID() == data); } - // MVT_BOOL - template<> template<> - void LLSDMessageBuilderTestObject::test<39>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_BOOL true and false", "[LLSDMessageBuilder]") { bool valueTrue = true; bool valueFalse = false; @@ -703,13 +606,11 @@ namespace 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()); + CHECK(output["testBlock"][0]["testBoolTrue"].asBoolean()); + CHECK_FALSE(output["testBlock"][0]["testBoolFalse"].asBoolean()); } - // MVT_IP_ADDR - template<> template<> - void LLSDMessageBuilderTestObject::test<40>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_IP_ADDR as ll_sd_from_ipaddr does", "[LLSDMessageBuilder]") { U32 data(0xff887766); LLSD v = ll_sd_from_ipaddr(data); @@ -721,13 +622,10 @@ namespace 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); + CHECK_THAT(output["testBlock"][0]["testBinData"], ll_test::LLSDEquals(v)); } - // MVT_IP_PORT - template<> template<> - void LLSDMessageBuilderTestObject::test<41>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_IP_PORT as an integer", "[LLSDMessageBuilder]") { U16 data = 0xff88; @@ -738,13 +636,10 @@ namespace 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); + CHECK(output["testBlock"][0]["testBinData"].asInteger() == data); } - // MVT_U16Vec3 - template<> template<> - void LLSDMessageBuilderTestObject::test<42>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_U16Vec3 as six bytes", "[LLSDMessageBuilder]") { U16 data[3] = {0,1,2}; @@ -756,15 +651,12 @@ namespace LLSD output = builder.getMessage(); std::vector v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_U16Vec3 data copied from legacy to llsd give a valid vector", v.size() > 0); + REQUIRE(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); + CHECK_THAT(ll_test::Memory((U16*)&v[0], 6), ll_test::MemoryMatches(data, 6)); } - // MVT_U16Quat - template<> template<> - void LLSDMessageBuilderTestObject::test<43>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_U16Quat as eight bytes", "[LLSDMessageBuilder]") { U16 data[4] = {0,1,2,4}; @@ -776,15 +668,12 @@ namespace LLSD output = builder.getMessage(); std::vector v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_U16Quat data copied from legacy to llsd give a valid vector", v.size() > 0); + REQUIRE(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); + CHECK_THAT(ll_test::Memory((U16*)&v[0], 8), ll_test::MemoryMatches(data, 8)); } - // MVT_S16Array - template<> template<> - void LLSDMessageBuilderTestObject::test<44>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies MVT_S16Array as binary", "[LLSDMessageBuilder]") { S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18}; @@ -796,14 +685,12 @@ namespace LLSD output = builder.getMessage(); std::vector v = output["testBlock"][0]["testBinData"].asBinary(); - ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + REQUIRE(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); + CHECK_THAT(ll_test::Memory((U16*)&v[0], 19), ll_test::MemoryMatches(data, 19)); } - template<> template<> - void LLSDMessageBuilderTestObject::test<45>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies a U8 from an LLTemplateMessageBuilder", "[LLSDMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultTemplateBlock(MVT_U8, 1)); @@ -815,12 +702,11 @@ namespace builder.copyFromMessageData(*template_builder->getCurrentMessage()); LLSD output = builder.getMessage(); - ensure_equals(output["Test0"][0]["Test0"].asInteger(), 2); + CHECK(output["Test0"][0]["Test0"].asInteger() == 2); } - template<> template<> - void LLSDMessageBuilderTestObject::test<46>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData copies a string from an LLTemplateMessageBuilder", "[LLSDMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultTemplateBlock(MVT_VARIABLE, 1)); @@ -832,11 +718,10 @@ namespace sd_builder.copyFromMessageData(*builder->getCurrentMessage()); LLSD output = sd_builder.getMessage(); - ensure_equals(output["Test0"][0]["Test0"].asString(), std::string("testing")); + CHECK(output["Test0"][0]["Test0"].asString() == std::string("testing")); } - template<> template<> - void LLSDMessageBuilderTestObject::test<47>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData gives an empty MVT_VARIABLE an empty value", "[LLSDMessageBuilder]") // an empty MVT_VARIABLE field stores no payload (getData() is null), // so the legacy-to-llsd copy must not probe it for a terminating NUL // and must yield an empty value instead of reading out of bounds @@ -848,14 +733,11 @@ namespace builder.copyFromMessageData(*messageData); LLSD output = builder.getMessage(); - ensure("Ensure empty variable copied from legacy to llsd is present", - output["testBlock"][0]["testBinData"].isDefined()); - ensure_equals("Ensure empty variable copied from legacy to llsd is empty", - output["testBlock"][0]["testBinData"].asBinary().size(), (size_t)0); + CHECK(output["testBlock"][0]["testBinData"].isDefined()); + CHECK(output["testBlock"][0]["testBinData"].asBinary().size() == (size_t)0); } - template<> template<> - void LLSDMessageBuilderTestObject::test<48>() + TEST_CASE_METHOD(LLSDMessageBuilderTestData, "LLSDMessageBuilder: copyFromMessageData skips a placeholder variable never filled", "[LLSDMessageBuilder]") // a placeholder variable in an opened block that was never filled // (size -1) has no payload at all; the legacy-to-llsd copy must skip // it rather than read through its null data pointer @@ -873,10 +755,8 @@ namespace sd_builder.copyFromMessageData(*builder->getCurrentMessage()); LLSD output = sd_builder.getMessage(); - ensure_equals("Ensure filled variable copied", - output["Test0"][0]["Test0"].asInteger(), 7); - ensure("Ensure unfilled placeholder variable not copied", - !output["Test0"][0].has("Test1")); + CHECK(output["Test0"][0]["Test0"].asInteger() == 7); + CHECK_FALSE(output["Test0"][0].has("Test1")); } } diff --git a/indra/llmessage/tests/llsdmessagereader_test.cpp b/indra/llmessage/tests/llsdmessagereader_test.cpp index 62ac6ed029..2490bfd265 100644 --- a/indra/llmessage/tests/llsdmessagereader_test.cpp +++ b/indra/llmessage/tests/llsdmessagereader_test.cpp @@ -25,9 +25,8 @@ * $/LicenseInfo$ */ -#include +#include #include "linden_common.h" -#include "lltut.h" #include "v3dmath.h" #include "v3math.h" #include "v4math.h" @@ -38,40 +37,39 @@ #include "llsdutil.h" #include "llsdutil_math.h" -namespace tut -{ namespace { struct LLSDMessageReaderTestData { - static void ensureMessageName(const std::string& msg_name, + static void require_message_name(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()), + REQUIRE(std::string(msg.getMessageName()) == expected_name); } - static void ensureNumberOfBlocks(const LLSD& msg_data, + static void require_block_count(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()), + CAPTURE(block); + REQUIRE(msg.getNumberOfBlocks(block.c_str()) == expected_number); } - static void ensureMessageSize(const LLSD& msg_data, + static void require_message_size(const LLSD& msg_data, S32 expected_size) { LLSDMessageReader msg; msg.setMessage("fakename", msg_data); - ensure_equals( "Ensure size", msg.getMessageSize(), expected_size); + REQUIRE(msg.getMessageSize() == expected_size); } - static void ensureBool(const LLSD& msg_data, + static void require_bool(const LLSD& msg_data, const std::string& block, const std::string& var, S32 blocknum, @@ -81,43 +79,34 @@ namespace 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); + CAPTURE(block, var, blocknum); + REQUIRE(test_data == expected); } }; - typedef test_group LLSDMessageReaderTestGroup; - typedef LLSDMessageReaderTestGroup::object LLSDMessageReaderTestObject; - LLSDMessageReaderTestGroup llsdMessageReaderTestGroup("LLSDMessageReader"); -} - template<> template<> - void LLSDMessageReaderTestObject::test<1>() - // construction and test of empty LLSD + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: an empty map has an empty name no blocks and size zero", "[LLSDMessageReader]") { LLSD message = LLSD::emptyMap(); - ensureMessageName("", message, ""); - ensureNumberOfBlocks(message, "Fakeblock", 0); - ensureMessageSize(message, 0); + require_message_name("", message, ""); + require_block_count(message, "Fakeblock", 0); + require_message_size(message, 0); } - template<> template<> - void LLSDMessageReaderTestObject::test<2>() - // construction and test of simple message with one block + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: a message with one block keeps its name and counts one block", "[LLSDMessageReader]") { 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); + require_message_name("name2", message, "name2"); + require_block_count(message, "block1", 1); + require_message_size(message, 0); } - template<> template<> - void LLSDMessageReaderTestObject::test<3>() - // multiple blocks + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getBOOL reads each of two blocks and both are counted", "[LLSDMessageReader]") { LLSD message = LLSD::emptyMap(); message["block1"] = LLSD::emptyArray(); @@ -129,16 +118,14 @@ namespace 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); + require_message_name("name3", message, "name3"); + require_bool(message, "block1", "BoolField1", 0, true); + require_bool(message, "block1", "BoolField1", 1, false); + require_bool(message, "block1", "BoolField2", 1, true); + require_block_count(message, "block1", 2); + require_message_size(message, 0); } -namespace -{ template LLSDMessageReader testType(const T& value) { @@ -148,95 +135,73 @@ namespace msg.setMessage("fakename", message); return msg; } -} - template<> template<> - void LLSDMessageReaderTestObject::test<4>() - // S8 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getS8 reads back a negative S8", "[LLSDMessageReader]") { S8 outValue, inValue = -3; LLSDMessageReader msg = testType(inValue); msg.getS8("block", "var", outValue); - ensure_equals("Ensure S8", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void - LLSDMessageReaderTestObject::test<5>() - // U8 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getU8 reads back a U8", "[LLSDMessageReader]") { U8 outValue, inValue = 2; LLSDMessageReader msg = testType(inValue); msg.getU8("block", "var", outValue); - ensure_equals("Ensure U8", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<6>() - // S16 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getS16 reads back an S16", "[LLSDMessageReader]") { S16 outValue, inValue = 90; LLSDMessageReader msg = testType(inValue); msg.getS16("block", "var", outValue); - ensure_equals("Ensure S16", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<7>() - // U16 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getU16 reads back a U16", "[LLSDMessageReader]") { U16 outValue, inValue = 3; LLSDMessageReader msg = testType(inValue); msg.getU16("block", "var", outValue); - ensure_equals("Ensure S16", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<8>() - // S32 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getS32 reads back an S32", "[LLSDMessageReader]") { S32 outValue, inValue = 44; LLSDMessageReader msg = testType(inValue); msg.getS32("block", "var", outValue); - ensure_equals("Ensure S32", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<9>() - // F32 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getF32 reads back an F32", "[LLSDMessageReader]") { F32 outValue, inValue = 121.44f; LLSDMessageReader msg = testType(inValue); msg.getF32("block", "var", outValue); - ensure_equals("Ensure F32", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<10>() - // U32 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getU32 reads back a U32 stored by ll_sd_from_U32", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<11>() - // U64 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getU64 reads back a U64 stored by ll_sd_from_U64", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<12>() - // F64 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getF64 reads back an F64", "[LLSDMessageReader]") { F64 outValue, inValue = 3232143.33; LLSDMessageReader msg = testType(inValue); msg.getF64("block", "var", outValue); - ensure_equals("Ensure F64", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<13>() - // String + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getString copies a string into a buffer", "[LLSDMessageReader]") { std::string outValue, inValue = "testing"; LLSDMessageReader msg = testType(inValue.c_str()); @@ -244,80 +209,64 @@ namespace char buffer[MAX_STRING]; msg.getString("block", "var", MAX_STRING, buffer); outValue = buffer; - ensure_equals("Ensure String", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<14>() - // Vector3 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getVector3 reads back an LLVector3", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<15>() - // Vector4 + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getVector4 reads back an LLVector4", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<16>() - // Vector3d + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getVector3d reads back an LLVector3d", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<17>() - // Quaternion + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getQuat reads back an LLQuaternion", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<18>() - // UUID + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getUUID reads back a generated UUID", "[LLSDMessageReader]") { LLUUID outValue, inValue; inValue.generate(); LLSDMessageReader msg = testType(inValue); msg.getUUID("block", "var", outValue); - ensure_equals("Ensure UUID", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<19>() - // IPAddr + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getIPAddr reads back an address stored by ll_sd_from_ipaddr", "[LLSDMessageReader]") { 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); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<20>() - // IPPort + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getIPPort reads back a port", "[LLSDMessageReader]") { U16 outValue, inValue = 80; LLSDMessageReader msg = testType(inValue); msg.getIPPort("block", "var", outValue); - ensure_equals("Ensure IPPort", outValue, inValue); + CHECK(outValue == inValue); } - template<> template<> - void LLSDMessageReaderTestObject::test<21>() - // Binary + TEST_CASE_METHOD(LLSDMessageReaderTestData, "LLSDMessageReader: getBinaryData reads back two bytes", "[LLSDMessageReader]") { std::vector outValue(2), inValue(2); inValue[0] = 0; @@ -325,6 +274,6 @@ namespace LLSDMessageReader msg = testType(inValue); msg.getBinaryData("block", "var", &(outValue[0]), static_cast(inValue.size())); - ensure_equals("Ensure Binary", outValue, inValue); + CHECK(outValue == inValue); } } diff --git a/indra/llmessage/tests/lltemplatemessagebuilder_test.cpp b/indra/llmessage/tests/lltemplatemessagebuilder_test.cpp index 5449f5a959..93aa839121 100644 --- a/indra/llmessage/tests/lltemplatemessagebuilder_test.cpp +++ b/indra/llmessage/tests/lltemplatemessagebuilder_test.cpp @@ -25,9 +25,8 @@ * $/LicenseInfo$ */ -#include +#include #include "linden_common.h" -#include "lltut.h" #include "llmessagesystem_fixture.h" #include "llmessagetemplate.h" @@ -41,8 +40,6 @@ #include "v3math.h" #include "v4math.h" -namespace tut -{ namespace { static LLTemplateMessageBuilder::message_template_name_map_t nameMap; @@ -104,14 +101,8 @@ namespace }; - typedef test_group LLTemplateMessageBuilderTestGroup; - typedef LLTemplateMessageBuilderTestGroup::object LLTemplateMessageBuilderTestObject; - LLTemplateMessageBuilderTestGroup templateMessageBuilderTestGroup("LLTemplateMessageBuilder"); -} - template<> template<> - void LLTemplateMessageBuilderTestObject::test<1>() - // construction and test of undefined + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a block with no variables builds and reads back", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock()); @@ -120,9 +111,7 @@ namespace delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<2>() - // bool + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addBOOL round trips a bool", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1)); @@ -131,13 +120,11 @@ namespace builder->addBOOL(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure bool", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<3>() - // U8 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU8 round trips a U8", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U8, 1)); @@ -146,13 +133,11 @@ namespace builder->addU8(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U8", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<4>() - // S16 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addS16 round trips an S16", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_S16, 2)); @@ -161,13 +146,11 @@ namespace builder->addS16(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S16", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<5>() - // U16 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU16 round trips a U16", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U16, 2)); @@ -176,13 +159,11 @@ namespace builder->addU16(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U16", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<6>() - // S32 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addS32 round trips an S32", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_S32, 4)); @@ -191,13 +172,11 @@ namespace builder->addS32(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S32", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<7>() - // F32 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addF32 round trips an F32", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_F32, 4)); @@ -206,13 +185,11 @@ namespace builder->addF32(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F32", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<8>() - // U32 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU32 round trips a U32", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U32, 4)); @@ -221,13 +198,11 @@ namespace builder->addU32(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U32", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<9>() - // U64 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU64 round trips a U64", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U64, 8)); @@ -236,13 +211,11 @@ namespace builder->addU64(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U64", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<10>() - // F64 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addF64 round trips an F64", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_F64, 8)); @@ -251,13 +224,11 @@ namespace builder->addF64(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F64", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<11>() - // Vector3 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addVector3 round trips an LLVector3", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12)); @@ -266,13 +237,11 @@ namespace builder->addVector3(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<12>() - // Vector4 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addVector4 round trips an LLVector4", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16)); @@ -281,13 +250,11 @@ namespace builder->addVector4(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector4", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<13>() - // Vector3d + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addVector3d round trips an LLVector3d", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24)); @@ -296,13 +263,11 @@ namespace builder->addVector3d(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3d", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<14>() - // Quaternion + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addQuat round trips an LLQuaternion", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12)); @@ -312,13 +277,11 @@ namespace builder->addQuat(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLQuaternion", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<15>() - // UUID + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addUUID round trips a generated UUID", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16)); @@ -328,13 +291,11 @@ namespace builder->addUUID(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure UUID", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<16>() - // IPAddr + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addIPAddr round trips an address", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4)); @@ -343,13 +304,11 @@ namespace builder->addIPAddr(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPAddr", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<17>() - // IPPort + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addIPPort round trips a port", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2)); @@ -358,13 +317,11 @@ namespace builder->addIPPort(_PREHASH_Test0, inValue); LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPPort", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<18>() - // String + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addString round trips a string", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1)); @@ -375,12 +332,11 @@ namespace char buffer[MAX_STRING]; reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer); outValue = buffer; - ensure_equals("Ensure String", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<19>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: binary order follows the template and not the block names", "[LLTemplateMessageBuilder]") // block name !-> binary order { U8 buffer1[MAX_BUFFER_SIZE]; @@ -415,12 +371,11 @@ namespace 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); + CHECK(bufferSize1 == bufferSize2); + CHECK(memcmp(buffer1, buffer2, bufferSize1) == 0); } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<20>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: binary order follows the template and not the build order", "[LLTemplateMessageBuilder]") // block build order !-> binary order { U8 buffer1[MAX_BUFFER_SIZE]; @@ -450,12 +405,11 @@ namespace 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); + CHECK(bufferSize1 == bufferSize2); + CHECK(memcmp(buffer1, buffer2, bufferSize1) == 0); } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<21>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a block appended to the template appends its data to the bytes", "[LLTemplateMessageBuilder]") // block appended in declaration -> data appended in binary { U8 buffer1[MAX_BUFFER_SIZE]; @@ -487,13 +441,13 @@ namespace 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); + CHECK(bufferSize1 != bufferSize2); + UNSCOPED_INFO("the first message is a prefix of the second"); + CHECK(memcmp(buffer1, buffer2, bufferSize1) == 0); + CHECK(memcmp(buffer1, buffer2, bufferSize2) != 0); } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<22>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: each repeat of a repeated penultimate block reads back", "[LLTemplateMessageBuilder]") // repeated penultimate block (crashes when data in LLDynamicArrayIndexed) { U32 inTest00 = 0, inTest01 = 1, inTest1 = 2; @@ -511,14 +465,13 @@ namespace 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); + CHECK(inTest00 == outTest00); + CHECK(inTest01 == outTest01); + CHECK(inTest1 == outTest1); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<23>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a variable block never added reads back with no repeats", "[LLTemplateMessageBuilder]") // variable repeated block name never accessed { U32 inTest = 1, outTest; @@ -533,13 +486,12 @@ namespace LLTemplateMessageReader* reader = setReader(messageTemplate, builder); reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outTest); S32 blockCount = reader->getNumberOfBlocks(const_cast(_PREHASH_Test1)); - ensure_equals("Ensure block count", blockCount, 0); - ensure_equals("Ensure Test0", inTest, outTest); + CHECK(blockCount == 0); + CHECK(inTest == outTest); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<24>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: copyToBuilder forwards a message it read to a new builder", "[LLTemplateMessageBuilder]") // forwarding message { // build template @@ -564,9 +516,7 @@ namespace delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<25>() - // non-zero offset with undefined + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a block with no variables builds and reads back at offset 10", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock()); @@ -576,9 +526,7 @@ namespace delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<26>() - // non-zero offset with bool + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addBOOL round trips a bool built at offset 1", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_BOOL, 1)); @@ -588,13 +536,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 1); reader->getBOOL(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure bool", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<27>() - // non-zero offset with U8 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU8 round trips a U8 built at offset 255", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U8, 1)); @@ -604,13 +550,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 255); reader->getU8(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U8", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<28>() - // non-zero offset with S16 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addS16 round trips an S16 built at offset 2", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_S16, 2)); @@ -620,13 +564,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 2); reader->getS16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S16", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<29>() - // non-zero offset with U16 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU16 round trips a U16 built at offset 4", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U16, 2)); @@ -636,13 +578,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 4); reader->getU16(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U16", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<30>() - // non-zero offset with S32 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addS32 round trips an S32 built at offset 4", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_S32, 4)); @@ -652,13 +592,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 4); reader->getS32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure S32", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<31>() - // non-zero offset with F32 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addF32 round trips an F32 built at offset 16", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_F32, 4)); @@ -668,13 +606,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 16); reader->getF32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F32", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<32>() - // non-zero offset with U32 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU32 round trips a U32 built at offset 127", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U32, 4)); @@ -684,13 +620,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 127); reader->getU32(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U32", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<33>() - // non-zero offset with U64 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addU64 round trips a U64 built at offset 32", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_U64, 8)); @@ -700,13 +634,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 32); reader->getU64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure U64", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<34>() - // non-zero offset with F64 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addF64 round trips an F64 built at offset 128", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_F64, 8)); @@ -716,13 +648,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 128); reader->getF64(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure F64", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<35>() - // non-zero offset with Vector3 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addVector3 round trips an LLVector3 built at offset 63", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLVector3, 12)); @@ -732,13 +662,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 63); reader->getVector3(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<36>() - // non-zero offset with Vector4 + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addVector4 round trips an LLVector4 built at offset 64", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLVector4, 16)); @@ -748,13 +676,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 64); reader->getVector4(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector4", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<37>() - // non-zero offset with Vector3d + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addVector3d round trips an LLVector3d built at offset 64", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLVector3d, 24)); @@ -764,13 +690,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 64); reader->getVector3d(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLVector3d", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<38>() - // non-zero offset with Quaternion + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addQuat round trips an LLQuaternion built at offset 12", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLQuaternion, 12)); @@ -780,13 +704,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 12); reader->getQuat(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure LLQuaternion", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<39>() - // non-zero offset with UUID + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addUUID round trips a generated UUID built at offset 31", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_LLUUID, 16)); @@ -797,13 +719,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 31); reader->getUUID(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure UUID", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<40>() - // non-zero offset with IPAddr + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addIPAddr round trips an address built at offset 32", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_IP_ADDR, 4)); @@ -813,13 +733,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 32); reader->getIPAddr(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPAddr", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<41>() - // non-zero offset with IPPort + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addIPPort round trips a port built at offset 6", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_IP_PORT, 2)); @@ -829,13 +747,11 @@ namespace LLTemplateMessageReader* reader = setReader( messageTemplate, builder, 6); reader->getIPPort(_PREHASH_Test0, _PREHASH_Test0, outValue); - ensure_equals("Ensure IPPort", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<42>() - // non-zero offset with String + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addString round trips a string built at offset 255", "[LLTemplateMessageBuilder]") { LLMessageTemplate messageTemplate = defaultTemplate(); messageTemplate.addBlock(defaultBlock(MVT_VARIABLE, 1)); @@ -847,12 +763,11 @@ namespace char buffer[MAX_STRING]; reader->getString(_PREHASH_Test0, _PREHASH_Test0, MAX_STRING, buffer); outValue = buffer; - ensure_equals("Ensure String", inValue, outValue); + CHECK(inValue == outValue); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<43>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a single block past the end of the message reads as zero", "[LLTemplateMessageBuilder]") // read past end of message -> default values (forward compatibility) { // build message with single block @@ -879,13 +794,12 @@ namespace 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); + CHECK(outValue == inValue); + CHECK(outValue2 == 0); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<44>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a variable block past the end of the message has no repeats", "[LLTemplateMessageBuilder]") // read variable block past end of message -> 0 repeats { // build message with single block @@ -912,13 +826,12 @@ namespace 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); + CHECK(outValue == inValue); + CHECK(outValue2 == 0); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<45>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: variable data past the end of the message reads as empty", "[LLTemplateMessageBuilder]") // read variable length data past end of message -> 0 length { // build message with single block @@ -950,13 +863,12 @@ namespace 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); + CHECK(outValue == inValue); + CHECK(strlen(outBuffer) == 0); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<46>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: a length running past the end of the message clamps to zero", "[LLTemplateMessageBuilder]") // variable-length field whose on-wire size claims more bytes than // the message contains -> read clamps to 0 length instead of // running off the end of the buffer @@ -983,13 +895,11 @@ namespace new LLTemplateMessageReader(numberMap); reader->validateMessage(buffer, builtSize, LLHost()); reader->readMessage(buffer, LLHost()); - ensure_equals("Ensure malformed length clamped to empty", - reader->getSize(_PREHASH_Test0, _PREHASH_Test0), 0); + CHECK(reader->getSize(_PREHASH_Test0, _PREHASH_Test0) == 0); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<47>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: addString truncates an oversized string and leaves the caller's alone", "[LLTemplateMessageBuilder]") // stuffing an oversized string into a Variable-1 field truncates the // stored copy without writing into the caller's buffer { @@ -998,20 +908,18 @@ namespace LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate); std::string in(300, 'x'); builder->addString(_PREHASH_Test0, in); - ensure_equals("Ensure caller buffer untouched", in[254], 'x'); - ensure_equals("Ensure caller size untouched", in.size(), (size_t)300); + CHECK(in[254] == 'x'); + CHECK(in.size() == (size_t)300); // round-trip: stored copy is clamped to 255 bytes and NUL-terminated LLTemplateMessageReader* reader = setReader(messageTemplate, builder); char outBuffer[1024]; reader->getString(_PREHASH_Test0, _PREHASH_Test0, 1024, outBuffer); - ensure_equals("Ensure stored string truncated and terminated", - strlen(outBuffer), (size_t)254); + CHECK(strlen(outBuffer) == (size_t)254); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<48>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: 200 repeats of a variable block and the block after round trip", "[LLTemplateMessageBuilder]") // A variable block repeated far past 64 times, alongside a second // block, all round-trip intact. The old data model keyed each repeat // by (block-name pointer + repeat index), walking the string table; @@ -1040,22 +948,21 @@ namespace LLTemplateMessageReader* reader = setReader(messageTemplate, builder); - ensure_equals("variable block count", - reader->getNumberOfBlocks(_PREHASH_Test0), NUM_BLOCKS); + CHECK(reader->getNumberOfBlocks(_PREHASH_Test0) == NUM_BLOCKS); for (S32 i = 0; i < NUM_BLOCKS; ++i) { U32 value = 0xffffffff; reader->getU32(_PREHASH_Test0, _PREHASH_Test0, value, i); - ensure_equals("variable block repeat intact", value, (U32)i); + CAPTURE(i); + REQUIRE(value == (U32)i); } U32 single = 0; reader->getU32(_PREHASH_Test1, _PREHASH_Test0, single); - ensure_equals("adjacent single block intact", single, (U32)0xdeadbeef); + CHECK(single == (U32)0xdeadbeef); delete reader; } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<49>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: one reader decodes messages of differing repeat counts in turn", "[LLTemplateMessageBuilder]") // Decode several messages through one reader to exercise the pooled // LLMsgData reuse path: blocks recycle between decodes and no stale // block or value leaks across messages of differing repeat counts. @@ -1105,20 +1012,20 @@ namespace reader.validateMessage(buf, sz, LLHost()); reader.readMessage(buf, LLHost()); - ensure_equals("reuse block count", - reader.getNumberOfBlocks(_PREHASH_Test0), count); + CAPTURE(pass); + REQUIRE(reader.getNumberOfBlocks(_PREHASH_Test0) == count); for (S32 i = 0; i < count; ++i) { U32 v = 0xffffffff; reader.getU32(_PREHASH_Test0, _PREHASH_Test0, v, i); - ensure_equals("reuse repeat value", v, base + (U32)i); + CAPTURE(i); + REQUIRE(v == base + (U32)i); } reader.clearMessage(); } } - template<> template<> - void LLTemplateMessageBuilderTestObject::test<50>() + TEST_CASE_METHOD(LLTemplateMessageBuilderTestData, "LLTemplateMessageBuilder: one builder builds messages of differing repeat counts in turn", "[LLTemplateMessageBuilder]") // Reuse one builder across messages to exercise the pooled LLMsgData // on the send side: the second build must not inherit blocks or values // from the first. @@ -1152,13 +1059,14 @@ namespace LLTemplateMessageReader reader(numberMap); reader.validateMessage(buf, sz, LLHost()); reader.readMessage(buf, LLHost()); - ensure_equals("builder reuse block count", - reader.getNumberOfBlocks(_PREHASH_Test0), count); + CAPTURE(pass); + REQUIRE(reader.getNumberOfBlocks(_PREHASH_Test0) == count); for (S32 i = 0; i < count; ++i) { U32 v = 0xffffffff; reader.getU32(_PREHASH_Test0, _PREHASH_Test0, v, i); - ensure_equals("builder reuse value", v, base + (U32)i); + CAPTURE(i); + REQUIRE(v == base + (U32)i); } builder->clearMessage(); } diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp index 8169afd2c0..a1e8210358 100644 --- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -25,7 +25,8 @@ */ #include "lltemplatemessagedispatcher.h" -#include "lltut.h" +#include +#include #include "llhttpnode.h" #include "llhost.h" @@ -78,8 +79,6 @@ const LLHost& LLMessageSystem::getSender() const return host; } -namespace tut -{ namespace { static LLTemplateMessageReader::message_template_number_map_t numberMap; @@ -100,32 +99,21 @@ namespace std::string mMessageName; }; - typedef test_group factory; - typedef factory::object object; -} } namespace { - tut::factory tf("LLTemplateMessageDispatcher"); -} - -namespace tut -{ - // does an empty message stop processing? - template<> template<> - void object::test<1>() + TEST_CASE_METHOD(LLTemplateMessageDispatcherData, "LLTemplateMessageDispatcher: an empty message stops processing", "[LLTemplateMessageDispatcher]") { LLTemplateMessageReader* pReader = NULL; LLTemplateMessageDispatcher t(*pReader); t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure(! gUdpDispatchWasCalled); - ensure(! gClearRecvWasCalled); + CHECK_FALSE(gUdpDispatchWasCalled); + CHECK_FALSE(gClearRecvWasCalled); } // does the disaptch invoke the udp send method? - template<> template<> - void object::test<2>() + TEST_CASE_METHOD(LLTemplateMessageDispatcherData, "LLTemplateMessageDispatcher: dispatch hands a valid message to the reader", "[LLTemplateMessageDispatcher]") { LLTemplateMessageReader* pReader = NULL; LLTemplateMessageDispatcher t(*pReader); @@ -134,12 +122,10 @@ namespace tut fillVector(vector_data, gBinaryTemplateData); mMessage["body"]["binary-template-data"] = vector_data; t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure("udp dispatch was called", gUdpDispatchWasCalled); + CHECK(gUdpDispatchWasCalled); } - // what if the message wasn't valid? We would hope the message gets cleared! - template<> template<> - void object::test<3>() + TEST_CASE_METHOD(LLTemplateMessageDispatcherData, "LLTemplateMessageDispatcher: an invalid message gets cleared", "[LLTemplateMessageDispatcher]") { LLTemplateMessageReader* pReader = NULL; LLTemplateMessageDispatcher t(*pReader); @@ -148,12 +134,10 @@ namespace tut mMessage["body"]["binary-template-data"] = vector_data; gValidateMessage = false; t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure("clear received message was called", gClearRecvWasCalled); + CHECK(gClearRecvWasCalled); } - // is the binary data passed through correctly? - template<> template<> - void object::test<4>() + TEST_CASE_METHOD(LLTemplateMessageDispatcherData, "LLTemplateMessageDispatcher: the binary data passes through unchanged", "[LLTemplateMessageDispatcher]") { LLTemplateMessageReader* pReader = NULL; LLTemplateMessageDispatcher t(*pReader); @@ -162,7 +146,7 @@ namespace tut fillVector(vector_data, gBinaryTemplateData); mMessage["body"]["binary-template-data"] = vector_data; t.dispatch(mMessageName, mMessage, mResponsePtr); - ensure("data couriered correctly", strcmp(gBinaryTemplateData, gUdpDispatchedData) == 0); + CHECK(std::string_view(gBinaryTemplateData) == std::string_view(gUdpDispatchedData)); } } diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp index aff273c755..48169075ce 100644 --- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -25,7 +25,7 @@ */ #include "lltrustedmessageservice.h" -#include "../test/lltut.h" +#include #include "llhost.cpp" // LLHost is a value type for test purposes. #include "net.cpp" // Needed by LLHost. @@ -84,8 +84,6 @@ void LLMessageSystem::dispatchTemplate(const std::string& msg_name, messageDispatchedAsBinary = true; } -namespace tut -{ namespace { struct LLTrustedMessageServiceData @@ -100,25 +98,16 @@ namespace } }; - typedef test_group factory; - typedef factory::object object; -} } namespace -{ - tut::factory tf("LLTrustedMessageServiceData"); -} - -namespace tut { // characterisation tests // 1) test that messages get forwarded with names etc. as current behaviour (something like LLMessageSystem::dispatch(name, data...) // test llsd messages are sent as normal using LLMessageSystem::dispatch() (eventually) - template<> template<> - void object::test<1>() + TEST_CASE_METHOD(LLTrustedMessageServiceData, "LLTrustedMessageServiceData: an llsd message goes to dispatch with a body", "[LLTrustedMessageServiceData]") { LLHTTPNode::ResponsePtr response; LLSD input; @@ -126,14 +115,13 @@ namespace tut LLTrustedMessageService adapter; adapter.post(response, context, input); // test original ting got called wit nowt, ya get me blood? - ensure_equals(messageDispatched, true); - ensure(lastLLSD.has("body")); + CHECK(messageDispatched); + CHECK(lastLLSD.has("body")); } // test that llsd wrapped binary-template-data messages are // sent via LLMessageSystem::binaryDispatch() or similar - template<> template<> - void object::test<2>() + TEST_CASE_METHOD(LLTrustedMessageServiceData, "LLTrustedMessageServiceData: binary-template-data goes to dispatchTemplate", "[LLTrustedMessageServiceData]") { LLHTTPNode::ResponsePtr response; LLSD input; @@ -142,8 +130,8 @@ namespace tut LLTrustedMessageService adapter; adapter.post(response, context, input); - ensure("check template-binary-data message was dispatched as binary", messageDispatchedAsBinary); - ensure_equals(lastLLSD["body"]["binary-template-data"].asString(), "10001010110"); + CHECK(messageDispatchedAsBinary); + CHECK(lastLLSD["body"]["binary-template-data"].asString() == "10001010110"); // test somit got called with "10001010110" (something like LLMessageSystem::dispatchTemplate(blah)) } } diff --git a/indra/llmessage/tests/llxfer_file_test.cpp b/indra/llmessage/tests/llxfer_file_test.cpp index e7479f7402..f3250a7512 100644 --- a/indra/llmessage/tests/llxfer_file_test.cpp +++ b/indra/llmessage/tests/llxfer_file_test.cpp @@ -29,22 +29,11 @@ #include "../llxfer_file.h" -#include "../test/lltut.h" +#include -namespace tut -{ namespace { - struct llxfer_data - { - }; - typedef test_group llxfer_test; - typedef llxfer_test::object llxfer_object; - tut::llxfer_test llxfer("LLXferFile"); -} - - template<> template<> - void llxfer_object::test<1>() + TEST_CASE("LLXferFile: an oversized local filename is cut short of LL_MAX_PATH", "[LLXferFile]") { // test that we handle an oversized filename correctly. std::string oversized_filename; @@ -55,7 +44,6 @@ namespace } LLXfer_File xff(oversized_filename, false, 1); - ensure("oversized local_filename nul-terminated", - xff.getFileName().length() < LL_MAX_PATH); + CHECK(xff.getFileName().length() < LL_MAX_PATH); } } diff --git a/indra/llmessage/tests/llxorcipher_test.cpp b/indra/llmessage/tests/llxorcipher_test.cpp index 992fe27f94..821d460282 100644 --- a/indra/llmessage/tests/llxorcipher_test.cpp +++ b/indra/llmessage/tests/llxorcipher_test.cpp @@ -27,24 +27,13 @@ */ #include "linden_common.h" -#include "lltut.h" +#include +#include "altestmatchers.h" #include "llxorcipher.h" -namespace tut -{ namespace { - struct cipher - { - }; - typedef test_group 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>() + TEST_CASE("cipher: encrypt then decrypt with the same pad round-trips the data", "[cipher]") { const U32 len = 3; const U8 pad[] = "abc"; @@ -56,18 +45,16 @@ namespace LLXORCipher xorCipher1(pad, len); U32 length = xorCipher.requiredEncryptionSpace(50); - ensure("requiredEncryptionSpace() function failed", (length == 50)); + CHECK(length == 50); U32 lenEncrypted = xorCipher.encrypt((U8 *) str, str_len, encrypted, str_len); - ensure("Encryption failed", (lenEncrypted == str_len)); + CHECK(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); + CHECK(lenDecrypted == str_len); + CHECK_THAT(ll_test::Memory(str, str_len), ll_test::MemoryMatches(decrypted, lenDecrypted)); } - // operator= - template<> template<> - void cipher_object_t::test<2>() + TEST_CASE("cipher: operator= copies the pad so the copy decrypts", "[cipher]") { const U8 pad[] = "ABCDEFGHIJKLMNOPQ"; // pad len longer than data to be ciphered const U32 pad_len = sizeof(pad); @@ -86,12 +73,10 @@ namespace // 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); + CHECK_THAT(ll_test::Memory(str, str_len), ll_test::MemoryMatches(decrypted, lenDecrypted)); } - //in place encrypt->decrypt - template<> template<> - void cipher_object_t::test<3>() + TEST_CASE("cipher: in-place encrypt changes the data and decrypt restores it", "[cipher]") { U32 padNum = 0x12349087; const U8* pad = (U8*) &padNum; @@ -104,9 +89,9 @@ namespace 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); + CHECK(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); + CHECK_THAT(ll_test::Memory(str, str_len), ll_test::MemoryMatches(str1, str_len)); } } diff --git a/indra/llmessage/tests/llzerocode_test.cpp b/indra/llmessage/tests/llzerocode_test.cpp index 84426be147..4ec13cf8f5 100644 --- a/indra/llmessage/tests/llzerocode_test.cpp +++ b/indra/llmessage/tests/llzerocode_test.cpp @@ -28,21 +28,12 @@ #include "../llzerocode.h" -#include "../test/lltut.h" +#include #include -namespace tut -{ namespace { - struct zerocode_data - { - }; - typedef test_group zerocode_test; - typedef zerocode_test::object zerocode_object; - tut::zerocode_test zerocode_testcase("LLZeroCode"); - // Builds header_size bytes of header (with header[0] == header0) followed by body. static std::vector makeBuffer(U32 header_size, U8 header0, const std::vector& body) { @@ -59,9 +50,10 @@ namespace // asserts the round trip reproduces src exactly, including untouched header bits other // than the zero-code flag. When compression is not expected to help, asserts encode() // refuses it. - static void ensureRoundTrip(const char* msg, U32 header_size, U8 header0, - const std::vector& body, bool expect_compressed) + static void require_round_trip(const char* what, U32 header_size, U8 header0, + const std::vector& body, bool expect_compressed) { + INFO(what); std::vector src = makeBuffer(header_size, header0, body); std::vector enc(2 * src.size() + 16, 0xAA); @@ -70,88 +62,83 @@ namespace if (!expect_compressed) { - ensure(std::string(msg) + ": encode should refuse (no benefit)", enc_size < 0); + UNSCOPED_INFO("encode refuses: no benefit"); + REQUIRE(enc_size < 0); return; } - ensure(std::string(msg) + ": encode should succeed", enc_size >= 0); - ensure(std::string(msg) + ": encoded size should be smaller", (U32)enc_size < src.size()); - ensure(std::string(msg) + ": FLAG should be set on encoded output", (enc[0] & LLZeroCode::FLAG) != 0); + REQUIRE(enc_size >= 0); + REQUIRE((U32)enc_size < src.size()); + REQUIRE((enc[0] & LLZeroCode::FLAG) != 0); if (header_size > 0) { - ensure_equals(std::string(msg) + ": non-flag header bits preserved on encode", - (U8)(enc[0] & ~LLZeroCode::FLAG), (U8)(header0 & ~LLZeroCode::FLAG)); + UNSCOPED_INFO("encode keeps the header bits other than FLAG"); + REQUIRE((U8)(enc[0] & ~LLZeroCode::FLAG) == (U8)(header0 & ~LLZeroCode::FLAG)); } std::vector dec(src.size() + 16, 0xBB); bool overflow = false; U32 dec_size = LLZeroCode::decode(enc.data(), (U32)enc_size, dec.data(), (U32)dec.size(), header_size, overflow); - ensure(std::string(msg) + ": decode should not overflow", !overflow); - ensure_equals(std::string(msg) + ": decoded size should match original", dec_size, (U32)src.size()); - ensure(std::string(msg) + ": decoded bytes should match original", - memcmp(dec.data(), src.data(), src.size()) == 0); + REQUIRE_FALSE(overflow); + REQUIRE(dec_size == (U32)src.size()); + REQUIRE(memcmp(dec.data(), src.data(), src.size()) == 0); } -} // Basic mixed body; header carries an unrelated flag bit (0x40) that must survive untouched. - template<> template<> - void zerocode_object::test<1>() + TEST_CASE("LLZeroCode: a mixed body round-trips and keeps other header bits", "[LLZeroCode]") { - ensureRoundTrip("mixed body", 6, 0x40, - {0,0,0,5,0,0,0,0,0,0,7,8,9,0,0}, true); + require_round_trip("mixed body", 6, 0x40, + {0,0,0,5,0,0,0,0,0,0,7,8,9,0,0}, true); } // A body with no zero bytes at all cannot benefit from zero-coding. - template<> template<> - void zerocode_object::test<2>() + TEST_CASE("LLZeroCode: encode refuses a body with no zero bytes", "[LLZeroCode]") { - ensureRoundTrip("no zero bytes", 1, 0x00, {1,2,3,4,5,6,7,8,9}, false); + require_round_trip("no zero bytes", 1, 0x00, {1,2,3,4,5,6,7,8,9}, false); } // Isolated zero-byte runs of length 1 or 2 cost as much or more than they save // (marker + terminator == 2 bytes), so encode must refuse them. - template<> template<> - void zerocode_object::test<3>() + TEST_CASE("LLZeroCode: encode refuses isolated runs of one or two zeros", "[LLZeroCode]") { - ensureRoundTrip("isolated single zero", 1, 0x00, {5, 0}, false); - ensureRoundTrip("isolated double zero", 1, 0x00, {5, 0, 0, 9}, false); + require_round_trip("isolated single zero", 1, 0x00, {5, 0}, false); + require_round_trip("isolated double zero", 1, 0x00, {5, 0, 0, 9}, false); } // A long enough zero run followed by other data pays off. - template<> template<> - void zerocode_object::test<4>() + TEST_CASE("LLZeroCode: a long zero run followed by data round-trips smaller", "[LLZeroCode]") { std::vector body(20, 0); body.push_back(99); - ensureRoundTrip("long zero run", 1, 0x00, body, true); + require_round_trip("long zero run", 1, 0x00, body, true); } // Wrap boundary: runs are split into chunks of at most 255 zero bytes each // (encode never emits the doubled-0x00 wire form; see test<7> for that). // A run only shrinks the packet once it is longer than 2 bytes. - template<> template<> - void zerocode_object::test<5>() + TEST_CASE("LLZeroCode: runs around the 255-byte wrap round-trip before a trailing byte", "[LLZeroCode]") { static const U32 lengths[] = {1, 2, 253, 254, 255, 256, 257, 300, 509, 510, 511, 1000}; for (U32 n : lengths) { + CAPTURE(n); std::vector body(n, 0); body.push_back(42); // trailing nonzero byte - ensureRoundTrip("wrap boundary (with trailing byte)", 1, 0x00, body, n > 2); + require_round_trip("wrap boundary (with trailing byte)", 1, 0x00, body, n > 2); } } // Same boundary check, but with the zero run flushed at end-of-buffer // (no trailing nonzero byte to force the terminator write mid-loop). - template<> template<> - void zerocode_object::test<6>() + TEST_CASE("LLZeroCode: runs around the 255-byte wrap round-trip at the end of the buffer", "[LLZeroCode]") { static const U32 lengths[] = {1, 2, 254, 255, 256, 300}; for (U32 n : lengths) { + CAPTURE(n); std::vector body(n, 0); - ensureRoundTrip("wrap boundary (end-of-buffer flush)", 1, 0x00, body, n > 2); + require_round_trip("wrap boundary (end-of-buffer flush)", 1, 0x00, body, n > 2); } } @@ -159,8 +146,7 @@ namespace // (worth +255 zero bytes per extra marker) for compatibility with any // encoder other than this one's chunking strategy, even though encode() // itself never emits it. - template<> template<> - void zerocode_object::test<7>() + TEST_CASE("LLZeroCode: decode accepts the doubled-marker wrap form", "[LLZeroCode]") { // header (1 byte, FLAG set) + [0x00 marker][0x00 extra-wrap-marker][terminator=5] // decoded body length = 1 (marker) + 1 (extra marker) + 255 (memset) + (5 - 1) = 261 @@ -169,81 +155,80 @@ namespace bool overflow = false; U32 dec_size = LLZeroCode::decode(encoded.data(), (U32)encoded.size(), dec.data(), (U32)dec.size(), 1, overflow); - ensure("wrap format: no overflow", !overflow); - ensure_equals("wrap format: decoded size", dec_size, (U32)262); - ensure_equals("wrap format: FLAG cleared on header", dec[0], (U8)0x00); + CHECK_FALSE(overflow); + CHECK(dec_size == (U32)262); + UNSCOPED_INFO("decode clears FLAG on the header"); + CHECK(dec[0] == (U8)0x00); for (U32 i = 1; i < dec_size; ++i) { - ensure_equals("wrap format: decoded byte is zero", dec[i], (U8)0); + CAPTURE(i); + REQUIRE(dec[i] == (U8)0); } } // decode() is a no-op (returns 0, does not touch dst) when FLAG is not set. - template<> template<> - void zerocode_object::test<8>() + TEST_CASE("LLZeroCode: decode does nothing when FLAG is not set", "[LLZeroCode]") { std::vector src = makeBuffer(6, 0x00, {1,2,3,0,0,0}); std::vector dec(64, 0xCC); bool overflow = false; U32 dec_size = LLZeroCode::decode(src.data(), (U32)src.size(), dec.data(), (U32)dec.size(), 6, overflow); - ensure_equals("not zero-coded: decode returns 0", dec_size, (U32)0); - ensure("not zero-coded: no overflow", !overflow); + CHECK(dec_size == (U32)0); + CHECK_FALSE(overflow); } // encode() refuses to write into an undersized destination buffer. - template<> template<> - void zerocode_object::test<9>() + TEST_CASE("LLZeroCode: encode refuses an undersized destination", "[LLZeroCode]") { std::vector body(50, 0); std::vector src = makeBuffer(1, 0, body); std::vector enc(src.size(), 0); // smaller than the required 2 * src_size S32 r = LLZeroCode::encode(src.data(), (U32)src.size(), enc.data(), (U32)enc.size(), 1); - ensure("encode: capacity guard rejects undersized dst", r < 0); + CHECK(r < 0); } // decode() reports overflow (rather than writing out of bounds) when dst is too small, // whether the destination is smaller than a single byte's worth of headroom... - template<> template<> - void zerocode_object::test<10>() + TEST_CASE("LLZeroCode: decode flags overflow into a destination only the header fits", "[LLZeroCode]") { std::vector body(500, 0); std::vector src = makeBuffer(1, 0, body); std::vector enc(2 * src.size() + 16, 0); S32 enc_size = LLZeroCode::encode(src.data(), (U32)src.size(), enc.data(), (U32)enc.size(), 1); - ensure("decode overflow setup: encode succeeded", enc_size >= 0); + CHECK(enc_size >= 0); std::vector dec(1, 0); // capacity == header_size exactly bool overflow = false; U32 dec_size = LLZeroCode::decode(enc.data(), (U32)enc_size, dec.data(), (U32)dec.size(), 1, overflow); - ensure("decode overflow (minimal capacity): overflow flagged", overflow); - ensure_equals("decode overflow (minimal capacity): partial output discarded", dec_size, 0u); + CHECK(overflow); + UNSCOPED_INFO("the partial output is discarded"); + CHECK(dec_size == 0u); } // ...or comfortably larger than 256 bytes but still short of the true decoded size. - template<> template<> - void zerocode_object::test<11>() + TEST_CASE("LLZeroCode: decode flags overflow into a destination short of the output", "[LLZeroCode]") { std::vector body(500, 0); std::vector src = makeBuffer(1, 0, body); std::vector enc(2 * src.size() + 16, 0); S32 enc_size = LLZeroCode::encode(src.data(), (U32)src.size(), enc.data(), (U32)enc.size(), 1); - ensure("decode overflow setup: encode succeeded", enc_size >= 0); + CHECK(enc_size >= 0); std::vector dec(300, 0); // > 256, but less than the true decoded size (~501) bool overflow = false; U32 dec_size = LLZeroCode::decode(enc.data(), (U32)enc_size, dec.data(), (U32)dec.size(), 1, overflow); - ensure("decode overflow (insufficient capacity): overflow flagged", overflow); - ensure_equals("decode overflow (insufficient capacity): partial output discarded", dec_size, 0u); + CHECK(overflow); + UNSCOPED_INFO("the partial output is discarded"); + CHECK(dec_size == 0u); } // A pathological alternating zero/non-zero pattern grows under zero-coding // (every isolated zero costs 2 output bytes for 1 input byte), so encode // must refuse it and leave the original buffer in use. - template<> template<> - void zerocode_object::test<12>() + TEST_CASE("LLZeroCode: encode refuses alternating zero and non-zero bytes", "[LLZeroCode]") { std::vector body; for (int i = 0; i < 200; ++i) @@ -251,6 +236,6 @@ namespace body.push_back(0); body.push_back((U8)(i + 1)); } - ensureRoundTrip("alternating pattern", 1, 0x00, body, false); + require_round_trip("alternating pattern", 1, 0x00, body, false); } } diff --git a/indra/llmessage/tests/message_test.cpp b/indra/llmessage/tests/message_test.cpp index 2e3be7f899..acf1a380f4 100644 --- a/indra/llmessage/tests/message_test.cpp +++ b/indra/llmessage/tests/message_test.cpp @@ -25,15 +25,23 @@ * $/LicenseInfo$ */ -#include +#include #include "linden_common.h" -#include "lltut.h" #include "llhttpconstants.h" #include "llmessageconfig.h" #include "llmessagesystem_fixture.h" #include "llsdserialize.h" #include "message.h" #include "message_prehash.h" +#include "net.h" + +#if !LL_WINDOWS +#include +#include +#include +#include +#include +#endif namespace { @@ -50,8 +58,6 @@ namespace }; } -namespace tut -{ namespace { struct LLMessageSystemTestData @@ -112,20 +118,88 @@ namespace } }; - typedef test_group LLMessageSystemTestGroup; - typedef LLMessageSystemTestGroup::object LLMessageSystemTestObject; - LLMessageSystemTestGroup messageTestGroup("LLMessageSystem"); -} - template<> template<> - void LLMessageSystemTestObject::test<1>() + TEST_CASE_METHOD(LLMessageSystemTestData, "LLMessageSystem: dispatch of an unknown message answers HTTP_NOT_FOUND", "[LLMessageSystem]") // dispatch unknown message { const char* name = "notamessasge"; const LLSD message; const LLPointer response = new Response(); gMessageSystem->dispatch(name, message, response); - ensure_equals(response->mStatus, HTTP_NOT_FOUND); + CHECK(response->mStatus == HTTP_NOT_FOUND); + } + + TEST_CASE_METHOD(LLMessageSystemTestData, "LLMessageSystem: a system whose template failed to load still closes its socket", "[LLMessageSystem]") + // a system whose template failed to load still closes its socket + { + U32 port = 0; + { + // The template loads before the socket opens, so a system + // without one is not OK, and has a socket all the same. + LLMessageSystem system("notafile", NET_USE_OS_ASSIGNED_PORT, 1, 0, 0, false, 5.f, 100.f); + UNSCOPED_INFO("not OK without its template"); + CHECK_FALSE(system.isOK()); + CHECK(system.mSocket >= 0); + port = system.getListenPort(); + } + // Its port is free again: start_net binds it, rather than moving on + // to the discovery range as it does from a port in use. + S32 socket = -1; + int bound = port; + UNSCOPED_INFO("start_net binds"); + CHECK(start_net(socket, bound) == 0); + end_net(socket); + UNSCOPED_INFO("the port the system had"); + CHECK(bound == (int)port); + UNSCOPED_INFO("and end_net leaves no socket"); + CHECK(socket == -1); } + +#if !LL_WINDOWS + TEST_CASE_METHOD(LLMessageSystemTestData, "LLMessageSystem: start_net closes its socket when it finds no port to bind", "[LLMessageSystem]") + // start_net closes the socket it made when it finds no port to bind + { + // Every port start_net would try is taken: the one it is asked for + // is the first of the discovery range, where it goes on to look. + std::vector held; + for (U32 port = PORT_DISCOVERY_RANGE_MIN; port <= PORT_DISCOVERY_RANGE_MAX; ++port) + { + const int holder = ::socket(AF_INET, SOCK_DGRAM, 0); + sockaddr_in address{}; + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(INADDR_ANY); + address.sin_port = htons(port); + if (holder >= 0 && ::bind(holder, (sockaddr*)&address, sizeof(address)) == 0) + { + held.push_back(holder); + } + else if (holder >= 0) + { + // In use by something else, which takes it from start_net too. + ::close(holder); + } + } + + // A new descriptor is the lowest free one, so the one before + // start_net is the one after, unless start_net left one open. + const int before = ::open("/dev/null", O_RDONLY); + ::close(before); + S32 socket = -1; + int port = PORT_DISCOVERY_RANGE_MIN; + const S32 result = start_net(socket, port); + const int after = ::open("/dev/null", O_RDONLY); + ::close(after); + for (int holder : held) + { + ::close(holder); + } + + UNSCOPED_INFO("no port to bind"); + CHECK(result == 3); + CHECK(socket == -1); + UNSCOPED_INFO("no descriptor left open"); + CHECK(after == before); + } +#endif } diff --git a/indra/test/sync.h b/indra/test/sync.h index 82eef1e5f5..b7dd613adf 100644 --- a/indra/test/sync.h +++ b/indra/test/sync.h @@ -17,11 +17,19 @@ #define LL_SYNC_H #include "llcond.h" -#include "lltut.h" #include "stringize.h" #include "llerror.h" #include "llcoros.h" +// A timeout fails the test the way the test's framework does, until the +// last TUT test that uses this is converted: al_add_test_binary defines +// AL_TEST_CATCH2 for a Catch2 binary. +#if AL_TEST_CATCH2 +#include +#else +#include "lltut.h" +#endif + /** * Instantiate Sync in any test in which we need to suspend one coroutine * until we're sure that another has had a chance to run. Simply calling @@ -105,9 +113,14 @@ class Sync LL_DEBUGS() << name << " yield_until(" << until << ") suspending" << LL_ENDL; if (! mCond.wait_for_equal(mTimeout, until)) { +#if AL_TEST_CATCH2 + FAIL(name << ' ' << func << '(' << arg << ") timed out after " << int(mTimeout.value()) + << "ms (expected " << until << ", actual " << mCond.get() << ')'); +#else tut::fail(STRINGIZE(name << ' ' << func << '(' << arg << ") timed out after " << int(mTimeout.value()) << "ms (expected " << until << ", actual " << mCond.get() << ')')); +#endif } // each time we wake up, bump mCond bump(); diff --git a/scripts/testing/tut2catch.py b/scripts/testing/tut2catch.py index e18de81228..97aaa9613c 100644 --- a/scripts/testing/tut2catch.py +++ b/scripts/testing/tut2catch.py @@ -10,7 +10,8 @@ each case as TUT built it for each test; or a plain TEST_CASE(": ", "[]") where the struct holds nothing and nothing else names it, and the struct goes. - The name is, first, one --names gives; then the test's + The name is, first, one --names gives (for #if twins, a + list, one a twin in declaration order); then the test's set_test_name literal; then the first sentence of the comment written above the test, where that is prose; else #N. " #N" is added to a name another case of the file has @@ -2280,7 +2281,10 @@ def test_containing(self, offset): def name_tests(self): for data, group in self.groups.items(): seen = [] # (the #if branches around a case, its name) - for test in sorted(group.tests, key=lambda t: t.n): + twins = {} # test -> how many of its #if twins came before + for test in sorted(group.tests, key=lambda t: (t.n, -1 if t.start is None else t.start)): + twin = twins.get(test.n, 0) + twins[test.n] = twin + 1 if test.macro: test.tut_name = None # left as it is: no case, and parity says so continue @@ -2306,6 +2310,8 @@ def name_tests(self): # A name given in --names wins; then set_test_name's; then the # first sentence of the comment written above the test. given = self.name_overrides.get((group.name, test.n)) + if isinstance(given, list): + given = given[twin] if twin < len(given) else None if given is None and text_name is None: given = self.comment_name(test) if given is not None: @@ -3232,7 +3238,9 @@ def tut_friends(): def load_names(path): - """--names: {"": {"": {"": ""}}}.""" + """--names: {"": {"": {"": ""}}}, or + for a test defined in branches of one #if, a list of names, one a + twin in the order the file declares them.""" if not path: return {} with open(path) as f: @@ -3241,6 +3249,8 @@ def load_names(path): for file, groups in data.items(): for group, tests in groups.items(): for n, name in tests.items(): + if not isinstance(name, str) and not (isinstance(name, list) and all(isinstance(x, str) for x in name)): + raise SystemExit(f"--names: {file} {group} {n}: a name, or a list of names, not {name!r}") out[(os.path.normpath(file), group, int(n))] = name return out @@ -3348,7 +3358,8 @@ def main(): parser.add_argument("--jobs", type=int, default=1, help="files to convert at once") parser.add_argument("--quiet", action="store_true", help="print only the marks and the totals") parser.add_argument("--names", help='cases\' names, as JSON: {"": {"": ' - '{"": ""}}}; each wins over the test\'s own') + '{"": ""}}}, or a list of names for a test in branches of one #if, ' + 'one a twin in the order the file declares them; each wins over the test\'s own') args = parser.parse_args() files = [os.path.abspath(f) for f in args.files] diff --git a/scripts/testing/tut_parity.py b/scripts/testing/tut_parity.py index 41825ad42e..c2139ecfd0 100644 --- a/scripts/testing/tut_parity.py +++ b/scripts/testing/tut_parity.py @@ -10,7 +10,10 @@ A test TUT never reported (a dummy test slot) is not a test. With them it keeps the sha256 of the TUT source, the one indra/**/tests/.cpp git tracks, and it refuses an - executable built before that source last changed. A test built at other + executable built before that source last changed: the entry's + own target, wherever it is in the command (llcorehttp's runs + under a Python peer), as check finds a Catch2 entry's binary. A + test built at other x86-64 tiers too (an entry ending _baseline, _v2, _v3, _v4) is kept a tier apart, under @. check after converting and building: runs each converted file's CTest @@ -35,7 +38,9 @@ of the file is one of its TUT tests; - each pair agrees: ok is a pass, a TUT skip is a Catch2 skip, and every TUT failure (fail, exception, abnormal end) is a Catch2 failure; and the - name TUT printed is the one the mapping folded into the case's; + name TUT printed is the one the mapping folded into the case's, but + where a test skipped or failed before its set_test_name ran, and so + printed none, which is listed; - the cases run in the order TUT ran their tests, groups by name and each group's tests by number, since a test may lean on what the ones before it left; @@ -184,6 +189,21 @@ def tut_identity(name): return (m.group(1)[:-len(tier) - 1] if tier else m.group(1)) + "_test", tier +def executable_in(command, target): + """The file in an entry's command named for its target, wherever a + launcher put it; else the command's first word.""" + for word in command: + if os.path.splitext(os.path.basename(word))[0] == target and os.path.isfile(word): + return word + return command[0] if command else None + + +def tut_executable(name, command): + """The test executable in a TUT entry's command: INTEGRATION_TEST_ + for INTEGRATION_TEST_RUNNER_, and the entry's own name otherwise.""" + return executable_in(command, name.replace("INTEGRATION_TEST_RUNNER_", "INTEGRATION_TEST_", 1)) + + def tut_source(stem): """The TUT source a stem names, as git tracks it under ROOT, and the sha256 of its bytes: (None, None) unless exactly one @@ -223,10 +243,10 @@ def record(args): file=sys.stderr) # An executable older than its source is not of it: its results # would stand for tests the file no longer has. - command = test["command"] - if source is not None and command and os.path.isfile(command[0]) and \ - os.path.getmtime(os.path.join(ROOT, source)) > os.path.getmtime(command[0]): - print(f"{name}: {source} changed since {command[0]} was built; build it again to record it", + executable = tut_executable(name, test["command"]) + if source is not None and executable and os.path.isfile(executable) and \ + os.path.getmtime(os.path.join(ROOT, source)) > os.path.getmtime(executable): + print(f"{name}: {source} changed since {executable} was built; build it again to record it", file=sys.stderr) return 2 code, text = run(test, ["-v"], args.timeout) @@ -531,10 +551,10 @@ def check_run(args, label, path, entry_name, test, recorded, entries, file_cases first_problem = len(problems) # A converted file changed since its binary was built is not what the # binary runs: its cases, lines and counts would not be the run's. - command = test["command"] - if command and os.path.isfile(command[0]) and \ - os.path.getmtime(os.path.join(ROOT, path)) > os.path.getmtime(command[0]): - problems.append(f"{label}: changed since {command[0]} was built; build it again to check it") + executable = executable_in(test["command"], entry_name.split("/", 1)[0]) + if executable and os.path.isfile(executable) and \ + os.path.getmtime(os.path.join(ROOT, path)) > os.path.getmtime(executable): + problems.append(f"{label}: changed since {executable} was built; build it again to check it") return None code, cases, output = catch2_results(test, args.timeout) # Where the host cannot run a tier, either side exits with the skip code @@ -648,8 +668,13 @@ def compiled(first, last, conditional): paired[name] = key matched += 1 if e.get("tut_name") is not None and e["tut_name"] != t["name"]: - problems.append(f"{label}: {e['group']} test<{e['n']}>: TUT named it {t['name']!r}, " - f"the mapping {e['tut_name']!r}") + # TUT prints a test's name once its set_test_name has run: one + # that skipped or failed before that printed none. + if not t["name"] and t["result"] != "ok": + listed.append(f"{e['group']} {e['n']}: ended before its set_test_name, so TUT printed no name") + else: + problems.append(f"{label}: {e['group']} test<{e['n']}>: TUT named it {t['name']!r}, " + f"the mapping {e['tut_name']!r}") if by_name[name]["result"] == t["result"]: agree += 1 else: