Fixup TrafficStats test wrt mobile vs total vs loopback

- Use getMobileBlabla() instead of getTotalBlabla()
- Have getTotalBlabla() reflect the fact that it includes loopback.
- Adjust checks to take headers, acks, and packet counts into account.

Change-Id: I9e1dfbbbdb9a6f932a14a2e3baee7a34469b9008
diff --git a/tests/tests/net/src/android/net/cts/TrafficStatsTest.java b/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
index a5bbd98..89933bf 100644
--- a/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
+++ b/tests/tests/net/src/android/net/cts/TrafficStatsTest.java
@@ -42,19 +42,29 @@
                    TrafficStats.getMobileRxBytes() >= 0);
     }
 
+    long tcpPacketToIpBytes(long packetCount, long bytes) {
+        // ip header + tcp header + data.
+        // Tcp header is mostly 32. Syn has different tcp options -> 40. Don't care.
+        return packetCount * (20 + 32 + bytes);
+    }
+
     public void testTrafficStatsForLocalhost() throws IOException {
-        long mobileTxPacketsBefore = TrafficStats.getTotalTxPackets();
-        long mobileRxPacketsBefore = TrafficStats.getTotalRxPackets();
-        long mobileTxBytesBefore = TrafficStats.getTotalTxBytes();
-        long mobileRxBytesBefore = TrafficStats.getTotalRxBytes();
+        long mobileTxPacketsBefore = TrafficStats.getMobileTxPackets();
+        long mobileRxPacketsBefore = TrafficStats.getMobileRxPackets();
+        long mobileTxBytesBefore = TrafficStats.getMobileTxBytes();
+        long mobileRxBytesBefore = TrafficStats.getMobileRxBytes();
         long totalTxPacketsBefore = TrafficStats.getTotalTxPackets();
         long totalRxPacketsBefore = TrafficStats.getTotalRxPackets();
         long totalTxBytesBefore = TrafficStats.getTotalTxBytes();
         long totalRxBytesBefore = TrafficStats.getTotalRxBytes();
         long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid());
         long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid());
+        long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid());
+        long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid());
 
         // Transfer 1MB of data across an explicitly localhost socket.
+        final int byteCount = 1024;
+        final int packetCount = 1024;
 
         final ServerSocket server = new ServerSocket(0);
         new Thread("TrafficStatsTest.testTrafficStatsForLocalhost") {
@@ -62,9 +72,15 @@
             public void run() {
                 try {
                     Socket socket = new Socket("localhost", server.getLocalPort());
+                    // Make sure that each write()+flush() turns into a packet:
+                    // disable Nagle.
+                    socket.setTcpNoDelay(true);
                     OutputStream out = socket.getOutputStream();
-                    byte[] buf = new byte[1024];
-                    for (int i = 0; i < 1024; i++) out.write(buf);
+                    byte[] buf = new byte[byteCount];
+                    for (int i = 0; i < packetCount; i++) {
+                        out.write(buf);
+                        out.flush();
+                    }
                     out.close();
                     socket.close();
                 } catch (IOException e) {
@@ -75,9 +91,9 @@
         try {
             Socket socket = server.accept();
             InputStream in = socket.getInputStream();
-            byte[] buf = new byte[1024];
+            byte[] buf = new byte[byteCount];
             int read = 0;
-            while (read < 1048576) {
+            while (read < byteCount * packetCount) {
                 int n = in.read(buf);
                 assertTrue("Unexpected EOF", n > 0);
                 read += n;
@@ -92,50 +108,76 @@
         } catch (InterruptedException e) {
         }
 
-        long mobileTxPacketsAfter = TrafficStats.getTotalTxPackets();
-        long mobileRxPacketsAfter = TrafficStats.getTotalRxPackets();
-        long mobileTxBytesAfter = TrafficStats.getTotalTxBytes();
-        long mobileRxBytesAfter = TrafficStats.getTotalRxBytes();
+        long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets();
+        long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets();
+        long mobileTxBytesAfter = TrafficStats.getMobileTxBytes();
+        long mobileRxBytesAfter = TrafficStats.getMobileRxBytes();
         long totalTxPacketsAfter = TrafficStats.getTotalTxPackets();
         long totalRxPacketsAfter = TrafficStats.getTotalRxPackets();
         long totalTxBytesAfter = TrafficStats.getTotalTxBytes();
         long totalRxBytesAfter = TrafficStats.getTotalRxBytes();
         long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid());
         long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid());
-
-        // Localhost traffic should *not* count against mobile or total stats.
-        // There might be some other traffic, but nowhere near 1MB.
-
-        assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter,
-               mobileTxPacketsAfter >= mobileTxPacketsBefore &&
-               mobileTxPacketsAfter <= mobileTxPacketsBefore + 500);
-        assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter,
-               mobileRxPacketsAfter >= mobileRxPacketsBefore &&
-               mobileRxPacketsAfter <= mobileRxPacketsBefore + 500);
-        assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter,
-               mobileTxBytesAfter >= mobileTxBytesBefore &&
-               mobileTxBytesAfter <= mobileTxBytesBefore + 200000);
-        assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter,
-               mobileRxBytesAfter >= mobileRxBytesBefore &&
-               mobileRxBytesAfter <= mobileRxBytesBefore + 200000);
-
-        assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter,
-               totalTxPacketsAfter >= totalTxPacketsBefore &&
-               totalTxPacketsAfter <= totalTxPacketsBefore + 500);
-        assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter,
-               totalRxPacketsAfter >= totalRxPacketsBefore &&
-               totalRxPacketsAfter <= totalRxPacketsBefore + 500);
-        assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter,
-               totalTxBytesAfter >= totalTxBytesBefore &&
-               totalTxBytesAfter <= totalTxBytesBefore + 200000);
-        assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter,
-               totalRxBytesAfter >= totalRxBytesBefore &&
-               totalRxBytesAfter <= totalRxBytesBefore + 200000);
+        long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid());
+        long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid());
+        long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore;
+        long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore;
+        long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore;
+        long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore;
 
         // Localhost traffic *does* count against per-UID stats.
-        assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter,
-               uidTxBytesAfter >= uidTxBytesBefore + 1048576);
-        assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter,
-               uidRxBytesAfter >= uidRxBytesBefore + 1048576);
+        /*
+         * Calculations:
+         *  - bytes
+         *   bytes is approx: packets * data + packets * acks;
+         *   but sometimes there are less acks than packets, so we set a lower
+         *   limit of 1 ack.
+         *  - setup/teardown
+         *   + 7 approx.: syn, syn-ack, ack, fin-ack, ack, fin-ack, ack;
+         *   but sometimes the last find-acks just vanish, so we set a lower limit of +5.
+         */
+        assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets,
+            uidTxDeltaPackets >= packetCount + 5 &&
+            uidTxDeltaPackets <= packetCount + packetCount + 7);
+        assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets,
+            uidRxDeltaPackets >= packetCount + 5 &&
+            uidRxDeltaPackets <= packetCount + packetCount + 7);
+        assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes,
+            uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) &&
+            uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0));
+        assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes,
+            uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) &&
+            uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0));
+
+        // Localhost traffic *does* count against total stats.
+        // Fudge by 132 packets of 1500 bytes not related to the test.
+        assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter,
+            totalTxPacketsAfter >= totalTxPacketsBefore + uidTxDeltaPackets &&
+            totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132);
+        assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter,
+            totalRxPacketsAfter >= totalRxPacketsBefore + uidRxDeltaPackets &&
+            totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132);
+        assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter,
+            totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes &&
+            totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500);
+        assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter,
+            totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes &&
+            totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500);
+
+        // Localhost traffic should *not* count against mobile stats,
+        // There might be some other traffic, but nowhere near 1MB.
+        assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter,
+            mobileTxPacketsAfter >= mobileTxPacketsBefore &&
+            mobileTxPacketsAfter <= mobileTxPacketsBefore + 500);
+        assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter,
+            mobileRxPacketsAfter >= mobileRxPacketsBefore &&
+            mobileRxPacketsAfter <= mobileRxPacketsBefore + 500);
+        assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter,
+            mobileTxBytesAfter >= mobileTxBytesBefore &&
+            mobileTxBytesAfter <= mobileTxBytesBefore + 200000);
+        assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter,
+            mobileRxBytesAfter >= mobileRxBytesBefore &&
+            mobileRxBytesAfter <= mobileRxBytesBefore + 200000);
+
     }
 }