• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.settingslib.net;
18 
19 import static android.app.usage.NetworkStats.Bucket.UID_ALL;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertThrows;
23 import static org.mockito.Mockito.doNothing;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.annotation.NonNull;
30 import android.app.usage.NetworkStats;
31 import android.app.usage.NetworkStatsManager;
32 import android.content.Context;
33 import android.net.ConnectivityManager;
34 import android.net.NetworkPolicy;
35 import android.net.NetworkPolicyManager;
36 import android.net.NetworkTemplate;
37 import android.text.format.DateUtils;
38 import android.util.Range;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.Mock;
44 import org.mockito.MockitoAnnotations;
45 import org.robolectric.RobolectricTestRunner;
46 import org.robolectric.util.ReflectionHelpers;
47 
48 import java.time.ZonedDateTime;
49 import java.util.ArrayList;
50 import java.util.Iterator;
51 import java.util.List;
52 import java.util.Queue;
53 import java.util.concurrent.LinkedBlockingQueue;
54 
55 @RunWith(RobolectricTestRunner.class)
56 public class NetworkCycleDataLoaderTest {
57 
58     @Mock
59     private NetworkStatsManager mNetworkStatsManager;
60     @Mock
61     private NetworkPolicyManager mNetworkPolicyManager;
62     @Mock
63     private Context mContext;
64     @Mock
65     private NetworkPolicy mPolicy;
66     @Mock
67     private Iterator<Range<ZonedDateTime>> mIterator;
68 
69     private NetworkCycleDataTestLoader mLoader;
70 
71     @Before
setUp()72     public void setUp() {
73         MockitoAnnotations.initMocks(this);
74         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
75             .thenReturn(mNetworkStatsManager);
76         when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
77             .thenReturn(mNetworkPolicyManager);
78         when(mPolicy.cycleIterator()).thenReturn(mIterator);
79         when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
80     }
81 
82     @Test
loadInBackground_noNetworkPolicy_shouldLoad4WeeksData()83     public void loadInBackground_noNetworkPolicy_shouldLoad4WeeksData() {
84         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
85         doNothing().when(mLoader).loadFourWeeksData();
86 
87         mLoader.loadInBackground();
88 
89         verify(mLoader).loadFourWeeksData();
90     }
91 
92     @Test
loadInBackground_hasNetworkPolicy_shouldLoadPolicyData()93     public void loadInBackground_hasNetworkPolicy_shouldLoadPolicyData() {
94         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
95         ReflectionHelpers.setField(mLoader, "mPolicy", mPolicy);
96 
97         mLoader.loadInBackground();
98 
99         verify(mLoader).loadPolicyData();
100     }
101 
102     @Test
loadInBackground_hasCyclePeriod_shouldLoadDataForSpecificCycles()103     public void loadInBackground_hasCyclePeriod_shouldLoadDataForSpecificCycles() {
104         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
105         doNothing().when(mLoader).loadDataForSpecificCycles();
106         final ArrayList<Long> cycles = new ArrayList<>();
107         cycles.add(67890L);
108         cycles.add(12345L);
109         ReflectionHelpers.setField(mLoader, "mCycles", cycles);
110 
111         mLoader.loadInBackground();
112 
113         verify(mLoader).loadDataForSpecificCycles();
114     }
115 
116     @Test
loadPolicyData_shouldRecordUsageFromPolicyCycle()117     public void loadPolicyData_shouldRecordUsageFromPolicyCycle() {
118         final int networkType = ConnectivityManager.TYPE_MOBILE;
119         final String subId = "TestSubscriber";
120         final ZonedDateTime now = ZonedDateTime.now();
121         final Range<ZonedDateTime> cycle = new Range<>(now, now);
122         final long nowInMs = now.toInstant().toEpochMilli();
123         // mock 1 cycle data.
124         // hasNext() will be called internally in next(), hence setting it to return true twice.
125         when(mIterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
126         when(mIterator.next()).thenReturn(cycle);
127         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
128         ReflectionHelpers.setField(mLoader, "mPolicy", mPolicy);
129 
130         mLoader.loadPolicyData();
131 
132         verify(mLoader).recordUsage(nowInMs, nowInMs);
133     }
134 
makeMockBucket(int uid, long rxBytes, long txBytes, long start, long end)135     private NetworkStats.Bucket makeMockBucket(int uid, long rxBytes, long txBytes,
136             long start, long end) {
137         NetworkStats.Bucket ret = mock(NetworkStats.Bucket.class);
138         when(ret.getUid()).thenReturn(uid);
139         when(ret.getRxBytes()).thenReturn(rxBytes);
140         when(ret.getTxBytes()).thenReturn(txBytes);
141         when(ret.getStartTimeStamp()).thenReturn(start);
142         when(ret.getEndTimeStamp()).thenReturn(end);
143         return ret;
144     }
145 
146     @Test
loadFourWeeksData_shouldRecordUsageForLast4Weeks()147     public void loadFourWeeksData_shouldRecordUsageForLast4Weeks() {
148         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
149         final long now = System.currentTimeMillis();
150         final long fourWeeksAgo = now - (DateUtils.WEEK_IN_MILLIS * 4);
151         final long twoDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 2);
152         mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, twoDaysAgo, now));
153 
154         mLoader.loadFourWeeksData();
155 
156         verify(mLoader).recordUsage(fourWeeksAgo, now);
157     }
158 
159     @Test
loadDataForSpecificCycles_shouldRecordUsageForSpecifiedTime()160     public void loadDataForSpecificCycles_shouldRecordUsageForSpecifiedTime() {
161         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
162         final long now = System.currentTimeMillis();
163         final long tenDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 10);
164         final long twentyDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 20);
165         final long thirtyDaysAgo = now - (DateUtils.DAY_IN_MILLIS * 30);
166         final ArrayList<Long> cycles = new ArrayList<>();
167         cycles.add(now);
168         cycles.add(tenDaysAgo);
169         cycles.add(twentyDaysAgo);
170         cycles.add(thirtyDaysAgo);
171         ReflectionHelpers.setField(mLoader, "mCycles", cycles);
172 
173         mLoader.loadDataForSpecificCycles();
174 
175         verify(mLoader).recordUsage(tenDaysAgo, now);
176         verify(mLoader).recordUsage(twentyDaysAgo, tenDaysAgo);
177         verify(mLoader).recordUsage(thirtyDaysAgo, twentyDaysAgo);
178     }
179 
180     @Test
getTimeRangeOf()181     public void getTimeRangeOf() {
182         mLoader = spy(new NetworkCycleDataTestLoader(mContext));
183         // If empty, new Range(MAX_VALUE, MIN_VALUE) will be constructed. Hence, the function
184         // should throw.
185         assertThrows(IllegalArgumentException.class,
186                 () -> mLoader.getTimeRangeOf(mock(NetworkStats.class)));
187 
188         mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
189         // Feed the function with unused NetworkStats. The actual data injection is
190         // done by addBucket.
191         assertEquals(new Range(0L, 10L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
192 
193         mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 0, 10));
194         mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 30, 40));
195         mLoader.addBucket(makeMockBucket(UID_ALL, 123, 456, 10, 25));
196         assertEquals(new Range(0L, 40L), mLoader.getTimeRangeOf(mock(NetworkStats.class)));
197     }
198 
199     public class NetworkCycleDataTestLoader extends NetworkCycleDataLoader<List<NetworkCycleData>> {
200         private final Queue<NetworkStats.Bucket> mMockedBuckets = new LinkedBlockingQueue<>();
201 
NetworkCycleDataTestLoader(Context context)202         private NetworkCycleDataTestLoader(Context context) {
203             super(NetworkCycleDataLoader.builder(mContext)
204                     .setNetworkTemplate(mock(NetworkTemplate.class)));
205             mContext = context;
206         }
207 
208         @Override
recordUsage(long start, long end)209         void recordUsage(long start, long end) {
210         }
211 
212         @Override
getCycleUsage()213         List<NetworkCycleData> getCycleUsage() {
214             return null;
215         }
216 
addBucket(NetworkStats.Bucket bucket)217         public void addBucket(NetworkStats.Bucket bucket) {
218             mMockedBuckets.add(bucket);
219         }
220 
221         @Override
hasNextBucket(@onNull NetworkStats unused)222         public boolean hasNextBucket(@NonNull NetworkStats unused) {
223             return !mMockedBuckets.isEmpty();
224         }
225 
226         @Override
getNextBucket(@onNull NetworkStats unused)227         public NetworkStats.Bucket getNextBucket(@NonNull NetworkStats unused) {
228             return mMockedBuckets.remove();
229         }
230     }
231 }
232