/** * @file llhost_test.cpp * @author Adroit * @date 2007-02 * @brief llhost test cases. * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "linden_common.h" #include "../llhost.h" #include "../test/lltut.h" namespace tut { struct host_data { }; typedef test_group<host_data> host_test; typedef host_test::object host_object; tut::host_test host_testcase("LLHost"); template<> template<> void host_object::test<1>() { LLHost host; ensure("IP address is not NULL", (0 == host.getAddress()) && (0 == host.getPort()) && !host.isOk()); } template<> template<> void host_object::test<2>() { U32 ip_addr = 0xc098017d; U32 port = 8080; LLHost host(ip_addr, port); ensure("IP address is invalid", ip_addr == host.getAddress()); ensure("Port Number is invalid", port == host.getPort()); ensure("IP address and port number both should be ok", host.isOk()); } template<> template<> void host_object::test<3>() { const char* str = "192.168.1.1"; U32 port = 8080; LLHost host(str, port); ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str))); ensure("Port Number is invalid", (port == host.getPort())); } template<> template<> void host_object::test<4>() { U32 ip = ip_string_to_u32("192.168.1.1"); U32 port = 22; U64 ip_port = (((U64) ip) << 32) | port; LLHost host(ip_port); ensure("IP address is invalid", ip == host.getAddress()); ensure("Port Number is invalid", port == host.getPort()); } template<> template<> void host_object::test<5>() { std::string ip_port_string = "192.168.1.1:8080"; U32 ip = ip_string_to_u32("192.168.1.1"); U32 port = 8080; LLHost host(ip_port_string); ensure("IP address from IP:port is invalid", ip == host.getAddress()); ensure("Port Number from from IP:port is invalid", port == host.getPort()); } template<> template<> void host_object::test<6>() { U32 ip = 0xc098017d, port = 8080; LLHost host; host.set(ip,port); ensure("IP address is invalid", (ip == host.getAddress())); ensure("Port Number is invalid", (port == host.getPort())); } template<> template<> void host_object::test<7>() { const char* str = "192.168.1.1"; U32 port = 8080, ip; LLHost host; host.set(str,port); ip = ip_string_to_u32(str); ensure("IP address is invalid", (ip == host.getAddress())); ensure("Port Number is invalid", (port == host.getPort())); str = "64.233.187.99"; ip = ip_string_to_u32(str); host.setAddress(str); ensure("IP address is invalid", (ip == host.getAddress())); ip = 0xc098017b; host.setAddress(ip); ensure("IP address is invalid", (ip == host.getAddress())); // should still use the old port ensure("Port Number is invalid", (port == host.getPort())); port = 8084; host.setPort(port); ensure("Port Number is invalid", (port == host.getPort())); // should still use the old address ensure("IP address is invalid", (ip == host.getAddress())); } template<> template<> void host_object::test<8>() { const std::string str("192.168.1.1"); U32 port = 8080; LLHost host; host.set(str,port); std::string ip_string = host.getIPString(); ensure("Function Failed", (ip_string == str)); std::string ip_string_port = host.getIPandPort(); ensure("Function Failed", (ip_string_port == "192.168.1.1:8080")); } // getHostName() and setHostByName template<> template<> void host_object::test<9>() { skip("this test is irreparably flaky"); // skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\""); // nat: is it reasonable to expect LLHost::getHostName() to echo // back something resembling the string passed to setHostByName()? // // If that's not even reasonable, would a round trip in the /other/ // direction make more sense? (Call getHostName() for something with // known IP address; call setHostByName(); verify IP address) // // Failing that... is there a plausible way to test getHostName() and // setHostByName()? Hopefully without putting up a dummy local DNS // server? // monty: If you don't control the DNS server or the DNS configuration // for the test point then, no, none of these will necessarily be // reliable and may start to fail at any time. Forward translation // is subject to CNAME records and round-robin address assignment. // Reverse lookup is 1-to-many and is more and more likely to have // nothing to do with the forward translation. // // So the test is increasingly meaningless on a real network. std::string hostStr = "lindenlab.com"; LLHost host; host.setHostByName(hostStr); // reverse DNS will likely result in appending of some // sub-domain to the main hostname. so look for // the main domain name and not do the exact compare std::string hostname = host.getHostName(); try { ensure("getHostName failed", hostname.find(hostStr) != std::string::npos); } catch (const std::exception&) { std::cerr << "set '" << hostStr << "'; reported '" << hostname << "'" << std::endl; throw; } } // setHostByName for dotted IP template<> template<> void host_object::test<10>() { std::string hostStr = "64.233.167.99"; LLHost host; host.setHostByName(hostStr); ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str())); } template<> template<> void host_object::test<11>() { LLHost host1(0xc098017d, 8080); LLHost host2 = host1; ensure("Both IP addresses are not same", (host1.getAddress() == host2.getAddress())); ensure("Both port numbers are not same", (host1.getPort() == host2.getPort())); } template<> template<> void host_object::test<12>() { LLHost host1("192.168.1.1", 8080); std::string str1 = "192.168.1.1:8080"; std::ostringstream stream; stream << host1; ensure("Operator << failed", ( stream.str()== str1)); // There is no istream >> llhost operator. //std::istringstream is(stream.str()); //LLHost host2; //is >> host2; //ensure("Operator >> failed. Not compatible with <<", host1 == host2); } // operators ==, !=, < template<> template<> void host_object::test<13>() { U32 ip_addr = 0xc098017d; U32 port = 8080; LLHost host1(ip_addr, port); LLHost host2(ip_addr, port); ensure("operator== failed", host1 == host2); // change port host2.setPort(7070); ensure("operator!= failed", host1 != host2); // set port back to 8080 and change IP address now host2.setPort(8080); host2.setAddress(ip_addr+10); ensure("operator!= failed", host1 != host2); ensure("operator< failed", host1 < host2); // set IP address back to same value and change port host2.setAddress(ip_addr); host2.setPort(host1.getPort() + 10); ensure("operator< failed", host1 < host2); } // invalid ip address string template<> template<> void host_object::test<14>() { LLHost host1("10.0.1.2", 6143); ensure("10.0.1.2 should be a valid address", host1.isOk()); LLHost host2("booger-brains", 6143); ensure("booger-brains should be an invalid ip addess", !host2.isOk()); LLHost host3("255.255.255.255", 6143); ensure("255.255.255.255 should be valid broadcast address", host3.isOk()); } }