1
0
mirror of https://github.com/square/okhttp.git synced 2025-08-08 23:42:08 +03:00

Make FakeDns more capable.

This commit is contained in:
Yuri Schimke
2017-03-03 22:41:02 +00:00
committed by jwilson
parent 89621df62d
commit 9e0b5b81b0
3 changed files with 72 additions and 63 deletions

View File

@@ -19,39 +19,61 @@ import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public final class FakeDns implements Dns { public final class FakeDns implements Dns {
private List<String> requestedHosts = new ArrayList<>(); private final Map<String, List<InetAddress>> hostAddresses = new LinkedHashMap<>();
private List<InetAddress> addresses = Collections.emptyList(); private final List<String> requestedHosts = new ArrayList<>();
private int nextAddress = 100;
/** Sets the addresses to be returned by this fake DNS service. */ /** Sets the results for {@code hostname}. */
public FakeDns addresses(List<InetAddress> addresses) { public FakeDns set(String hostname, List<InetAddress> addresses) {
this.addresses = new ArrayList<>(addresses); hostAddresses.put(hostname, addresses);
return this; return this;
} }
/** Sets the service to throw when a hostname is requested. */ /** Clears the results for {@code hostname}. */
public FakeDns unknownHost() { public FakeDns clear(String hostname) {
this.addresses = Collections.emptyList(); hostAddresses.remove(hostname);
return this; return this;
} }
public InetAddress address(int index) { public InetAddress lookup(String hostname, int index) throws UnknownHostException {
return addresses.get(index); return hostAddresses.get(hostname).get(index);
} }
@Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
requestedHosts.add(hostname); requestedHosts.add(hostname);
if (addresses.isEmpty()) throw new UnknownHostException();
return addresses; List<InetAddress> result = hostAddresses.get(hostname);
if (result != null) return result;
throw new UnknownHostException();
} }
public void assertRequests(String... expectedHosts) { public void assertRequests(String... expectedHosts) {
assertEquals(Arrays.asList(expectedHosts), requestedHosts); assertEquals(Arrays.asList(expectedHosts), requestedHosts);
requestedHosts.clear(); requestedHosts.clear();
} }
/** Allocates and returns {@code count} fake addresses like [255.0.0.100, 255.0.0.101]. */
public List<InetAddress> allocate(int count) {
try {
List<InetAddress> result = new ArrayList<>();
for (int i = 0; i < count; i++) {
if (nextAddress > 255) {
throw new AssertionError("too many addresses allocated");
}
result.add(InetAddress.getByAddress(
new byte[] {(byte) 255, (byte) 0, (byte) 0, (byte) nextAddress++}));
}
return result;
} catch (UnknownHostException e) {
throw new AssertionError();
}
}
} }

View File

@@ -1518,7 +1518,7 @@ public final class CallTest {
// Attempt conditional cache validation and a DNS miss. // Attempt conditional cache validation and a DNS miss.
client.connectionPool().evictAll(); client.connectionPool().evictAll();
client = client.newBuilder() client = client.newBuilder()
.dns(new FakeDns().unknownHost()) .dns(new FakeDns())
.build(); .build();
executeSynchronously("/").assertFailure(UnknownHostException.class); executeSynchronously("/").assertFailure(UnknownHostException.class);
} }
@@ -2347,9 +2347,9 @@ public final class CallTest {
} }
@Test public void customDns() throws Exception { @Test public void customDns() throws Exception {
// Configure a DNS that returns our MockWebServer for every hostname. // Configure a DNS that returns our local MockWebServer for android.com.
FakeDns dns = new FakeDns(); FakeDns dns = new FakeDns();
dns.addresses(Dns.SYSTEM.lookup(server.url("/").host())); dns.set("android.com", Dns.SYSTEM.lookup(server.url("/").host()));
client = client.newBuilder() client = client.newBuilder()
.dns(dns) .dns(dns)
.build(); .build();

View File

@@ -87,8 +87,8 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 1)); dns.set(uriHost, dns.allocate(1));
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(0), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 0), uriPort);
dns.assertRequests(uriHost); dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
@@ -104,11 +104,11 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 1)); dns.set(uriHost, dns.allocate(1));
Route route = routeSelector.next(); Route route = routeSelector.next();
routeDatabase.failed(route); routeDatabase.failed(route);
routeSelector = new RouteSelector(address, routeDatabase); routeSelector = new RouteSelector(address, routeDatabase);
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(0), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 0), uriPort);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
try { try {
routeSelector.next(); routeSelector.next();
@@ -123,9 +123,9 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 2)); dns.set(proxyAHost, dns.allocate(2));
assertRoute(routeSelector.next(), address, proxyA, dns.address(0), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 0), proxyAPort);
assertRoute(routeSelector.next(), address, proxyA, dns.address(1), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 1), proxyAPort);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
dns.assertRequests(proxyAHost); dns.assertRequests(proxyAHost);
@@ -138,9 +138,9 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 2)); dns.set(uriHost, dns.allocate(2));
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(0), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 0), uriPort);
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(1), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 1), uriPort);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
dns.assertRequests(uriHost); dns.assertRequests(uriHost);
@@ -164,8 +164,8 @@ public final class RouteSelectorTest {
authenticator, null, protocols, connectionSpecs, nullProxySelector); authenticator, null, protocols, connectionSpecs, nullProxySelector);
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 1)); dns.set(uriHost, dns.allocate(1));
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(0), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 0), uriPort);
dns.assertRequests(uriHost); dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
@@ -176,9 +176,9 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 2)); dns.set(uriHost, dns.allocate(2));
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(0), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 0), uriPort);
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(1), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 1), uriPort);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
dns.assertRequests(uriHost); dns.assertRequests(uriHost);
@@ -195,15 +195,15 @@ public final class RouteSelectorTest {
// First try the IP addresses of the first proxy, in sequence. // First try the IP addresses of the first proxy, in sequence.
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 2)); dns.set(proxyAHost, dns.allocate(2));
assertRoute(routeSelector.next(), address, proxyA, dns.address(0), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 0), proxyAPort);
assertRoute(routeSelector.next(), address, proxyA, dns.address(1), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 1), proxyAPort);
dns.assertRequests(proxyAHost); dns.assertRequests(proxyAHost);
// Next try the IP address of the second proxy. // Next try the IP address of the second proxy.
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(254, 1)); dns.set(proxyBHost, dns.allocate(1));
assertRoute(routeSelector.next(), address, proxyB, dns.address(0), proxyBPort); assertRoute(routeSelector.next(), address, proxyB, dns.lookup(proxyBHost, 0), proxyBPort);
dns.assertRequests(proxyBHost); dns.assertRequests(proxyBHost);
// No more proxies to try. // No more proxies to try.
@@ -219,8 +219,8 @@ public final class RouteSelectorTest {
// Only the origin server will be attempted. // Only the origin server will be attempted.
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 1)); dns.set(uriHost, dns.allocate(1));
assertRoute(routeSelector.next(), address, NO_PROXY, dns.address(0), uriPort); assertRoute(routeSelector.next(), address, NO_PROXY, dns.lookup(uriHost, 0), uriPort);
dns.assertRequests(uriHost); dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
@@ -236,12 +236,12 @@ public final class RouteSelectorTest {
proxySelector.assertRequests(address.url().uri()); proxySelector.assertRequests(address.url().uri());
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 1)); dns.set(proxyAHost, dns.allocate(1));
assertRoute(routeSelector.next(), address, proxyA, dns.address(0), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 0), proxyAPort);
dns.assertRequests(proxyAHost); dns.assertRequests(proxyAHost);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.unknownHost(); dns.clear(proxyBHost);
try { try {
routeSelector.next(); routeSelector.next();
fail(); fail();
@@ -250,8 +250,8 @@ public final class RouteSelectorTest {
dns.assertRequests(proxyBHost); dns.assertRequests(proxyBHost);
assertTrue(routeSelector.hasNext()); assertTrue(routeSelector.hasNext());
dns.addresses(makeFakeAddresses(255, 1)); dns.set(proxyAHost, dns.allocate(1));
assertRoute(routeSelector.next(), address, proxyA, dns.address(0), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 0), proxyAPort);
dns.assertRequests(proxyAHost); dns.assertRequests(proxyAHost);
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
@@ -264,16 +264,16 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
// Proxy A // Proxy A
dns.addresses(makeFakeAddresses(255, 2)); dns.set(proxyAHost, dns.allocate(2));
assertRoute(routeSelector.next(), address, proxyA, dns.address(0), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 0), proxyAPort);
dns.assertRequests(proxyAHost); dns.assertRequests(proxyAHost);
assertRoute(routeSelector.next(), address, proxyA, dns.address(1), proxyAPort); assertRoute(routeSelector.next(), address, proxyA, dns.lookup(proxyAHost, 1), proxyAPort);
// Proxy B // Proxy B
dns.addresses(makeFakeAddresses(254, 2)); dns.set(proxyBHost, dns.allocate(2));
assertRoute(routeSelector.next(), address, proxyB, dns.address(0), proxyBPort); assertRoute(routeSelector.next(), address, proxyB, dns.lookup(proxyBHost, 0), proxyBPort);
dns.assertRequests(proxyBHost); dns.assertRequests(proxyBHost);
assertRoute(routeSelector.next(), address, proxyB, dns.address(1), proxyBPort); assertRoute(routeSelector.next(), address, proxyB, dns.lookup(proxyBHost, 1), proxyBPort);
// No more proxies to attempt. // No more proxies to attempt.
assertFalse(routeSelector.hasNext()); assertFalse(routeSelector.hasNext());
@@ -284,7 +284,7 @@ public final class RouteSelectorTest {
RouteSelector routeSelector = new RouteSelector(address, routeDatabase); RouteSelector routeSelector = new RouteSelector(address, routeDatabase);
final int numberOfAddresses = 2; final int numberOfAddresses = 2;
dns.addresses(makeFakeAddresses(255, numberOfAddresses)); dns.set(uriHost, dns.allocate(numberOfAddresses));
// Extract the regular sequence of routes from selector. // Extract the regular sequence of routes from selector.
List<Route> regularRoutes = new ArrayList<>(); List<Route> regularRoutes = new ArrayList<>();
@@ -351,17 +351,4 @@ public final class RouteSelectorTest {
return new Address(uriHost, uriPort, dns, socketFactory, sslSocketFactory, return new Address(uriHost, uriPort, dns, socketFactory, sslSocketFactory,
hostnameVerifier, null, authenticator, null, protocols, connectionSpecs, proxySelector); hostnameVerifier, null, authenticator, null, protocols, connectionSpecs, proxySelector);
} }
private static List<InetAddress> makeFakeAddresses(int prefix, int count) {
try {
List<InetAddress> result = new ArrayList<>();
for (int i = 0; i < count; i++) {
result.add(InetAddress.getByAddress(
new byte[] {(byte) prefix, (byte) 0, (byte) 0, (byte) i}));
}
return result;
} catch (UnknownHostException e) {
throw new AssertionError();
}
}
} }