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.internal.os;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.content.Context;
24 import android.os.Parcel;
25 import android.util.Log;
26 
27 import androidx.test.InstrumentationRegistry;
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.mockito.MockitoAnnotations;
40 
41 /**
42  * Test BatteryStatsHistory.
43  */
44 @RunWith(AndroidJUnit4.class)
45 public class BatteryStatsHistoryTest {
46     private static final String TAG = "BatteryStatsHistoryTest";
47     private static final int MAX_HISTORY_FILES = 32;
48     private final BatteryStatsImpl mBatteryStatsImpl = new MockBatteryStatsImpl();
49     private final Parcel mHistoryBuffer = Parcel.obtain();
50     private File mSystemDir;
51     private File mHistoryDir;
52 
53     @Before
setUp()54     public void setUp() {
55         MockitoAnnotations.initMocks(this);
56         Context context = InstrumentationRegistry.getContext();
57         mSystemDir = context.getDataDir();
58         mHistoryDir = new File(mSystemDir, BatteryStatsHistory.HISTORY_DIR);
59         String[] files = mHistoryDir.list();
60         if (files != null) {
61             for (int i = 0; i < files.length; i++) {
62                 new File(mHistoryDir, files[i]).delete();
63             }
64         }
65         mHistoryDir.delete();
66     }
67 
68     @Test
testConstruct()69     public void testConstruct() {
70         BatteryStatsHistory history =
71                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
72         createActiveFile(history);
73         verifyFileNumbers(history, Arrays.asList(0));
74         verifyActiveFile(history, "0.bin");
75     }
76 
77     @Test
testStartNextFile()78     public void testStartNextFile() {
79         BatteryStatsHistory history =
80                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
81 
82         List<Integer> fileList = new ArrayList<>();
83         fileList.add(0);
84         createActiveFile(history);
85 
86         // create file 1 to 31.
87         for (int i = 1; i < MAX_HISTORY_FILES; i++) {
88             fileList.add(i);
89             history.startNextFile();
90             createActiveFile(history);
91             verifyFileNumbers(history, fileList);
92             verifyActiveFile(history, i + ".bin");
93         }
94 
95         // create file 32
96         history.startNextFile();
97         createActiveFile(history);
98         fileList.add(32);
99         fileList.remove(0);
100         // verify file 0 is deleted.
101         verifyFileDeleted("0.bin");
102         verifyFileNumbers(history, fileList);
103         verifyActiveFile(history, "32.bin");
104 
105         // create file 33
106         history.startNextFile();
107         createActiveFile(history);
108         // verify file 1 is deleted
109         fileList.add(33);
110         fileList.remove(0);
111         verifyFileDeleted("1.bin");
112         verifyFileNumbers(history, fileList);
113         verifyActiveFile(history, "33.bin");
114 
115         assertEquals(0, history.getHistoryUsedSize());
116 
117         // create a new BatteryStatsHistory object, it will pick up existing history files.
118         BatteryStatsHistory history2 =
119                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
120         // verify construct can pick up all files from file system.
121         verifyFileNumbers(history2, fileList);
122         verifyActiveFile(history2, "33.bin");
123 
124         history2.resetAllFiles();
125         createActiveFile(history2);
126         // verify all existing files are deleted.
127         for (int i = 2; i < 33; ++i) {
128             verifyFileDeleted(i + ".bin");
129         }
130 
131         // verify file 0 is created
132         verifyFileNumbers(history2, Arrays.asList(0));
133         verifyActiveFile(history2, "0.bin");
134 
135         // create file 1.
136         history2.startNextFile();
137         createActiveFile(history2);
138         verifyFileNumbers(history2, Arrays.asList(0, 1));
139         verifyActiveFile(history2, "1.bin");
140     }
141 
verifyActiveFile(BatteryStatsHistory history, String file)142     private void verifyActiveFile(BatteryStatsHistory history, String file) {
143         final File expectedFile = new File(mHistoryDir, file);
144         assertEquals(expectedFile.getPath(), history.getActiveFile().getBaseFile().getPath());
145         assertTrue(expectedFile.exists());
146     }
147 
verifyFileNumbers(BatteryStatsHistory history, List<Integer> fileList)148     private void verifyFileNumbers(BatteryStatsHistory history, List<Integer> fileList) {
149         assertEquals(fileList.size(), history.getFilesNumbers().size());
150         for (int i = 0; i < fileList.size(); i++) {
151             assertEquals(fileList.get(i), history.getFilesNumbers().get(i));
152             final File expectedFile =
153                     new File(mHistoryDir, fileList.get(i) + ".bin");
154             assertTrue(expectedFile.exists());
155         }
156     }
157 
verifyFileDeleted(String file)158     private void verifyFileDeleted(String file) {
159         assertFalse(new File(mHistoryDir, file).exists());
160     }
161 
createActiveFile(BatteryStatsHistory history)162     private void createActiveFile(BatteryStatsHistory history) {
163         final File file = history.getActiveFile().getBaseFile();
164         try {
165             file.createNewFile();
166         } catch (IOException e) {
167             Log.e(TAG, "Error creating history file " + file.getPath(), e);
168         }
169     }
170 }