nat_linden avatar nat_linden committed 3aac4dc

MAINT-1144: Re-enable skipped LLHTTPClient tests with local server.
Over the years we've skipped more and more of the tests in
llhttpclient_test.cpp (nee llhttpclient_tut.cpp) because they've relied on
particular behaviors from Internet sites not under our control.
We skipped a test that fetches llsd+xml from secondlife.com because
"secondlife.com is not reliable enough for unit tests."
We skipped a test that tries to observe a failure with "http://www.invalid"
because some local ISPs turn "no such domain" DNS errors into valid pages
offering the requester to buy the specified domain name.
Today we've had to skip tests attempting to contact "http://www.google.com"
for reasons we haven't yet diagnosed, but that probably have to do with
Google's IPv6 rollout.
Use local temp server test_llsdmessage_peer.py as the success destination,
eliminating DNS, Internet access and remote server behavior as failure modes.
Use idle localhost port for failure test.
Re-enable all skipped LLHTTPClient tests!
Re-enable on Windows!
In support of these tests, modify test_llsdmessage_peer.py:
Support HEAD as no-data variant of GET.
Change GET result dict to avoid resembling an error response -- confusing.
Make GET/POST return actual dict rather than undecorated string "success".
Because of that last, change llcapabilitylistener_test.cpp and
llsdmessage_test.cpp to extract "reply" key from response rather than
expecting response to be a string itself.

Comments (0)

Files changed (4)

indra/llmessage/tests/llhttpclient_test.cpp

 /** 
- * @file llhttpclient_tut.cpp
+ * @file llhttpclient_test.cpp
  * @brief Testing the HTTP client classes.
  *
  * $LicenseInfo:firstyear=2006&license=viewerlgpl$
 #include <tut/tut.hpp>
 #include "linden_common.h"
 
-// These are too slow on Windows to actually include in the build. JC
-#if !LL_WINDOWS
-
 #include "lltut.h"
 #include "llhttpclient.h"
 #include "llformat.h"
 #include "llsdhttpserver.h"
 #include "lliohttpserver.h"
 #include "lliosocket.h"
+#include "stringize.h"
 
 namespace tut
 {
 	struct HTTPClientTestData
 	{
 	public:
-		HTTPClientTestData()
+		HTTPClientTestData():
+			local_server(STRINGIZE("http://127.0.0.1:" << getenv("PORT") << "/"))
 		{
 			apr_pool_create(&mPool, NULL);
 			LLCurl::initClass(false);
 			delete mServerPump;
 			mServerPump = NULL;
 		}
-	
+
+		const std::string local_server;
+
 	private:
 		apr_pool_t* mPool;
 		LLPumpIO* mServerPump;
 		LLPumpIO* mClientPump;
 
-		
 	protected:
 		void ensureStatusOK()
 		{
 	template<> template<>
 	void HTTPClientTestObject::test<1>()
 	{
-		skip("google.com unit tests stopped working 2012-06-06");
-		LLHTTPClient::get("http://www.google.com/", newResult());
+		LLHTTPClient::get(local_server, newResult());
 		runThePump();
 		ensureStatusOK();
 		ensure("result object wasn't destroyed", mResultDeleted);
 	template<> template<>
 	void HTTPClientTestObject::test<2>()
 	{
-		skip("error test depends on dev's local ISP not supplying \"helpful\" search page");
-		LLHTTPClient::get("http://www.invalid", newResult());
+		// Please nobody listen on this particular port...
+		LLHTTPClient::get("http://127.0.0.1:7950", newResult());
 		runThePump();
 		ensureStatusError();
 	}
 		// won't ever let it run.  Instead get from a known LLSD
 		// source and compare results with the non-blocking get which
 		// is tested against the mini server earlier.
-		skip("secondlife.com is not reliable enough for unit tests.");
-
-
-		LLSD expected;
-
-		LLHTTPClient::get("http://secondlife.com/xmlhttp/homepage.php", newResult());
+		LLHTTPClient::get(local_server, newResult());
 		runThePump();
 		ensureStatusOK();
-		expected = getResult();
+		LLSD expected = getResult();
 
 		LLSD result;
-		result = LLHTTPClient::blockingGet("http://secondlife.com/xmlhttp/homepage.php");
+		result = LLHTTPClient::blockingGet(local_server);
 		LLSD body = result["body"];
 		ensure_equals("echoed result matches", body.size(), expected.size());
 	}
 	template<> template<>
 		void HTTPClientTestObject::test<8>()
 	{
-		skip("google.com unit tests stopped working 2012-06-06");
 		// This is testing for the presence of the Header in the returned results
 		// from an HTTP::get call.
-		LLHTTPClient::get("http://www.google.com/", newResult());
+		LLHTTPClient::get(local_server, newResult());
 		runThePump();
 		ensureStatusOK();
 		LLSD header = getHeader();
 	template<> template<>
 	void HTTPClientTestObject::test<9>()
 	{
-		skip("google.com unit tests stopped working 2012-06-06");
-		LLHTTPClient::head("http://www.google.com/", newResult());
+		LLHTTPClient::head(local_server, newResult());
 		runThePump();
 		ensureStatusOK();
 		ensure("result object wasn't destroyed", mResultDeleted);
 	}
 }
-
-#endif	// !LL_WINDOWS

indra/llmessage/tests/llsdmessage_test.cpp

         httpPump.post(request);
         ensure("got response", netio.pump());
         ensure("success response", success);
-        ensure_equals(result.asString(), "success");
+        ensure_equals(result["reply"].asString(), "success");
 
         body["status"] = 499;
         body["reason"] = "custom error message";

indra/llmessage/tests/test_llsdmessage_peer.py

 ##         debug("root node tag %s", tree.getroot().tag)
 ##         return llsd.to_python(tree.getroot())
 
-    def do_GET(self):
+    def do_HEAD(self):
+        self.do_GET(withdata=False)
+
+    def do_GET(self, withdata=True):
         # Of course, don't attempt to read data.
-        self.answer(dict(reply="success", status=500,
-                         reason="Your GET operation requested failure"))
+        data = dict(reply="success", body="avatar", random=17)
+        self.answer(data, withdata=withdata)
 
     def do_POST(self):
         # Read the provided POST data.
         self.answer(self.read_xml())
 
-    def answer(self, data):
+    def answer(self, data, withdata=True):
         debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
         if "fail" not in self.path:
-            response = llsd.format_xml(data.get("reply", llsd.LLSD("success")))
+            data = data.copy()          # we're going to modify
+            # Ensure there's a "reply" key in data, even if there wasn't before
+            data["reply"] = data.get("reply", llsd.LLSD("success"))
+            response = llsd.format_xml(data)
             debug("success: %s", response)
             self.send_response(200)
             self.send_header("Content-type", "application/llsd+xml")
             self.send_header("Content-Length", str(len(response)))
             self.end_headers()
-            self.wfile.write(response)
+            if withdata:
+                self.wfile.write(response)
         else:                           # fail requested
             status = data.get("status", 500)
             # self.responses maps an int status to a (short, long) pair of

indra/newview/tests/llcapabilitylistener_test.cpp

         regionPump.post(request);
         ensure("got response", netio.pump());
         ensure("success response", success);
-        ensure_equals(result.asString(), "success");
+        ensure_equals(result["reply"].asString(), "success");
 
         body["status"] = 499;
         body["reason"] = "custom error message";
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.