diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:43:28 +0300 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:56:09 +0300 |
commit | 1b68f71348ecf3983b76b40d7940da8377f049b7 (patch) | |
tree | 2974eddaef130a067c26033d60a59fc790365b3d /indra/llcorehttp/tests | |
parent | af4ea94efc1999f3b19fd8d643d0331f0b77e265 (diff) |
#824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed
Diffstat (limited to 'indra/llcorehttp/tests')
-rwxr-xr-x | indra/llcorehttp/tests/llcorehttp_test.cpp | 148 | ||||
-rw-r--r-- | indra/llcorehttp/tests/llcorehttp_test.h | 26 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_allocator.cpp | 144 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_allocator.h | 2 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_bufferarray.hpp | 576 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_bufferstream.hpp | 288 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_httpheaders.hpp | 586 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_httpoperation.hpp | 106 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_httprequest.hpp | 5248 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_httprequestqueue.hpp | 124 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_httpstatus.hpp | 364 | ||||
-rwxr-xr-x | indra/llcorehttp/tests/test_llcorehttp_peer.py | 6 | ||||
-rw-r--r-- | indra/llcorehttp/tests/test_refcounted.hpp | 136 |
13 files changed, 3877 insertions, 3877 deletions
diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp index 362b2309ee..c0cc2c8030 100755 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llcorehttp_test * @brief Main test runner * @@ -56,26 +56,26 @@ void ssl_thread_id_callback(CRYPTO_THREADID*); void ssl_locking_callback(int mode, int type, const char * file, int line); -#if 0 // lltut provides main and runner +#if 0 // lltut provides main and runner namespace tut { - test_runner_singleton runner; + test_runner_singleton runner; } int main() { - curl_global_init(CURL_GLOBAL_ALL); + curl_global_init(CURL_GLOBAL_ALL); - // *FIXME: Need threaded/SSL curl setup here. - - tut::reporter reporter; + // *FIXME: Need threaded/SSL curl setup here. - tut::runner.get().set_callback(&reporter); - tut::runner.get().run_tests(); - return !reporter.all_ok(); + tut::reporter reporter; - curl_global_cleanup(); + tut::runner.get().set_callback(&reporter); + tut::runner.get().run_tests(); + return !reporter.all_ok(); + + curl_global_cleanup(); } #endif // 0 @@ -85,95 +85,95 @@ LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; void init_curl() { - curl_global_init(CURL_GLOBAL_ALL); - - ssl_mutex_count = CRYPTO_num_locks(); - if (ssl_mutex_count > 0) - { - ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; - - for (int i(0); i < ssl_mutex_count; ++i) - { - ssl_mutex_list[i] = new LLCoreInt::HttpMutex; - } - - CRYPTO_set_locking_callback(ssl_locking_callback); - CRYPTO_THREADID_set_callback(ssl_thread_id_callback); - } - - LLProxy::getInstance(); + curl_global_init(CURL_GLOBAL_ALL); + + ssl_mutex_count = CRYPTO_num_locks(); + if (ssl_mutex_count > 0) + { + ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; + + for (int i(0); i < ssl_mutex_count; ++i) + { + ssl_mutex_list[i] = new LLCoreInt::HttpMutex; + } + + CRYPTO_set_locking_callback(ssl_locking_callback); + CRYPTO_THREADID_set_callback(ssl_thread_id_callback); + } + + LLProxy::getInstance(); } void term_curl() { - SUBSYSTEM_CLEANUP(LLProxy); - - CRYPTO_set_locking_callback(NULL); - for (int i(0); i < ssl_mutex_count; ++i) - { - delete ssl_mutex_list[i]; - } - delete [] ssl_mutex_list; + SUBSYSTEM_CLEANUP(LLProxy); + + CRYPTO_set_locking_callback(NULL); + for (int i(0); i < ssl_mutex_count; ++i) + { + delete ssl_mutex_list[i]; + } + delete [] ssl_mutex_list; } void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid) { #if defined(WIN32) - CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread()); + CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread()); #else - CRYPTO_THREADID_set_pointer(pthreadid, pthread_self()); + CRYPTO_THREADID_set_pointer(pthreadid, pthread_self()); #endif } void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) { - if (type >= 0 && type < ssl_mutex_count) - { - if (mode & CRYPTO_LOCK) - { - ssl_mutex_list[type]->lock(); - } - else - { - ssl_mutex_list[type]->unlock(); - } - } + if (type >= 0 && type < ssl_mutex_count) + { + if (mode & CRYPTO_LOCK) + { + ssl_mutex_list[type]->lock(); + } + else + { + ssl_mutex_list[type]->unlock(); + } + } } 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(); + 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); - } - } + 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 index a9567435ce..133cb3121a 100644 --- a/indra/llcorehttp/tests/llcorehttp_test.h +++ b/indra/llcorehttp/tests/llcorehttp_test.h @@ -1,4 +1,4 @@ -/** +/** * @file llcorehttp_test.h * @brief Main test runner * @@ -26,9 +26,9 @@ #ifndef _LLCOREHTTP_TEST_H_ -#define _LLCOREHTTP_TEST_H_ +#define _LLCOREHTTP_TEST_H_ -#include "linden_common.h" // Modifies curl interfaces +#include "linden_common.h" // Modifies curl interfaces #include <curl/curl.h> #include <openssl/crypto.h> @@ -49,16 +49,16 @@ extern void stop_thread(LLCore::HttpRequest * req); class ScopedCurlInit { public: - ScopedCurlInit() - { - init_curl(); - } + ScopedCurlInit() + { + init_curl(); + } - ~ScopedCurlInit() - { - term_curl(); - } + ~ScopedCurlInit() + { + term_curl(); + } }; - -#endif // _LLCOREHTTP_TEST_H_ + +#endif // _LLCOREHTTP_TEST_H_ diff --git a/indra/llcorehttp/tests/test_allocator.cpp b/indra/llcorehttp/tests/test_allocator.cpp index 597e0d2fc9..757736acbb 100644 --- a/indra/llcorehttp/tests/test_allocator.cpp +++ b/indra/llcorehttp/tests/test_allocator.cpp @@ -1,4 +1,4 @@ -/** +/** * @file test_allocator.cpp * @brief quick and dirty allocator for tracking memory allocations * @@ -45,15 +45,15 @@ struct BlockHeader { - struct Block * next; - std::size_t size; - bool in_use; + struct Block * next; + std::size_t size; + bool in_use; }; struct Block { - BlockHeader hdr; - unsigned char data[1]; + BlockHeader hdr; + unsigned char data[1]; }; #define TRACE_MSG(val) std::cout << __FUNCTION__ << "(" << val << ") [" << __FILE__ << ":" << __LINE__ << "]" << std::endl; @@ -66,109 +66,109 @@ volatile std::size_t MemTotal = 0; static bool CAS(void * volatile * ptr, void * expected, void * new_value) { #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 - return OSAtomicCompareAndSwapPtr( expected, new_value, ptr ); + return OSAtomicCompareAndSwapPtr( expected, new_value, ptr ); #elif defined(_MSC_VER) - return expected == InterlockedCompareExchangePointer( ptr, new_value, expected ); + return expected == InterlockedCompareExchangePointer( ptr, new_value, expected ); #elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ ) > 40100 - return __sync_bool_compare_and_swap( ptr, expected, new_value ); + return __sync_bool_compare_and_swap( ptr, expected, new_value ); #endif } static void * GetMem(std::size_t size) { - // TRACE_MSG(size); - volatile Block * pBlock = NULL; - volatile Block * pNewNext = NULL; - - // do a lock-free update of the global next pointer - do - { - pBlock = pNext; - pNewNext = (volatile Block *)(pBlock->data + size); - - } while(! CAS((void * volatile *) &pNext, (void *) pBlock, (void *) pNewNext)); - - // if we get here, we safely carved out a block of memory in the - // memory pool... - - // initialize our block - pBlock->hdr.next = (Block *)(pBlock->data + size); - pBlock->hdr.size = size; - pBlock->hdr.in_use = true; - memset((void *) pBlock->data, 0, pBlock->hdr.size); - - // do a lock-free update of the global memory total - volatile size_t total = 0; - volatile size_t new_total = 0; - do - { - total = MemTotal; - new_total = total + size; - - } while (! CAS((void * volatile *) &MemTotal, (void *) total, (void *) new_total)); - - return (void *) pBlock->data; + // TRACE_MSG(size); + volatile Block * pBlock = NULL; + volatile Block * pNewNext = NULL; + + // do a lock-free update of the global next pointer + do + { + pBlock = pNext; + pNewNext = (volatile Block *)(pBlock->data + size); + + } while(! CAS((void * volatile *) &pNext, (void *) pBlock, (void *) pNewNext)); + + // if we get here, we safely carved out a block of memory in the + // memory pool... + + // initialize our block + pBlock->hdr.next = (Block *)(pBlock->data + size); + pBlock->hdr.size = size; + pBlock->hdr.in_use = true; + memset((void *) pBlock->data, 0, pBlock->hdr.size); + + // do a lock-free update of the global memory total + volatile size_t total = 0; + volatile size_t new_total = 0; + do + { + total = MemTotal; + new_total = total + size; + + } while (! CAS((void * volatile *) &MemTotal, (void *) total, (void *) new_total)); + + return (void *) pBlock->data; } static void FreeMem(void * p) { - // get the pointer to the block record - Block * pBlock = (Block *)((unsigned char *) p - sizeof(BlockHeader)); - - // TRACE_MSG(pBlock->hdr.size); - bool * cur_in_use = &(pBlock->hdr.in_use); - volatile bool in_use = false; - bool new_in_use = false; - do - { - in_use = pBlock->hdr.in_use; - } while (! CAS((void * volatile *) cur_in_use, (void *) in_use, (void *) new_in_use)); - - // do a lock-free update of the global memory total - volatile size_t total = 0; - volatile size_t new_total = 0; - do - { - total = MemTotal; - new_total = total - pBlock->hdr.size; - } while (! CAS((void * volatile *)&MemTotal, (void *) total, (void *) new_total)); + // get the pointer to the block record + Block * pBlock = (Block *)((unsigned char *) p - sizeof(BlockHeader)); + + // TRACE_MSG(pBlock->hdr.size); + bool * cur_in_use = &(pBlock->hdr.in_use); + volatile bool in_use = false; + bool new_in_use = false; + do + { + in_use = pBlock->hdr.in_use; + } while (! CAS((void * volatile *) cur_in_use, (void *) in_use, (void *) new_in_use)); + + // do a lock-free update of the global memory total + volatile size_t total = 0; + volatile size_t new_total = 0; + do + { + total = MemTotal; + new_total = total - pBlock->hdr.size; + } while (! CAS((void * volatile *)&MemTotal, (void *) total, (void *) new_total)); } std::size_t GetMemTotal() { - return MemTotal; + return MemTotal; } void * operator new(std::size_t size) //throw(std::bad_alloc) { - return GetMem( size ); + return GetMem( size ); } void * operator new[](std::size_t size) //throw(std::bad_alloc) { - return GetMem( size ); + return GetMem( size ); } void operator delete(void * p) throw() { - if (p) - { - FreeMem( p ); - } + if (p) + { + FreeMem( p ); + } } void operator delete[](void * p) throw() { - if (p) - { - FreeMem( p ); - } + if (p) + { + FreeMem( p ); + } } diff --git a/indra/llcorehttp/tests/test_allocator.h b/indra/llcorehttp/tests/test_allocator.h index abd88f4c98..2a06431d1b 100644 --- a/indra/llcorehttp/tests/test_allocator.h +++ b/indra/llcorehttp/tests/test_allocator.h @@ -1,4 +1,4 @@ -/** +/** * @file test_allocator.h * @brief quick and dirty allocator for tracking memory allocations * diff --git a/indra/llcorehttp/tests/test_bufferarray.hpp b/indra/llcorehttp/tests/test_bufferarray.hpp index cc4ad2a906..2a272e73d7 100644 --- a/indra/llcorehttp/tests/test_bufferarray.hpp +++ b/indra/llcorehttp/tests/test_bufferarray.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_bufferarray.hpp * @brief unit tests for the LLCore::BufferArray class * @@ -40,8 +40,8 @@ namespace tut struct BufferArrayTestData { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. }; typedef test_group<BufferArrayTestData> BufferArrayTestGroupType; @@ -51,327 +51,327 @@ 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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 diff --git a/indra/llcorehttp/tests/test_bufferstream.hpp b/indra/llcorehttp/tests/test_bufferstream.hpp index 2739a6e38e..556abf45a2 100644 --- a/indra/llcorehttp/tests/test_bufferstream.hpp +++ b/indra/llcorehttp/tests/test_bufferstream.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_bufferstream.hpp * @brief unit tests for the LLCore::BufferArrayStreamBuf/BufferArrayStream classes * @@ -42,8 +42,8 @@ namespace tut struct BufferStreamTestData { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. }; typedef test_group<BufferStreamTestData> BufferStreamTestGroupType; @@ -55,194 +55,194 @@ typedef BufferArrayStreamBuf::traits_type tst_traits_t; template <> template <> void BufferStreamTestObjectType::test<1>() { - 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)); - - // release the implicit reference, causing the object to be released - delete bsb; - bsb = NULL; + 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)); + + // release the implicit reference, causing the object to be released + delete bsb; + bsb = NULL; } template <> template <> void BufferStreamTestObjectType::test<2>() { - 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()); - - // release the implicit reference, causing the object to be released - delete bas; - bas = NULL; + 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()); + + // release the implicit reference, causing the object to be released + delete bas; + bas = NULL; } template <> template <> void BufferStreamTestObjectType::test<3>() { - 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); - - // I can release my ref on the BA - ba->release(); - ba = NULL; - - // release the implicit reference, causing the object to be released - delete bsb; - bsb = NULL; + 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); + + // I can release my ref on the BA + ba->release(); + ba = NULL; + + // release the implicit reference, causing the object to be released + delete bsb; + bsb = NULL; } template <> template <> void BufferStreamTestObjectType::test<4>() { - set_test_name("BufferArrayStream construction with empty BufferArray"); + set_test_name("BufferArrayStream construction with empty BufferArray"); - // create a new ref counted BufferArray with implicit reference - BufferArray * ba = new BufferArray; + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; - { - // create a new ref counted object with an implicit reference - BufferArrayStream bas(ba); - } + { + // create a new ref counted object with an implicit reference + BufferArrayStream bas(ba); + } - // release the implicit reference, causing the object to be released - ba->release(); - ba = NULL; + // release the implicit reference, causing the object to be released + ba->release(); + ba = NULL; } template <> template <> void BufferStreamTestObjectType::test<5>() { - 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."); - const size_t c_len(strlen(content)); - ba->append(content, c_len); - - // Creat an adapter for the BufferArray - BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); - - // I can release my ref on the BA - ba->release(); - 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('!')); - - // release the implicit reference, causing the object to be released - delete bsb; - bsb = NULL; + 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."); + const size_t c_len(strlen(content)); + ba->append(content, c_len); + + // Creat an adapter for the BufferArray + BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); + + // I can release my ref on the BA + ba->release(); + 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('!')); + + // release the implicit reference, causing the object to be released + delete bsb; + bsb = NULL; } template <> template <> void BufferStreamTestObjectType::test<6>() { - 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."); - //const size_t c_len(strlen(content)); - //ba->append(content, strlen(content)); - - { - // Creat an adapter for the BufferArray - BufferArrayStream bas(ba); - - // Basic operations - bas << "Hello" << 27 << "."; - ensure("BA length 8", ba->size() == 8); - - std::string str; - bas >> str; - ensure("reads correctly", str == "Hello27."); - } - - // release the implicit reference, causing the object to be released - ba->release(); - ba = NULL; + 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."); + //const size_t c_len(strlen(content)); + //ba->append(content, strlen(content)); + + { + // Creat an adapter for the BufferArray + BufferArrayStream bas(ba); + + // Basic operations + bas << "Hello" << 27 << "."; + ensure("BA length 8", ba->size() == 8); + + std::string str; + bas >> str; + ensure("reads correctly", str == "Hello27."); + } + + // release the implicit reference, causing the object to be released + ba->release(); + ba = NULL; } template <> template <> void BufferStreamTestObjectType::test<7>() { - set_test_name("BufferArrayStream with LLSD serialization"); + set_test_name("BufferArrayStream with LLSD serialization"); + + // create a new ref counted BufferArray with implicit reference + BufferArray * ba = new BufferArray; - // create a new ref counted BufferArray with implicit reference - BufferArray * ba = new BufferArray; + { + // Creat an adapter for the BufferArray + BufferArrayStream bas(ba); - { - // Creat an adapter for the BufferArray - BufferArrayStream bas(ba); + // LLSD + LLSD llsd = LLSD::emptyMap(); - // LLSD - LLSD llsd = LLSD::emptyMap(); + llsd["int"] = LLSD::Integer(3); + llsd["float"] = LLSD::Real(923289.28992); + llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj"); - llsd["int"] = LLSD::Integer(3); - llsd["float"] = LLSD::Real(923289.28992); - llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj"); + LLSD llsd_map = LLSD::emptyMap(); + llsd_map["int"] = LLSD::Integer(-2889); + llsd_map["float"] = LLSD::Real(2.37829e32); + llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP"); - LLSD llsd_map = LLSD::emptyMap(); - llsd_map["int"] = LLSD::Integer(-2889); - llsd_map["float"] = LLSD::Real(2.37829e32); - llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP"); + llsd["map"] = llsd_map; - llsd["map"] = llsd_map; - - // Serialize it - LLSDSerialize::toXML(llsd, bas); + // Serialize it + LLSDSerialize::toXML(llsd, bas); - std::string str; - bas >> str; - // std::cout << "SERIALIZED LLSD: " << str << std::endl; - ensure("Extracted string has reasonable length", str.size() > 60); - } + std::string str; + bas >> str; + // std::cout << "SERIALIZED LLSD: " << str << std::endl; + ensure("Extracted string has reasonable length", str.size() > 60); + } - // release the implicit reference, causing the object to be released - ba->release(); - ba = NULL; + // release the implicit reference, causing the object to be released + ba->release(); + ba = NULL; } diff --git a/indra/llcorehttp/tests/test_httpheaders.hpp b/indra/llcorehttp/tests/test_httpheaders.hpp index 6aefb5054b..d8eff78ca5 100644 --- a/indra/llcorehttp/tests/test_httpheaders.hpp +++ b/indra/llcorehttp/tests/test_httpheaders.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_httpheaders.hpp * @brief unit tests for the LLCore::HttpHeaders class * @@ -39,8 +39,8 @@ namespace tut struct HttpHeadersTestData { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. }; typedef test_group<HttpHeadersTestData> HttpHeadersTestGroupType; @@ -50,181 +50,181 @@ HttpHeadersTestGroupType HttpHeadersTestGroup("HttpHeaders Tests"); template <> template <> void HttpHeadersTestObjectType::test<1>() { - set_test_name("HttpHeaders construction"); + 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()); + // 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()); - // release the implicit reference, causing the object to be released + // release the implicit reference, causing the object to be released headers.reset(); } template <> template <> void HttpHeadersTestObjectType::test<2>() { - set_test_name("HttpHeaders construction"); - - // create a new ref counted object with an implicit reference - HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); - - { - // Append a few strings - std::string str1n("Pragma"); - std::string str1v(""); - headers->append(str1n, str1v); - std::string str2n("Accept"); - std::string str2v("application/json"); - headers->append(str2n, str2v); - - ensure("Headers retained", 2 == headers->size()); - 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); - } - - // release the implicit reference, causing the object to be released + set_test_name("HttpHeaders construction"); + + // create a new ref counted object with an implicit reference + HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); + + { + // Append a few strings + std::string str1n("Pragma"); + std::string str1v(""); + headers->append(str1n, str1v); + std::string str2n("Accept"); + std::string str2v("application/json"); + headers->append(str2n, str2v); + + ensure("Headers retained", 2 == headers->size()); + 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); + } + + // release the implicit reference, causing the object to be released headers.reset(); } template <> template <> void HttpHeadersTestObjectType::test<3>() { - 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()); - - { - // Append a few strings - std::string str1n("Uno"); - std::string str1v("1"); - headers->append(str1n, str1v); - std::string str2n("doS"); - std::string str2v("2-2-2-2"); - headers->append(str2n, str2v); - std::string str3n("TRES"); - std::string str3v("trois gymnopedie"); - headers->append(str3n, str3v); - - ensure("Headers retained", 3 == headers->size()); - - 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); - - // appends above are raw and find is case sensitive - result = headers->find("TReS"); - ensure("Last item not found due to case", result == NULL); - - result = headers->find("TRE"); - ensure("Last item not found due to prefixing (1)", result == NULL); - - result = headers->find("TRESS"); - ensure("Last item not found due to prefixing (2)", result == NULL); - } - - // release the implicit reference, causing the object to be released + 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()); + + { + // Append a few strings + std::string str1n("Uno"); + std::string str1v("1"); + headers->append(str1n, str1v); + std::string str2n("doS"); + std::string str2v("2-2-2-2"); + headers->append(str2n, str2v); + std::string str3n("TRES"); + std::string str3v("trois gymnopedie"); + headers->append(str3n, str3v); + + ensure("Headers retained", 3 == headers->size()); + + 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); + + // appends above are raw and find is case sensitive + result = headers->find("TReS"); + ensure("Last item not found due to case", result == NULL); + + result = headers->find("TRE"); + ensure("Last item not found due to prefixing (1)", result == NULL); + + result = headers->find("TRESS"); + ensure("Last item not found due to prefixing (2)", result == NULL); + } + + // release the implicit reference, causing the object to be released headers.reset(); } template <> template <> void HttpHeadersTestObjectType::test<4>() { - set_test_name("HttpHeaders normalized header entry"); + set_test_name("HttpHeaders normalized header entry"); - // create a new ref counted object with an implicit reference + // create a new ref counted object with an implicit reference HttpHeaders::ptr_t headers = HttpHeaders::ptr_t(new HttpHeaders()); - { - static char line1[] = " AcCePT : image/yourfacehere"; - static char line1v[] = "image/yourfacehere"; - headers->appendNormal(line1, sizeof(line1) - 1); - - ensure("First append worked in some fashion", 1 == headers->size()); - - 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); - - // Left-clean on value - static char line2[] = " next : \t\tlinejunk \t"; - headers->appendNormal(line2, sizeof(line2) - 1); - ensure("Second append worked", 2 == headers->size()); - result = headers->find("next"); - ensure("Found 'next'", result != NULL); - ensure("next value is left-clean", 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); - - // 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()); - result = headers->find("fancy-pants"); - ensure("Found 'fancy-pants'", result != NULL); - ensure("fancy-pants value has colons", 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()); - 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); - - // 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()); - result = headers->find(""); - ensure("Found no-name", result != NULL); - ensure("no-name value is something", 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()); - result = headers->find(""); - ensure("Found 2nd no-name", result != NULL); - ensure("2nd no-name value is nothing", result != NULL && result->size() == 0); - - // Line without colons is taken as-is and unstripped in name - static char line7[] = " \toskdgioasdghaosdghoowg28342908tg8902hg0hwedfhqew890v7qh0wdebv78q0wdevbhq>?M>BNM<ZV>?NZ? \t"; - headers->appendNormal(line7, sizeof(line7) - 1); - ensure("Seventh append worked", 2 == headers->size()); - result = headers->find(line7); - ensure("Found whatsit line", result != NULL); - ensure("Whatsit line has no value", 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()); - result = headers->find("binary"); - ensure("Found 'binary'", result != NULL); - ensure("binary value was limited to 'ignore'", result != NULL && - *result == "ignore"); - - } - - // release the implicit reference, causing the object to be released + { + static char line1[] = " AcCePT : image/yourfacehere"; + static char line1v[] = "image/yourfacehere"; + headers->appendNormal(line1, sizeof(line1) - 1); + + ensure("First append worked in some fashion", 1 == headers->size()); + + 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); + + // Left-clean on value + static char line2[] = " next : \t\tlinejunk \t"; + headers->appendNormal(line2, sizeof(line2) - 1); + ensure("Second append worked", 2 == headers->size()); + result = headers->find("next"); + ensure("Found 'next'", result != NULL); + ensure("next value is left-clean", 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); + + // 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()); + result = headers->find("fancy-pants"); + ensure("Found 'fancy-pants'", result != NULL); + ensure("fancy-pants value has colons", 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()); + 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); + + // 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()); + result = headers->find(""); + ensure("Found no-name", result != NULL); + ensure("no-name value is something", 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()); + result = headers->find(""); + ensure("Found 2nd no-name", result != NULL); + ensure("2nd no-name value is nothing", result != NULL && result->size() == 0); + + // Line without colons is taken as-is and unstripped in name + static char line7[] = " \toskdgioasdghaosdghoowg28342908tg8902hg0hwedfhqew890v7qh0wdebv78q0wdevbhq>?M>BNM<ZV>?NZ? \t"; + headers->appendNormal(line7, sizeof(line7) - 1); + ensure("Seventh append worked", 2 == headers->size()); + result = headers->find(line7); + ensure("Found whatsit line", result != NULL); + ensure("Whatsit line has no value", 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()); + result = headers->find("binary"); + ensure("Found 'binary'", result != NULL); + ensure("binary value was limited to 'ignore'", result != NULL && + *result == "ignore"); + + } + + // release the implicit reference, causing the object to be released headers.reset(); } @@ -232,79 +232,79 @@ void HttpHeadersTestObjectType::test<4>() template <> template <> void HttpHeadersTestObjectType::test<5>() { - set_test_name("HttpHeaders iterator tests"); + set_test_name("HttpHeaders iterator tests"); - // create a new ref counted object with an implicit reference + // 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); - HttpHeaders::const_iterator cend(headers->end()), cbegin(headers->begin()); - ensure("Empty container has equal rbegin/rend const iterators", cend == cbegin); - - ensure("Empty container has equal begin/end iterators", headers->end() == headers->begin()); - - { - static char line1[] = " AcCePT : image/yourfacehere"; - static char line1v[] = "image/yourfacehere"; - headers->appendNormal(line1, sizeof(line1) - 1); - - static char line2[] = " next : \t\tlinejunk \t"; - static char line2v[] = "linejunk \t"; - headers->appendNormal(line2, sizeof(line2) - 1); - - static char line3[] = "FancY-PANTs::plop:-neuf-=vleem="; - static char line3v[] = ":plop:-neuf-=vleem="; - headers->appendNormal(line3, sizeof(line3) - 1); - - static char line4[] = "all-talk-no-walk:"; - static char line4v[] = ""; - headers->appendNormal(line4, sizeof(line4) - 1); - - static char line5[] = ":all-talk-no-walk"; - static char line5v[] = "all-talk-no-walk"; - headers->appendNormal(line5, sizeof(line5) - 1); - - static char line6[] = " :"; - static char line6v[] = ""; - headers->appendNormal(line6, sizeof(line6) - 1); - - ensure("All entries accounted for", 6 == headers->size()); - - static char * values[] = { - line1v, - line2v, - line3v, - line4v, - line5v, - line6v - }; - - int i(0); - HttpHeaders::const_iterator cend(headers->end()); - for (HttpHeaders::const_iterator it(headers->begin()); - cend != it; - ++it, ++i) - { - std::ostringstream str; - str << "Const Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); - } - - // Rewind, do non-consts - i = 0; - HttpHeaders::iterator end(headers->end()); - for (HttpHeaders::iterator it(headers->begin()); - end != it; - ++it, ++i) - { - std::ostringstream str; - str << "Const Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); - } - } - - // release the implicit reference, causing the object to be released + HttpHeaders::iterator end(headers->end()), begin(headers->begin()); + ensure("Empty container has equal begin/end const iterators", end == begin); + HttpHeaders::const_iterator cend(headers->end()), cbegin(headers->begin()); + ensure("Empty container has equal rbegin/rend const iterators", cend == cbegin); + + ensure("Empty container has equal begin/end iterators", headers->end() == headers->begin()); + + { + static char line1[] = " AcCePT : image/yourfacehere"; + static char line1v[] = "image/yourfacehere"; + headers->appendNormal(line1, sizeof(line1) - 1); + + static char line2[] = " next : \t\tlinejunk \t"; + static char line2v[] = "linejunk \t"; + headers->appendNormal(line2, sizeof(line2) - 1); + + static char line3[] = "FancY-PANTs::plop:-neuf-=vleem="; + static char line3v[] = ":plop:-neuf-=vleem="; + headers->appendNormal(line3, sizeof(line3) - 1); + + static char line4[] = "all-talk-no-walk:"; + static char line4v[] = ""; + headers->appendNormal(line4, sizeof(line4) - 1); + + static char line5[] = ":all-talk-no-walk"; + static char line5v[] = "all-talk-no-walk"; + headers->appendNormal(line5, sizeof(line5) - 1); + + static char line6[] = " :"; + static char line6v[] = ""; + headers->appendNormal(line6, sizeof(line6) - 1); + + ensure("All entries accounted for", 6 == headers->size()); + + static char * values[] = { + line1v, + line2v, + line3v, + line4v, + line5v, + line6v + }; + + int i(0); + HttpHeaders::const_iterator cend(headers->end()); + for (HttpHeaders::const_iterator it(headers->begin()); + cend != it; + ++it, ++i) + { + std::ostringstream str; + str << "Const Iterator value # " << i << " was " << values[i]; + ensure(str.str(), (*it).second == values[i]); + } + + // Rewind, do non-consts + i = 0; + HttpHeaders::iterator end(headers->end()); + for (HttpHeaders::iterator it(headers->begin()); + end != it; + ++it, ++i) + { + std::ostringstream str; + str << "Const Iterator value # " << i << " was " << values[i]; + ensure(str.str(), (*it).second == values[i]); + } + } + + // release the implicit reference, causing the object to be released headers.reset(); } @@ -312,77 +312,77 @@ void HttpHeadersTestObjectType::test<5>() template <> template <> void HttpHeadersTestObjectType::test<6>() { - set_test_name("HttpHeaders reverse iterator tests"); + set_test_name("HttpHeaders reverse iterator tests"); - // create a new ref counted object with an implicit reference + // 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); - HttpHeaders::const_reverse_iterator crend(headers->rend()), crbegin(headers->rbegin()); - ensure("Empty container has equal rbegin/rend const iterators", crend == crbegin); - - { - static char line1[] = " AcCePT : image/yourfacehere"; - static char line1v[] = "image/yourfacehere"; - headers->appendNormal(line1, sizeof(line1) - 1); - - static char line2[] = " next : \t\tlinejunk \t"; - static char line2v[] = "linejunk \t"; - headers->appendNormal(line2, sizeof(line2) - 1); - - static char line3[] = "FancY-PANTs::plop:-neuf-=vleem="; - static char line3v[] = ":plop:-neuf-=vleem="; - headers->appendNormal(line3, sizeof(line3) - 1); - - static char line4[] = "all-talk-no-walk:"; - static char line4v[] = ""; - headers->appendNormal(line4, sizeof(line4) - 1); - - static char line5[] = ":all-talk-no-walk"; - static char line5v[] = "all-talk-no-walk"; - headers->appendNormal(line5, sizeof(line5) - 1); - - static char line6[] = " :"; - static char line6v[] = ""; - headers->appendNormal(line6, sizeof(line6) - 1); - - ensure("All entries accounted for", 6 == headers->size()); - - static char * values[] = { - line6v, - line5v, - line4v, - line3v, - line2v, - line1v - }; - - int i(0); - HttpHeaders::const_reverse_iterator cend(headers->rend()); - for (HttpHeaders::const_reverse_iterator it(headers->rbegin()); - cend != it; - ++it, ++i) - { - std::ostringstream str; - str << "Const Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); - } - - // Rewind, do non-consts - i = 0; - HttpHeaders::reverse_iterator end(headers->rend()); - for (HttpHeaders::reverse_iterator it(headers->rbegin()); - end != it; - ++it, ++i) - { - std::ostringstream str; - str << "Iterator value # " << i << " was " << values[i]; - ensure(str.str(), (*it).second == values[i]); - } - } - - // release the implicit reference, causing the object to be released + HttpHeaders::reverse_iterator rend(headers->rend()), rbegin(headers->rbegin()); + ensure("Empty container has equal rbegin/rend const iterators", rend == rbegin); + HttpHeaders::const_reverse_iterator crend(headers->rend()), crbegin(headers->rbegin()); + ensure("Empty container has equal rbegin/rend const iterators", crend == crbegin); + + { + static char line1[] = " AcCePT : image/yourfacehere"; + static char line1v[] = "image/yourfacehere"; + headers->appendNormal(line1, sizeof(line1) - 1); + + static char line2[] = " next : \t\tlinejunk \t"; + static char line2v[] = "linejunk \t"; + headers->appendNormal(line2, sizeof(line2) - 1); + + static char line3[] = "FancY-PANTs::plop:-neuf-=vleem="; + static char line3v[] = ":plop:-neuf-=vleem="; + headers->appendNormal(line3, sizeof(line3) - 1); + + static char line4[] = "all-talk-no-walk:"; + static char line4v[] = ""; + headers->appendNormal(line4, sizeof(line4) - 1); + + static char line5[] = ":all-talk-no-walk"; + static char line5v[] = "all-talk-no-walk"; + headers->appendNormal(line5, sizeof(line5) - 1); + + static char line6[] = " :"; + static char line6v[] = ""; + headers->appendNormal(line6, sizeof(line6) - 1); + + ensure("All entries accounted for", 6 == headers->size()); + + static char * values[] = { + line6v, + line5v, + line4v, + line3v, + line2v, + line1v + }; + + int i(0); + HttpHeaders::const_reverse_iterator cend(headers->rend()); + for (HttpHeaders::const_reverse_iterator it(headers->rbegin()); + cend != it; + ++it, ++i) + { + std::ostringstream str; + str << "Const Iterator value # " << i << " was " << values[i]; + ensure(str.str(), (*it).second == values[i]); + } + + // Rewind, do non-consts + i = 0; + HttpHeaders::reverse_iterator end(headers->rend()); + for (HttpHeaders::reverse_iterator it(headers->rbegin()); + end != it; + ++it, ++i) + { + std::ostringstream str; + str << "Iterator value # " << i << " was " << values[i]; + ensure(str.str(), (*it).second == values[i]); + } + } + + // release the implicit reference, causing the object to be released headers.reset(); } diff --git a/indra/llcorehttp/tests/test_httpoperation.hpp b/indra/llcorehttp/tests/test_httpoperation.hpp index c6407e8d04..6778c3440b 100644 --- a/indra/llcorehttp/tests/test_httpoperation.hpp +++ b/indra/llcorehttp/tests/test_httpoperation.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_httpoperation.hpp * @brief unit tests for the LLCore::HttpOperation-derived classes * @@ -41,11 +41,11 @@ namespace class TestHandler : public LLCore::HttpHandler { public: - virtual void onCompleted(HttpHandle, HttpResponse *) - { - std::cout << "TestHandler::onCompleted() invoked" << std::endl; - } - + virtual void onCompleted(HttpHandle, HttpResponse *) + { + std::cout << "TestHandler::onCompleted() invoked" << std::endl; + } + }; @@ -54,53 +54,53 @@ public: namespace tut { - struct HttpOperationTestData - { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. - }; - - typedef test_group<HttpOperationTestData> 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); - - // release the implicit reference, causing the object to be released - op.reset(); - } - - template <> template <> - void HttpOperationTestObjectType::test<2>() - { - set_test_name("HttpOpNull construction with handlers"); - - // Get some handlers - LLCore::HttpHandler::ptr_t h1 (new TestHandler()); - - // create a new ref counted object with an implicit reference - HttpOperation::ptr_t op (new HttpOpNull()); - - // Add the handlers - op->setReplyPath(LLCore::HttpOperation::HttpReplyQueuePtr_t(), h1); - - // Check ref count - ensure(op.unique() == 1); - - // release the reference, releasing the operation but - // not the handlers. - op.reset(); - - // release the handlers - h1.reset(); - } + struct HttpOperationTestData + { + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + }; + + typedef test_group<HttpOperationTestData> 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); + + // release the implicit reference, causing the object to be released + op.reset(); + } + + template <> template <> + void HttpOperationTestObjectType::test<2>() + { + set_test_name("HttpOpNull construction with handlers"); + + // Get some handlers + LLCore::HttpHandler::ptr_t h1 (new TestHandler()); + + // create a new ref counted object with an implicit reference + HttpOperation::ptr_t op (new HttpOpNull()); + + // Add the handlers + op->setReplyPath(LLCore::HttpOperation::HttpReplyQueuePtr_t(), h1); + + // Check ref count + ensure(op.unique() == 1); + + // release the reference, releasing the operation but + // not the handlers. + op.reset(); + + // release the handlers + h1.reset(); + } } diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 3eaac10aeb..aed906bb8f 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_httprequest.hpp * @brief unit tests for the LLCore::HttpRequest class * @@ -51,8 +51,8 @@ using namespace LLCoreInt; // loaded system where the unit test is in competition with // other programs. static const int LOOP_SLEEP_INTERVAL(10000); -static const int LOOP_COUNT_SHORT(500); // 5-second dwell time -static const int LOOP_COUNT_LONG(3000); // 30-second dwell time +static const int LOOP_COUNT_SHORT(500); // 5-second dwell time +static const int LOOP_COUNT_LONG(3000); // 30-second dwell time namespace { @@ -72,117 +72,117 @@ typedef std::vector<std::pair<boost::regex, boost::regex> > regex_container_t; struct HttpRequestTestData { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. - int mHandlerCalls; - HttpStatus mStatus; + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. + int mHandlerCalls; + HttpStatus mStatus; }; class TestHandler2 : public LLCore::HttpHandler { public: - TestHandler2(HttpRequestTestData * state, - const std::string & name) - : mState(state), - mName(name), - mExpectHandle(LLCORE_HTTP_HANDLE_INVALID) - {} - - virtual void onCompleted(HttpHandle handle, HttpResponse * response) - { - if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle) - { - ensure("Expected handle received in handler", mExpectHandle == handle); - } - ensure("Handler got a response", NULL != response); - 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); - } - if (mState) - { - mState->mHandlerCalls++; - } - if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty()) - { - ensure("Response required with header check", response != NULL); - HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this - ensure("Some quantity of headers returned", header != NULL); - - if (! mHeadersRequired.empty()) - { - for (int i(0); i < mHeadersRequired.size(); ++i) - { - bool found = false; - for (HttpHeaders::const_iterator iter(header->begin()); - header->end() != iter; - ++iter) - { - // std::cerr << "Header: " << (*iter).first - // << ": " << (*iter).second << std::endl; - - if (boost::regex_match((*iter).first, - mHeadersRequired[i].first) && - boost::regex_match((*iter).second, - mHeadersRequired[i].second)) - { - found = true; - break; - } - } - std::ostringstream str; - str << "Required header #" << i << " " - << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second - << " not found in response"; - ensure(str.str(), found); - } - } - - if (! mHeadersDisallowed.empty()) - { - for (int i(0); i < mHeadersDisallowed.size(); ++i) - { - for (HttpHeaders::const_iterator iter(header->begin()); - header->end() != iter; - ++iter) - { - if (boost::regex_match((*iter).first, - mHeadersDisallowed[i].first) && - boost::regex_match((*iter).second, - mHeadersDisallowed[i].second)) - { - std::ostringstream str; - str << "Disallowed header #" << i << " " - << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second - << " found in response"; - ensure(str.str(), false); - } - } - } - } - } - - if (! mCheckContentType.empty()) - { - ensure("Response required with content type check", response != NULL); - std::string con_type(response->getContentType()); - ensure("Content-Type as expected (" + mCheckContentType + ")", - mCheckContentType == con_type); - } - - // std::cout << "TestHandler2::onCompleted() invoked" << std::endl; - } - - HttpRequestTestData * mState; - std::string mName; - HttpHandle mExpectHandle; - std::string mCheckContentType; - regex_container_t mHeadersRequired; - regex_container_t mHeadersDisallowed; + TestHandler2(HttpRequestTestData * state, + const std::string & name) + : mState(state), + mName(name), + mExpectHandle(LLCORE_HTTP_HANDLE_INVALID) + {} + + virtual void onCompleted(HttpHandle handle, HttpResponse * response) + { + if (LLCORE_HTTP_HANDLE_INVALID != mExpectHandle) + { + ensure("Expected handle received in handler", mExpectHandle == handle); + } + ensure("Handler got a response", NULL != response); + 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); + } + if (mState) + { + mState->mHandlerCalls++; + } + if (! mHeadersRequired.empty() || ! mHeadersDisallowed.empty()) + { + ensure("Response required with header check", response != NULL); + HttpHeaders::ptr_t header(response->getHeaders()); // Will not hold onto this + ensure("Some quantity of headers returned", header != NULL); + + if (! mHeadersRequired.empty()) + { + for (int i(0); i < mHeadersRequired.size(); ++i) + { + bool found = false; + for (HttpHeaders::const_iterator iter(header->begin()); + header->end() != iter; + ++iter) + { + // std::cerr << "Header: " << (*iter).first + // << ": " << (*iter).second << std::endl; + + if (boost::regex_match((*iter).first, + mHeadersRequired[i].first) && + boost::regex_match((*iter).second, + mHeadersRequired[i].second)) + { + found = true; + break; + } + } + std::ostringstream str; + str << "Required header #" << i << " " + << mHeadersRequired[i].first << "=" << mHeadersRequired[i].second + << " not found in response"; + ensure(str.str(), found); + } + } + + if (! mHeadersDisallowed.empty()) + { + for (int i(0); i < mHeadersDisallowed.size(); ++i) + { + for (HttpHeaders::const_iterator iter(header->begin()); + header->end() != iter; + ++iter) + { + if (boost::regex_match((*iter).first, + mHeadersDisallowed[i].first) && + boost::regex_match((*iter).second, + mHeadersDisallowed[i].second)) + { + std::ostringstream str; + str << "Disallowed header #" << i << " " + << mHeadersDisallowed[i].first << "=" << mHeadersDisallowed[i].second + << " found in response"; + ensure(str.str(), false); + } + } + } + } + } + + if (! mCheckContentType.empty()) + { + ensure("Response required with content type check", response != NULL); + std::string con_type(response->getContentType()); + ensure("Content-Type as expected (" + mCheckContentType + ")", + mCheckContentType == con_type); + } + + // std::cout << "TestHandler2::onCompleted() invoked" << std::endl; + } + + HttpRequestTestData * mState; + std::string mName; + HttpHandle mExpectHandle; + std::string mCheckContentType; + regex_container_t mHeadersRequired; + regex_container_t mHeadersDisallowed; }; typedef test_group<HttpRequestTestData> HttpRequestTestGroupType; @@ -192,72 +192,72 @@ HttpRequestTestGroupType HttpRequestTestGroup("HttpRequest Tests"); template <> template <> void HttpRequestTestObjectType::test<1>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest construction"); - - HttpRequest * req = NULL; - - try - { - // Get singletons created - HttpRequest::createService(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // release the request object - delete req; - req = NULL; - - HttpRequest::destroyService(); - } - catch (...) - { - delete req; - HttpRequest::destroyService(); - throw; - } + ScopedCurlInit ready; + + set_test_name("HttpRequest construction"); + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // release the request object + delete req; + req = NULL; + + HttpRequest::destroyService(); + } + catch (...) + { + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<2>() { - ScopedCurlInit ready; - - set_test_name("HttpRequest and Null Op queued"); - - HttpRequest * req = NULL; - - try - { - // Get singletons created - HttpRequest::createService(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a NoOp - HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t()); - ensure("Request issued", 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()); - - // Okay, tear it down - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ScopedCurlInit ready; + + set_test_name("HttpRequest and Null Op queued"); + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a NoOp + HttpHandle handle = req->requestNoOp(LLCore::HttpHandler::ptr_t()); + ensure("Request issued", 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()); + + // Okay, tear it down + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } namespace @@ -268,1243 +268,1243 @@ namespace template <> template <> void HttpRequestTestObjectType::test<3>() { - 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - - try - { - // Get singletons created + HttpRequest * req = NULL; + + try + { + // Get singletons created HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a NoOp - HttpHandle handle = req->requestNoOp(handlerp); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_SHORT); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a NoOp + HttpHandle handle = req->requestNoOp(handlerp); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_SHORT); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<4>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - set_test_name("2 HttpRequest instances, one thread"); + 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"); - TestHandler2 handler2(this, "handler2"); + // Handler can be stack-allocated *if* there are no dangling + // references to it after completion of this method. + TestHandler2 handler1(this, "handler1"); + TestHandler2 handler2(this, "handler2"); LLCore::HttpHandler::ptr_t handler1p(&handler1, NoOpDeletor); LLCore::HttpHandler::ptr_t handler2p(&handler2, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req1 = NULL; - HttpRequest * req2 = NULL; - - try - { - - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req1 = new HttpRequest(); - req2 = new HttpRequest(); - - // Issue some NoOps - HttpHandle handle = req1->requestNoOp(handler1p); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); - handler1.mExpectHandle = handle; - - handle = req2->requestNoOp(handler2p); - ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); - handler2.mExpectHandle = handle; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 2) - { - req1->update(1000000); - req2->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - handler2.mExpectHandle = handle; - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 3) - { - req1->update(1000000); - req2->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 3); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req1; - req1 = NULL; - delete req2; - req2 = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 3 == mHandlerCalls); - } - catch (...) - { - stop_thread(req1); - delete req1; - delete req2; - HttpRequest::destroyService(); - throw; - } + mHandlerCalls = 0; + + HttpRequest * req1 = NULL; + HttpRequest * req2 = NULL; + + try + { + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req1 = new HttpRequest(); + req2 = new HttpRequest(); + + // Issue some NoOps + HttpHandle handle = req1->requestNoOp(handler1p); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler1.mExpectHandle = handle; + + handle = req2->requestNoOp(handler2p); + ensure("Valid handle returned for first request", handle != LLCORE_HTTP_HANDLE_INVALID); + handler2.mExpectHandle = handle; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 2) + { + req1->update(1000000); + req2->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + handler2.mExpectHandle = handle; + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 3) + { + req1->update(1000000); + req2->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 3); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req1; + req1 = NULL; + delete req2; + req2 = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 3 == mHandlerCalls); + } + catch (...) + { + stop_thread(req1); + delete req1; + delete req2; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<5>() { - 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - - try - { - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a Spin - HttpHandle handle = req->requestSpin(1); - ensure("Valid handle returned for spin request", 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); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_SHORT); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("NoOp notification received", mHandlerCalls == 1); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a Spin + HttpHandle handle = req->requestSpin(1); + ensure("Valid handle returned for spin request", 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); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_SHORT); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("NoOp notification received", mHandlerCalls == 1); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<6>() { - 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. - TestHandler2 handler(this, "handler"); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - - try - { + 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. + TestHandler2 handler(this, "handler"); + mHandlerCalls = 0; + + HttpRequest * req = NULL; + + try + { LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a Spin - HttpHandle handle = req->requestSpin(0); // Hard spin - ensure("Valid handle returned for spin request", 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); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_SHORT); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("No notifications received", mHandlerCalls == 0); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a Spin + HttpHandle handle = req->requestSpin(0); // Hard spin + ensure("Valid handle returned for spin request", 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); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_SHORT); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("No notifications received", mHandlerCalls == 0); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<7>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - set_test_name("HttpRequest GET to dead port + Stop execution"); + 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. - TestHandler2 handler(this, "handler"); + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; - - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); opts = HttpOptions::ptr_t(new HttpOptions()); - opts->setRetries(1); // Don't try for too long - default retries take about 18S - - // Issue a GET that can't connect - mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - "http://127.0.0.1:2/nothing/here", - 0, - 0, - opts, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options + opts->setRetries(1); // Don't try for too long - default retries take about 18S + + // Issue a GET that can't connect + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + "http://127.0.0.1:2/nothing/here", + 0, + 0, + opts, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options opts.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<8>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET to real service"); + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - // 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base, - HttpOptions::ptr_t(), + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base, + HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<9>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - 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"); + 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. - TestHandler2 handler(this, "handler"); + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, - HttpOptions::ptr_t(), + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, + HttpOptions::ptr_t(), HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<10>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest PUT to real service"); + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - // 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; + + HttpRequest * req = NULL; + BufferArray * body = new BufferArray; - HttpRequest * req = NULL; - BufferArray * body = new BufferArray; - - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - static const char * body_text("Now is the time for all good men..."); - body->append(body_text, strlen(body_text)); - mStatus = HttpStatus(200); - HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - url_base, - body, + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + static const char * body_text("Now is the time for all good men..."); + body->append(body_text, strlen(body_text)); + mStatus = HttpStatus(200); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + url_base, + body, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // Lose the request body - body->release(); - body = NULL; - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - if (body) - { - body->release(); - } - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // Lose the request body + body->release(); + body = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + if (body) + { + body->release(); + } + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<11>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest POST to real service"); + 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. - TestHandler2 handler(this, "handler"); + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - BufferArray * body = new BufferArray; - - try - { + HttpRequest * req = NULL; + BufferArray * body = new BufferArray; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - static const char * body_text("Now is the time for all good men..."); - body->append(body_text, strlen(body_text)); - mStatus = HttpStatus(200); - HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - url_base, - body, + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + static const char * body_text("Now is the time for all good men..."); + body->append(body_text, strlen(body_text)); + mStatus = HttpStatus(200); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + url_base, + body, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // Lose the request body - body->release(); - body = NULL; - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - if (body) - { - body->release(); - } - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // Lose the request body + body->release(); + body = NULL; + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + if (body) + { + body->release(); + } + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<12>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET with some tracing"); + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - // 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); + HttpRequest::createService(); - // Enable tracing - HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); + // Enable tracing + HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<13>() { - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - 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. - TestHandler2 handler(this, "handler"); - handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + 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. + TestHandler2 handler(this, "handler"); + handler.mHeadersRequired.reserve(20); // Avoid memory leak test failure LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; - try - { + try + { // Get singletons created - HttpRequest::createService(); + HttpRequest::createService(); - // Enable tracing - HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); + // Enable tracing + HttpRequest::setStaticPolicyOption(HttpRequest::PO_TRACE, HttpRequest::DEFAULT_POLICY_ID, 2, NULL); - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); opts = HttpOptions::ptr_t(new HttpOptions()); - opts->setWantHeaders(true); - - // Issue a GET that succeeds - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, - opts, + opts->setWantHeaders(true); + + // Issue a GET that succeeds + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, + opts, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - // release options + // release options opts.reset(); - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<14>() { - 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. - TestHandler2 handler(this, "handler"); - LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; - - try - { - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - opts = HttpOptions::ptr_t(new HttpOptions); - opts->setRetries(0); // Don't retry - opts->setTimeout(2); - - // Issue a GET that sleeps - mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base, - 0, - 0, - opts, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options - opts.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + 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. + TestHandler2 handler(this, "handler"); + LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); + std::string url_base(get_base_url() + "/sleep/"); // path to a 30-second sleep + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; + + try + { + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + opts = HttpOptions::ptr_t(new HttpOptions); + opts->setRetries(0); // Don't retry + opts->setTimeout(2); + + // Issue a GET that sleeps + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base, + 0, + 0, + opts, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options + opts.reset(); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + opts.reset(); + delete req; + HttpRequest::destroyService(); + throw; + } } // Test retrieval of Content-Type/Content-Encoding headers template <> template <> void HttpRequestTestObjectType::test<15>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("HttpRequest GET with Content-Type"); + 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. - TestHandler2 handler(this, "handler"); + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - // Load and clear the string setting to preload std::string object - // for memory return tests. - handler.mCheckContentType = "application/llsd+xml"; - handler.mCheckContentType.clear(); - mHandlerCalls = 0; + // Load and clear the string setting to preload std::string object + // for memory return tests. + handler.mCheckContentType = "application/llsd+xml"; + handler.mCheckContentType.clear(); + mHandlerCalls = 0; - HttpRequest * req = NULL; + HttpRequest * req = NULL; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - handler.mCheckContentType = "application/llsd+xml"; - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base, + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + handler.mCheckContentType = "application/llsd+xml"; + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base, HttpOptions::ptr_t(), HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - - ensure("Two handler calls on the way out", 2 == mHandlerCalls); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + + ensure("Two handler calls on the way out", 2 == mHandlerCalls); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -1512,236 +1512,236 @@ void HttpRequestTestObjectType::test<15>() template <> template <> void HttpRequestTestObjectType::test<16>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest GET"); + std::string url_base(get_base_url()); - // 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // Issue a GET that *can* connect - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 1); - - // Do a texture-style fetch - headers = HttpHeaders::ptr_t(new HttpHeaders); - headers->append("Accept", "image/x-j2c"); - - mStatus = HttpStatus(200); - handler.mHeadersRequired.clear(); - handler.mHeadersDisallowed.clear(); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("image/x-j2c", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("\\W*X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - 0, - 47, - options, - headers, - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", mHandlerCalls == 2); - - - // 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 3) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 3); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // Issue a GET that *can* connect + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 1); + + // Do a texture-style fetch + headers = HttpHeaders::ptr_t(new HttpHeaders); + headers->append("Accept", "image/x-j2c"); + + mStatus = HttpStatus(200); + handler.mHeadersRequired.clear(); + handler.mHeadersDisallowed.clear(); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("image/x-j2c", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("\\W*X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + 0, + 47, + options, + headers, + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", mHandlerCalls == 2); + + + // 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 3) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 3); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -1749,183 +1749,183 @@ void HttpRequestTestObjectType::test<16>() template <> template <> void HttpRequestTestObjectType::test<17>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); + std::string url_base(get_base_url()); - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest POST"); + 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. - TestHandler2 handler(this, "handler"); + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // And a buffer array - const char * msg("It was the best of times, it was the worst of times."); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default POST - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer_encoding", boost::regex::icase), - boost::regex(".*chunked.*", boost::regex::icase))); - HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // And a buffer array + const char * msg("It was the best of times, it was the worst of times."); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default POST + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer_encoding", boost::regex::icase), + boost::regex(".*chunked.*", boost::regex::icase))); + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); delete req; - HttpRequest::destroyService(); - throw; - } + HttpRequest::destroyService(); + throw; + } } @@ -1933,184 +1933,184 @@ void HttpRequestTestObjectType::test<17>() template <> template <> void HttpRequestTestObjectType::test<18>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); - std::string url_base(get_base_url()); - - set_test_name("Header generation for HttpRequest PUT"); + std::string url_base(get_base_url()); - // 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. - TestHandler2 handler(this, "handler"); + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // options set - options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // And a buffer array - const char * msg("It was the best of times, it was the worst of times."); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default PUT - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*chunked.*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set + options = HttpOptions::ptr_t(new HttpOptions()); + options->setWantHeaders(true); + + // And a buffer array + const char * msg("It was the best of times, it was the worst of times."); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default PUT + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*chunked.*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); delete req; - HttpRequest::destroyService(); - throw; - } + HttpRequest::destroyService(); + throw; + } } @@ -2118,189 +2118,189 @@ void HttpRequestTestObjectType::test<18>() template <> template <> void HttpRequestTestObjectType::test<19>() { - // 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? - // - // Test server /reflect/ response headers (mirrored from request) - // - // X-Reflect-content-type: text/plain - // X-Reflect-content-type: text/html - // X-Reflect-content-type: application/llsd+xml - // - skip("FIXME: Bad assertions or broken functionality."); - - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - 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. - TestHandler2 handler(this, "handler"); + // 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? + // + // Test server /reflect/ response headers (mirrored from request) + // + // X-Reflect-content-type: text/plain + // X-Reflect-content-type: text/html + // X-Reflect-content-type: application/llsd+xml + // + skip("FIXME: Bad assertions or broken functionality."); + + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; - try - { + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); - // options set + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // headers - headers = HttpHeaders::ptr_t(new HttpHeaders); - headers->append("Keep-Alive", "120"); - headers->append("Accept-encoding", "deflate"); - headers->append("Accept", "text/plain"); - - // Issue a GET with modified headers - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("text/plain", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("deflate", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("120", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("300", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - options, - headers, - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // headers + headers = HttpHeaders::ptr_t(new HttpHeaders); + headers->append("Keep-Alive", "120"); + headers->append("Accept-encoding", "deflate"); + headers->append("Accept", "text/plain"); + + // Issue a GET with modified headers + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("text/plain", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("deflate", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("120", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("300", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + options, + headers, + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -2308,214 +2308,214 @@ void HttpRequestTestObjectType::test<19>() template <> template <> void HttpRequestTestObjectType::test<20>() { - // 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? - // - // Test server /reflect/ response headers (mirrored from request) - // - // X-Reflect-content-type: text/plain - // X-Reflect-content-type: text/html - // X-Reflect-content-type: application/llsd+xml - // - skip("FIXME: Bad assertions or broken functionality."); - - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - 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. - TestHandler2 handler(this, "handler"); + // 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? + // + // Test server /reflect/ response headers (mirrored from request) + // + // X-Reflect-content-type: text/plain + // X-Reflect-content-type: text/html + // X-Reflect-content-type: application/llsd+xml + // + skip("FIXME: Bad assertions or broken functionality."); + + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // options set + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // headers - headers = HttpHeaders::ptr_t(new HttpHeaders()); - headers->append("keep-Alive", "120"); - headers->append("Accept", "text/html"); - headers->append("content-type", "application/llsd+xml"); - headers->append("cache-control", "no-store"); - - // And a buffer array - const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default POST - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("text/html", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("120", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/llsd\\+xml", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex("no-store", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("300", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - - HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - headers, - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // headers + headers = HttpHeaders::ptr_t(new HttpHeaders()); + headers->append("keep-Alive", "120"); + headers->append("Accept", "text/html"); + headers->append("content-type", "application/llsd+xml"); + headers->append("cache-control", "no-store"); + + // And a buffer array + const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default POST + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("text/html", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("120", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/llsd\\+xml", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex("no-store", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/x-www-form-urlencoded", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("300", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + + HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + headers, + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -2523,516 +2523,516 @@ void HttpRequestTestObjectType::test<20>() template <> template <> void HttpRequestTestObjectType::test<21>() { - // 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? - // - // Test server /reflect/ response headers (mirrored from request) - // - // X-Reflect-content-type: text/plain - // X-Reflect-content-type: text/html - // X-Reflect-content-type: application/llsd+xml - // - skip("FIXME: Bad assertions or broken functionality."); - - ScopedCurlInit ready; - - // Warmup boost::regex to pre-alloc memory for memory size tests - boost::regex warmup("askldjflasdj;f", boost::regex::icase); - boost::regex_match("akl;sjflajfk;ajsk", warmup); - - 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. - TestHandler2 handler(this, "handler"); + // 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? + // + // Test server /reflect/ response headers (mirrored from request) + // + // X-Reflect-content-type: text/plain + // X-Reflect-content-type: text/html + // X-Reflect-content-type: application/llsd+xml + // + skip("FIXME: Bad assertions or broken functionality."); + + ScopedCurlInit ready; + + // Warmup boost::regex to pre-alloc memory for memory size tests + boost::regex warmup("askldjflasdj;f", boost::regex::icase); + boost::regex_match("akl;sjflajfk;ajsk", warmup); + + 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t options; - HttpHeaders::ptr_t headers; - BufferArray * ba = NULL; - - try - { + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpHeaders::ptr_t headers; + BufferArray * ba = NULL; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // options set + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setWantHeaders(true); - - // headers - headers = HttpHeaders::ptr_t(new HttpHeaders); - headers->append("content-type", "text/plain"); - headers->append("content-type", "text/html"); - headers->append("content-type", "application/llsd+xml"); - - // And a buffer array - const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); - ba = new BufferArray; - ba->append(msg, strlen(msg)); - - // Issue a default PUT - mStatus = HttpStatus(200); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-connection", boost::regex::icase), - boost::regex("keep-alive", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept", boost::regex::icase), - boost::regex("\\*/\\*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-accept-encoding", boost::regex::icase), - boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-keep-alive", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-host", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-length", boost::regex::icase), - boost::regex("\\d+", boost::regex::icase))); - handler.mHeadersRequired.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("application/llsd\\+xml", boost::regex::icase))); - - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-cache-control", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-pragma", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-range", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-referer", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-expect", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), - boost::regex(".*", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("text/plain", boost::regex::icase))); - handler.mHeadersDisallowed.push_back( - regex_container_t::value_type( - boost::regex("X-Reflect-content-type", boost::regex::icase), - boost::regex("text/html", boost::regex::icase))); - HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, - url_base + "reflect/", - ba, - options, - headers, - handlerp); - ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); - ba->release(); - ba = NULL; - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 2) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 2); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options & headers + options->setWantHeaders(true); + + // headers + headers = HttpHeaders::ptr_t(new HttpHeaders); + headers->append("content-type", "text/plain"); + headers->append("content-type", "text/html"); + headers->append("content-type", "application/llsd+xml"); + + // And a buffer array + const char * msg("<xml><llsd><string>It was the best of times, it was the worst of times.</string></llsd></xml>"); + ba = new BufferArray; + ba->append(msg, strlen(msg)); + + // Issue a default PUT + mStatus = HttpStatus(200); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-connection", boost::regex::icase), + boost::regex("keep-alive", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept", boost::regex::icase), + boost::regex("\\*/\\*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-accept-encoding", boost::regex::icase), + boost::regex("((gzip|deflate),\\s*)+(gzip|deflate)", boost::regex::icase))); // close enough + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-keep-alive", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-host", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-length", boost::regex::icase), + boost::regex("\\d+", boost::regex::icase))); + handler.mHeadersRequired.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("application/llsd\\+xml", boost::regex::icase))); + + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-cache-control", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-pragma", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-range", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-referer", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-expect", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-transfer-encoding", boost::regex::icase), + boost::regex(".*", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("text/plain", boost::regex::icase))); + handler.mHeadersDisallowed.push_back( + regex_container_t::value_type( + boost::regex("X-Reflect-content-type", boost::regex::icase), + boost::regex("text/html", boost::regex::icase))); + HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, + url_base + "reflect/", + ba, + options, + headers, + handlerp); + ensure("Valid handle returned for get request", handle != LLCORE_HTTP_HANDLE_INVALID); + ba->release(); + ba = NULL; + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 2) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 2); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options & headers options.reset(); headers.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - if (ba) - { - ba->release(); - ba = NULL; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + if (ba) + { + ba->release(); + ba = NULL; + } options.reset(); headers.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } // BUG-2295 Tests - Content-Range header received but no body template <> template <> void HttpRequestTestObjectType::test<22>() { - ScopedCurlInit ready; + ScopedCurlInit ready; + + std::string url_base(get_base_url()); + // std::cerr << "Base: " << url_base << std::endl; - std::string url_base(get_base_url()); - // std::cerr << "Base: " << url_base << std::endl; - - set_test_name("BUG-2295"); + set_test_name("BUG-2295"); #if LL_WINDOWS && ADDRESS_SIZE == 64 - // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it - if (getenv("TEAMCITY_PROJECT_NAME")) - { - skip("BUG-2295 - partial load on W64 causes freeze"); - } + // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it + if (getenv("TEAMCITY_PROJECT_NAME")) + { + skip("BUG-2295 - partial load on W64 causes freeze"); + } #endif - // 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. - TestHandler2 handler(this, "handler"); + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - mHandlerCalls = 0; + mHandlerCalls = 0; - HttpOptions::ptr_t options; - HttpRequest * req = NULL; + HttpOptions::ptr_t options; + HttpRequest * req = NULL; - try - { + try + { // options set options = HttpOptions::ptr_t(new HttpOptions()); - options->setRetries(1); // Partial_File is retryable and can timeout in here - options->setDNSCacheTimeout(30); - - // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); - - // create a new ref counted object with an implicit reference - req = new HttpRequest(); - - // ====================================== - // Issue bug2295 GETs that will get a 206 - // ====================================== - mStatus = HttpStatus(206); - static const int test_count(3); - for (int i(0); i < test_count; ++i) - { - char buffer[128]; - sprintf(buffer, "/bug2295/%d/", i); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + buffer, - 0, - 25, - options, + options->setRetries(1); // Partial_File is retryable and can timeout in here + options->setDNSCacheTimeout(30); + + // Get singletons created + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); + + // create a new ref counted object with an implicit reference + req = new HttpRequest(); + + // ====================================== + // Issue bug2295 GETs that will get a 206 + // ====================================== + mStatus = HttpStatus(206); + static const int test_count(3); + for (int i(0); i < test_count; ++i) + { + char buffer[128]; + sprintf(buffer, "/bug2295/%d/", i); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + buffer, + 0, + 25, + options, + HttpHeaders::ptr_t(), + handlerp); + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + } + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < test_count) + { + 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); + + // ====================================== + // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE) + // ====================================== + mHandlerCalls = 0; + mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE); + static const int test2_count(1); + for (int i(0); i < test2_count; ++i) + { + char buffer[128]; + sprintf(buffer, "/bug2295/00000012/%d/", i); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + buffer, + 0, + 25, + options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - } - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < test_count) - { - 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); - - // ====================================== - // Issue bug2295 GETs that will get a libcurl 18 (PARTIAL_FILE) - // ====================================== - mHandlerCalls = 0; - mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_PARTIAL_FILE); - static const int test2_count(1); - for (int i(0); i < test2_count; ++i) - { - char buffer[128]; - sprintf(buffer, "/bug2295/00000012/%d/", i); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + buffer, - 0, - 25, - options, - HttpHeaders::ptr_t(), - handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - } - - // Run the notification pump. - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < test2_count) - { - 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); - - // ====================================== - // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status - // ====================================== - mHandlerCalls = 0; - mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR); - static const int test3_count(1); - for (int i(0); i < test3_count; ++i) - { - char buffer[128]; - sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url_base + buffer, - 0, - 25, - options, + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + } + + // Run the notification pump. + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < test2_count) + { + 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); + + // ====================================== + // Issue bug2295 GETs that will get an llcorehttp HE_INV_CONTENT_RANGE_HDR status + // ====================================== + mHandlerCalls = 0; + mStatus = HttpStatus(HttpStatus::LLCORE, HE_INV_CONTENT_RANGE_HDR); + static const int test3_count(1); + for (int i(0); i < test3_count; ++i) + { + char buffer[128]; + sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url_base + buffer, + 0, + 25, + options, HttpHeaders::ptr_t(), handlerp); - ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); - } - - // Run the notification pump. - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < test3_count) - { - 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); - - // ====================================== - // 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Shutdown request executed in reasonable time", count < limit); - ensure("Shutdown handler invocation", mHandlerCalls == 1); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options + ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID); + } + + // Run the notification pump. + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < test3_count) + { + 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); + + // ====================================== + // 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Shutdown request executed in reasonable time", count < limit); + ensure("Shutdown handler invocation", mHandlerCalls == 1); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options options.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); - delete req; - HttpRequest::destroyService(); - throw; - } + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); + delete req; + HttpRequest::destroyService(); + throw; + } } template <> template <> void HttpRequestTestObjectType::test<23>() { - ScopedCurlInit ready; + ScopedCurlInit ready; - set_test_name("HttpRequest GET 503s with 'Retry-After'"); + set_test_name("HttpRequest GET 503s with 'Retry-After'"); #if LL_WINDOWS && ADDRESS_SIZE == 64 - // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it - if (getenv("TEAMCITY_PROJECT_NAME")) - { - skip("llcorehttp 503-with-retry test hangs on Windows 64"); - } + // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it + if (getenv("TEAMCITY_PROJECT_NAME")) + { + skip("llcorehttp 503-with-retry test hangs on Windows 64"); + } #endif - // 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 - // the parsing result isn't supported. - - // 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. - TestHandler2 handler(this, "handler"); + // 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 + // the parsing result isn't supported. + + // 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. + TestHandler2 handler(this, "handler"); LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); - std::string url_base(get_base_url() + "/503/"); // path to 503 generators - mHandlerCalls = 0; - - HttpRequest * req = NULL; - HttpOptions::ptr_t opts; - - try - { + std::string url_base(get_base_url() + "/503/"); // path to 503 generators + mHandlerCalls = 0; + + HttpRequest * req = NULL; + HttpOptions::ptr_t opts; + + try + { // Get singletons created - HttpRequest::createService(); - - // Start threading early so that thread memory is invariant - // over the test. - HttpRequest::startThread(); + HttpRequest::createService(); + + // Start threading early so that thread memory is invariant + // over the test. + HttpRequest::startThread(); - // create a new ref counted object with an implicit reference - req = new HttpRequest(); + // create a new ref counted object with an implicit reference + req = new HttpRequest(); opts = HttpOptions::ptr_t(new HttpOptions()); - opts->setRetries(1); // Retry once only - opts->setUseRetryAfter(true); // Try to parse the retry-after header - - // Issue a GET that 503s with valid retry-after - mStatus = HttpStatus(503); - int url_limit(6); - for (int i(0); i < url_limit; ++i) - { - std::ostringstream url; - url << url_base << i << "/"; - HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, - url.str(), - 0, - 0, - opts, + opts->setRetries(1); // Retry once only + opts->setUseRetryAfter(true); // Try to parse the retry-after header + + // Issue a GET that 503s with valid retry-after + mStatus = HttpStatus(503); + int url_limit(6); + for (int i(0); i < url_limit; ++i) + { + std::ostringstream url; + url << url_base << i << "/"; + HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, + url.str(), + 0, + 0, + opts, HttpHeaders::ptr_t(), handlerp); - std::ostringstream testtag; - testtag << "Valid handle returned for 503 request #" << i; - ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID); - } - - - // Run the notification pump. - int count(0); - int limit(LOOP_COUNT_LONG); - while (count++ < limit && mHandlerCalls < url_limit) - { - req->update(0); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Request executed in reasonable time", count < limit); - ensure("One handler invocation for request", 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); - - // Run the notification pump again - count = 0; - limit = LOOP_COUNT_LONG; - while (count++ < limit && mHandlerCalls < 1) - { - req->update(1000000); - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Second request executed in reasonable time", count < limit); - ensure("Second handler invocation", mHandlerCalls == 1); - - // See that we actually shutdown the thread - count = 0; - limit = LOOP_COUNT_SHORT; - while (count++ < limit && ! HttpService::isStopped()) - { - usleep(LOOP_SLEEP_INTERVAL); - } - ensure("Thread actually stopped running", HttpService::isStopped()); - - // release options + std::ostringstream testtag; + testtag << "Valid handle returned for 503 request #" << i; + ensure(testtag.str(), handle != LLCORE_HTTP_HANDLE_INVALID); + } + + + // Run the notification pump. + int count(0); + int limit(LOOP_COUNT_LONG); + while (count++ < limit && mHandlerCalls < url_limit) + { + req->update(0); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Request executed in reasonable time", count < limit); + ensure("One handler invocation for request", 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); + + // Run the notification pump again + count = 0; + limit = LOOP_COUNT_LONG; + while (count++ < limit && mHandlerCalls < 1) + { + req->update(1000000); + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Second request executed in reasonable time", count < limit); + ensure("Second handler invocation", mHandlerCalls == 1); + + // See that we actually shutdown the thread + count = 0; + limit = LOOP_COUNT_SHORT; + while (count++ < limit && ! HttpService::isStopped()) + { + usleep(LOOP_SLEEP_INTERVAL); + } + ensure("Thread actually stopped running", HttpService::isStopped()); + + // release options opts.reset(); - - // release the request object - delete req; - req = NULL; - - // Shut down service - HttpRequest::destroyService(); - } - catch (...) - { - stop_thread(req); + + // release the request object + delete req; + req = NULL; + + // Shut down service + HttpRequest::destroyService(); + } + catch (...) + { + stop_thread(req); opts.reset(); - delete req; - HttpRequest::destroyService(); - throw; - } + delete req; + HttpRequest::destroyService(); + throw; + } } @@ -3045,7 +3045,7 @@ namespace void usleep(unsigned long usec) { - Sleep((DWORD) (usec / 1000UL)); + Sleep((DWORD) (usec / 1000UL)); } #endif diff --git a/indra/llcorehttp/tests/test_httprequestqueue.hpp b/indra/llcorehttp/tests/test_httprequestqueue.hpp index dba9e0b250..c6fa1b7534 100644 --- a/indra/llcorehttp/tests/test_httprequestqueue.hpp +++ b/indra/llcorehttp/tests/test_httprequestqueue.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_httprequestqueue.hpp * @brief unit tests for the LLCore::HttpRequestQueue class * @@ -42,8 +42,8 @@ namespace tut struct HttpRequestqueueTestData { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. + // the test objects inherit from this so the member functions and variables + // can be referenced directly inside of the test functions. }; typedef test_group<HttpRequestqueueTestData> HttpRequestqueueTestGroupType; @@ -53,102 +53,102 @@ HttpRequestqueueTestGroupType HttpRequestqueueTestGroup("HttpRequestqueue Tests" template <> template <> void HttpRequestqueueTestObjectType::test<1>() { - set_test_name("HttpRequestQueue construction"); + 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); + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); - // release the implicit reference, causing the object to be released - HttpRequestQueue::term(); + ensure("One ref on construction of HttpRequestQueue", HttpRequestQueue::instanceOf()->getRefCount() == 1); + + // release the implicit reference, causing the object to be released + HttpRequestQueue::term(); } template <> template <> void HttpRequestqueueTestObjectType::test<2>() { - set_test_name("HttpRequestQueue refcount works"); + set_test_name("HttpRequestQueue refcount works"); + + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); + + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + rq->addRef(); - // create a new ref counted object with an implicit reference - HttpRequestQueue::init(); + // release the singleton, hold on to the object + HttpRequestQueue::term(); - HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); - rq->addRef(); - - // release the singleton, hold on to the object - HttpRequestQueue::term(); - - ensure("One ref after term() called", rq->getRefCount() == 1); + ensure("One ref after term() called", rq->getRefCount() == 1); - // Drop ref - rq->release(); + // Drop ref + rq->release(); } template <> template <> void HttpRequestqueueTestObjectType::test<3>() { - set_test_name("HttpRequestQueue addOp/fetchOp work"); + set_test_name("HttpRequestQueue addOp/fetchOp work"); - // create a new ref counted object with an implicit reference - HttpRequestQueue::init(); + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); - HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); - HttpOperation::ptr_t op(new HttpOpNull()); + HttpOperation::ptr_t op(new HttpOpNull()); - rq->addOp(op); // transfer my refcount + 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<bool>(op)); + op = rq->fetchOp(true); // Potentially hangs the test on failure + ensure("One goes in, one comes out", static_cast<bool>(op)); op.reset(); - op = rq->fetchOp(false); - ensure("Better not be two of them", !op); - - // release the singleton, hold on to the object - HttpRequestQueue::term(); + op = rq->fetchOp(false); + ensure("Better not be two of them", !op); + + // release the singleton, hold on to the object + HttpRequestQueue::term(); } template <> template <> void HttpRequestqueueTestObjectType::test<4>() { - set_test_name("HttpRequestQueue addOp/fetchAll work"); + set_test_name("HttpRequestQueue addOp/fetchAll work"); + + // create a new ref counted object with an implicit reference + HttpRequestQueue::init(); - // create a new ref counted object with an implicit reference - HttpRequestQueue::init(); + HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); - HttpRequestQueue * rq = HttpRequestQueue::instanceOf(); + HttpOperation::ptr_t op (new HttpOpNull()); + rq->addOp(op); // transfer my refcount - HttpOperation::ptr_t op (new HttpOpNull()); - rq->addOp(op); // transfer my refcount + op.reset(new HttpOpNull()); + rq->addOp(op); // transfer my refcount - op.reset(new HttpOpNull()); - rq->addOp(op); // transfer my refcount + op.reset(new HttpOpNull()); + rq->addOp(op); // transfer my refcount - op.reset(new HttpOpNull()); - rq->addOp(op); // transfer my refcount - - { - HttpRequestQueue::OpContainer ops; - rq->fetchAll(true, ops); // Potentially hangs the test on failure - ensure("Three go in, three come out", 3 == ops.size()); + { + HttpRequestQueue::OpContainer ops; + rq->fetchAll(true, ops); // Potentially hangs the test on failure + ensure("Three go in, three come out", 3 == ops.size()); - op = rq->fetchOp(false); - ensure("Better not be any more of them", !op); + op = rq->fetchOp(false); + ensure("Better not be any more of them", !op); op.reset(); - // release the singleton, hold on to the object - HttpRequestQueue::term(); + // release the singleton, hold on to the object + HttpRequestQueue::term(); - // Release them + // Release them ops.clear(); -// while (! ops.empty()) -// { -// HttpOperation * op = ops.front(); -// ops.erase(ops.begin()); -// op->release(); -// } - } +// while (! ops.empty()) +// { +// HttpOperation * op = ops.front(); +// ops.erase(ops.begin()); +// op->release(); +// } + } } } // end namespace tut diff --git a/indra/llcorehttp/tests/test_httpstatus.hpp b/indra/llcorehttp/tests/test_httpstatus.hpp index cbe3f574d4..eac7ba8557 100644 --- a/indra/llcorehttp/tests/test_httpstatus.hpp +++ b/indra/llcorehttp/tests/test_httpstatus.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_llrefcounted * @brief unit tests for HttpStatus struct * @@ -39,8 +39,8 @@ namespace tut struct HttpStatusTestData { - HttpStatusTestData() - {} + HttpStatusTestData() + {} }; typedef test_group<HttpStatusTestData> HttpStatusTestGroupType; @@ -51,250 +51,250 @@ HttpStatusTestGroupType HttpStatusTestGroup("HttpStatus Tests"); template <> template <> void HttpStatusTestObjectType::test<1>() { - set_test_name("HttpStatus construction"); - - // auto allocation fine for this - HttpStatus status; + set_test_name("HttpStatus construction"); - status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0); - - ensure(bool(status)); - ensure(false == !(status)); + // auto allocation fine for this + HttpStatus status; - status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0); + status = HttpStatus(HttpStatus::EXT_CURL_EASY, 0); - ensure(bool(status)); - ensure(false == !(status)); + ensure(bool(status)); + ensure(false == !(status)); - status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS); - - ensure(bool(status)); - ensure(false == !(status)); + status = HttpStatus(HttpStatus::EXT_CURL_MULTI, 0); - status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1); + ensure(bool(status)); + ensure(false == !(status)); - ensure(false == bool(status)); - ensure(!(status)); + status = HttpStatus(HttpStatus::LLCORE, HE_SUCCESS); - status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME); + ensure(bool(status)); + ensure(false == !(status)); - ensure(false == bool(status)); - ensure(!(status)); + status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -1); + + ensure(false == bool(status)); + ensure(!(status)); + + status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_DOWNLOAD_RESUME); + + ensure(false == bool(status)); + ensure(!(status)); } // template <> template <> // void HttpStatusTestObjectType::test<2>() // { -// set_test_name("HttpStatus memory structure"); -// -// // Require that an HttpStatus object can be trivially -// // returned as a function return value in registers. -// // One should fit in an int on all platforms. -// -// //ensure(sizeof(HttpStatus) <= sizeof(int)); +// set_test_name("HttpStatus memory structure"); +// +// // Require that an HttpStatus object can be trivially +// // returned as a function return value in registers. +// // One should fit in an int on all platforms. +// +// //ensure(sizeof(HttpStatus) <= sizeof(int)); // } template <> template <> void HttpStatusTestObjectType::test<2>() { - 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()); - - status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT); - msg = status.toString(); - // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); - - status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY); - msg = status.toString(); - // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); - - status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); - msg = status.toString(); - // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + 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()); + + status = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_BAD_FUNCTION_ARGUMENT); + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status = HttpStatus(HttpStatus::EXT_CURL_MULTI, CURLM_OUT_OF_MEMORY); + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); } template <> template <> void HttpStatusTestObjectType::test<3>() { - 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()); - - status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470); - msg = status.toString(); - // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); - - status = HttpStatus(HttpStatus::LLCORE, 923); - msg = status.toString(); - // std::cout << "Result: " << msg << std::endl; - ensure(! msg.empty()); + 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()); + + status = HttpStatus(HttpStatus::EXT_CURL_MULTI, -470); + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); + + status = HttpStatus(HttpStatus::LLCORE, 923); + msg = status.toString(); + // std::cout << "Result: " << msg << std::endl; + ensure(! msg.empty()); } template <> template <> void HttpStatusTestObjectType::test<4>() { - set_test_name("HttpStatus equality/inequality testing"); + 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. + // 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); + HttpStatus status1(HttpStatus::LLCORE, HE_SUCCESS); + HttpStatus status2(HttpStatus::EXT_CURL_EASY, HE_SUCCESS); + ensure(status1 != status2); - status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR); - status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); + status1 = HttpStatus(HttpStatus::LLCORE, HE_REPLY_ERROR); + status1 = HttpStatus(HttpStatus::LLCORE, HE_SHUTTING_DOWN); - ensure(status1 != status2); + ensure(status1 != status2); } template <> template <> void HttpStatusTestObjectType::test<5>() { - 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)); - - // 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 - - // Same statuses with distinct success/fail are distinct - status = HttpStatus(200, HE_SUCCESS); - HttpStatus status2(200, HE_REPLY_ERROR); - ensure(status != status2); - - // Normally an error but application says okay - status = HttpStatus(406, HE_SUCCESS); - msg = status.toString(); - ensure(msg.empty()); - ensure(bool(status)); - - // Different statuses but both successful are distinct - status = HttpStatus(200, HE_SUCCESS); - status2 = HttpStatus(201, HE_SUCCESS); - ensure(status != status2); - - // Different statuses but both failed are distinct - status = HttpStatus(200, HE_REPLY_ERROR); - status2 = HttpStatus(201, HE_REPLY_ERROR); - ensure(status != status2); + 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)); + + // 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 + + // Same statuses with distinct success/fail are distinct + status = HttpStatus(200, HE_SUCCESS); + HttpStatus status2(200, HE_REPLY_ERROR); + ensure(status != status2); + + // Normally an error but application says okay + status = HttpStatus(406, HE_SUCCESS); + msg = status.toString(); + ensure(msg.empty()); + ensure(bool(status)); + + // Different statuses but both successful are distinct + status = HttpStatus(200, HE_SUCCESS); + status2 = HttpStatus(201, HE_SUCCESS); + ensure(status != status2); + + // Different statuses but both failed are distinct + status = HttpStatus(200, HE_REPLY_ERROR); + status2 = HttpStatus(201, HE_REPLY_ERROR); + ensure(status != status2); } template <> template <> void HttpStatusTestObjectType::test<6>() { - set_test_name("HttpStatus HTTP status text strings"); + 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"); + HttpStatus status(100, HE_REPLY_ERROR); + std::string msg(status.toString()); + ensure(! msg.empty()); // Should be something + ensure(msg == "Continue"); - status = HttpStatus(200, HE_SUCCESS); - msg = status.toString(); - ensure(msg.empty()); // Success is empty + status = HttpStatus(200, HE_SUCCESS); + msg = status.toString(); + ensure(msg.empty()); // Success is empty - status = HttpStatus(199, HE_REPLY_ERROR); - msg = status.toString(); - ensure(msg == "Unknown error"); + status = HttpStatus(199, HE_REPLY_ERROR); + msg = status.toString(); + ensure(msg == "Unknown error"); - status = HttpStatus(505, HE_REPLY_ERROR); - msg = status.toString(); - ensure(msg == "HTTP Version not supported"); + status = HttpStatus(505, HE_REPLY_ERROR); + msg = status.toString(); + ensure(msg == "HTTP Version not supported"); - status = HttpStatus(506, HE_REPLY_ERROR); - msg = status.toString(); - ensure(msg == "Unknown error"); + status = HttpStatus(506, HE_REPLY_ERROR); + msg = status.toString(); + ensure(msg == "Unknown error"); - status = HttpStatus(999, HE_REPLY_ERROR); - msg = status.toString(); - ensure(msg == "Unknown error"); + status = HttpStatus(999, HE_REPLY_ERROR); + msg = status.toString(); + ensure(msg == "Unknown error"); } template <> template <> void HttpStatusTestObjectType::test<7>() { - 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"); + 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"); } template <> template <> void HttpStatusTestObjectType::test<8>() { - 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"); - - status = HttpStatus(200); - msg = status.toTerseString(); - // std::cout << "Result: " << msg << std::endl; - ensure("Normal HTTP 200", 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 - - 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"); - - 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"); - - 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"); - - status = HttpStatus(22000, 1); - msg = status.toTerseString(); - // std::cout << "Result: " << msg << std::endl; - ensure("Undecodable error", msg == "Unknown_1"); - - status = HttpStatus(22000, -1); - msg = status.toTerseString(); - // std::cout << "Result: " << msg << std::endl; - ensure("Undecodable error 65535", msg == "Unknown_65535"); + 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"); + + status = HttpStatus(200); + msg = status.toTerseString(); + // std::cout << "Result: " << msg << std::endl; + ensure("Normal HTTP 200", 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 + + 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"); + + 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"); + + 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"); + + status = HttpStatus(22000, 1); + msg = status.toTerseString(); + // std::cout << "Result: " << msg << std::endl; + ensure("Undecodable error", msg == "Unknown_1"); + + status = HttpStatus(22000, -1); + msg = status.toTerseString(); + // std::cout << "Result: " << msg << std::endl; + ensure("Undecodable error 65535", msg == "Unknown_65535"); } } // end namespace tut -#endif // TEST_HTTP_STATUS_H +#endif // TEST_HTTP_STATUS_H diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py index b9992538ba..b2805fda11 100755 --- a/indra/llcorehttp/tests/test_llcorehttp_peer.py +++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py @@ -50,12 +50,12 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler): """This subclass of BaseHTTPRequestHandler is to receive and echo LLSD-flavored messages sent by the C++ LLHTTPClient. - Target URLs are fairly free-form and are assembled by + Target URLs are fairly free-form and are assembled by concatinating fragments. Currently defined fragments are: - '/reflect/' Request headers are bounced back to caller after prefixing with 'X-Reflect-' - - '/fail/' Body of request can contain LLSD with + - '/fail/' Body of request can contain LLSD with 'reason' string and 'status' integer which will become response header. - '/bug2295/' 206 response, no data in body: @@ -69,7 +69,7 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler): -- '/bug2295/inv_cont_range/0/' Generates HE_INVALID_CONTENT_RANGE error in llcorehttp. - '/503/' Generate 503 responses with various kinds of 'retry-after' headers - -- '/503/0/' "Retry-After: 2" + -- '/503/0/' "Retry-After: 2" -- '/503/1/' "Retry-After: Thu, 31 Dec 2043 23:59:59 GMT" -- '/503/2/' "Retry-After: Fri, 31 Dec 1999 23:59:59 GMT" -- '/503/3/' "Retry-After: " diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp index 2310812d5a..c0c8e78413 100644 --- a/indra/llcorehttp/tests/test_refcounted.hpp +++ b/indra/llcorehttp/tests/test_refcounted.hpp @@ -1,4 +1,4 @@ -/** +/** * @file test_refcounted.hpp * @brief unit tests for the LLCoreInt::RefCounted class * @@ -34,93 +34,93 @@ using namespace LLCoreInt; namespace tut { - struct RefCountedTestData - { - // the test objects inherit from this so the member functions and variables - // can be referenced directly inside of the test functions. - }; + 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<RefCountedTestData> RefCountedTestGroupType; - typedef RefCountedTestGroupType::object RefCountedTestObjectType; - RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests"); + typedef test_group<RefCountedTestData> RefCountedTestGroupType; + typedef RefCountedTestGroupType::object RefCountedTestObjectType; + RefCountedTestGroupType RefCountedTestGroup("RefCounted Tests"); - template <> template <> - void RefCountedTestObjectType::test<1>() - { - set_test_name("RefCounted construction with implicit count"); + template <> template <> + void RefCountedTestObjectType::test<1>() + { + 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); + // create a new ref counted object with an implicit reference + RefCounted * rc = new RefCounted(true); + ensure(rc->getRefCount() == 1); - // release the implicit reference, causing the object to be released - rc->release(); - } + // release the implicit reference, causing the object to be released + rc->release(); + } - template <> template <> - void RefCountedTestObjectType::test<2>() - { - set_test_name("RefCounted construction without implicit count"); + template <> template <> + void RefCountedTestObjectType::test<2>() + { + 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); + // create a new ref counted object with an implicit reference + RefCounted * rc = new RefCounted(false); + ensure(rc->getRefCount() == 0); - // add a reference - rc->addRef(); - ensure(rc->getRefCount() == 1); + // add a reference + rc->addRef(); + ensure(rc->getRefCount() == 1); - // release the implicit reference, causing the object to be released - rc->release(); - } + // release the implicit reference, causing the object to be released + rc->release(); + } - template <> template <> - void RefCountedTestObjectType::test<3>() - { - set_test_name("RefCounted addRef and release"); + template <> template <> + void RefCountedTestObjectType::test<3>() + { + set_test_name("RefCounted addRef and release"); - RefCounted * rc = new RefCounted(false); + RefCounted * rc = new RefCounted(false); - for (int i = 0; i < 1024; ++i) - { - rc->addRef(); - } + for (int i = 0; i < 1024; ++i) + { + rc->addRef(); + } - ensure(rc->getRefCount() == 1024); + ensure(rc->getRefCount() == 1024); - for (int i = 0; i < 1024; ++i) - { - rc->release(); - } - } + for (int i = 0; i < 1024; ++i) + { + rc->release(); + } + } - template <> template <> - void RefCountedTestObjectType::test<4>() - { - set_test_name("RefCounted isLastRef check"); + template <> template <> + void RefCountedTestObjectType::test<4>() + { + set_test_name("RefCounted isLastRef check"); - RefCounted * rc = new RefCounted(true); + RefCounted * rc = new RefCounted(true); - // with only one reference, isLastRef should be true - ensure(rc->isLastRef()); + // with only one reference, isLastRef should be true + ensure(rc->isLastRef()); - // release it to clean up memory - rc->release(); - } + // release it to clean up memory + rc->release(); + } - template <> template <> - void RefCountedTestObjectType::test<5>() - { - set_test_name("RefCounted noRef check"); + template <> template <> + void RefCountedTestObjectType::test<5>() + { + set_test_name("RefCounted noRef check"); - RefCounted * rc = new RefCounted(false); + RefCounted * rc = new RefCounted(false); - // set the noRef - rc->noRef(); + // set the noRef + rc->noRef(); - // with only one reference, isLastRef should be true - ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); - } + // with only one reference, isLastRef should be true + ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); + } } #endif // disabling on Win64 -#endif // TEST_LLCOREINT_REF_COUNTED_H_ +#endif // TEST_LLCOREINT_REF_COUNTED_H_ |