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 
testFromStringBadPort()62   public void testFromStringBadPort() {
63     // Out-of-range ports.
64     checkFromStringCase("google.com:65536", 1, null, 99, false);
65     checkFromStringCase("google.com:9999999999", 1, null, 99, false);
66     // Invalid port parts.
67     checkFromStringCase("google.com:port", 1, null, 99, false);
68     checkFromStringCase("google.com:-25", 1, null, 99, false);
69     checkFromStringCase("google.com:+25", 1, null, 99, false);
70     checkFromStringCase("google.com:25  ", 1, null, 99, false);
71     checkFromStringCase("google.com:25\t", 1, null, 99, false);
72     checkFromStringCase("google.com:0x25 ", 1, null, 99, false);
73   }
74 
testFromStringUnparseableNonsense()75   public void testFromStringUnparseableNonsense() {
76     // Some nonsense that causes parse failures.
77     checkFromStringCase("[goo.gl]", 1, null, 99, false);
78     checkFromStringCase("[goo.gl]:80", 1, null, 99, false);
79     checkFromStringCase("[", 1, null, 99, false);
80     checkFromStringCase("[]:", 1, null, 99, false);
81     checkFromStringCase("[]:80", 1, null, 99, false);
82     checkFromStringCase("[]bad", 1, null, 99, false);
83   }
84 
testFromStringParseableNonsense()85   public void testFromStringParseableNonsense() {
86     // Examples of nonsense that gets through.
87     checkFromStringCase("[[:]]", 86, "[:]", 86, false);
88     checkFromStringCase("x:y:z", 87, "x:y:z", 87, false);
89     checkFromStringCase("", 88, "", 88, false);
90     checkFromStringCase(":", 99, "", 99, false);
91     checkFromStringCase(":123", -1, "", 123, true);
92     checkFromStringCase("\nOMG\t", 89, "\nOMG\t", 89, false);
93   }
94 
checkFromStringCase( String hpString, int defaultPort, String expectHost, int expectPort, boolean expectHasExplicitPort)95   private static void checkFromStringCase(
96       String hpString,
97       int defaultPort,
98       String expectHost,
99       int expectPort,
100       boolean expectHasExplicitPort) {
101     HostAndPort hp;
102     try {
103       hp = HostAndPort.fromString(hpString);
104     } catch (IllegalArgumentException e) {
105       // Make sure we expected this.
106       assertNull(expectHost);
107       return;
108     }
109     assertNotNull(expectHost);
110 
111     // Apply withDefaultPort(), yielding hp2.
112     final boolean badDefaultPort = (defaultPort < 0 || defaultPort > 65535);
113     HostAndPort hp2 = null;
114     try {
115       hp2 = hp.withDefaultPort(defaultPort);
116       assertFalse(badDefaultPort);
117     } catch (IllegalArgumentException e) {
118       assertTrue(badDefaultPort);
119     }
120 
121     // Check the pre-withDefaultPort() instance.
122     if (expectHasExplicitPort) {
123       assertTrue(hp.hasPort());
124       assertEquals(expectPort, hp.getPort());
125     } else {
126       assertFalse(hp.hasPort());
127       try {
128         hp.getPort();
129         fail("Expected IllegalStateException");
130       } catch (IllegalStateException expected) {
131       }
132     }
133     assertEquals(expectHost, hp.getHost());
134 
135     // Check the post-withDefaultPort() instance (if any).
136     if (!badDefaultPort) {
137       try {
138         int port = hp2.getPort();
139         assertTrue(expectPort != -1);
140         assertEquals(expectPort, port);
141       } catch (IllegalStateException e) {
142         // Make sure we expected this to fail.
143         assertEquals(-1, expectPort);
144       }
145       assertEquals(expectHost, hp2.getHost());
146     }
147   }
148 
testFromParts()149   public void testFromParts() {
150     HostAndPort hp = HostAndPort.fromParts("gmail.com", 81);
151     assertEquals("gmail.com", hp.getHost());
152     assertTrue(hp.hasPort());
153     assertEquals(81, hp.getPort());
154 
155     try {
156       HostAndPort.fromParts("gmail.com:80", 81);
157       fail("Expected IllegalArgumentException");
158     } catch (IllegalArgumentException expected) {
159     }
160 
161     try {
162       HostAndPort.fromParts("gmail.com", -1);
163       fail("Expected IllegalArgumentException");
164     } catch (IllegalArgumentException expected) {
165     }
166   }
167 
testFromHost()168   public void testFromHost() {
169     HostAndPort hp = HostAndPort.fromHost("gmail.com");
170     assertEquals("gmail.com", hp.getHost());
171     assertFalse(hp.hasPort());
172 
173     hp = HostAndPort.fromHost("[::1]");
174     assertEquals("::1", hp.getHost());
175     assertFalse(hp.hasPort());
176 
177     try {
178       HostAndPort.fromHost("gmail.com:80");
179       fail("Expected IllegalArgumentException");
180     } catch (IllegalArgumentException expected) {
181     }
182 
183     try {
184       HostAndPort.fromHost("[gmail.com]");
185       fail("Expected IllegalArgumentException");
186     } catch (IllegalArgumentException expected) {
187     }
188   }
189 
testGetPortOrDefault()190   public void testGetPortOrDefault() {
191     assertEquals(80, HostAndPort.fromString("host:80").getPortOrDefault(123));
192     assertEquals(123, HostAndPort.fromString("host").getPortOrDefault(123));
193   }
194 
testHashCodeAndEquals()195   public void testHashCodeAndEquals() {
196     HostAndPort hpNoPort1 = HostAndPort.fromString("foo::123");
197     HostAndPort hpNoPort2 = HostAndPort.fromString("foo::123");
198     HostAndPort hpNoPort3 = HostAndPort.fromString("[foo::123]");
199     HostAndPort hpNoPort4 = HostAndPort.fromHost("[foo::123]");
200     HostAndPort hpNoPort5 = HostAndPort.fromHost("foo::123");
201 
202     HostAndPort hpWithPort1 = HostAndPort.fromParts("[foo::123]", 80);
203     HostAndPort hpWithPort2 = HostAndPort.fromParts("foo::123", 80);
204     HostAndPort hpWithPort3 = HostAndPort.fromString("[foo::123]:80");
205 
206     new EqualsTester()
207         .addEqualityGroup(hpNoPort1, hpNoPort2, hpNoPort3, hpNoPort4, hpNoPort5)
208         .addEqualityGroup(hpWithPort1, hpWithPort2, hpWithPort3)
209         .testEquals();
210   }
211 
testRequireBracketsForIPv6()212   public void testRequireBracketsForIPv6() {
213     // Bracketed IPv6 works fine.
214     assertEquals("::1", HostAndPort.fromString("[::1]").requireBracketsForIPv6().getHost());
215     assertEquals("::1", HostAndPort.fromString("[::1]:80").requireBracketsForIPv6().getHost());
216     // Non-bracketed non-IPv6 works fine.
217     assertEquals("x", HostAndPort.fromString("x").requireBracketsForIPv6().getHost());
218     assertEquals("x", HostAndPort.fromString("x:80").requireBracketsForIPv6().getHost());
219 
220     // Non-bracketed IPv6 fails.
221     try {
222       HostAndPort.fromString("::1").requireBracketsForIPv6();
223       fail("Expected IllegalArgumentException");
224     } catch (IllegalArgumentException expected) {
225     }
226   }
227 
testToString()228   public void testToString() {
229     // With ports.
230     assertEquals("foo:101", "" + HostAndPort.fromString("foo:101"));
231     assertEquals(":102", HostAndPort.fromString(":102").toString());
232     assertEquals("[1::2]:103", HostAndPort.fromParts("1::2", 103).toString());
233     assertEquals("[::1]:104", HostAndPort.fromString("[::1]:104").toString());
234 
235     // Without ports.
236     assertEquals("foo", "" + HostAndPort.fromString("foo"));
237     assertEquals("", HostAndPort.fromString("").toString());
238     assertEquals("[1::2]", HostAndPort.fromString("1::2").toString());
239     assertEquals("[::1]", HostAndPort.fromString("[::1]").toString());
240 
241     // Garbage in, garbage out.
242     assertEquals("[::]]:107", HostAndPort.fromParts("::]", 107).toString());
243     assertEquals("[[:]]:108", HostAndPort.fromString("[[:]]:108").toString());
244   }
245 
testSerialization()246   public void testSerialization() {
247     SerializableTester.reserializeAndAssert(HostAndPort.fromParts("host", 80));
248     SerializableTester.reserializeAndAssert(HostAndPort.fromString("host"));
249     SerializableTester.reserializeAndAssert(HostAndPort.fromString("host:80"));
250     SerializableTester.reserializeAndAssert(HostAndPort.fromString("[::1]:104"));
251     SerializableTester.reserializeAndAssert(HostAndPort.fromParts("1::2", 103));
252   }
253 }
254