DnsResolver cts changes to match API council requests

Bug: 129261432
Test: atest DnsResolverTest

Merged-In: I42df921cc3bb01ea25a671d5a1af678a6d3f5872
(cherry picked from commit 89996844304a2919f8cd000f82a4d1af9de3df01)

Change-Id: Ibcb92ac23cf413322234bba9100293ab794cf50e
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
index 0ff6cd8..40d64cf 100644
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
@@ -39,13 +39,14 @@
 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 @@
             '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 @@
         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 @@
         }
     }
 
-    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 @@
             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 @@
                 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 @@
                 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 void testQueryBlobCancel() throws ErrnoException {
+    public void testRawQueryBlobCancel() throws ErrnoException {
         final byte[] blob = new byte[]{
             /* Header */
             0x55, 0x66, /* Transaction ID */
@@ -422,7 +352,7 @@
             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 @@
                 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 @@
                 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 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 @@
      * 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 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 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 @@
                 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");
+            }
+        }
+    }
 }