View Javadoc
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.SerializableTester;
21  
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  
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  
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  
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  
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  
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  
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  
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.getHostText());
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.getHostText());
146     }
147   }
148 
149   public void testFromParts() {
150     HostAndPort hp = HostAndPort.fromParts("gmail.com", 81);
151     assertEquals("gmail.com", hp.getHostText());
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 
168   public void testFromHost() {
169     HostAndPort hp = HostAndPort.fromHost("gmail.com");
170     assertEquals("gmail.com", hp.getHostText());
171     assertFalse(hp.hasPort());
172 
173     hp = HostAndPort.fromHost("[::1]");
174     assertEquals("::1", hp.getHostText());
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 
190   public void testGetPortOrDefault() {
191     assertEquals(80, HostAndPort.fromString("host:80").getPortOrDefault(123));
192     assertEquals(123, HostAndPort.fromString("host").getPortOrDefault(123));
193   }
194 
195   public void testHashCodeAndEquals() {
196     HostAndPort hp1 = HostAndPort.fromString("foo::123");
197     HostAndPort hp2 = HostAndPort.fromString("foo::123");
198     HostAndPort hp3 = HostAndPort.fromString("[foo::123]");
199     HostAndPort hp4 = HostAndPort.fromParts("[foo::123]", 80);
200     HostAndPort hp5 = HostAndPort.fromString("[foo::123]:80");
201     assertEquals(hp1.hashCode(), hp1.hashCode());
202     assertEquals(hp1.hashCode(), hp2.hashCode());
203     assertFalse(hp1.hashCode() == hp3.hashCode());
204     assertFalse(hp3.hashCode() == hp4.hashCode());
205     assertEquals(hp4.hashCode(), hp5.hashCode());
206 
207     assertTrue(hp1.equals(hp1));
208     assertTrue(hp1.equals(hp2));
209     assertFalse(hp1.equals(hp3));
210     assertFalse(hp3.equals(hp4));
211     assertTrue(hp4.equals(hp5));
212     assertFalse(hp1.equals(null));
213   }
214 
215   public void testRequireBracketsForIPv6() {
216     // Bracketed IPv6 works fine.
217     assertEquals("::1", HostAndPort.fromString("[::1]").requireBracketsForIPv6().getHostText());
218     assertEquals("::1", HostAndPort.fromString("[::1]:80").requireBracketsForIPv6().getHostText());
219     // Non-bracketed non-IPv6 works fine.
220     assertEquals("x", HostAndPort.fromString("x").requireBracketsForIPv6().getHostText());
221     assertEquals("x", HostAndPort.fromString("x:80").requireBracketsForIPv6().getHostText());
222 
223     // Non-bracketed IPv6 fails.
224     try {
225       HostAndPort.fromString("::1").requireBracketsForIPv6();
226       fail("Expected IllegalArgumentException");
227     } catch (IllegalArgumentException expected) {
228     }
229   }
230 
231   public void testToString() {
232     // With ports.
233     assertEquals("foo:101", "" + HostAndPort.fromString("foo:101"));
234     assertEquals(":102", HostAndPort.fromString(":102").toString());
235     assertEquals("[1::2]:103", HostAndPort.fromParts("1::2", 103).toString());
236     assertEquals("[::1]:104", HostAndPort.fromString("[::1]:104").toString());
237 
238     // Without ports.
239     assertEquals("foo", "" + HostAndPort.fromString("foo"));
240     assertEquals("", HostAndPort.fromString("").toString());
241     assertEquals("[1::2]", HostAndPort.fromString("1::2").toString());
242     assertEquals("[::1]", HostAndPort.fromString("[::1]").toString());
243 
244     // Garbage in, garbage out.
245     assertEquals("[::]]:107", HostAndPort.fromParts("::]", 107).toString());
246     assertEquals("[[:]]:108", HostAndPort.fromString("[[:]]:108").toString());
247   }
248 
249   public void testSerialization() {
250     SerializableTester.reserializeAndAssert(HostAndPort.fromParts("host", 80));
251     SerializableTester.reserializeAndAssert(HostAndPort.fromString("host"));
252     SerializableTester.reserializeAndAssert(HostAndPort.fromString("host:80"));
253     SerializableTester.reserializeAndAssert(HostAndPort.fromString("[::1]:104"));
254     SerializableTester.reserializeAndAssert(HostAndPort.fromParts("1::2", 103));
255   }
256 }