[icmp] Add test to verify no duplicated icmp echo reply on mesh-local
addresses.

Bug: 333493455

Test: atest ThreadNetworkIntegrationTests:android.net.thread.ThreadIntegrationTest#edPingsMeshLocalAddresses_oneReplyPerRequest

Change-Id: I07aefa1311f15d3f801de64c0342694296f09469
diff --git a/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java b/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java
index e211e22..998e70d 100644
--- a/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java
+++ b/thread/tests/integration/src/android/net/thread/ThreadIntegrationTest.java
@@ -31,6 +31,7 @@
 
 import static com.google.common.io.BaseEncoding.base16;
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.content.Context;
 import android.net.InetAddresses;
@@ -237,6 +238,21 @@
         assertTunInterfaceMemberOfGroup(GROUP_ADDR_ALL_ROUTERS);
     }
 
+    @Test
+    public void edPingsMeshLocalAddresses_oneReplyPerRequest() throws Exception {
+        mController.joinAndWait(DEFAULT_DATASET);
+        startFtdChild(mFtd, DEFAULT_DATASET);
+        List<Inet6Address> meshLocalAddresses = mOtCtl.getMeshLocalAddresses();
+
+        for (Inet6Address address : meshLocalAddresses) {
+            assertWithMessage(
+                            "There may be duplicated replies of ping request to "
+                                    + address.getHostAddress())
+                    .that(mFtd.ping(address, 2))
+                    .isEqualTo(2);
+        }
+    }
+
     // TODO (b/323300829): add more tests for integration with linux platform and
     // ConnectivityService
 
diff --git a/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java b/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java
index 5e70f6c..9370ee3 100644
--- a/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java
+++ b/thread/tests/integration/src/android/net/thread/utils/FullThreadDevice.java
@@ -422,7 +422,21 @@
                 PING_TIMEOUT_SECONDS);
     }
 
-    private void ping(
+    /** Returns the number of ping reply packets received. */
+    public int ping(Inet6Address address, int count) {
+        List<String> output =
+                ping(
+                        address,
+                        null,
+                        PING_SIZE,
+                        count,
+                        PING_INTERVAL,
+                        HOP_LIMIT,
+                        PING_TIMEOUT_SECONDS);
+        return getReceivedPacketsCount(output);
+    }
+
+    private List<String> ping(
             Inet6Address address,
             Inet6Address source,
             int size,
@@ -445,7 +459,21 @@
                         + hopLimit
                         + " "
                         + timeout;
-        executeCommand(cmd);
+        return executeCommand(cmd);
+    }
+
+    private int getReceivedPacketsCount(List<String> stringList) {
+        Pattern pattern = Pattern.compile("([\\d]+) packets received");
+
+        for (String message : stringList) {
+            Matcher matcher = pattern.matcher(message);
+            if (matcher.find()) {
+                String packetCountStr = matcher.group(1);
+                return Integer.parseInt(packetCountStr);
+            }
+        }
+        // No match found
+        return -1;
     }
 
     @FormatMethod