Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.net;
     18 
     19 import static android.net.ConnectivityManager.TYPE_MOBILE;
     20 import static android.net.NetworkStats.SET_DEFAULT;
     21 import static android.net.NetworkStats.TAG_NONE;
     22 import static android.net.NetworkStats.UID_ALL;
     23 import static android.net.NetworkTemplate.buildTemplateMobileAll;
     24 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
     25 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
     26 
     27 import android.content.res.Resources;
     28 import android.net.NetworkIdentity;
     29 import android.net.NetworkStats;
     30 import android.net.NetworkTemplate;
     31 import android.os.Process;
     32 import android.os.UserHandle;
     33 import android.telephony.TelephonyManager;
     34 import android.test.AndroidTestCase;
     35 import android.test.MoreAsserts;
     36 import android.test.suitebuilder.annotation.MediumTest;
     37 
     38 import com.android.frameworks.servicestests.R;
     39 
     40 import java.io.ByteArrayInputStream;
     41 import java.io.ByteArrayOutputStream;
     42 import java.io.DataOutputStream;
     43 import java.io.File;
     44 import java.io.FileOutputStream;
     45 import java.io.InputStream;
     46 import java.io.OutputStream;
     47 
     48 import libcore.io.IoUtils;
     49 import libcore.io.Streams;
     50 
     51 /**
     52  * Tests for {@link NetworkStatsCollection}.
     53  */
     54 @MediumTest
     55 public class NetworkStatsCollectionTest extends AndroidTestCase {
     56 
     57     private static final String TEST_FILE = "test.bin";
     58     private static final String TEST_IMSI = "310260000000000";
     59 
     60     @Override
     61     public void setUp() throws Exception {
     62         super.setUp();
     63 
     64         // ignore any device overlay while testing
     65         NetworkTemplate.forceAllNetworkTypes();
     66     }
     67 
     68     public void testReadLegacyNetwork() throws Exception {
     69         final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
     70         stageFile(R.raw.netstats_v1, testFile);
     71 
     72         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
     73         collection.readLegacyNetwork(testFile);
     74 
     75         // verify that history read correctly
     76         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
     77                 636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE);
     78 
     79         // now export into a unified format
     80         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
     81         collection.write(new DataOutputStream(bos));
     82 
     83         // clear structure completely
     84         collection.reset();
     85         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
     86                 0L, 0L, 0L, 0L, NetworkStatsAccess.Level.DEVICE);
     87 
     88         // and read back into structure, verifying that totals are same
     89         collection.read(new ByteArrayInputStream(bos.toByteArray()));
     90         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
     91                 636016770L, 709306L, 88038768L, 518836L, NetworkStatsAccess.Level.DEVICE);
     92     }
     93 
     94     public void testReadLegacyUid() throws Exception {
     95         final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
     96         stageFile(R.raw.netstats_uid_v4, testFile);
     97 
     98         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
     99         collection.readLegacyUid(testFile, false);
    100 
    101         // verify that history read correctly
    102         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
    103                 637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE);
    104 
    105         // now export into a unified format
    106         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
    107         collection.write(new DataOutputStream(bos));
    108 
    109         // clear structure completely
    110         collection.reset();
    111         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
    112                 0L, 0L, 0L, 0L, NetworkStatsAccess.Level.DEVICE);
    113 
    114         // and read back into structure, verifying that totals are same
    115         collection.read(new ByteArrayInputStream(bos.toByteArray()));
    116         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
    117                 637076152L, 711413L, 88343717L, 521022L, NetworkStatsAccess.Level.DEVICE);
    118     }
    119 
    120     public void testReadLegacyUidTags() throws Exception {
    121         final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
    122         stageFile(R.raw.netstats_uid_v4, testFile);
    123 
    124         final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
    125         collection.readLegacyUid(testFile, true);
    126 
    127         // verify that history read correctly
    128         assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
    129                 77017831L, 100995L, 35436758L, 92344L);
    130 
    131         // now export into a unified format
    132         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
    133         collection.write(new DataOutputStream(bos));
    134 
    135         // clear structure completely
    136         collection.reset();
    137         assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
    138                 0L, 0L, 0L, 0L);
    139 
    140         // and read back into structure, verifying that totals are same
    141         collection.read(new ByteArrayInputStream(bos.toByteArray()));
    142         assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
    143                 77017831L, 100995L, 35436758L, 92344L);
    144     }
    145 
    146     public void testStartEndAtomicBuckets() throws Exception {
    147         final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
    148 
    149         // record empty data straddling between buckets
    150         final NetworkStats.Entry entry = new NetworkStats.Entry();
    151         entry.rxBytes = 32;
    152         collection.recordData(null, UID_ALL, SET_DEFAULT, TAG_NONE, 30 * MINUTE_IN_MILLIS,
    153                 90 * MINUTE_IN_MILLIS, entry);
    154 
    155         // assert that we report boundary in atomic buckets
    156         assertEquals(0, collection.getStartMillis());
    157         assertEquals(2 * HOUR_IN_MILLIS, collection.getEndMillis());
    158     }
    159 
    160     public void testAccessLevels() throws Exception {
    161         final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
    162         final NetworkStats.Entry entry = new NetworkStats.Entry();
    163         final NetworkIdentitySet identSet = new NetworkIdentitySet();
    164         identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
    165                 TEST_IMSI, null, false, true));
    166 
    167         int myUid = Process.myUid();
    168         int otherUidInSameUser = Process.myUid() + 1;
    169         int uidInDifferentUser = Process.myUid() + UserHandle.PER_USER_RANGE;
    170 
    171         // Record one entry for the current UID.
    172         entry.rxBytes = 32;
    173         collection.recordData(identSet, myUid, SET_DEFAULT, TAG_NONE, 0, 60 * MINUTE_IN_MILLIS,
    174                 entry);
    175 
    176         // Record one entry for another UID in this user.
    177         entry.rxBytes = 64;
    178         collection.recordData(identSet, otherUidInSameUser, SET_DEFAULT, TAG_NONE, 0,
    179                 60 * MINUTE_IN_MILLIS, entry);
    180 
    181         // Record one entry for the system UID.
    182         entry.rxBytes = 128;
    183         collection.recordData(identSet, Process.SYSTEM_UID, SET_DEFAULT, TAG_NONE, 0,
    184                 60 * MINUTE_IN_MILLIS, entry);
    185 
    186         // Record one entry for a UID in a different user.
    187         entry.rxBytes = 256;
    188         collection.recordData(identSet, uidInDifferentUser, SET_DEFAULT, TAG_NONE, 0,
    189                 60 * MINUTE_IN_MILLIS, entry);
    190 
    191         // Verify the set of relevant UIDs for each access level.
    192         MoreAsserts.assertEquals(new int[] { myUid },
    193                 collection.getRelevantUids(NetworkStatsAccess.Level.DEFAULT));
    194         MoreAsserts.assertEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser },
    195                 collection.getRelevantUids(NetworkStatsAccess.Level.USER));
    196         MoreAsserts.assertEquals(
    197                 new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser, uidInDifferentUser },
    198                 collection.getRelevantUids(NetworkStatsAccess.Level.DEVICE));
    199 
    200         // Verify security check in getHistory.
    201         assertNotNull(collection.getHistory(buildTemplateMobileAll(TEST_IMSI), myUid, SET_DEFAULT,
    202                 TAG_NONE, 0, NetworkStatsAccess.Level.DEFAULT));
    203         try {
    204             collection.getHistory(buildTemplateMobileAll(TEST_IMSI), otherUidInSameUser,
    205                     SET_DEFAULT, TAG_NONE, 0, NetworkStatsAccess.Level.DEFAULT);
    206             fail("Should have thrown SecurityException for accessing different UID");
    207         } catch (SecurityException e) {
    208             // expected
    209         }
    210 
    211         // Verify appropriate aggregation in getSummary.
    212         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32, 0, 0, 0,
    213                 NetworkStatsAccess.Level.DEFAULT);
    214         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32 + 64 + 128, 0, 0, 0,
    215                 NetworkStatsAccess.Level.USER);
    216         assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI), 32 + 64 + 128 + 256, 0, 0,
    217                 0, NetworkStatsAccess.Level.DEVICE);
    218     }
    219 
    220     /**
    221      * Copy a {@link Resources#openRawResource(int)} into {@link File} for
    222      * testing purposes.
    223      */
    224     private void stageFile(int rawId, File file) throws Exception {
    225         new File(file.getParent()).mkdirs();
    226         InputStream in = null;
    227         OutputStream out = null;
    228         try {
    229             in = getContext().getResources().openRawResource(rawId);
    230             out = new FileOutputStream(file);
    231             Streams.copy(in, out);
    232         } finally {
    233             IoUtils.closeQuietly(in);
    234             IoUtils.closeQuietly(out);
    235         }
    236     }
    237 
    238     private static void assertSummaryTotal(NetworkStatsCollection collection,
    239             NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets,
    240             @NetworkStatsAccess.Level int accessLevel) {
    241         final NetworkStats.Entry entry = collection.getSummary(
    242                 template, Long.MIN_VALUE, Long.MAX_VALUE, accessLevel)
    243                 .getTotal(null);
    244         assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
    245     }
    246 
    247     private static void assertSummaryTotalIncludingTags(NetworkStatsCollection collection,
    248             NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
    249         final NetworkStats.Entry entry = collection.getSummary(
    250                 template, Long.MIN_VALUE, Long.MAX_VALUE, NetworkStatsAccess.Level.DEVICE)
    251                 .getTotalIncludingTags(null);
    252         assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
    253     }
    254 
    255     private static void assertEntry(
    256             NetworkStats.Entry entry, long rxBytes, long rxPackets, long txBytes, long txPackets) {
    257         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
    258         assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
    259         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
    260         assertEquals("unexpected txPackets", txPackets, entry.txPackets);
    261     }
    262 }
    263