Move network stats to FileRotator pattern. am: 6298b780ae

Original change: undetermined

Change-Id: I150cf3d53b73e8e1e22f83fe4334d9ffa6d09af0
This commit is contained in:
Jeff Sharkey
2021-05-31 05:23:57 +00:00
committed by Automerger Merge Worker
4 changed files with 217 additions and 33 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -39,6 +39,7 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
import static org.easymock.EasyMock.anyLong;
import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
@@ -63,10 +64,12 @@ import android.os.INetworkManagementService;
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.TrustedTime;
import com.android.server.net.NetworkStatsService;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
import org.easymock.Capture;
import org.easymock.EasyMock;
@@ -89,6 +92,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private static final String IMSI_1 = "310004";
private static final String IMSI_2 = "310260";
private static final long KB_IN_BYTES = 1024;
private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES;
private static final long GB_IN_BYTES = 1024 * MB_IN_BYTES;
private static NetworkTemplate sTemplateWifi = buildTemplateWifi();
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
@@ -282,13 +289,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
verifyAndReset();
// talk with zombie service to assert stats have gone; and assert that
// we persisted them to file.
expectDefaultSettings();
replay();
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
assertStatsFilesExist(true);
// boot through serviceReady() again
@@ -319,6 +319,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
// TODO: simulate reboot to test bucket resize
@Suppress
public void testStatsBucketResize() throws Exception {
NetworkStatsHistory history = null;
@@ -602,7 +604,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
verifyAndReset();
}
public void testSummaryForAllUid() throws Exception {
@@ -755,11 +756,15 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L));
final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
expectNetworkStatsPoll(tetherIfacePairs, new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L));
final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -808,6 +813,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private void expectNetworkState(NetworkState... state) throws Exception {
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
}
private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
@@ -815,23 +823,35 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
}
private void expectNetworkStatsUidDetail(
NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
throws Exception {
expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
// also include tethering details, since they are folded into UID
expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).atLeastOnce();
expect(mNetManager.getNetworkStatsTethering(aryEq(tetherIfacePairs)))
.andReturn(tetherStats).atLeastOnce();
}
private void expectDefaultSettings() throws Exception {
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
}
private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory)
private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
throws Exception {
expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes();
expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes();
expect(mSettings.getNetworkMaxHistory()).andReturn(maxHistory).anyTimes();
expect(mSettings.getUidBucketDuration()).andReturn(bucketDuration).anyTimes();
expect(mSettings.getUidMaxHistory()).andReturn(maxHistory).anyTimes();
expect(mSettings.getTagMaxHistory()).andReturn(maxHistory).anyTimes();
expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
expect(mSettings.getGlobalAlertBytes()).andReturn(MB_IN_BYTES).anyTimes();
expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
final Config config = new Config(bucketDuration, persistBytes, deleteAge, deleteAge);
expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
}
private void expectCurrentTime() throws Exception {
@@ -843,27 +863,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void expectNetworkStatsPoll() throws Exception {
expectNetworkStatsPoll(new String[0], new NetworkStats(getElapsedRealtime(), 0));
}
private void expectNetworkStatsPoll(String[] tetherIfacePairs, NetworkStats tetherStats)
throws Exception {
mNetManager.setGlobalAlert(anyLong());
expectLastCall().anyTimes();
expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).anyTimes();
expect(mNetManager.getNetworkStatsTethering(eq(tetherIfacePairs)))
.andReturn(tetherStats).anyTimes();
}
private void assertStatsFilesExist(boolean exist) {
final File networkFile = new File(mStatsDir, "netstats.bin");
final File uidFile = new File(mStatsDir, "netstats_uid.bin");
final File basePath = new File(mStatsDir, "netstats");
if (exist) {
assertTrue(networkFile.exists());
assertTrue(uidFile.exists());
assertTrue(basePath.list().length > 0);
} else {
assertFalse(networkFile.exists());
assertFalse(uidFile.exists());
assertTrue(basePath.list().length == 0);
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.net;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkIdentity;
import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.frameworks.servicestests.R;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import libcore.io.IoUtils;
import libcore.io.Streams;
/**
* Tests for {@link NetworkStatsCollection}.
*/
@MediumTest
public class NetworkStatsCollectionTest extends AndroidTestCase {
private static final String TEST_FILE = "test.bin";
private static final String TEST_IMSI = "310260000000000";
public void testReadLegacyNetwork() throws Exception {
final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
stageFile(R.raw.netstats_v1, testFile);
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
collection.readLegacyNetwork(testFile);
// verify that history read correctly
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
636014522L, 709291L, 88037144L, 518820L);
// now export into a unified format
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
collection.write(new DataOutputStream(bos));
// clear structure completely
collection.reset();
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
0L, 0L, 0L, 0L);
// and read back into structure, verifying that totals are same
collection.read(new ByteArrayInputStream(bos.toByteArray()));
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
636014522L, 709291L, 88037144L, 518820L);
}
public void testReadLegacyUid() throws Exception {
final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
stageFile(R.raw.netstats_uid_v4, testFile);
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
collection.readLegacyUid(testFile, false);
// verify that history read correctly
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
637073904L, 711398L, 88342093L, 521006L);
// now export into a unified format
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
collection.write(new DataOutputStream(bos));
// clear structure completely
collection.reset();
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
0L, 0L, 0L, 0L);
// and read back into structure, verifying that totals are same
collection.read(new ByteArrayInputStream(bos.toByteArray()));
assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
637073904L, 711398L, 88342093L, 521006L);
}
public void testReadLegacyUidTags() throws Exception {
final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
stageFile(R.raw.netstats_uid_v4, testFile);
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
collection.readLegacyUid(testFile, true);
// verify that history read correctly
assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
77017831L, 100995L, 35436758L, 92344L);
// now export into a unified format
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
collection.write(new DataOutputStream(bos));
// clear structure completely
collection.reset();
assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
0L, 0L, 0L, 0L);
// and read back into structure, verifying that totals are same
collection.read(new ByteArrayInputStream(bos.toByteArray()));
assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
77017831L, 100995L, 35436758L, 92344L);
}
/**
* Copy a {@link Resources#openRawResource(int)} into {@link File} for
* testing purposes.
*/
private void stageFile(int rawId, File file) throws Exception {
new File(file.getParent()).mkdirs();
InputStream in = null;
OutputStream out = null;
try {
in = getContext().getResources().openRawResource(rawId);
out = new FileOutputStream(file);
Streams.copy(in, out);
} finally {
IoUtils.closeQuietly(in);
IoUtils.closeQuietly(out);
}
}
public static NetworkIdentitySet buildWifiIdent() {
final NetworkIdentitySet set = new NetworkIdentitySet();
set.add(new NetworkIdentity(ConnectivityManager.TYPE_WIFI, 0, null, false));
return set;
}
private static void assertSummaryTotal(NetworkStatsCollection collection,
NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
final NetworkStats.Entry entry = collection.getSummary(
template, Long.MIN_VALUE, Long.MAX_VALUE).getTotal(null);
assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
}
private static void assertSummaryTotalIncludingTags(NetworkStatsCollection collection,
NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
final NetworkStats.Entry entry = collection.getSummary(
template, Long.MIN_VALUE, Long.MAX_VALUE).getTotalIncludingTags(null);
assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
}
private static void assertEntry(
NetworkStats.Entry entry, long rxBytes, long rxPackets, long txBytes, long txPackets) {
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
assertEquals("unexpected txPackets", txPackets, entry.txPackets);
}
}