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