1 /*
2  * Copyright (C) 2017 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.internal.os;
18 
19 import static android.os.BatteryStats.STATS_SINCE_CHARGED;
20 
21 import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray;
22 import static com.android.internal.os.BatteryStatsImpl.TimeBase;
23 
24 import static org.junit.Assert.assertTrue;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.verifyNoMoreInteractions;
27 import static org.mockito.Mockito.verifyZeroInteractions;
28 import static org.mockito.Mockito.when;
29 
30 import android.os.Parcel;
31 import android.support.test.filters.SmallTest;
32 import android.support.test.runner.AndroidJUnit4;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.mockito.Mock;
38 import org.mockito.Mockito;
39 import org.mockito.MockitoAnnotations;
40 
41 import java.util.Arrays;
42 
43 /**
44  * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}.
45  *
46  * To run the tests, use
47  *
48  * runtest -c com.android.internal.os.LongSamplingCounterArrayTest frameworks-core
49  *
50  * or the following steps:
51  *
52  * Build: m FrameworksCoreTests
53  * Install: adb install -r \
54  *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
55  * Run: adb shell am instrument -e class com.android.internal.os.LongSamplingCounterArrayTest -w \
56  *     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
57  */
58 @SmallTest
59 @RunWith(AndroidJUnit4.class)
60 public class LongSamplingCounterArrayTest {
61 
62     private static final long[] COUNTS = {1111, 2222, 3333, 4444};
63     private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888};
64     private static final long[] PLUGGED_COUNTS = {9999, 11111, 22222, 33333};
65     private static final long[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777};
66     private static final long[] ZEROES = {0, 0, 0, 0};
67 
68     @Mock private TimeBase mTimeBase;
69     private LongSamplingCounterArray mCounterArray;
70 
71     @Before
setUp()72     public void setUp() {
73         MockitoAnnotations.initMocks(this);
74         mCounterArray = new LongSamplingCounterArray(mTimeBase);
75         Mockito.reset(mTimeBase);
76     }
77 
78     @Test
testReadWriteParcel()79     public void testReadWriteParcel() {
80         final Parcel parcel = Parcel.obtain();
81         initializeCounterArrayWithDefaultValues();
82         LongSamplingCounterArray.writeToParcel(parcel, mCounterArray);
83         parcel.setDataPosition(0);
84 
85         // Now clear counterArray and verify values are read from parcel correctly.
86         updateCounts(null, null, null, null);
87         mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase);
88         assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
89         assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
90         assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
91         assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
92                 "Unexpected unpluggedCounts");
93         parcel.recycle();
94     }
95 
96     @Test
testReadWriteSummaryParcel()97     public void testReadWriteSummaryParcel() {
98         final Parcel parcel = Parcel.obtain();
99         initializeCounterArrayWithDefaultValues();
100         LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray);
101         parcel.setDataPosition(0);
102 
103         // Now clear counterArray and verify values are read from parcel correctly.
104         updateCounts(null, null, null, null);
105         mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase);
106         assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
107         assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
108         assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
109         assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
110         parcel.recycle();
111     }
112 
113     @Test
testOnTimeStarted()114     public void testOnTimeStarted() {
115         initializeCounterArrayWithDefaultValues();
116         mCounterArray.onTimeStarted(0, 0, 0);
117         assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mCounts, "Unexpected counts");
118         assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
119         assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
120         assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
121                 "Unexpected unpluggedCounts");
122     }
123 
124     @Test
testOnTimeStopped()125     public void testOnTimeStopped() {
126         initializeCounterArrayWithDefaultValues();
127         mCounterArray.onTimeStopped(0, 0, 0);
128         assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
129         assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
130         assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
131         assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
132                 "Unexpected unpluggedCounts");
133     }
134 
135     @Test
testGetCountsLocked()136     public void testGetCountsLocked() {
137         initializeCounterArrayWithDefaultValues();
138 
139         when(mTimeBase.isRunning()).thenReturn(false);
140         long[] actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
141         long[] expectedVal = PLUGGED_COUNTS;
142         assertArrayEquals(expectedVal, actualVal, "Unexpected values");
143 
144         when(mTimeBase.isRunning()).thenReturn(true);
145         actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
146         expectedVal = COUNTS;
147         assertArrayEquals(expectedVal, actualVal, "Unexpected values");
148     }
149 
150     @Test
testAddCountLocked()151     public void testAddCountLocked() {
152         final long[] deltas = {123, 234, 345, 456};
153         mCounterArray.addCountLocked(deltas);
154         assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts");
155         assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
156         assertArrayEquals(null, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
157         assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
158 
159         initializeCounterArrayWithDefaultValues();
160         final long[] newCounts = new long[deltas.length];
161         for (int i = 0; i < deltas.length; ++i) {
162             newCounts[i] = COUNTS[i] + deltas[i];
163         }
164         mCounterArray.addCountLocked(deltas);
165         assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts");
166         assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
167         assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
168         assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
169                 "Unexpected unpluggedCounts");
170     }
171 
172     @Test
testReset()173     public void testReset() {
174         initializeCounterArrayWithDefaultValues();
175         // Test with detachIfReset=false
176         mCounterArray.reset(false /* detachIfReset */);
177         assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
178         assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
179         assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
180         assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
181         verifyZeroInteractions(mTimeBase);
182 
183         initializeCounterArrayWithDefaultValues();
184         // Test with detachIfReset=true
185         mCounterArray.reset(true /* detachIfReset */);
186         assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
187         assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
188         assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
189         assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
190         verify(mTimeBase).remove(mCounterArray);
191         verifyNoMoreInteractions(mTimeBase);
192     }
193 
194     @Test
testDetach()195     public void testDetach() {
196         mCounterArray.detach();
197         verify(mTimeBase).remove(mCounterArray);
198         verifyNoMoreInteractions(mTimeBase);
199     }
200 
initializeCounterArrayWithDefaultValues()201     private void initializeCounterArrayWithDefaultValues() {
202         updateCounts(COUNTS, LOADED_COUNTS, PLUGGED_COUNTS, UNPLUGGED_COUNTS);
203     }
204 
assertArrayEquals(long[] expected, long[] actual, String msg)205     private void assertArrayEquals(long[] expected, long[] actual, String msg) {
206         assertTrue(msg + ", expected: " + Arrays.toString(expected)
207                 + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual));
208     }
209 
updateCounts(long[] counts, long[] loadedCounts, long[] pluggedCounts, long[] unpluggedCounts)210     private void updateCounts(long[] counts, long[] loadedCounts,
211             long[] pluggedCounts, long[] unpluggedCounts) {
212         mCounterArray.mCounts = counts;
213         mCounterArray.mLoadedCounts = loadedCounts;
214         mCounterArray.mPluggedCounts = pluggedCounts;
215         mCounterArray.mUnpluggedCounts = unpluggedCounts;
216     }
217 }
218