Home | History | Annotate | Download | only in model
      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 package com.android.launcher3.model;
     17 
     18 import static junit.framework.Assert.assertEquals;
     19 import static junit.framework.Assert.assertFalse;
     20 import static junit.framework.Assert.assertNotSame;
     21 import static junit.framework.Assert.assertTrue;
     22 
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.database.Cursor;
     26 import android.database.sqlite.SQLiteDatabase;
     27 import android.database.sqlite.SQLiteOpenHelper;
     28 import android.support.test.InstrumentationRegistry;
     29 import android.support.test.filters.SmallTest;
     30 import android.support.test.runner.AndroidJUnit4;
     31 
     32 import com.android.launcher3.LauncherProvider;
     33 import com.android.launcher3.LauncherProvider.DatabaseHelper;
     34 import com.android.launcher3.LauncherSettings.Favorites;
     35 import com.android.launcher3.R;
     36 
     37 import org.junit.Before;
     38 import org.junit.Test;
     39 import org.junit.runner.RunWith;
     40 
     41 import java.io.File;
     42 
     43 /**
     44  * Tests for {@link DbDowngradeHelper}
     45  */
     46 @SmallTest
     47 @RunWith(AndroidJUnit4.class)
     48 public class DbDowngradeHelperTest {
     49 
     50     private static final String SCHEMA_FILE = "test_schema.json";
     51     private static final String DB_FILE = "test.db";
     52 
     53     private Context mContext;
     54     private File mSchemaFile;
     55     private File mDbFile;
     56 
     57     @Before
     58     public void setup() {
     59         mContext = InstrumentationRegistry.getTargetContext();
     60         mSchemaFile = mContext.getFileStreamPath(SCHEMA_FILE);
     61         mDbFile = mContext.getDatabasePath(DB_FILE);
     62     }
     63 
     64     @Test
     65     public void testUpdateSchemaFile() throws Exception {
     66         Context myContext = InstrumentationRegistry.getContext();
     67         int testResId = myContext.getResources().getIdentifier(
     68                 "db_schema_v10", "raw", myContext.getPackageName());
     69         mSchemaFile.delete();
     70         assertFalse(mSchemaFile.exists());
     71 
     72         DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
     73         assertTrue(mSchemaFile.exists());
     74         assertEquals(10, DbDowngradeHelper.parse(mSchemaFile).version);
     75 
     76         // Schema is updated on version upgrade
     77         assertTrue(mSchemaFile.setLastModified(0));
     78         DbDowngradeHelper.updateSchemaFile(mSchemaFile, 11, myContext, testResId);
     79         assertNotSame(0, mSchemaFile.lastModified());
     80 
     81         // Schema is not updated when version is same
     82         assertTrue(mSchemaFile.setLastModified(0));
     83         DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
     84         assertEquals(0, mSchemaFile.lastModified());
     85 
     86         // Schema is not updated on version downgrade
     87         DbDowngradeHelper.updateSchemaFile(mSchemaFile, 3, myContext, testResId);
     88         assertEquals(0, mSchemaFile.lastModified());
     89     }
     90 
     91     @Test
     92     public void testDowngrade_success_v24() throws Exception {
     93         setupTestDb();
     94 
     95         TestOpenHelper helper = new TestOpenHelper(24);
     96         assertEquals(24, helper.getReadableDatabase().getVersion());
     97         helper.close();
     98     }
     99 
    100     @Test
    101     public void testDowngrade_success_v22() throws Exception {
    102         setupTestDb();
    103 
    104         SQLiteOpenHelper helper = new TestOpenHelper(22);
    105         assertEquals(22, helper.getWritableDatabase().getVersion());
    106 
    107         // Check column does not exist
    108         try (Cursor c = helper.getWritableDatabase().query(Favorites.TABLE_NAME,
    109                 null, null, null, null, null, null)) {
    110             assertEquals(-1, c.getColumnIndex(Favorites.OPTIONS));
    111 
    112             // Check data is present
    113             assertEquals(10, c.getCount());
    114         }
    115         helper.close();
    116 
    117         helper = new DatabaseHelper(mContext, null, DB_FILE) {
    118             @Override
    119             public void onOpen(SQLiteDatabase db) { }
    120         };
    121         assertEquals(LauncherProvider.SCHEMA_VERSION, helper.getWritableDatabase().getVersion());
    122 
    123         try (Cursor c = helper.getWritableDatabase().query(Favorites.TABLE_NAME,
    124                 null, null, null, null, null, null)) {
    125             // Check column exists
    126             assertNotSame(-1, c.getColumnIndex(Favorites.OPTIONS));
    127 
    128             // Check data is present
    129             assertEquals(10, c.getCount());
    130         }
    131         helper.close();
    132     }
    133 
    134     @Test(expected = DowngradeFailException.class)
    135     public void testDowngrade_fail_v20() throws Exception {
    136         setupTestDb();
    137 
    138         TestOpenHelper helper = new TestOpenHelper(20);
    139         helper.getReadableDatabase().getVersion();
    140     }
    141 
    142     private void setupTestDb() throws Exception {
    143         mSchemaFile.delete();
    144         mDbFile.delete();
    145 
    146         DbDowngradeHelper.updateSchemaFile(mSchemaFile, LauncherProvider.SCHEMA_VERSION, mContext,
    147                 R.raw.downgrade_schema);
    148 
    149         DatabaseHelper dbHelper = new DatabaseHelper(mContext, null, DB_FILE) {
    150             @Override
    151             public void onOpen(SQLiteDatabase db) { }
    152         };
    153         // Insert dummy data
    154         for (int i = 0; i < 10; i++) {
    155             ContentValues values = new ContentValues();
    156             values.put(Favorites._ID, i);
    157             values.put(Favorites.TITLE, "title " + i);
    158             dbHelper.getWritableDatabase().insert(Favorites.TABLE_NAME, null, values);
    159         }
    160         dbHelper.close();
    161     }
    162 
    163     private class TestOpenHelper extends SQLiteOpenHelper {
    164 
    165         public TestOpenHelper(int version) {
    166             super(mContext, DB_FILE, null, version);
    167         }
    168 
    169         @Override
    170         public void onCreate(SQLiteDatabase sqLiteDatabase) {
    171             throw new RuntimeException("DB should already be created");
    172         }
    173 
    174         @Override
    175         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    176             throw new RuntimeException("Only downgrade supported");
    177         }
    178 
    179         @Override
    180         public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    181             try {
    182                 DbDowngradeHelper.parse(mSchemaFile).onDowngrade(db, oldVersion, newVersion);
    183             } catch (Exception e) {
    184                 throw new DowngradeFailException(e);
    185             }
    186         }
    187     }
    188 
    189     private static class DowngradeFailException extends RuntimeException {
    190         public DowngradeFailException(Exception e) {
    191             super(e);
    192         }
    193     }
    194 }
    195