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 17package com.android.server.net; 18 19import static android.net.ConnectivityManager.TYPE_MOBILE; 20import static android.net.NetworkStats.SET_DEFAULT; 21import static android.net.NetworkStats.TAG_NONE; 22import static android.net.NetworkStats.UID_ALL; 23import static android.net.NetworkTemplate.buildTemplateMobileAll; 24import static android.text.format.DateUtils.HOUR_IN_MILLIS; 25import static android.text.format.DateUtils.MINUTE_IN_MILLIS; 26 27import android.content.res.Resources; 28import android.net.NetworkIdentity; 29import android.net.NetworkStats; 30import android.net.NetworkTemplate; 31import android.os.Process; 32import android.os.UserHandle; 33import android.telephony.TelephonyManager; 34import android.test.AndroidTestCase; 35import android.test.MoreAsserts; 36import android.test.suitebuilder.annotation.MediumTest; 37 38import com.android.frameworks.servicestests.R; 39 40import java.io.ByteArrayInputStream; 41import java.io.ByteArrayOutputStream; 42import java.io.DataOutputStream; 43import java.io.File; 44import java.io.FileOutputStream; 45import java.io.InputStream; 46import java.io.OutputStream; 47 48import libcore.io.IoUtils; 49import libcore.io.Streams; 50 51/** 52 * Tests for {@link NetworkStatsCollection}. 53 */ 54@MediumTest 55public 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