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