1 /* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.net; 18 19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.testing.EqualsTester; 21 import com.google.common.testing.SerializableTester; 22 import junit.framework.TestCase; 23 24 /** 25 * Tests for {@link HostAndPort} 26 * 27 * @author Paul Marks 28 */ 29 @GwtCompatible 30 public class HostAndPortTest extends TestCase { 31 testFromStringWellFormed()32 public void testFromStringWellFormed() { 33 // Well-formed inputs. 34 checkFromStringCase("google.com", 80, "google.com", 80, false); 35 checkFromStringCase("google.com", 80, "google.com", 80, false); 36 checkFromStringCase("192.0.2.1", 82, "192.0.2.1", 82, false); 37 checkFromStringCase("[2001::1]", 84, "2001::1", 84, false); 38 checkFromStringCase("2001::3", 86, "2001::3", 86, false); 39 checkFromStringCase("host:", 80, "host", 80, false); 40 } 41 testFromStringBadDefaultPort()42 public void testFromStringBadDefaultPort() { 43 // Well-formed strings with bad default ports. 44 checkFromStringCase("gmail.com:81", -1, "gmail.com", 81, true); 45 checkFromStringCase("192.0.2.2:83", -1, "192.0.2.2", 83, true); 46 checkFromStringCase("[2001::2]:85", -1, "2001::2", 85, true); 47 checkFromStringCase("goo.gl:65535", 65536, "goo.gl", 65535, true); 48 // No port, bad default. 49 checkFromStringCase("google.com", -1, "google.com", -1, false); 50 checkFromStringCase("192.0.2.1", 65536, "192.0.2.1", -1, false); 51 checkFromStringCase("[2001::1]", -1, "2001::1", -1, false); 52 checkFromStringCase("2001::3", 65536, "2001::3", -1, false); 53 } 54 testFromStringUnusedDefaultPort()55 public void testFromStringUnusedDefaultPort() { 56 // Default port, but unused. 57 checkFromStringCase("gmail.com:81", 77, "gmail.com", 81, true); 58 checkFromStringCase("192.0.2.2:83", 77, "192.0.2.2", 83, true); 59 checkFromStringCase("[2001::2]:85", 77, "2001::2", 85, true); 60 } 61 testFromStringNonAsciiDigits()62 public void testFromStringNonAsciiDigits() { 63 // Same as testFromStringUnusedDefaultPort but with Gujarati digits for port numbers. 64 checkFromStringCase("gmail.com:૮1", 77, null, -1, false); 65 checkFromStringCase("192.0.2.2:૮૩", 77, null, -1, false); 66 checkFromStringCase("[2001::2]:૮૫", 77, null, -1, false); 67 } 68 testFromStringBadPort()69 public void testFromStringBadPort() { 70 // Out-of-range ports. 71 checkFromStringCase("google.com:65536", 1, null, 99, false); 72 checkFromStringCase("google.com:9999999999", 1, null, 99, false); 73 // Invalid port parts. 74 checkFromStringCase("google.com:port", 1, null, 99, false); 75 checkFromStringCase("google.com:-25", 1, null, 99, false); 76 checkFromStringCase("google.com:+25", 1, null, 99, false); 77 checkFromStringCase("google.com:25 ", 1, null, 99, false); 78 checkFromStringCase("google.com:25\t", 1, null, 99, false); 79 checkFromStringCase("google.com:0x25 ", 1, null, 99, false); 80 } 81 testFromStringUnparseableNonsense()82 public void testFromStringUnparseableNonsense() { 83 // Some nonsense that causes parse failures. 84 checkFromStringCase("[goo.gl]", 1, null, 99, false); 85 checkFromStringCase("[goo.gl]:80", 1, null, 99, false); 86 checkFromStringCase("[", 1, null, 99, false); 87 checkFromStringCase("[]:", 1, null, 99, false); 88 checkFromStringCase("[]:80", 1, null, 99, false); 89 checkFromStringCase("[]bad", 1, null, 99, false); 90 } 91 testFromStringParseableNonsense()92 public void testFromStringParseableNonsense() { 93 // Examples of nonsense that gets through. 94 checkFromStringCase("[[:]]", 86, "[:]", 86, false); 95 checkFromStringCase("x:y:z", 87, "x:y:z", 87, false); 96 checkFromStringCase("", 88, "", 88, false); 97 checkFromStringCase(":", 99, "", 99, false); 98 checkFromStringCase(":123", -1, "", 123, true); 99 checkFromStringCase("\nOMG\t", 89, "\nOMG\t", 89, false); 100 } 101 checkFromStringCase( String hpString, int defaultPort, String expectHost, int expectPort, boolean expectHasExplicitPort)102 private static void checkFromStringCase( 103 String hpString, 104 int defaultPort, 105 String expectHost, 106 int expectPort, 107 boolean expectHasExplicitPort) { 108 HostAndPort hp; 109 try { 110 hp = HostAndPort.fromString(hpString); 111 } catch (IllegalArgumentException e) { 112 // Make sure we expected this. 113 assertNull(expectHost); 114 return; 115 } 116 assertNotNull(expectHost); 117 118 // Apply withDefaultPort(), yielding hp2. 119 final boolean badDefaultPort = (defaultPort < 0 || defaultPort > 65535); 120 HostAndPort hp2 = null; 121 try { 122 hp2 = hp.withDefaultPort(defaultPort); 123 assertFalse(badDefaultPort); 124 } catch (IllegalArgumentException e) { 125 assertTrue(badDefaultPort); 126 } 127 128 // Check the pre-withDefaultPort() instance. 129 if (expectHasExplicitPort) { 130 assertTrue(hp.hasPort()); 131 assertEquals(expectPort, hp.getPort()); 132 } else { 133 assertFalse(hp.hasPort()); 134 try { 135 hp.getPort(); 136 fail("Expected IllegalStateException"); 137 } catch (IllegalStateException expected) { 138 } 139 } 140 assertEquals(expectHost, hp.getHost()); 141 142 // Check the post-withDefaultPort() instance (if any). 143 if (!badDefaultPort) { 144 try { 145 int port = hp2.getPort(); 146 assertTrue(expectPort != -1); 147 assertEquals(expectPort, port); 148 } catch (IllegalStateException e) { 149 // Make sure we expected this to fail. 150 assertEquals(-1, expectPort); 151 } 152 assertEquals(expectHost, hp2.getHost()); 153 } 154 } 155 testFromParts()156 public void testFromParts() { 157 HostAndPort hp = HostAndPort.fromParts("gmail.com", 81); 158 assertEquals("gmail.com", hp.getHost()); 159 assertTrue(hp.hasPort()); 160 assertEquals(81, hp.getPort()); 161 162 try { 163 HostAndPort.fromParts("gmail.com:80", 81); 164 fail("Expected IllegalArgumentException"); 165 } catch (IllegalArgumentException expected) { 166 } 167 168 try { 169 HostAndPort.fromParts("gmail.com", -1); 170 fail("Expected IllegalArgumentException"); 171 } catch (IllegalArgumentException expected) { 172 } 173 } 174 testFromHost()175 public void testFromHost() { 176 HostAndPort hp = HostAndPort.fromHost("gmail.com"); 177 assertEquals("gmail.com", hp.getHost()); 178 assertFalse(hp.hasPort()); 179 180 hp = HostAndPort.fromHost("[::1]"); 181 assertEquals("::1", hp.getHost()); 182 assertFalse(hp.hasPort()); 183 184 try { 185 HostAndPort.fromHost("gmail.com:80"); 186 fail("Expected IllegalArgumentException"); 187 } catch (IllegalArgumentException expected) { 188 } 189 190 try { 191 HostAndPort.fromHost("[gmail.com]"); 192 fail("Expected IllegalArgumentException"); 193 } catch (IllegalArgumentException expected) { 194 } 195 } 196 testGetPortOrDefault()197 public void testGetPortOrDefault() { 198 assertEquals(80, HostAndPort.fromString("host:80").getPortOrDefault(123)); 199 assertEquals(123, HostAndPort.fromString("host").getPortOrDefault(123)); 200 } 201 testHashCodeAndEquals()202 public void testHashCodeAndEquals() { 203 HostAndPort hpNoPort1 = HostAndPort.fromString("foo::123"); 204 HostAndPort hpNoPort2 = HostAndPort.fromString("foo::123"); 205 HostAndPort hpNoPort3 = HostAndPort.fromString("[foo::123]"); 206 HostAndPort hpNoPort4 = HostAndPort.fromHost("[foo::123]"); 207 HostAndPort hpNoPort5 = HostAndPort.fromHost("foo::123"); 208 209 HostAndPort hpWithPort1 = HostAndPort.fromParts("[foo::123]", 80); 210 HostAndPort hpWithPort2 = HostAndPort.fromParts("foo::123", 80); 211 HostAndPort hpWithPort3 = HostAndPort.fromString("[foo::123]:80"); 212 213 new EqualsTester() 214 .addEqualityGroup(hpNoPort1, hpNoPort2, hpNoPort3, hpNoPort4, hpNoPort5) 215 .addEqualityGroup(hpWithPort1, hpWithPort2, hpWithPort3) 216 .testEquals(); 217 } 218 testRequireBracketsForIPv6()219 public void testRequireBracketsForIPv6() { 220 // Bracketed IPv6 works fine. 221 assertEquals("::1", HostAndPort.fromString("[::1]").requireBracketsForIPv6().getHost()); 222 assertEquals("::1", HostAndPort.fromString("[::1]:80").requireBracketsForIPv6().getHost()); 223 // Non-bracketed non-IPv6 works fine. 224 assertEquals("x", HostAndPort.fromString("x").requireBracketsForIPv6().getHost()); 225 assertEquals("x", HostAndPort.fromString("x:80").requireBracketsForIPv6().getHost()); 226 227 // Non-bracketed IPv6 fails. 228 try { 229 HostAndPort.fromString("::1").requireBracketsForIPv6(); 230 fail("Expected IllegalArgumentException"); 231 } catch (IllegalArgumentException expected) { 232 } 233 } 234 testToString()235 public void testToString() { 236 // With ports. 237 assertEquals("foo:101", "" + HostAndPort.fromString("foo:101")); 238 assertEquals(":102", HostAndPort.fromString(":102").toString()); 239 assertEquals("[1::2]:103", HostAndPort.fromParts("1::2", 103).toString()); 240 assertEquals("[::1]:104", HostAndPort.fromString("[::1]:104").toString()); 241 242 // Without ports. 243 assertEquals("foo", "" + HostAndPort.fromString("foo")); 244 assertEquals("", HostAndPort.fromString("").toString()); 245 assertEquals("[1::2]", HostAndPort.fromString("1::2").toString()); 246 assertEquals("[::1]", HostAndPort.fromString("[::1]").toString()); 247 248 // Garbage in, garbage out. 249 assertEquals("[::]]:107", HostAndPort.fromParts("::]", 107).toString()); 250 assertEquals("[[:]]:108", HostAndPort.fromString("[[:]]:108").toString()); 251 } 252 testSerialization()253 public void testSerialization() { 254 SerializableTester.reserializeAndAssert(HostAndPort.fromParts("host", 80)); 255 SerializableTester.reserializeAndAssert(HostAndPort.fromString("host")); 256 SerializableTester.reserializeAndAssert(HostAndPort.fromString("host:80")); 257 SerializableTester.reserializeAndAssert(HostAndPort.fromString("[::1]:104")); 258 SerializableTester.reserializeAndAssert(HostAndPort.fromParts("1::2", 103)); 259 } 260 } 261