blob: 98463721b501c21bfbd679ad50f52b08c062bfdd [file] [log] [blame]
Jeff Sharkey3f391352011-06-05 17:42:53 -07001/*
2 * Copyright (C) 2011 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;
18
19import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
20import static android.net.ConnectivityManager.TYPE_WIFI;
21import static android.net.NetworkStats.UID_ALL;
22import static android.net.TrafficStats.TEMPLATE_WIFI;
23import static android.text.format.DateUtils.DAY_IN_MILLIS;
24import static android.text.format.DateUtils.HOUR_IN_MILLIS;
25import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
26import static org.easymock.EasyMock.anyLong;
27import static org.easymock.EasyMock.createMock;
28import static org.easymock.EasyMock.eq;
29import static org.easymock.EasyMock.expect;
30import static org.easymock.EasyMock.expectLastCall;
31import static org.easymock.EasyMock.isA;
32
33import android.app.AlarmManager;
34import android.app.IAlarmManager;
35import android.app.PendingIntent;
36import android.content.Intent;
37import android.net.IConnectivityManager;
38import android.net.LinkProperties;
39import android.net.NetworkInfo;
40import android.net.NetworkInfo.DetailedState;
41import android.net.NetworkState;
42import android.net.NetworkStats;
43import android.net.NetworkStatsHistory;
44import android.os.INetworkManagementService;
45import android.test.AndroidTestCase;
46import android.test.suitebuilder.annotation.LargeTest;
47import android.util.TrustedTime;
48
49import com.android.server.net.NetworkStatsService;
50
51import org.easymock.EasyMock;
52
53import java.io.File;
54
55/**
56 * Tests for {@link NetworkStatsService}.
57 */
58@LargeTest
59public class NetworkStatsServiceTest extends AndroidTestCase {
60 private static final String TAG = "NetworkStatsServiceTest";
61
62 private static final String TEST_IFACE = "test0";
63 private static final long TEST_START = 1194220800000L;
64
65 private BroadcastInterceptingContext mServiceContext;
66 private File mStatsDir;
67
68 private INetworkManagementService mNetManager;
69 private IAlarmManager mAlarmManager;
70 private TrustedTime mTime;
71 private IConnectivityManager mConnManager;
72
73 private NetworkStatsService mService;
74
75 @Override
76 public void setUp() throws Exception {
77 super.setUp();
78
79 mServiceContext = new BroadcastInterceptingContext(getContext());
80 mStatsDir = getContext().getFilesDir();
81
82 mNetManager = createMock(INetworkManagementService.class);
83 mAlarmManager = createMock(IAlarmManager.class);
84 mTime = createMock(TrustedTime.class);
85 mConnManager = createMock(IConnectivityManager.class);
86
87 mService = new NetworkStatsService(
88 mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir);
89 mService.bindConnectivityManager(mConnManager);
90
91 expectSystemReady();
92
93 replay();
94 mService.systemReady();
95 verifyAndReset();
96
97 }
98
99 @Override
100 public void tearDown() throws Exception {
101 for (File file : mStatsDir.listFiles()) {
102 file.delete();
103 }
104
105 mServiceContext = null;
106 mStatsDir = null;
107
108 mNetManager = null;
109 mAlarmManager = null;
110 mTime = null;
111
112 mService = null;
113
114 super.tearDown();
115 }
116
117 private static NetworkState buildWifi() {
118 final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
119 info.setDetailedState(DetailedState.CONNECTED, null, null);
120 final LinkProperties prop = new LinkProperties();
121 prop.setInterfaceName(TEST_IFACE);
122 return new NetworkState(info, prop, null);
123 }
124
125 public void testHistoryForWifi() throws Exception {
126 long elapsedRealtime = 0;
127 NetworkState[] state = null;
128 NetworkStats stats = null;
129 NetworkStats detail = null;
130
131 // pretend that wifi network comes online; service should ask about full
132 // network state, and poll any existing interfaces before updating.
133 state = new NetworkState[] { buildWifi() };
134 stats = new NetworkStats.Builder(elapsedRealtime, 0).build();
135 detail = new NetworkStats.Builder(elapsedRealtime, 0).build();
136
137 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
138 expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
139 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
140 expectTime(TEST_START + elapsedRealtime);
141
142 replay();
143 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
144 verifyAndReset();
145
146 // verify service has empty history for wifi
147 assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
148
149 // modify some number on wifi, and trigger poll event
150 elapsedRealtime += HOUR_IN_MILLIS;
151 stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
152 TEST_IFACE, UID_ALL, 1024L, 2048L).build();
153
154 expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
155 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
156 expectTime(TEST_START + elapsedRealtime);
157
158 replay();
159 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
160 verifyAndReset();
161
162 // verify service recorded history
163 assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
164
165 // and bump forward again, with counters going higher. this is
166 // important, since polling should correctly subtract last snapshot.
167 elapsedRealtime += DAY_IN_MILLIS;
168 stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
169 TEST_IFACE, UID_ALL, 4096L, 8192L).build();
170
171 expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
172 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
173 expectTime(TEST_START + elapsedRealtime);
174
175 replay();
176 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
177 verifyAndReset();
178
179 // verify service recorded history
180 assertNetworkTotal(TEMPLATE_WIFI, 4096L, 8192L);
181 }
182
183 public void testHistoryForRebootPersist() throws Exception {
184 long elapsedRealtime = 0;
185 NetworkState[] state = null;
186 NetworkStats stats = null;
187 NetworkStats detail = null;
188
189 // assert that no stats file exists
190 final File statsFile = new File(mStatsDir, "netstats.bin");
191 assertFalse(statsFile.exists());
192
193 // pretend that wifi network comes online; service should ask about full
194 // network state, and poll any existing interfaces before updating.
195 state = new NetworkState[] { buildWifi() };
196 stats = new NetworkStats.Builder(elapsedRealtime, 0).build();
197 detail = new NetworkStats.Builder(elapsedRealtime, 0).build();
198
199 expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
200 expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
201 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
202 expectTime(TEST_START + elapsedRealtime);
203
204 replay();
205 mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
206 verifyAndReset();
207
208 // verify service has empty history for wifi
209 assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
210
211 // modify some number on wifi, and trigger poll event
212 elapsedRealtime += HOUR_IN_MILLIS;
213 stats = new NetworkStats.Builder(elapsedRealtime, 1).addEntry(
214 TEST_IFACE, UID_ALL, 1024L, 2048L).build();
215
216 expect(mNetManager.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
217 expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
218 expectTime(TEST_START + elapsedRealtime);
219
220 replay();
221 mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
222 verifyAndReset();
223
224 // verify service recorded history
225 assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
226
227 // graceful shutdown system, which should trigger persist of stats, and
228 // clear any values in memory.
229 mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
230
231 // talk with zombie service to assert stats have gone; and assert that
232 // we persisted them to file.
233 assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
234 assertTrue(statsFile.exists());
235
236 // boot through serviceReady() again
237 expectSystemReady();
238
239 replay();
240 mService.systemReady();
241 verifyAndReset();
242
243 // after systemReady(), we should have historical stats loaded again
244 assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
245
246 }
247
248 private void assertNetworkTotal(int template, long rx, long tx) {
249 final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
250 final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
251 assertEquals(rx, total[0]);
252 assertEquals(tx, total[1]);
253 }
254
255 private void expectSystemReady() throws Exception {
256 mAlarmManager.remove(isA(PendingIntent.class));
257 expectLastCall().anyTimes();
258
259 mAlarmManager.setInexactRepeating(
260 eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
261 expectLastCall().atLeastOnce();
262 }
263
264 public void expectTime(long currentTime) throws Exception {
265 expect(mTime.forceRefresh()).andReturn(false).anyTimes();
266 expect(mTime.hasCache()).andReturn(true).anyTimes();
267 expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes();
268 expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
269 expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
270 }
271
272 private void replay() {
273 EasyMock.replay(mNetManager, mAlarmManager, mTime, mConnManager);
274 }
275
276 private void verifyAndReset() {
277 EasyMock.verify(mNetManager, mAlarmManager, mTime, mConnManager);
278 EasyMock.reset(mNetManager, mAlarmManager, mTime, mConnManager);
279 }
280}