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.timezone; 18 19 import org.junit.After; 20 import org.junit.Before; 21 import org.junit.Test; 22 23 import android.content.Context; 24 import android.support.test.InstrumentationRegistry; 25 import android.support.test.filters.SmallTest; 26 27 import java.io.File; 28 import java.io.PrintWriter; 29 import java.io.StringWriter; 30 31 import static junit.framework.Assert.assertTrue; 32 import static org.junit.Assert.assertEquals; 33 import static org.junit.Assert.assertFalse; 34 import static org.junit.Assert.assertNotNull; 35 import static org.junit.Assert.assertNull; 36 37 @SmallTest 38 public class PackageStatusStorageTest { 39 private static final PackageVersions VALID_PACKAGE_VERSIONS = new PackageVersions(1, 2); 40 41 private PackageStatusStorage mPackageStatusStorage; 42 43 @Before 44 public void setUp() throws Exception { 45 Context context = InstrumentationRegistry.getContext(); 46 File dataDir = context.getFilesDir(); 47 48 // Using the instrumentation context means the database is created in a test app-specific 49 // directory. 50 mPackageStatusStorage = new PackageStatusStorage(dataDir); 51 } 52 53 @After 54 public void tearDown() throws Exception { 55 mPackageStatusStorage.deleteFileForTests(); 56 } 57 58 @Test 59 public void getPackageStatus_initialState() { 60 assertNull(mPackageStatusStorage.getPackageStatus()); 61 } 62 63 @Test 64 public void resetCheckState() { 65 // Assert initial state. 66 assertNull(mPackageStatusStorage.getPackageStatus()); 67 68 CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 69 70 // There should now be a state. 71 assertNotNull(mPackageStatusStorage.getPackageStatus()); 72 73 // Now clear the state. 74 mPackageStatusStorage.resetCheckState(); 75 76 // After reset, there should be no package state again. 77 assertNull(mPackageStatusStorage.getPackageStatus()); 78 79 CheckToken token2 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 80 81 // Token after a reset should still be distinct. 82 assertFalse(token1.equals(token2)); 83 84 // Now clear the state again. 85 mPackageStatusStorage.resetCheckState(); 86 87 // After reset, there should be no package state again. 88 assertNull(mPackageStatusStorage.getPackageStatus()); 89 90 CheckToken token3 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 91 92 // A CheckToken generated after a reset should still be distinct. 93 assertFalse(token2.equals(token3)); 94 } 95 96 @Test 97 public void generateCheckToken_missingFileBehavior() { 98 // Assert initial state. 99 assertNull(mPackageStatusStorage.getPackageStatus()); 100 101 CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 102 assertNotNull(token1); 103 104 // There should now be state. 105 assertNotNull(mPackageStatusStorage.getPackageStatus()); 106 107 // Corrupt the data by removing the file. 108 mPackageStatusStorage.deleteFileForTests(); 109 110 // Check that generateCheckToken recovers. 111 assertNotNull(mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS)); 112 } 113 114 @Test 115 public void getPackageStatus_missingFileBehavior() { 116 // Assert initial state. 117 assertNull(mPackageStatusStorage.getPackageStatus()); 118 119 CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 120 assertNotNull(token1); 121 122 // There should now be a state. 123 assertNotNull(mPackageStatusStorage.getPackageStatus()); 124 125 // Corrupt the data by removing the file. 126 mPackageStatusStorage.deleteFileForTests(); 127 128 assertNull(mPackageStatusStorage.getPackageStatus()); 129 } 130 131 @Test 132 public void markChecked_missingFileBehavior() { 133 // Assert initial state. 134 CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 135 assertNotNull(token1); 136 137 // There should now be a state. 138 assertNotNull(mPackageStatusStorage.getPackageStatus()); 139 140 // Corrupt the data by removing the file. 141 mPackageStatusStorage.deleteFileForTests(); 142 143 // The missing file should mean token1 is now considered invalid, so we should get a false. 144 assertFalse(mPackageStatusStorage.markChecked(token1, true /* succeeded */)); 145 146 // The storage should have recovered and we should be able to carry on like before. 147 CheckToken token2 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 148 assertTrue(mPackageStatusStorage.markChecked(token2, true /* succeeded */)); 149 } 150 151 @Test 152 public void checkToken_tokenIsUnique() { 153 PackageVersions packageVersions = VALID_PACKAGE_VERSIONS; 154 PackageStatus expectedPackageStatus = 155 new PackageStatus(PackageStatus.CHECK_STARTED, packageVersions); 156 157 CheckToken token1 = mPackageStatusStorage.generateCheckToken(packageVersions); 158 assertEquals(packageVersions, token1.mPackageVersions); 159 160 PackageStatus actualPackageStatus1 = mPackageStatusStorage.getPackageStatus(); 161 assertEquals(expectedPackageStatus, actualPackageStatus1); 162 163 CheckToken token2 = mPackageStatusStorage.generateCheckToken(packageVersions); 164 assertEquals(packageVersions, token1.mPackageVersions); 165 assertFalse(token1.mOptimisticLockId == token2.mOptimisticLockId); 166 assertFalse(token1.equals(token2)); 167 } 168 169 @Test 170 public void markChecked_checkSucceeded() { 171 PackageVersions packageVersions = VALID_PACKAGE_VERSIONS; 172 173 CheckToken token = mPackageStatusStorage.generateCheckToken(packageVersions); 174 boolean writeOk = mPackageStatusStorage.markChecked(token, true /* succeeded */); 175 assertTrue(writeOk); 176 177 PackageStatus expectedPackageStatus = 178 new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions); 179 assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus()); 180 } 181 182 @Test 183 public void markChecked_checkFailed() { 184 PackageVersions packageVersions = VALID_PACKAGE_VERSIONS; 185 186 CheckToken token = mPackageStatusStorage.generateCheckToken(packageVersions); 187 boolean writeOk = mPackageStatusStorage.markChecked(token, false /* succeeded */); 188 assertTrue(writeOk); 189 190 PackageStatus expectedPackageStatus = 191 new PackageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, packageVersions); 192 assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus()); 193 } 194 195 @Test 196 public void markChecked_optimisticLocking_multipleToken() { 197 PackageVersions packageVersions = VALID_PACKAGE_VERSIONS; 198 CheckToken token1 = mPackageStatusStorage.generateCheckToken(packageVersions); 199 CheckToken token2 = mPackageStatusStorage.generateCheckToken(packageVersions); 200 201 PackageStatus packageStatusBeforeChecked = mPackageStatusStorage.getPackageStatus(); 202 203 boolean writeOk1 = mPackageStatusStorage.markChecked(token1, true /* succeeded */); 204 // Generation of token2 should mean that token1 is no longer valid. 205 assertFalse(writeOk1); 206 assertEquals(packageStatusBeforeChecked, mPackageStatusStorage.getPackageStatus()); 207 208 boolean writeOk2 = mPackageStatusStorage.markChecked(token2, true /* succeeded */); 209 // token2 should still be valid, and the attempt with token1 should have had no effect. 210 assertTrue(writeOk2); 211 PackageStatus expectedPackageStatus = 212 new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions); 213 assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus()); 214 } 215 216 @Test 217 public void markChecked_optimisticLocking_repeatedTokenUse() { 218 PackageVersions packageVersions = VALID_PACKAGE_VERSIONS; 219 CheckToken token = mPackageStatusStorage.generateCheckToken(packageVersions); 220 221 boolean writeOk1 = mPackageStatusStorage.markChecked(token, true /* succeeded */); 222 assertTrue(writeOk1); 223 224 PackageStatus expectedPackageStatus = 225 new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions); 226 assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus()); 227 228 // token cannot be reused. 229 boolean writeOk2 = mPackageStatusStorage.markChecked(token, true /* succeeded */); 230 assertFalse(writeOk2); 231 assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus()); 232 } 233 234 @Test 235 public void dump() { 236 StringWriter stringWriter = new StringWriter(); 237 PrintWriter printWriter = new PrintWriter(stringWriter); 238 239 // Dump initial state. 240 mPackageStatusStorage.dump(printWriter); 241 242 // No crash and it does something. 243 assertFalse(stringWriter.toString().isEmpty()); 244 245 // Reset 246 stringWriter.getBuffer().setLength(0); 247 assertTrue(stringWriter.toString().isEmpty()); 248 249 // Store something. 250 mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS); 251 252 mPackageStatusStorage.dump(printWriter); 253 254 assertFalse(stringWriter.toString().isEmpty()); 255 } 256 } 257