CarStorageMonitoringTest.java revision b19bc326413285806ecca7fb7b54ec7a9074f286
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 17package com.android.car; 18 19import android.annotation.NonNull; 20import android.annotation.Nullable; 21import android.car.Car; 22import android.car.storagemonitoring.CarStorageMonitoringManager; 23import android.car.storagemonitoring.WearEstimate; 24import android.car.storagemonitoring.WearEstimateChange; 25import android.test.suitebuilder.annotation.MediumTest; 26import android.util.JsonWriter; 27import android.util.Log; 28import android.util.Pair; 29import com.android.car.storagemonitoring.WearEstimateRecord; 30import com.android.car.storagemonitoring.WearHistory; 31import com.android.car.storagemonitoring.WearInformation; 32import com.android.car.storagemonitoring.WearInformationProvider; 33import com.android.car.systeminterface.StorageMonitoringInterface; 34import com.android.car.systeminterface.SystemInterface; 35import com.android.car.systeminterface.SystemStateInterface; 36import com.android.car.systeminterface.TimeInterface; 37import java.io.File; 38import java.io.FileWriter; 39import java.io.IOException; 40import java.time.Duration; 41import java.time.Instant; 42import java.util.ArrayList; 43import java.util.Comparator; 44import java.util.HashMap; 45import java.util.List; 46import java.util.Map; 47 48/** Test the public entry points for the CarStorageMonitoringManager */ 49@MediumTest 50public class CarStorageMonitoringTest extends MockedCarTestBase { 51 private static final String TAG = CarStorageMonitoringTest.class.getSimpleName(); 52 53 private static final WearInformation DEFAULT_WEAR_INFORMATION = 54 new WearInformation(30, 0, WearInformation.PRE_EOL_INFO_NORMAL); 55 56 private static final class WearData { 57 static final WearData DEFAULT = new WearData(0, DEFAULT_WEAR_INFORMATION, null); 58 59 final long uptime; 60 @NonNull 61 final WearInformation wearInformation; 62 @Nullable 63 final WearHistory wearHistory; 64 65 WearData(long uptime, @Nullable WearInformation wearInformation, @Nullable WearHistory wearHistory) { 66 if (wearInformation == null) wearInformation = DEFAULT_WEAR_INFORMATION; 67 this.uptime = uptime; 68 this.wearInformation = wearInformation; 69 this.wearHistory = wearHistory; 70 } 71 } 72 73 private static final Map<String, WearData> PER_TEST_WEAR_DATA = 74 new HashMap<String, WearData>() {{ 75 put("testReadWearHistory", 76 new WearData(6500, DEFAULT_WEAR_INFORMATION, 77 WearHistory.fromRecords( 78 WearEstimateRecord.Builder.newBuilder() 79 .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE) 80 .toWearEstimate(new WearEstimate(10, 0)) 81 .atUptime(1000) 82 .atTimestamp(Instant.ofEpochMilli(5000)).build(), 83 WearEstimateRecord.Builder.newBuilder() 84 .fromWearEstimate(new WearEstimate(10, 0)) 85 .toWearEstimate(new WearEstimate(20, 0)) 86 .atUptime(4000) 87 .atTimestamp(Instant.ofEpochMilli(12000)).build(), 88 WearEstimateRecord.Builder.newBuilder() 89 .fromWearEstimate(new WearEstimate(20, 0)) 90 .toWearEstimate(new WearEstimate(30, 0)) 91 .atUptime(6500) 92 .atTimestamp(Instant.ofEpochMilli(17000)).build()))); 93 94 put("testNotAcceptableWearEvent", 95 new WearData(2520006499L, 96 new WearInformation(40, 0, WearInformation.PRE_EOL_INFO_NORMAL), 97 WearHistory.fromRecords( 98 WearEstimateRecord.Builder.newBuilder() 99 .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE) 100 .toWearEstimate(new WearEstimate(10, 0)) 101 .atUptime(1000) 102 .atTimestamp(Instant.ofEpochMilli(5000)).build(), 103 WearEstimateRecord.Builder.newBuilder() 104 .fromWearEstimate(new WearEstimate(10, 0)) 105 .toWearEstimate(new WearEstimate(20, 0)) 106 .atUptime(4000) 107 .atTimestamp(Instant.ofEpochMilli(12000)).build(), 108 WearEstimateRecord.Builder.newBuilder() 109 .fromWearEstimate(new WearEstimate(20, 0)) 110 .toWearEstimate(new WearEstimate(30, 0)) 111 .atUptime(6500) 112 .atTimestamp(Instant.ofEpochMilli(17000)).build()))); 113 114 put("testAcceptableWearEvent", 115 new WearData(2520006501L, 116 new WearInformation(40, 0, WearInformation.PRE_EOL_INFO_NORMAL), 117 WearHistory.fromRecords( 118 WearEstimateRecord.Builder.newBuilder() 119 .fromWearEstimate(WearEstimate.UNKNOWN_ESTIMATE) 120 .toWearEstimate(new WearEstimate(10, 0)) 121 .atUptime(1000) 122 .atTimestamp(Instant.ofEpochMilli(5000)).build(), 123 WearEstimateRecord.Builder.newBuilder() 124 .fromWearEstimate(new WearEstimate(10, 0)) 125 .toWearEstimate(new WearEstimate(20, 0)) 126 .atUptime(4000) 127 .atTimestamp(Instant.ofEpochMilli(12000)).build(), 128 WearEstimateRecord.Builder.newBuilder() 129 .fromWearEstimate(new WearEstimate(20, 0)) 130 .toWearEstimate(new WearEstimate(30, 0)) 131 .atUptime(6500) 132 .atTimestamp(Instant.ofEpochMilli(17000)).build()))); 133 }}; 134 135 private final MockSystemStateInterface mMockSystemStateInterface = 136 new MockSystemStateInterface(); 137 private final MockStorageMonitoringInterface mMockStorageMonitoringInterface = 138 new MockStorageMonitoringInterface(); 139 140 private CarStorageMonitoringManager mCarStorageMonitoringManager; 141 142 @Override 143 protected synchronized SystemInterface.Builder getSystemInterfaceBuilder() { 144 SystemInterface.Builder builder = super.getSystemInterfaceBuilder(); 145 return builder.withSystemStateInterface(mMockSystemStateInterface) 146 .withStorageMonitoringInterface(mMockStorageMonitoringInterface) 147 .withTimeInterface(new MockTimeInterface()); 148 } 149 150 @Override 151 protected synchronized void configureFakeSystemInterface() { 152 try { 153 final String testName = getName(); 154 final WearData wearData = PER_TEST_WEAR_DATA.getOrDefault(testName, WearData.DEFAULT); 155 final WearHistory wearHistory = wearData.wearHistory; 156 157 mMockStorageMonitoringInterface.setWearInformation(wearData.wearInformation); 158 159 if (wearHistory != null) { 160 File wearHistoryFile = new File(getFakeSystemInterface().getFilesDir(), 161 CarStorageMonitoringService.WEAR_INFO_FILENAME); 162 try (JsonWriter jsonWriter = new JsonWriter(new FileWriter(wearHistoryFile))) { 163 wearHistory.writeToJson(jsonWriter); 164 } 165 } 166 167 if (wearData.uptime > 0) { 168 File uptimeFile = new File(getFakeSystemInterface().getFilesDir(), 169 CarStorageMonitoringService.UPTIME_TRACKER_FILENAME); 170 try (JsonWriter jsonWriter = new JsonWriter(new FileWriter(uptimeFile))) { 171 jsonWriter.beginObject(); 172 jsonWriter.name("uptime").value(wearData.uptime); 173 jsonWriter.endObject(); 174 } 175 } 176 } catch (IOException e) { 177 Log.e(TAG, "failed to configure fake system interface", e); 178 fail("failed to configure fake system interface instance"); 179 } 180 181 } 182 183 @Override 184 protected void setUp() throws Exception { 185 super.setUp(); 186 187 mMockSystemStateInterface.executeBootCompletedActions(); 188 189 mCarStorageMonitoringManager = 190 (CarStorageMonitoringManager) getCar().getCarManager(Car.STORAGE_MONITORING_SERVICE); 191 } 192 193 public void testReadPreEolInformation() throws Exception { 194 assertEquals(DEFAULT_WEAR_INFORMATION.preEolInfo, 195 mCarStorageMonitoringManager.getPreEolIndicatorStatus()); 196 } 197 198 public void testReadWearEstimate() throws Exception { 199 final WearEstimate wearEstimate = mCarStorageMonitoringManager.getWearEstimate(); 200 201 assertNotNull(wearEstimate); 202 assertEquals(DEFAULT_WEAR_INFORMATION.lifetimeEstimateA, wearEstimate.typeA); 203 assertEquals(DEFAULT_WEAR_INFORMATION.lifetimeEstimateB, wearEstimate.typeB); 204 } 205 206 public void testReadWearHistory() throws Exception { 207 final List<WearEstimateChange> wearEstimateChanges = 208 mCarStorageMonitoringManager.getWearEstimateHistory(); 209 210 assertNotNull(wearEstimateChanges); 211 assertFalse(wearEstimateChanges.isEmpty()); 212 213 final WearHistory expectedWearHistory = PER_TEST_WEAR_DATA.get(getName()).wearHistory; 214 215 assertEquals(expectedWearHistory.size(), wearEstimateChanges.size()); 216 for (int i = 0; i < wearEstimateChanges.size(); ++i) { 217 final WearEstimateRecord expected = expectedWearHistory.get(i); 218 final WearEstimateChange actual = wearEstimateChanges.get(i); 219 220 assertTrue(expected.isSameAs(actual)); 221 } 222 } 223 224 private void checkLastWearEvent(boolean isAcceptable) throws Exception { 225 final List<WearEstimateChange> wearEstimateChanges = 226 mCarStorageMonitoringManager.getWearEstimateHistory(); 227 228 assertNotNull(wearEstimateChanges); 229 assertFalse(wearEstimateChanges.isEmpty()); 230 231 final WearData wearData = PER_TEST_WEAR_DATA.get(getName()); 232 233 final WearInformation expectedCurrentWear = wearData.wearInformation; 234 final WearEstimate expectedPreviousWear = wearData.wearHistory.getLast().getNewWearEstimate(); 235 236 final WearEstimateChange actualCurrentWear = 237 wearEstimateChanges.get(wearEstimateChanges.size() - 1); 238 239 assertEquals(isAcceptable, actualCurrentWear.isAcceptableDegradation); 240 assertEquals(expectedCurrentWear.toWearEstimate(), actualCurrentWear.newEstimate); 241 assertEquals(expectedPreviousWear, actualCurrentWear.oldEstimate); 242 } 243 244 public void testNotAcceptableWearEvent() throws Exception { 245 checkLastWearEvent(false); 246 } 247 248 public void testAcceptableWearEvent() throws Exception { 249 checkLastWearEvent(true); 250 } 251 252 static final class MockStorageMonitoringInterface implements StorageMonitoringInterface, 253 WearInformationProvider { 254 private WearInformation mWearInformation = null; 255 256 void setWearInformation(WearInformation wearInformation) { 257 mWearInformation = wearInformation; 258 } 259 260 @Override 261 public WearInformation load() { 262 return mWearInformation; 263 } 264 265 @Override 266 public WearInformationProvider[] getFlashWearInformationProviders() { 267 return new WearInformationProvider[] {this}; 268 } 269 } 270 271 static final class MockTimeInterface implements TimeInterface { 272 273 @Override 274 public long getUptime(boolean includeDeepSleepTime) { 275 return 0; 276 } 277 278 @Override 279 public void scheduleAction(Runnable r, long delayMs) {} 280 281 @Override 282 public void cancelAllActions() {} 283 } 284 285 static final class MockSystemStateInterface implements SystemStateInterface { 286 private final List<Pair<Runnable, Duration>> mActionsList = new ArrayList<>(); 287 288 @Override 289 public void shutdown() {} 290 291 @Override 292 public void enterDeepSleep(int wakeupTimeSec) {} 293 294 @Override 295 public void scheduleActionForBootCompleted(Runnable action, Duration delay) { 296 mActionsList.add(Pair.create(action, delay)); 297 mActionsList.sort(Comparator.comparing(d -> d.second)); 298 } 299 300 void executeBootCompletedActions() { 301 for (Pair<Runnable, Duration> action : mActionsList) { 302 action.first.run(); 303 } 304 } 305 } 306} 307