Merge "DnsResolver cts changes to match API council requests"
This commit is contained in:
@@ -39,13 +39,14 @@ import android.system.ErrnoException;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.util.Log;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class DnsResolverTest extends AndroidTestCase {
|
||||
private static final String TAG = "DnsResolverTest";
|
||||
@@ -53,7 +54,9 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
static final int TIMEOUT_MS = 12_000;
|
||||
static final int CANCEL_TIMEOUT_MS = 3_000;
|
||||
static final int CANCEL_RETRY_TIMES = 5;
|
||||
static final int NXDOMAIN = 3;
|
||||
|
||||
private ConnectivityManager mCM;
|
||||
private Executor mExecutor;
|
||||
@@ -94,73 +97,26 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
return testableNetworks.toArray(new Network[0]);
|
||||
}
|
||||
|
||||
public void testQueryWithInetAddressCallback() {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Query with InetAddressAnswerCallback " + dname;
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicReference<List<InetAddress>> answers = new AtomicReference<>();
|
||||
final DnsResolver.InetAddressAnswerCallback callback =
|
||||
new DnsResolver.InetAddressAnswerCallback() {
|
||||
@Override
|
||||
public void onAnswer(@NonNull List<InetAddress> answerList) {
|
||||
answers.set(answerList);
|
||||
for (InetAddress addr : answerList) {
|
||||
Log.d(TAG, "Reported addr: " + addr.toString());
|
||||
}
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
};
|
||||
mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP,
|
||||
mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.",
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
assertGreaterThan(msg + " returned 0 result", answers.get().size(), 0);
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static private void assertGreaterThan(String msg, int first, int second) {
|
||||
assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
|
||||
}
|
||||
|
||||
static private void assertValidAnswer(String msg, @NonNull DnsAnswer ans) {
|
||||
// Check rcode field.(0, No error condition).
|
||||
assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0);
|
||||
// Check answer counts.
|
||||
assertGreaterThan(msg + " No answer found", ans.getANCount(), 0);
|
||||
// Check question counts.
|
||||
assertGreaterThan(msg + " No question found", ans.getQDCount(), 0);
|
||||
}
|
||||
private static class DnsParseException extends Exception {
|
||||
public DnsParseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
static private void assertValidEmptyAnswer(String msg, @NonNull DnsAnswer ans) {
|
||||
// Check rcode field.(0, No error condition).
|
||||
assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0);
|
||||
// Check answer counts. Expect 0 answer.
|
||||
assertTrue(msg + " Not an empty answer", ans.getANCount() == 0);
|
||||
// Check question counts.
|
||||
assertGreaterThan(msg + " No question found", ans.getQDCount(), 0);
|
||||
public DnsParseException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DnsAnswer extends DnsPacket {
|
||||
DnsAnswer(@NonNull byte[] data) throws ParseException {
|
||||
DnsAnswer(@NonNull byte[] data) throws DnsParseException {
|
||||
super(data);
|
||||
// Check QR field.(query (0), or a response (1)).
|
||||
if ((mHeader.flags & (1 << 15)) == 0) {
|
||||
throw new ParseException("Not an answer packet");
|
||||
throw new DnsParseException("Not an answer packet");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,63 +131,116 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
class RawAnswerCallbackImpl extends DnsResolver.RawAnswerCallback {
|
||||
/**
|
||||
* A query callback that ensures that the query is cancelled and that onAnswer is never
|
||||
* called. If the query succeeds before it is cancelled, needRetry will return true so the
|
||||
* test can retry.
|
||||
*/
|
||||
class VerifyCancelCallback implements DnsResolver.Callback<byte[]> {
|
||||
private final CountDownLatch mLatch = new CountDownLatch(1);
|
||||
private final String mMsg;
|
||||
private final int mTimeout;
|
||||
private final CancellationSignal mCancelSignal;
|
||||
private int mRcode;
|
||||
private DnsAnswer mDnsAnswer;
|
||||
|
||||
RawAnswerCallbackImpl(@NonNull String msg, int timeout) {
|
||||
VerifyCancelCallback(@NonNull String msg, @Nullable CancellationSignal cancel) {
|
||||
this.mMsg = msg;
|
||||
this.mTimeout = timeout;
|
||||
this.mCancelSignal = cancel;
|
||||
this.mDnsAnswer = null;
|
||||
}
|
||||
|
||||
RawAnswerCallbackImpl(@NonNull String msg) {
|
||||
this(msg, TIMEOUT_MS);
|
||||
VerifyCancelCallback(@NonNull String msg) {
|
||||
this(msg, null);
|
||||
}
|
||||
|
||||
public boolean waitForAnswer(int timeout) throws InterruptedException {
|
||||
return mLatch.await(timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public boolean waitForAnswer() throws InterruptedException {
|
||||
return mLatch.await(mTimeout, TimeUnit.MILLISECONDS);
|
||||
return waitForAnswer(TIMEOUT_MS);
|
||||
}
|
||||
|
||||
public boolean needRetry() throws InterruptedException {
|
||||
return mLatch.await(CANCEL_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnswer(@NonNull byte[] answer) {
|
||||
public void onAnswer(@NonNull byte[] answer, int rcode) {
|
||||
if (mCancelSignal != null && mCancelSignal.isCanceled()) {
|
||||
fail(mMsg + " should not have returned any answers");
|
||||
}
|
||||
|
||||
mRcode = rcode;
|
||||
try {
|
||||
assertValidAnswer(mMsg, new DnsAnswer(answer));
|
||||
Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer));
|
||||
mLatch.countDown();
|
||||
} catch (ParseException e) {
|
||||
mDnsAnswer = new DnsAnswer(answer);
|
||||
} catch (DnsParseException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
}
|
||||
Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer));
|
||||
mLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
public void onError(@NonNull DnsResolver.DnsException error) {
|
||||
fail(mMsg + error.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
private void assertValidAnswer() {
|
||||
assertTrue(mMsg + "No valid answer", mDnsAnswer != null);
|
||||
assertTrue(mMsg + " Unexpected error: reported rcode" + mRcode +
|
||||
" blob's rcode " + mDnsAnswer.getRcode(), mRcode == mDnsAnswer.getRcode());
|
||||
}
|
||||
|
||||
public void assertHasAnswer() {
|
||||
assertValidAnswer();
|
||||
// Check rcode field.(0, No error condition).
|
||||
assertTrue(mMsg + " Response error, rcode: " + mRcode, mRcode == 0);
|
||||
// Check answer counts.
|
||||
assertGreaterThan(mMsg + " No answer found", mDnsAnswer.getANCount(), 0);
|
||||
// Check question counts.
|
||||
assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0);
|
||||
}
|
||||
|
||||
public void assertNXDomain() {
|
||||
assertValidAnswer();
|
||||
// Check rcode field.(3, NXDomain).
|
||||
assertTrue(mMsg + " Unexpected rcode: " + mRcode, mRcode == NXDOMAIN);
|
||||
// Check answer counts. Expect 0 answer.
|
||||
assertTrue(mMsg + " Not an empty answer", mDnsAnswer.getANCount() == 0);
|
||||
// Check question counts.
|
||||
assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0);
|
||||
}
|
||||
|
||||
public void assertEmptyAnswer() {
|
||||
assertValidAnswer();
|
||||
// Check rcode field.(0, No error condition).
|
||||
assertTrue(mMsg + " Response error, rcode: " + mRcode, mRcode == 0);
|
||||
// Check answer counts. Expect 0 answer.
|
||||
assertTrue(mMsg + " Not an empty answer", mDnsAnswer.getANCount() == 0);
|
||||
// Check question counts.
|
||||
assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryWithRawAnswerCallback() {
|
||||
public void testRawQuery() {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Query with RawAnswerCallback " + dname;
|
||||
final String msg = "RawQuery " + dname;
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg);
|
||||
mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
|
||||
mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
|
||||
callback.waitForAnswer());
|
||||
callback.assertHasAnswer();
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryBlobWithRawAnswerCallback() {
|
||||
public void testRawQueryBlob() {
|
||||
final byte[] blob = new byte[]{
|
||||
/* Header */
|
||||
0x55, 0x66, /* Transaction ID */
|
||||
@@ -246,137 +255,58 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
0x00, 0x01, /* Type */
|
||||
0x00, 0x01 /* Class */
|
||||
};
|
||||
final String msg = "Query with RawAnswerCallback " + byteArrayToHexString(blob);
|
||||
final String msg = "RawQuery blob " + byteArrayToHexString(blob);
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg);
|
||||
mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback);
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
|
||||
mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
|
||||
callback.waitForAnswer());
|
||||
callback.assertHasAnswer();
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryRoot() {
|
||||
public void testRawQueryRoot() {
|
||||
final String dname = "";
|
||||
final String msg = "Query with RawAnswerCallback empty dname(ROOT) ";
|
||||
final String msg = "RawQuery empty dname(ROOT) ";
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final DnsResolver.RawAnswerCallback callback = new DnsResolver.RawAnswerCallback() {
|
||||
@Override
|
||||
public void onAnswer(@NonNull byte[] answer) {
|
||||
try {
|
||||
// Except no answer record because of querying with empty dname(ROOT)
|
||||
assertValidEmptyAnswer(msg, new DnsAnswer(answer));
|
||||
latch.countDown();
|
||||
} catch (ParseException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
};
|
||||
mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
|
||||
mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + "but no answer after " + TIMEOUT_MS + "ms.",
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
|
||||
callback.waitForAnswer());
|
||||
// Except no answer record because of querying with empty dname(ROOT)
|
||||
callback.assertEmptyAnswer();
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + "Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryNXDomain() {
|
||||
public void testRawQueryNXDomain() {
|
||||
final String dname = "test1-nx.metric.gstatic.com";
|
||||
final String msg = "Query with InetAddressAnswerCallback " + dname;
|
||||
final String msg = "RawQuery " + dname;
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final DnsResolver.InetAddressAnswerCallback callback =
|
||||
new DnsResolver.InetAddressAnswerCallback() {
|
||||
@Override
|
||||
public void onAnswer(@NonNull List<InetAddress> answerList) {
|
||||
if (answerList.size() == 0) {
|
||||
latch.countDown();
|
||||
return;
|
||||
}
|
||||
fail(msg + " but get valid answers");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
fail(msg + e.getMessage());
|
||||
}
|
||||
};
|
||||
mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
|
||||
mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
callback.waitForAnswer());
|
||||
callback.assertNXDomain();
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A query callback that ensures that the query is cancelled and that onAnswer is never
|
||||
* called. If the query succeeds before it is cancelled, needRetry will return true so the
|
||||
* test can retry.
|
||||
*/
|
||||
class VerifyCancelCallback extends DnsResolver.RawAnswerCallback {
|
||||
private static final int CANCEL_TIMEOUT = 3_000;
|
||||
|
||||
private final CountDownLatch mLatch = new CountDownLatch(1);
|
||||
private final String mMsg;
|
||||
private final CancellationSignal mCancelSignal;
|
||||
|
||||
VerifyCancelCallback(@NonNull String msg, @NonNull CancellationSignal cancelSignal) {
|
||||
this.mMsg = msg;
|
||||
this.mCancelSignal = cancelSignal;
|
||||
}
|
||||
|
||||
public boolean needRetry() throws InterruptedException {
|
||||
return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnswer(@NonNull byte[] answer) {
|
||||
if (mCancelSignal.isCanceled()) {
|
||||
fail(mMsg + " should not have returned any answers");
|
||||
}
|
||||
mLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryCancel() throws ErrnoException {
|
||||
public void testRawQueryCancel() throws ErrnoException {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Test cancel query " + dname;
|
||||
final String msg = "Test cancel RawQuery " + dname;
|
||||
// Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
|
||||
// that the query is cancelled before it succeeds. If it is not cancelled before it
|
||||
// succeeds, retry the test until it is.
|
||||
@@ -390,7 +320,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final CancellationSignal cancelSignal = new CancellationSignal();
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal);
|
||||
mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
|
||||
mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
|
||||
mExecutor, cancelSignal, callback);
|
||||
mExecutor.execute(() -> {
|
||||
cancelSignal.cancel();
|
||||
@@ -399,7 +329,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
try {
|
||||
retry = callback.needRetry();
|
||||
assertTrue(msg + " query was not cancelled",
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + "Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
@@ -407,7 +337,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryBlobCancel() throws ErrnoException {
|
||||
public void testRawQueryBlobCancel() throws ErrnoException {
|
||||
final byte[] blob = new byte[]{
|
||||
/* Header */
|
||||
0x55, 0x66, /* Transaction ID */
|
||||
@@ -422,7 +352,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
0x00, 0x01, /* Type */
|
||||
0x00, 0x01 /* Class */
|
||||
};
|
||||
final String msg = "Test cancel raw Query " + byteArrayToHexString(blob);
|
||||
final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(blob);
|
||||
// Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
|
||||
// that the query is cancelled before it succeeds. If it is not cancelled before it
|
||||
// succeeds, retry the test until it is.
|
||||
@@ -436,7 +366,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final CancellationSignal cancelSignal = new CancellationSignal();
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal);
|
||||
mDns.query(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback);
|
||||
mDns.rawQuery(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback);
|
||||
mExecutor.execute(() -> {
|
||||
cancelSignal.cancel();
|
||||
latch.countDown();
|
||||
@@ -444,7 +374,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
try {
|
||||
retry = callback.needRetry();
|
||||
assertTrue(msg + " cancel is not done",
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
@@ -454,16 +384,16 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
|
||||
public void testCancelBeforeQuery() throws ErrnoException {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Test cancelled query " + dname;
|
||||
final String msg = "Test cancelled RawQuery " + dname;
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg, 3_000);
|
||||
final VerifyCancelCallback callback = new VerifyCancelCallback(msg);
|
||||
final CancellationSignal cancelSignal = new CancellationSignal();
|
||||
cancelSignal.cancel();
|
||||
mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
|
||||
mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY,
|
||||
mExecutor, cancelSignal, callback);
|
||||
try {
|
||||
assertTrue(msg + " should not return any answers",
|
||||
!callback.waitForAnswer());
|
||||
!callback.waitForAnswer(CANCEL_TIMEOUT_MS));
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
@@ -476,9 +406,7 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
* before it is cancelled, needRetry will return true so the
|
||||
* test can retry.
|
||||
*/
|
||||
class VerifyCancelInetAddressCallback extends DnsResolver.InetAddressAnswerCallback {
|
||||
private static final int CANCEL_TIMEOUT = 3_000;
|
||||
|
||||
class VerifyCancelInetAddressCallback implements DnsResolver.Callback<List<InetAddress>> {
|
||||
private final CountDownLatch mLatch = new CountDownLatch(1);
|
||||
private final String mMsg;
|
||||
private final List<InetAddress> mAnswers;
|
||||
@@ -495,31 +423,43 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
public boolean needRetry() throws InterruptedException {
|
||||
return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS);
|
||||
return mLatch.await(CANCEL_TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public boolean isAnswerEmpty() {
|
||||
return mAnswers.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasIpv6Answer() {
|
||||
for (InetAddress answer : mAnswers) {
|
||||
if (answer instanceof Inet6Address) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasIpv4Answer() {
|
||||
for (InetAddress answer : mAnswers) {
|
||||
if (answer instanceof Inet4Address) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnswer(@NonNull List<InetAddress> answerList) {
|
||||
public void onAnswer(@NonNull List<InetAddress> answerList, int rcode) {
|
||||
if (mCancelSignal != null && mCancelSignal.isCanceled()) {
|
||||
fail(mMsg + " should not have returned any answers");
|
||||
}
|
||||
for (InetAddress addr : answerList) {
|
||||
Log.d(TAG, "Reported addr: " + addr.toString());
|
||||
}
|
||||
mAnswers.clear();
|
||||
mAnswers.addAll(answerList);
|
||||
mLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
fail(mMsg + e.getMessage());
|
||||
public void onError(@NonNull DnsResolver.DnsException error) {
|
||||
fail(mMsg + error.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,8 +484,8 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
public void testQueryCancelForInetAddress() throws ErrnoException {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Test cancel query for InetAddress " + dname;
|
||||
// Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect
|
||||
// that the query is cancelled before it succeeds. If it is not cancelled before it
|
||||
// Start a DNS query and the cancel it immediately. Use VerifyCancelInetAddressCallback to
|
||||
// expect that the query is cancelled before it succeeds. If it is not cancelled before it
|
||||
// succeeds, retry the test until it is.
|
||||
for (Network network : getTestableNetworks()) {
|
||||
boolean retry = false;
|
||||
@@ -566,11 +506,49 @@ public class DnsResolverTest extends AndroidTestCase {
|
||||
try {
|
||||
retry = callback.needRetry();
|
||||
assertTrue(msg + " query was not cancelled",
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + "Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
} while (retry);
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryForInetAddressIpv4() {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Test query for IPv4 InetAddress " + dname;
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final VerifyCancelInetAddressCallback callback =
|
||||
new VerifyCancelInetAddressCallback(msg, null);
|
||||
mDns.query(network, dname, TYPE_A, FLAG_NO_CACHE_LOOKUP,
|
||||
mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
|
||||
callback.waitForAnswer());
|
||||
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
|
||||
assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer());
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryForInetAddressIpv6() {
|
||||
final String dname = "www.google.com";
|
||||
final String msg = "Test query for IPv6 InetAddress " + dname;
|
||||
for (Network network : getTestableNetworks()) {
|
||||
final VerifyCancelInetAddressCallback callback =
|
||||
new VerifyCancelInetAddressCallback(msg, null);
|
||||
mDns.query(network, dname, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
|
||||
mExecutor, null, callback);
|
||||
try {
|
||||
assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.",
|
||||
callback.waitForAnswer());
|
||||
assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty());
|
||||
assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer());
|
||||
} catch (InterruptedException e) {
|
||||
fail(msg + " Waiting for DNS lookup was interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user