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