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.server.power.stats;
18 
19 import static android.os.BatteryStats.STATS_SINCE_CHARGED;
20 
21 import static com.android.server.power.stats.BatteryStatsImpl.LongSamplingCounterArray;
22 import static com.android.server.power.stats.BatteryStatsImpl.TimeBase;
23 
24 import static org.junit.Assert.assertArrayEquals;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.verifyNoMoreInteractions;
27 import static org.mockito.Mockito.when;
28 
29 import android.os.Parcel;
30 
31 import androidx.test.filters.SmallTest;
32 import androidx.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 /**
42  * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}.
43  *
44  * atest FrameworksServiceTests:com.android.server.power.stats.LongSamplingCounterArrayTest
45  */
46 @SmallTest
47 @RunWith(AndroidJUnit4.class)
48 public class LongSamplingCounterArrayTest {
49 
50     private static final long[] COUNTS = {1111, 2222, 3333, 4444};
51     private static final long[] ZEROES = {0, 0, 0, 0};
52 
53     @Mock private TimeBase mTimeBase;
54     private LongSamplingCounterArray mCounterArray;
55 
56     @Before
setUp()57     public void setUp() {
58         MockitoAnnotations.initMocks(this);
59         mCounterArray = new LongSamplingCounterArray(mTimeBase);
60         Mockito.reset(mTimeBase);
61     }
62 
63     @Test
testReadWriteParcel()64     public void testReadWriteParcel() {
65         final Parcel parcel = Parcel.obtain();
66         updateCounts(COUNTS);
67         LongSamplingCounterArray.writeToParcel(parcel, mCounterArray);
68         parcel.setDataPosition(0);
69 
70         // Now clear counterArray and verify values are read from parcel correctly.
71         updateCounts(null);
72         mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase);
73         assertArrayEquals(COUNTS, mCounterArray.mCounts);
74         parcel.recycle();
75     }
76 
77     @Test
testReadWriteSummaryParcel()78     public void testReadWriteSummaryParcel() {
79         final Parcel parcel = Parcel.obtain();
80         updateCounts(COUNTS);
81         LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray);
82         parcel.setDataPosition(0);
83 
84         // Now clear counterArray and verify values are read from parcel correctly.
85         updateCounts(null);
86         mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase);
87         assertArrayEquals(COUNTS, mCounterArray.mCounts);
88         parcel.recycle();
89     }
90 
91     @Test
testOnTimeStarted()92     public void testOnTimeStarted() {
93         updateCounts(COUNTS);
94         mCounterArray.onTimeStarted(0, 0, 0);
95         assertArrayEquals(COUNTS, mCounterArray.mCounts);
96     }
97 
98     @Test
testOnTimeStopped()99     public void testOnTimeStopped() {
100         updateCounts(COUNTS);
101         mCounterArray.onTimeStopped(0, 0, 0);
102         assertArrayEquals(COUNTS, mCounterArray.mCounts);
103     }
104 
105     @Test
testGetCountsLocked()106     public void testGetCountsLocked() {
107         updateCounts(COUNTS);
108 
109         when(mTimeBase.isRunning()).thenReturn(false);
110         assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED));
111 
112         when(mTimeBase.isRunning()).thenReturn(true);
113         assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED));
114     }
115 
subtract(long[] val, long[] toSubtract)116     private long[] subtract(long[] val, long[] toSubtract) {
117         final long[] result = val.clone();
118         if (toSubtract != null) {
119             for (int i = val.length - 1; i >= 0; --i) {
120                 result[i] -= toSubtract[i];
121             }
122         }
123         return result;
124     }
125 
126     @Test
testAddCountLocked()127     public void testAddCountLocked() {
128         updateCounts(null);
129         final long[] deltas = {123, 234, 345, 456};
130         when(mTimeBase.isRunning()).thenReturn(true);
131         mCounterArray.addCountLocked(deltas);
132         assertArrayEquals(deltas, mCounterArray.mCounts);
133 
134         updateCounts(null);
135         mCounterArray.addCountLocked(deltas, false);
136         assertArrayEquals(null, mCounterArray.mCounts);
137         mCounterArray.addCountLocked(deltas, true);
138         assertArrayEquals(deltas, mCounterArray.mCounts);
139 
140         updateCounts(COUNTS);
141         final long[] newCounts = new long[deltas.length];
142         for (int i = 0; i < deltas.length; ++i) {
143             newCounts[i] = COUNTS[i] + deltas[i];
144         }
145         mCounterArray.addCountLocked(deltas);
146         assertArrayEquals(newCounts, mCounterArray.mCounts);
147 
148         updateCounts(COUNTS);
149         mCounterArray.addCountLocked(deltas, false);
150         assertArrayEquals(COUNTS, mCounterArray.mCounts);
151         mCounterArray.addCountLocked(deltas, true);
152         assertArrayEquals(newCounts, mCounterArray.mCounts);
153     }
154 
155     @Test
testReset()156     public void testReset() {
157         updateCounts(COUNTS);
158         // Test with detachIfReset=false
159         mCounterArray.reset(false /* detachIfReset */);
160         assertArrayEquals(ZEROES, mCounterArray.mCounts);
161         verifyNoMoreInteractions(mTimeBase);
162 
163         updateCounts(COUNTS);
164         // Test with detachIfReset=true
165         mCounterArray.reset(true /* detachIfReset */);
166         assertArrayEquals(ZEROES, mCounterArray.mCounts);
167         verify(mTimeBase).remove(mCounterArray);
168         verifyNoMoreInteractions(mTimeBase);
169     }
170 
171     @Test
testDetach()172     public void testDetach() {
173         mCounterArray.detach();
174         verify(mTimeBase).remove(mCounterArray);
175         verifyNoMoreInteractions(mTimeBase);
176     }
177 
updateCounts(long[] counts)178     private void updateCounts(long[] counts) {
179         mCounterArray.mCounts = counts == null ? null : counts.clone();
180     }
181 }
182