UrlSelectorImpl implements UrlSelector { @VisibleForTesting static UrlSelectorImpl create(Collection<String> baseUrls, boolean reshuffle) { return createWithFailedUrlCooldown(baseUrls, reshuffle, Duration.ZERO, Clock.systemUTC()); } private  UrlSelectorImpl(
            ImmutableList<HttpUrl> baseUrls, boolean reshuffle, Duration failedUrlCooldown, Clock clock); @Override Optional<HttpUrl> redirectTo(HttpUrl requestUrl, String redirectUrl); @Override Optional<HttpUrl> redirectToNext(HttpUrl requestUrl); @Override Optional<HttpUrl> redirectToCurrent(HttpUrl requestUrl); @Override Optional<HttpUrl> redirectToNextRoundRobin(HttpUrl requestUrl); @Override void markAsSucceeded(HttpUrl succeededUrl); @Override void markAsFailed(HttpUrl failedUrl); @Override List<HttpUrl> getBaseUrls();  }
@Test public void mustSpecifyAtLeastOneUrl() { assertThatThrownBy(() -> UrlSelectorImpl.create(set(), false)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Must specify at least one URL"); }
@Test public void baseUrlsMustBeCanonical() { for (String url : new String[] {"user:pass@foo.com/path", ""}) { Assertions.assertThatLoggableExceptionThrownBy(() -> UrlSelectorImpl.create(list(url), false)) .isInstanceOf(IllegalArgumentException.class) .hasLogMessage("Not a valid URL") .hasExactlyArgs(UnsafeArg.of("url", url)); } for (String url : new String[] { "http: }) { Assertions.assertThatLoggableExceptionThrownBy(() -> UrlSelectorImpl.create(list(url), false)) .isInstanceOf(IllegalArgumentException.class) .hasLogMessage("Base URLs must be 'canonical' and consist of schema, host, port, and path only") .hasExactlyArgs(UnsafeArg.of("url", url)); } for (String url : new String[] { "http: }) { UrlSelectorImpl.create(list(url), false); } }