1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.impl.routing;
29
30 import java.net.InetAddress;
31 import java.util.HashSet;
32 import java.util.Set;
33
34 import org.apache.hc.client5.http.HttpRoute;
35 import org.apache.hc.client5.http.RouteInfo.LayerType;
36 import org.apache.hc.client5.http.RouteInfo.TunnelType;
37 import org.apache.hc.client5.http.RouteTracker;
38 import org.apache.hc.client5.http.routing.HttpRouteDirector;
39 import org.apache.hc.core5.http.HttpHost;
40 import org.junit.Assert;
41 import org.junit.Test;
42
43
44
45
46 @SuppressWarnings("boxing")
47 public class TestRouteTracker {
48
49
50 public final static
51 HttpHost TARGET1 = new HttpHost("target1.test.invalid", 80);
52 public final static
53 HttpHost TARGET2 = new HttpHost("target2.test.invalid", 8080);
54
55
56
57
58 public final static
59 HttpHost PROXY1 = new HttpHost("proxy1.test.invalid", 80);
60 public final static
61 HttpHost PROXY2 = new HttpHost("proxy2.test.invalid", 1080);
62 public final static
63 HttpHost PROXY3 = new HttpHost("proxy3.test.invalid", 88);
64
65 public final static InetAddress LOCAL41;
66 public final static InetAddress LOCAL42;
67 public final static InetAddress LOCAL61;
68 public final static InetAddress LOCAL62;
69
70
71 static {
72 try {
73 LOCAL41 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 1 });
74 LOCAL42 = InetAddress.getByAddress(new byte[]{ 127, 0, 0, 2 });
75
76 LOCAL61 = InetAddress.getByAddress(new byte[]{
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
78 });
79 LOCAL62 = InetAddress.getByAddress(new byte[]{
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2
81 });
82
83 } catch (final Exception x) {
84 throw new ExceptionInInitializerError(x);
85 }
86 }
87
88 @SuppressWarnings("unused")
89 @Test
90 public void testCstrTargetLocal() {
91
92 RouteTracker rt = new RouteTracker(TARGET1, null);
93 Assert.assertEquals("wrong target (target,null)",
94 TARGET1, rt.getTargetHost());
95 Assert.assertEquals("wrong local address (target,null)",
96 null, rt.getLocalAddress());
97 Assert.assertEquals("wrong hop count (target,null)",
98 0, rt.getHopCount());
99 Assert.assertEquals("wrong proxy (target,null)",
100 null, rt.getProxyHost());
101 Assert.assertEquals("wrong route (target,null)",
102 null, rt.toRoute());
103 checkCTLS(rt, false, false, false, false);
104
105
106 rt = new RouteTracker(TARGET2, LOCAL61);
107 Assert.assertEquals("wrong target (target,local)",
108 TARGET2, rt.getTargetHost());
109 Assert.assertEquals("wrong local address (target,local)",
110 LOCAL61, rt.getLocalAddress());
111 Assert.assertEquals("wrong hop count (target,local)",
112 0, rt.getHopCount());
113 Assert.assertEquals("wrong proxy (target,local)",
114 null, rt.getProxyHost());
115 Assert.assertEquals("wrong route (target,local)",
116 null, rt.toRoute());
117 checkCTLS(rt, false, false, false, false);
118
119
120 rt = null;
121 try {
122 new RouteTracker(null, LOCAL41);
123 Assert.fail("null target not detected");
124 } catch (final NullPointerException iax) {
125
126 }
127 }
128
129 @SuppressWarnings("unused")
130 @Test
131 public void testCstrRoute() {
132
133 HttpRoute r = new HttpRoute(TARGET1);
134 RouteTracker rt = new RouteTracker(r);
135 Assert.assertEquals("wrong target (r1)",
136 TARGET1, rt.getTargetHost());
137 Assert.assertEquals("wrong local address (r1)",
138 null, rt.getLocalAddress());
139 Assert.assertEquals("wrong hop count (r1)",
140 0, rt.getHopCount());
141 Assert.assertEquals("wrong proxy (r1)",
142 null, rt.getProxyHost());
143 Assert.assertEquals("wrong route (r1)",
144 null, rt.toRoute());
145 checkCTLS(rt, false, false, false, false);
146
147 r = new HttpRoute(TARGET2, LOCAL61, true);
148 rt = new RouteTracker(r);
149 Assert.assertEquals("wrong target (r2)",
150 TARGET2, rt.getTargetHost());
151 Assert.assertEquals("wrong local address (r2)",
152 LOCAL61, rt.getLocalAddress());
153 Assert.assertEquals("wrong hop count (r2)",
154 0, rt.getHopCount());
155 Assert.assertEquals("wrong proxy (r2)",
156 null, rt.getProxyHost());
157 Assert.assertEquals("wrong route (r2)",
158 null, rt.toRoute());
159 checkCTLS(rt, false, false, false, false);
160
161
162 r = new HttpRoute(TARGET1, LOCAL42, PROXY3, true);
163 rt = new RouteTracker(r);
164 Assert.assertEquals("wrong target (r3)",
165 TARGET1, rt.getTargetHost());
166 Assert.assertEquals("wrong local address (r3)",
167 LOCAL42, rt.getLocalAddress());
168 Assert.assertEquals("wrong hop count (r3)",
169 0, rt.getHopCount());
170 Assert.assertEquals("wrong proxy (r3)",
171 null, rt.getProxyHost());
172 Assert.assertEquals("wrong route (r3)",
173 null, rt.toRoute());
174 checkCTLS(rt, false, false, false, false);
175
176
177 rt = null;
178 try {
179 new RouteTracker(null);
180 Assert.fail("null route not detected");
181 } catch (final NullPointerException npx) {
182
183 }
184 }
185
186 @Test
187 public void testIllegalArgs() {
188
189 final RouteTracker rt = new RouteTracker(TARGET2, null);
190
191 try {
192 rt.connectProxy(null, true);
193 Assert.fail("missing proxy argument not detected (connect/false)");
194 } catch (final NullPointerException iax) {
195
196 }
197
198 try {
199 rt.connectProxy(null, false);
200 Assert.fail("missing proxy argument not detected (connect/true)");
201 } catch (final NullPointerException iax) {
202
203 }
204
205 rt.connectProxy(PROXY1, false);
206
207 try {
208 rt.tunnelProxy(null, false);
209 Assert.fail("missing proxy argument not detected (tunnel/false)");
210 } catch (final NullPointerException iax) {
211
212 }
213
214 try {
215 rt.tunnelProxy(null, true);
216 Assert.fail("missing proxy argument not detected (tunnel/true)");
217 } catch (final NullPointerException iax) {
218
219 }
220
221 try {
222 rt.getHopTarget(-1);
223 Assert.fail("negative hop index not detected");
224 } catch (final IllegalArgumentException iax) {
225
226 }
227
228 try {
229 rt.getHopTarget(2);
230 Assert.fail("excessive hop index not detected");
231 } catch (final IllegalArgumentException iax) {
232
233 }
234 }
235
236 @Test
237 public void testIllegalStates() {
238
239 final RouteTracker rt = new RouteTracker(TARGET1, null);
240
241 try {
242 rt.tunnelTarget(false);
243 Assert.fail("unconnectedness not detected (tunnelTarget)");
244 } catch (final IllegalStateException isx) {
245
246 }
247
248 try {
249 rt.tunnelProxy(PROXY1, false);
250 Assert.fail("unconnectedness not detected (tunnelProxy)");
251 } catch (final IllegalStateException isx) {
252
253 }
254
255 try {
256 rt.layerProtocol(true);
257 Assert.fail("unconnectedness not detected (layerProtocol)");
258 } catch (final IllegalStateException isx) {
259
260 }
261
262
263
264 rt.connectTarget(false);
265
266 try {
267 rt.connectTarget(false);
268 Assert.fail("connectedness not detected (connectTarget)");
269 } catch (final IllegalStateException isx) {
270
271 }
272
273 try {
274 rt.connectProxy(PROXY2, false);
275 Assert.fail("connectedness not detected (connectProxy)");
276 } catch (final IllegalStateException isx) {
277
278 }
279
280 try {
281 rt.tunnelTarget(false);
282 Assert.fail("unproxiedness not detected (tunnelTarget)");
283 } catch (final IllegalStateException isx) {
284
285 }
286
287 try {
288 rt.tunnelProxy(PROXY1, false);
289 Assert.fail("unproxiedness not detected (tunnelProxy)");
290 } catch (final IllegalStateException isx) {
291
292 }
293 }
294
295 @Test
296 public void testDirectRoutes() {
297
298 final HttpRouteDirector rd = new BasicRouteDirector();
299 HttpRoute r = new HttpRoute(TARGET1, LOCAL41, false);
300 RouteTracker rt = new RouteTracker(r);
301 boolean complete = checkVia(rt, r, rd, 2);
302 Assert.assertTrue("incomplete route 1", complete);
303
304 r = new HttpRoute(TARGET2, LOCAL62, true);
305 rt = new RouteTracker(r);
306 complete = checkVia(rt, r, rd, 2);
307 Assert.assertTrue("incomplete route 2", complete);
308 }
309
310 @Test
311 public void testProxyRoutes() {
312
313 final HttpRouteDirector rd = new BasicRouteDirector();
314 HttpRoute r = new HttpRoute(TARGET2, null, PROXY1, false);
315 RouteTracker rt = new RouteTracker(r);
316 boolean complete = checkVia(rt, r, rd, 2);
317 Assert.assertTrue("incomplete route 1", complete);
318
319
320 r = new HttpRoute(TARGET1, LOCAL61, PROXY3, false,
321 TunnelType.TUNNELLED, LayerType.PLAIN);
322 rt = new RouteTracker(r);
323 complete = checkVia(rt, r, rd, 3);
324 Assert.assertTrue("incomplete route 2", complete);
325
326
327 r = new HttpRoute(TARGET1, LOCAL61, PROXY3, false,
328 TunnelType.TUNNELLED, LayerType.LAYERED);
329 rt = new RouteTracker(r);
330 complete = checkVia(rt, r, rd, 4);
331 Assert.assertTrue("incomplete route 3", complete);
332
333
334 r = new HttpRoute(TARGET1, LOCAL61, PROXY3, true);
335 rt = new RouteTracker(r);
336 complete = checkVia(rt, r, rd, 4);
337 Assert.assertTrue("incomplete route 4", complete);
338 }
339
340 @Test
341 public void testProxyChainRoutes() {
342
343 final HttpRouteDirector rd = new BasicRouteDirector();
344 HttpHost[] proxies = { PROXY1, PROXY2 };
345 HttpRoute r = new HttpRoute(TARGET2, LOCAL42, proxies, false,
346 TunnelType.PLAIN, LayerType.PLAIN);
347 RouteTracker rt = new RouteTracker(r);
348 boolean complete = checkVia(rt, r, rd, 3);
349 Assert.assertTrue("incomplete route 1", complete);
350
351
352 proxies = new HttpHost[]{ PROXY3, PROXY2 };
353 r = new HttpRoute(TARGET1, null, proxies, false,
354 TunnelType.TUNNELLED, LayerType.PLAIN);
355 rt = new RouteTracker(r);
356 complete = checkVia(rt, r, rd, 4);
357 Assert.assertTrue("incomplete route 2", complete);
358
359
360 proxies = new HttpHost[]{ PROXY3, PROXY2, PROXY1 };
361 r = new HttpRoute(TARGET2, LOCAL61, proxies, false,
362 TunnelType.TUNNELLED, LayerType.LAYERED);
363 rt = new RouteTracker(r);
364 complete = checkVia(rt, r, rd, 6);
365 Assert.assertTrue("incomplete route 3", complete);
366
367
368 proxies = new HttpHost[]{ PROXY1, PROXY3 };
369 r = new HttpRoute(TARGET1, LOCAL61, proxies, true,
370 TunnelType.TUNNELLED, LayerType.LAYERED);
371 rt = new RouteTracker(r);
372 complete = checkVia(rt, r, rd, 5);
373 Assert.assertTrue("incomplete route 4", complete);
374 }
375
376 @Test
377 public void testEqualsHashcodeCloneToString()
378 throws CloneNotSupportedException {
379
380 final RouteTracker rt0 = new RouteTracker(TARGET1, null);
381 final RouteTracker rt1 = new RouteTracker(TARGET2, null);
382 final RouteTracker rt2 = new RouteTracker(TARGET1, null);
383 final RouteTracker rt3 = new RouteTracker(TARGET1, null);
384 final RouteTracker rt4 = new RouteTracker(TARGET1, LOCAL41);
385 final RouteTracker rt6 = new RouteTracker(TARGET1, LOCAL62);
386
387 Assert.assertFalse("rt0", rt0.equals(null));
388 Assert.assertTrue("rt0", rt0.equals(rt0));
389 Assert.assertFalse("rt0", rt0.equals(rt0.toString()));
390
391 Assert.assertFalse("rt0 == rt4", rt0.equals(rt4));
392 Assert.assertFalse("rt0 == rt1", rt0.equals(rt1));
393
394
395 Assert.assertTrue("rt0 != rt2", rt0.equals(rt2));
396 rt2.connectTarget(false);
397 Assert.assertFalse("rt0 == rt2", rt0.equals(rt2));
398
399 Assert.assertTrue("rt0 != rt3", rt0.equals(rt3));
400 rt3.connectTarget(true);
401 Assert.assertFalse("rt0 == rt3", rt0.equals(rt3));
402 Assert.assertFalse("rt2 == rt3", rt2.equals(rt3));
403
404
405
406 Assert.assertFalse("rt4 == rt0", rt4.equals(rt0));
407 Assert.assertFalse("rt0 == rt6", rt0.equals(rt6));
408 Assert.assertFalse("rt6 == rt0", rt6.equals(rt0));
409 Assert.assertFalse("rt4 == rt6", rt4.equals(rt6));
410 Assert.assertFalse("rt6 == rt4", rt6.equals(rt4));
411
412
413 Assert.assertFalse("rt0 == rt4 (hashcode)", rt0.hashCode() == rt4.hashCode());
414 Assert.assertFalse("rt0 == rt6 (hashcode)", rt0.hashCode() == rt6.hashCode());
415 Assert.assertFalse("rt6 == rt4 (hashcode)", rt6.hashCode() == rt4.hashCode());
416
417 Assert.assertEquals("rt0 (clone)", rt0, rt0.clone());
418 Assert.assertEquals("rt4 (clone)", rt4, rt4.clone());
419 Assert.assertEquals("rt6 (clone)", rt6, rt6.clone());
420
421
422
423
424
425
426 final Set<RouteTracker> hs = new HashSet<>();
427
428
429
430
431 final Set<Integer> hc0 = new HashSet<>();
432 final Set<Integer> hc4 = new HashSet<>();
433 final Set<Integer> hc6 = new HashSet<>();
434
435 RouteTracker rt = null;
436
437 Assert.assertTrue(hs.add(rt0));
438 Assert.assertTrue(hs.add(rt4));
439 Assert.assertTrue(hs.add(rt6));
440
441 Assert.assertTrue(hc0.add(Integer.valueOf(rt0.hashCode())));
442 Assert.assertTrue(hc4.add(Integer.valueOf(rt4.hashCode())));
443 Assert.assertTrue(hc6.add(Integer.valueOf(rt6.hashCode())));
444
445 rt = (RouteTracker) rt0.clone();
446 rt.connectTarget(false);
447 Assert.assertTrue(hs.add(rt));
448 Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode())));
449
450 rt = (RouteTracker) rt0.clone();
451 rt.connectTarget(true);
452 Assert.assertTrue(hs.add(rt));
453 Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode())));
454
455
456
457 rt = (RouteTracker) rt4.clone();
458 rt.connectProxy(PROXY1, false);
459 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
460
461 Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
462
463 rt.tunnelTarget(false);
464 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
465 Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
466
467 rt.layerProtocol(true);
468 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
469 Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
470
471
472
473 rt = (RouteTracker) rt4.clone();
474 rt.connectProxy(PROXY1, true);
475 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
476
477 Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
478
479 rt.tunnelTarget(true);
480 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
481 Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
482
483 rt.layerProtocol(false);
484 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
485 Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
486
487
488
489 rt = (RouteTracker) rt6.clone();
490 rt.connectProxy(PROXY1, false);
491 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
492
493 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
494
495 rt.tunnelProxy(PROXY2, false);
496 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
497
498 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
499
500 rt.tunnelTarget(false);
501 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
502 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
503
504 rt.layerProtocol(true);
505 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
506 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
507
508
509
510 rt = (RouteTracker) rt6.clone();
511 rt.connectProxy(PROXY1, true);
512 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
513
514 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
515
516 rt.tunnelProxy(PROXY2, true);
517 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
518
519 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
520
521 rt.tunnelTarget(true);
522 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
523 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
524
525 rt.layerProtocol(false);
526 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
527 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
528
529
530
531 rt = (RouteTracker) rt6.clone();
532 rt.connectProxy(PROXY2, false);
533 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
534
535 Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
536
537 rt.tunnelProxy(PROXY1, false);
538 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
539
540
541
542 rt.tunnelTarget(false);
543 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
544
545
546
547 rt.layerProtocol(true);
548 Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
549
550
551
552
553
554 final Set<String> rtstrings = new HashSet<>();
555 for (final RouteTracker current: hs) {
556 final String rts = checkToString(current);
557 Assert.assertTrue("duplicate toString: " + rts, rtstrings.add(rts));
558 }
559 }
560
561
562
563 public final static void checkCTLS(final RouteTracker rt,
564 final boolean c, final boolean t,
565 final boolean l, final boolean s) {
566 final String rts = rt.toString();
567 Assert.assertEquals("wrong flag connected: " + rts, c, rt.isConnected());
568 Assert.assertEquals("wrong flag tunnelled: " + rts, t, rt.isTunnelled());
569 Assert.assertEquals("wrong enum tunnelled: " + rts,
570 t ? TunnelType.TUNNELLED : TunnelType.PLAIN,
571 rt.getTunnelType());
572 Assert.assertEquals("wrong flag layered: " + rts, l, rt.isLayered());
573 Assert.assertEquals("wrong enum layered: " + rts,
574 l ? LayerType.LAYERED : LayerType.PLAIN,
575 rt.getLayerType());
576 Assert.assertEquals("wrong flag secure: " + rts, s, rt.isSecure());
577 }
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592 public final static boolean checkVia(final RouteTracker rt, final HttpRoute r,
593 final HttpRouteDirector rd, final int steps) {
594
595 final String msg = r + " @ " + rt;
596
597 boolean complete = false;
598 int n = steps;
599 while (!complete && (n > 0)) {
600
601 final int action = rd.nextStep(r, rt.toRoute());
602 switch (action) {
603
604 case HttpRouteDirector.COMPLETE:
605 complete = true;
606 Assert.assertEquals(r, rt.toRoute());
607 break;
608
609 case HttpRouteDirector.CONNECT_TARGET: {
610 final boolean sec = r.isSecure();
611 rt.connectTarget(sec);
612 checkCTLS(rt, true, false, false, sec);
613 Assert.assertEquals("wrong hop count "+msg,
614 1, rt.getHopCount());
615 Assert.assertEquals("wrong hop0 "+msg,
616 r.getTargetHost(), rt.getHopTarget(0));
617 } break;
618
619 case HttpRouteDirector.CONNECT_PROXY: {
620
621 final boolean sec = false;
622 rt.connectProxy(r.getProxyHost(), sec);
623 checkCTLS(rt, true, false, false, sec);
624 Assert.assertEquals("wrong hop count "+msg,
625 2, rt.getHopCount());
626 Assert.assertEquals("wrong hop0 "+msg,
627 r.getProxyHost(), rt.getHopTarget(0));
628 Assert.assertEquals("wrong hop1 "+msg,
629 r.getTargetHost(), rt.getHopTarget(1));
630 } break;
631
632 case HttpRouteDirector.TUNNEL_TARGET: {
633 final int hops = rt.getHopCount();
634
635 final boolean sec = false;
636 rt.tunnelTarget(sec);
637 checkCTLS(rt, true, true, false, sec);
638 Assert.assertEquals("wrong hop count "+msg,
639 hops, rt.getHopCount());
640 Assert.assertEquals("wrong hop0 "+msg,
641 r.getProxyHost(), rt.getHopTarget(0));
642 Assert.assertEquals("wrong hopN "+msg,
643 r.getTargetHost(), rt.getHopTarget(hops-1));
644 } break;
645
646 case HttpRouteDirector.TUNNEL_PROXY: {
647 final int hops = rt.getHopCount();
648
649 final boolean sec = false;
650 final HttpHost pxy = r.getHopTarget(hops-1);
651 rt.tunnelProxy(pxy, sec);
652
653
654 checkCTLS(rt, true, false, false, sec);
655 Assert.assertEquals("wrong hop count "+msg,
656 hops+1, rt.getHopCount());
657 Assert.assertEquals("wrong hop0 "+msg,
658 r.getProxyHost(), rt.getHopTarget(0));
659 Assert.assertEquals("wrong hop"+hops+" "+msg,
660 pxy, rt.getHopTarget(hops-1));
661 Assert.assertEquals("wrong hopN "+msg,
662 r.getTargetHost(), rt.getHopTarget(hops));
663 } break;
664
665 case HttpRouteDirector.LAYER_PROTOCOL: {
666 final int hops = rt.getHopCount();
667 final boolean tun = rt.isTunnelled();
668 final boolean sec = r.isSecure();
669 rt.layerProtocol(sec);
670 checkCTLS(rt, true, tun, true, sec);
671 Assert.assertEquals("wrong hop count "+msg,
672 hops, rt.getHopCount());
673 Assert.assertEquals("wrong proxy "+msg,
674 r.getProxyHost(), rt.getProxyHost());
675 Assert.assertEquals("wrong target "+msg,
676 r.getTargetHost(), rt.getTargetHost());
677 } break;
678
679
680
681 default:
682 Assert.fail("unexpected action " + action + " from director, "+msg);
683 break;
684
685 }
686 n--;
687 }
688
689 return complete;
690 }
691
692
693
694
695
696
697
698
699
700 public final static String checkToString(final RouteTracker rt) {
701 if (rt == null) {
702 return null;
703 }
704
705 final String rts = rt.toString();
706
707 if (rt.getLocalAddress() != null) {
708 final String las = rt.getLocalAddress().toString();
709 Assert.assertFalse("no local address in toString(): " + rts,
710 !rts.contains(las));
711 }
712
713 for (int i=0; i<rt.getHopCount(); i++) {
714 final String hts = rt.getHopTarget(i).toString();
715 Assert.assertFalse("hop "+i+" ("+hts+") missing in toString(): " + rts,
716 !rts.contains(hts));
717 }
718
719 return rts;
720 }
721
722 }