1 /* 2 * Copyright (C) 2022 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.adservices.data.measurement.migration; 18 19 import static com.android.adservices.common.DbTestUtil.getDbHelperForTest; 20 import static com.android.adservices.data.measurement.migration.MigrationTestHelper.createReferenceDbAtVersion; 21 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.verify; 25 26 import android.content.Context; 27 import android.database.sqlite.SQLiteDatabase; 28 29 import androidx.test.core.app.ApplicationProvider; 30 31 import com.android.adservices.common.DbTestUtil; 32 import com.android.adservices.data.measurement.MeasurementDbHelper; 33 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.mockito.Mock; 37 38 import java.io.File; 39 import java.util.stream.Stream; 40 41 /** 42 * Base class for {@link IMeasurementDbMigrator}s migrating to v7+ versions. Extending this class 43 * brings in schema validation for creating the DB at a version as well as migrating from previous 44 * version to the target version. Verification is done against a database built at the target 45 * version using the scripts defined in {@link 46 * com.android.adservices.data.measurement.MeasurementDbSchemaTrail}. To introduce test class for 47 * migration to a new version x, i.e. MeasurementDbMigratorVxTest, the following steps need to be 48 * followed - 49 * 50 * <ol> 51 * <li>Create new entries for create table statements and create index statements for the new 52 * version in {@link com.android.adservices.data.measurement.MeasurementDbSchemaTrail} 53 * <li>Extend {@link MeasurementDbMigratorTestBase} 54 * <li>Override {@link MeasurementDbMigratorTestBase#getTargetVersion()} and return the integer x. 55 * <li>Override {@link MeasurementDbMigratorTestBase#getTestSubject()} and return the object to 56 * test, i.e. an instance of MeasurementDbMigratorVx. 57 * <li>Add a test for data migration to MeasurementDbMigratorVxTest class. 58 * </ol> 59 */ 60 public abstract class MeasurementDbMigratorTestBase { 61 protected static final Context sContext = ApplicationProvider.getApplicationContext(); 62 protected static final String MEASUREMENT_DATABASE_NAME_FOR_MIGRATION = 63 "adservices_msmt_migration.db"; 64 protected static final String MEASUREMENT_DATABASE_REFERENCE_DB_NAME = 65 "adservices_msmt_migration_reference.db"; 66 67 @Mock private SQLiteDatabase mDb; 68 69 @Before setup()70 public void setup() { 71 Stream.of(MEASUREMENT_DATABASE_NAME_FOR_MIGRATION, MEASUREMENT_DATABASE_REFERENCE_DB_NAME) 72 .map(sContext::getDatabasePath) 73 .filter(File::exists) 74 .forEach(File::delete); 75 } 76 77 @Test performMigration_alreadyOnHigherVersion_skipMigration()78 public void performMigration_alreadyOnHigherVersion_skipMigration() { 79 // Execution 80 getTestSubject().performMigration(mDb, (getTargetVersion() + 1), (getTargetVersion() + 2)); 81 82 // Verify 83 verify(mDb, never()).execSQL(any()); 84 } 85 86 @Test performMigration_lowerRequestedVersion_skipMigration()87 public void performMigration_lowerRequestedVersion_skipMigration() { 88 // Execution 89 getTestSubject().performMigration(mDb, (getTargetVersion() - 2), (getTargetVersion() - 1)); 90 91 // Verify 92 verify(mDb, never()).execSQL(any()); 93 } 94 95 @Test performMigration_createAtTargetVersion_dbIsAsExpected()96 public void performMigration_createAtTargetVersion_dbIsAsExpected() { 97 // Setup 98 MeasurementDbHelper dbHelper = 99 new MeasurementDbHelper( 100 sContext, 101 MEASUREMENT_DATABASE_NAME_FOR_MIGRATION, 102 getTargetVersion(), 103 getDbHelperForTest()); 104 SQLiteDatabase goldenDb = 105 createReferenceDbAtVersion( 106 sContext, MEASUREMENT_DATABASE_REFERENCE_DB_NAME, getTargetVersion()); 107 108 // Execution - invokes onCreate implicitly 109 SQLiteDatabase actualDb = dbHelper.getWritableDatabase(); 110 111 // Assertion 112 DbTestUtil.assertDatabasesEqual(goldenDb, actualDb); 113 } 114 115 @Test performMigration_migrateFromPrevToTargetVersion_dbIsAsExpected()116 public void performMigration_migrateFromPrevToTargetVersion_dbIsAsExpected() { 117 // Setup 118 int prevVersion = getTargetVersion() - 1; 119 MeasurementDbHelper dbHelper = 120 new MeasurementDbHelper( 121 sContext, 122 MEASUREMENT_DATABASE_NAME_FOR_MIGRATION, 123 prevVersion, 124 getDbHelperForTest()); 125 SQLiteDatabase goldenDb = 126 createReferenceDbAtVersion( 127 sContext, MEASUREMENT_DATABASE_REFERENCE_DB_NAME, getTargetVersion()); 128 129 // Execution 130 SQLiteDatabase actualDb = dbHelper.getWritableDatabase(); 131 getTestSubject().performMigration(actualDb, prevVersion, getTargetVersion()); 132 133 // Assertion 134 DbTestUtil.assertDatabasesEqual(goldenDb, actualDb); 135 } 136 getTargetVersion()137 abstract int getTargetVersion(); 138 getTestSubject()139 abstract AbstractMeasurementDbMigrator getTestSubject(); 140 } 141