diff options
| author | Oz Linden <oz@lindenlab.com> | 2017-02-02 15:49:16 -0500 | 
|---|---|---|
| committer | Oz Linden <oz@lindenlab.com> | 2017-02-02 15:49:16 -0500 | 
| commit | 1925fd2b8b9216e5d9388e6a0c077c99aa782cad (patch) | |
| tree | 2507c9889eb825302f7c3f1650b85e6208b04e4e /indra/llcorehttp | |
| parent | 7f544db197fcaa8a697ee9d9694d11b297a20266 (diff) | |
| parent | 080744d8990e6b18a80858803a20a5ec87020d82 (diff) | |
merge changes for 5.0.1-release
Diffstat (limited to 'indra/llcorehttp')
| -rw-r--r-- | indra/llcorehttp/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | indra/llcorehttp/_httpoprequest.cpp | 12 | ||||
| -rwxr-xr-x[-rw-r--r--] | indra/llcorehttp/tests/llcorehttp_test.cpp | 3 | ||||
| -rw-r--r-- | indra/llcorehttp/tests/test_httprequest.hpp | 67 | ||||
| -rwxr-xr-x | indra/llcorehttp/tests/test_llcorehttp_peer.py | 35 | ||||
| -rwxr-xr-x | indra/llcorehttp/tests/testrunner.py | 265 | 
6 files changed, 69 insertions, 318 deletions
| diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 2919e8b6e2..831a2813ee 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -93,6 +93,7 @@ target_link_libraries(    ${OPENSSL_LIBRARIES}    ${CRYPTO_LIBRARIES}    ${BOOST_THREAD_LIBRARY} +  ${BOOST_SYSTEM_LIBRARY}    )  # tests @@ -129,8 +130,8 @@ if (LL_TESTS)        ${CURL_LIBRARIES}        ${OPENSSL_LIBRARIES}        ${CRYPTO_LIBRARIES} -      ${BOOST_SYSTEM_LIBRARY}        ${BOOST_THREAD_LIBRARY} +      ${BOOST_SYSTEM_LIBRARY}        )    # If http_proxy is in the current environment (e.g. to fetch s3-proxy @@ -197,8 +198,8 @@ endif (DARWIN)        ${CURL_LIBRARIES}        ${OPENSSL_LIBRARIES}        ${CRYPTO_LIBRARIES} -      ${BOOST_SYSTEM_LIBRARY}        ${BOOST_THREAD_LIBRARY} +      ${BOOST_SYSTEM_LIBRARY}        )    add_executable(http_texture_load diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index db57869a1b..07cc0e4625 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -568,7 +568,17 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  		// Use the viewer-based thread-safe API which has a  		// fast/safe check for proxy enable.  Would like to  		// encapsulate this someway... -		LLProxy::getInstance()->applyProxySettings(mCurlHandle); +		if (LLProxy::instanceExists()) +		{ +			// Make sure proxy won't be initialized from here, +			// it might conflict with LLStartUp::startLLProxy() +			LLProxy::getInstance()->applyProxySettings(mCurlHandle); +		} +		else +		{ +			LL_WARNS() << "Proxy is not initialized!" << LL_ENDL; +		} +  	}  	else if (gpolicy.mHttpProxy.size())  	{ diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp index bef762f5ce..a310fc0508 100644..100755 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -46,6 +46,7 @@  #include "test_httprequestqueue.hpp"  #include "llproxy.h" +#include "llcleanup.h"  unsigned long ssl_thread_id_callback(void);  void ssl_locking_callback(int mode, int type, const char * file, int line); @@ -101,7 +102,7 @@ void init_curl()  void term_curl()  { -	LLProxy::cleanupClass(); +	SUBSYSTEM_CLEANUP(LLProxy);  	CRYPTO_set_locking_callback(NULL);  	for (int i(0); i < ssl_mutex_count; ++i) diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 463e55dd7e..6cd7960ecd 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -729,7 +729,7 @@ void HttpRequestTestObjectType::test<7>()  #if 0 // defined(WIN32)  		// Can't do this on any platform anymore, the LL logging system holds  		// on to memory and produces what looks like memory leaks... -	 +  		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());  		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());  #endif @@ -1459,21 +1459,21 @@ void HttpRequestTestObjectType::test<14>()  	// 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 -		 +	LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor); +	std::string url_base(get_base_url() + "/sleep/");   // path to a 30-second sleep +  	// record the total amount of dynamically allocated memory  	mMemTotal = GetMemTotal();  	mHandlerCalls = 0;  	HttpRequest * req = NULL;  	HttpOptions::ptr_t opts; -	 +  	try  	{ -        // Get singletons created +		// Get singletons created  		HttpRequest::createService(); -		 +  		// Start threading early so that thread memory is invariant  		// over the test.  		HttpRequest::startThread(); @@ -1482,10 +1482,10 @@ void HttpRequestTestObjectType::test<14>()  		req = new HttpRequest();  		ensure("Memory allocated on construction", mMemTotal < GetMemTotal()); -        opts = HttpOptions::ptr_t(new HttpOptions); -		opts->setRetries(0);			// Don't retry +		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, @@ -1494,8 +1494,8 @@ void HttpRequestTestObjectType::test<14>()  													 0,  													 0,  													 opts, -                                                     HttpHeaders::ptr_t(), -                                                     handlerp); +													 HttpHeaders::ptr_t(), +													 handlerp);  		ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);  		// Run the notification pump. @@ -1513,7 +1513,7 @@ void HttpRequestTestObjectType::test<14>()  		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; @@ -1535,30 +1535,29 @@ void HttpRequestTestObjectType::test<14>()  		ensure("Thread actually stopped running", HttpService::isStopped());  		// release options -        opts.reset(); -		 +		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); -#if defined(WIN32) -		// Can only do this memory test on Windows.  On other platforms, -		// the LL logging system holds on to memory and produces what looks -		// like memory leaks... -	 -		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal()); +#if 0 // defined(WIN32) +		// Can't do this on any platform anymore, the LL logging system holds +		// on to memory and produces what looks like memory leaks... + +		// printf("Old mem:	 %d, New mem:  %d\n", mMemTotal, GetMemTotal());  		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());  #endif  	}  	catch (...)  	{  		stop_thread(req); -        opts.reset(); +		opts.reset();  		delete req;  		HttpRequest::destroyService();  		throw; @@ -3065,12 +3064,11 @@ void HttpRequestTestObjectType::test<22>()  		// Shut down service  		HttpRequest::destroyService(); -	 -#if defined(WIN32) -		// Can only do this memory test on Windows.  On other platforms, -		// the LL logging system holds on to memory and produces what looks -		// like memory leaks... -	 + +#if 0 // defined(WIN32) +		// Can't do this on any platform anymore, the LL logging system holds +		// on to memory and produces what looks like memory leaks... +  		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());  		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());  #endif @@ -3195,12 +3193,11 @@ void HttpRequestTestObjectType::test<23>()  		// Shut down service  		HttpRequest::destroyService(); -	 -#if defined(WIN32) -		// Can only do this memory test on Windows.  On other platforms, -		// the LL logging system holds on to memory and produces what looks -		// like memory leaks... -	 + +#if 0 // defined(WIN32) +		// Can't do this on any platform anymore, the LL logging system holds +		// on to memory and produces what looks like memory leaks... +  		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());  		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());  #endif diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py index 6c5f37d407..493143641b 100755 --- a/indra/llcorehttp/tests/test_llcorehttp_peer.py +++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py @@ -34,16 +34,19 @@ import sys  import time  import select  import getopt -from threading import Thread  try:      from cStringIO import StringIO  except ImportError:      from StringIO import StringIO  from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -from SocketServer import ThreadingMixIn  from llbase.fastest_elementtree import parse as xml_parse  from llbase import llsd + +# we're in llcorehttp/tests ; testrunner.py is found in llmessage/tests +sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, +                             "llmessage", "tests")) +  from testrunner import freeport, run, debug, VERBOSE  class TestHTTPRequestHandler(BaseHTTPRequestHandler): @@ -269,7 +272,7 @@ class TestHTTPRequestHandler(BaseHTTPRequestHandler):              # Suppress error output as well              pass -class Server(ThreadingMixIn, HTTPServer): +class Server(HTTPServer):      # This pernicious flag is on by default in HTTPServer. But proper      # operation of freeport() absolutely depends on it being off.      allow_reuse_address = False @@ -293,22 +296,26 @@ if __name__ == "__main__":          if option == "-V" or option == "--valgrind":              do_valgrind = True -    # Instantiate a Server(TestHTTPRequestHandler) on the first free port -    # in the specified port range. Doing this inline is better than in a -    # daemon thread: if it blows up here, we'll get a traceback. If it blew up -    # in some other thread, the traceback would get eaten and we'd run the -    # subject test program anyway. -    httpd, port = freeport(xrange(8000, 8020), -                           lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) +    # function to make a server with specified port +    make_server = lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler) + +    if not sys.platform.startswith("win"): +        # Instantiate a Server(TestHTTPRequestHandler) on a port chosen by the +        # runtime. +        httpd = make_server(0) +    else: +        # "Then there's Windows" +        # Instantiate a Server(TestHTTPRequestHandler) on the first free port +        # in the specified port range. +        httpd, port = freeport(xrange(8000, 8020), make_server)      # Pass the selected port number to the subject test program via the      # environment. We don't want to impose requirements on the test program's      # command-line parsing -- and anyway, for C++ integration tests, that's      # performed in TUT code rather than our own. -    os.environ["LL_TEST_PORT"] = str(port) -    debug("$LL_TEST_PORT = %s", port) +    os.environ["LL_TEST_PORT"] = str(httpd.server_port) +    debug("$LL_TEST_PORT = %s", httpd.server_port)      if do_valgrind:          args = ["valgrind", "--log-file=./valgrind.log"] + args          path_search = True -    sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), use_path=path_search, *args)) - +    sys.exit(run(server_inst=httpd, use_path=path_search, *args)) diff --git a/indra/llcorehttp/tests/testrunner.py b/indra/llcorehttp/tests/testrunner.py deleted file mode 100755 index 9a2de71142..0000000000 --- a/indra/llcorehttp/tests/testrunner.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python -"""\ -@file   testrunner.py -@author Nat Goodspeed -@date   2009-03-20 -@brief  Utilities for writing wrapper scripts for ADD_COMM_BUILD_TEST unit tests - -$LicenseInfo:firstyear=2009&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2010, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA -$/LicenseInfo$ -""" - -from __future__ import with_statement - -import os -import sys -import re -import errno -import socket - -VERBOSE = os.environ.get("INTEGRATION_TEST_VERBOSE", "0") # default to quiet -# Support usage such as INTEGRATION_TEST_VERBOSE=off -- distressing to user if -# that construct actually turns on verbosity... -VERBOSE = not re.match(r"(0|off|false|quiet)$", VERBOSE, re.IGNORECASE) - -if VERBOSE: -    def debug(fmt, *args): -        print fmt % args -        sys.stdout.flush() -else: -    debug = lambda *args: None - -def freeport(portlist, expr): -    """ -    Find a free server port to use. Specifically, evaluate 'expr' (a -    callable(port)) until it stops raising EADDRINUSE exception. - -    Pass: - -    portlist: an iterable (e.g. xrange()) of ports to try. If you exhaust the -    range, freeport() lets the socket.error exception propagate. If you want -    unbounded, you could pass itertools.count(baseport), though of course in -    practice the ceiling is 2^16-1 anyway. But it seems prudent to constrain -    the range much more sharply: if we're iterating an absurd number of times, -    probably something else is wrong. - -    expr: a callable accepting a port number, specifically one of the items -    from portlist. If calling that callable raises socket.error with -    EADDRINUSE, freeport() retrieves the next item from portlist and retries. - -    Returns: (expr(port), port) - -    port: the value from portlist for which expr(port) succeeded - -    Raises: - -    Any exception raised by expr(port) other than EADDRINUSE. - -    socket.error if, for every item from portlist, expr(port) raises -    socket.error. The exception you see is the one from the last item in -    portlist. - -    StopIteration if portlist is completely empty. - -    Example: - -    class Server(HTTPServer): -        # If you use BaseHTTPServer.HTTPServer, turning off this flag is -        # essential for proper operation of freeport()! -        allow_reuse_address = False -    # ... -    server, port = freeport(xrange(8000, 8010), -                            lambda port: Server(("localhost", port), -                                                MyRequestHandler)) -    # pass 'port' to client code -    # call server.serve_forever() -    """ -    try: -        # If portlist is completely empty, let StopIteration propagate: that's an -        # error because we can't return meaningful values. We have no 'port', -        # therefore no 'expr(port)'. -        portiter = iter(portlist) -        port = portiter.next() - -        while True: -            try: -                # If this value of port works, return as promised. -                value = expr(port) - -            except socket.error, err: -                # Anything other than 'Address already in use', propagate -                if err.args[0] != errno.EADDRINUSE: -                    raise - -                # Here we want the next port from portiter. But on StopIteration, -                # we want to raise the original exception rather than -                # StopIteration. So save the original exc_info(). -                type, value, tb = sys.exc_info() -                try: -                    try: -                        port = portiter.next() -                    except StopIteration: -                        raise type, value, tb -                finally: -                    # Clean up local traceback, see docs for sys.exc_info() -                    del tb - -            else: -                debug("freeport() returning %s on port %s", value, port) -                return value, port - -            # Recap of the control flow above: -            # If expr(port) doesn't raise, return as promised. -            # If expr(port) raises anything but EADDRINUSE, propagate that -            # exception. -            # If portiter.next() raises StopIteration -- that is, if the port -            # value we just passed to expr(port) was the last available -- reraise -            # the EADDRINUSE exception. -            # If we've actually arrived at this point, portiter.next() delivered a -            # new port value. Loop back to pass that to expr(port). - -    except Exception, err: -        debug("*** freeport() raising %s: %s", err.__class__.__name__, err) -        raise - -def run(*args, **kwds): -    """All positional arguments collectively form a command line, executed as -    a synchronous child process. -    In addition, pass server=new_thread_instance as an explicit keyword (to -    differentiate it from an additional command-line argument). -    new_thread_instance should be an instantiated but not yet started Thread -    subclass instance, e.g.: -    run("python", "-c", 'print "Hello, world!"', server=TestHTTPServer(name="httpd")) -    """ -    # If there's no server= keyword arg, don't start a server thread: simply -    # run a child process. -    try: -        thread = kwds.pop("server") -    except KeyError: -        pass -    else: -        # Start server thread. Note that this and all other comm server -        # threads should be daemon threads: we'll let them run "forever," -        # confident that the whole process will terminate when the main thread -        # terminates, which will be when the child process terminates. -        thread.setDaemon(True) -        thread.start() -    # choice of os.spawnv(): -    # - [v vs. l] pass a list of args vs. individual arguments, -    # - [no p] don't use the PATH because we specifically want to invoke the -    #   executable passed as our first arg, -    # - [no e] child should inherit this process's environment. -    debug("Running %s...", " ".join(args)) -    if kwds.get("use_path", False): -        rc = os.spawnvp(os.P_WAIT, args[0], args) -    else: -        rc = os.spawnv(os.P_WAIT, args[0], args) -    debug("%s returned %s", args[0], rc) -    return rc - -# **************************************************************************** -#   test code -- manual at this point, see SWAT-564 -# **************************************************************************** -def test_freeport(): -    # ------------------------------- Helpers -------------------------------- -    from contextlib import contextmanager -    # helper Context Manager for expecting an exception -    # with exc(SomeError): -    #     raise SomeError() -    # raises AssertionError otherwise. -    @contextmanager -    def exc(exception_class, *args): -        try: -            yield -        except exception_class, err: -            for i, expected_arg in enumerate(args): -                assert expected_arg == err.args[i], \ -                       "Raised %s, but args[%s] is %r instead of %r" % \ -                       (err.__class__.__name__, i, err.args[i], expected_arg) -            print "Caught expected exception %s(%s)" % \ -                  (err.__class__.__name__, ', '.join(repr(arg) for arg in err.args)) -        else: -            assert False, "Failed to raise " + exception_class.__class__.__name__ - -    # helper to raise specified exception -    def raiser(exception): -        raise exception - -    # the usual -    def assert_equals(a, b): -        assert a == b, "%r != %r" % (a, b) - -    # ------------------------ Sanity check the above ------------------------ -    class SomeError(Exception): pass -    # Without extra args, accept any err.args value -    with exc(SomeError): -        raiser(SomeError("abc")) -    # With extra args, accept only the specified value -    with exc(SomeError, "abc"): -        raiser(SomeError("abc")) -    with exc(AssertionError): -        with exc(SomeError, "abc"): -            raiser(SomeError("def")) -    with exc(AssertionError): -        with exc(socket.error, errno.EADDRINUSE): -            raiser(socket.error(errno.ECONNREFUSED, 'Connection refused')) - -    # ----------- freeport() without engaging socket functionality ----------- -    # If portlist is empty, freeport() raises StopIteration. -    with exc(StopIteration): -        freeport([], None) - -    assert_equals(freeport([17], str), ("17", 17)) - -    # This is the magic exception that should prompt us to retry -    inuse = socket.error(errno.EADDRINUSE, 'Address already in use') -    # Get the iterator to our ports list so we can check later if we've used all -    ports = iter(xrange(5)) -    with exc(socket.error, errno.EADDRINUSE): -        freeport(ports, lambda port: raiser(inuse)) -    # did we entirely exhaust 'ports'? -    with exc(StopIteration): -        ports.next() - -    ports = iter(xrange(2)) -    # Any exception but EADDRINUSE should quit immediately -    with exc(SomeError): -        freeport(ports, lambda port: raiser(SomeError())) -    assert_equals(ports.next(), 1) - -    # ----------- freeport() with platform-dependent socket stuff ------------ -    # This is what we should've had unit tests to begin with (see CHOP-661). -    def newbind(port): -        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -        sock.bind(('127.0.0.1', port)) -        return sock - -    bound0, port0 = freeport(xrange(7777, 7780), newbind) -    assert_equals(port0, 7777) -    bound1, port1 = freeport(xrange(7777, 7780), newbind) -    assert_equals(port1, 7778) -    bound2, port2 = freeport(xrange(7777, 7780), newbind) -    assert_equals(port2, 7779) -    with exc(socket.error, errno.EADDRINUSE): -        bound3, port3 = freeport(xrange(7777, 7780), newbind) - -if __name__ == "__main__": -    test_freeport() | 
