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 android.database; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.assertTrue; 22import static org.junit.Assert.fail; 23 24import android.content.Context; 25import android.database.sqlite.SQLiteDatabase; 26import android.database.sqlite.SQLiteDatabaseConfiguration; 27import android.database.sqlite.SQLiteDebug; 28import android.database.sqlite.SQLiteOpenHelper; 29import android.support.test.InstrumentationRegistry; 30import android.support.test.filters.SmallTest; 31import android.support.test.runner.AndroidJUnit4; 32import android.util.Log; 33 34import org.junit.After; 35import org.junit.Before; 36import org.junit.Test; 37import org.junit.runner.RunWith; 38 39import java.util.ArrayList; 40import java.util.List; 41 42/** 43 * Tests for {@link SQLiteOpenHelper} 44 * 45 * <p>Run with: bit FrameworksCoreTests:android.database.SQLiteOpenHelperTest 46 */ 47@RunWith(AndroidJUnit4.class) 48@SmallTest 49public class SQLiteOpenHelperTest { 50 private static final String TAG = "SQLiteOpenHelperTest"; 51 52 private TestHelper mTestHelper; 53 private Context mContext; 54 private List<SQLiteOpenHelper> mHelpersToClose; 55 56 private static class TestHelper extends SQLiteOpenHelper { 57 TestHelper(Context context) { // In-memory 58 super(context, null, null, 1); 59 } 60 61 TestHelper(Context context, String name) { 62 super(context, name, null, 1); 63 } 64 65 TestHelper(Context context, String name, int version, SQLiteDatabase.OpenParams params) { 66 super(context, name, version, params); 67 } 68 69 @Override 70 public void onCreate(SQLiteDatabase db) { 71 } 72 73 @Override 74 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 75 } 76 } 77 78 @Before 79 public void setup() { 80 mContext = InstrumentationRegistry.getContext(); 81 mTestHelper = new TestHelper(mContext, "openhelper_test"); 82 mHelpersToClose = new ArrayList<>(); 83 mHelpersToClose.add(mTestHelper); 84 } 85 86 @After 87 public void teardown() { 88 for (SQLiteOpenHelper helper : mHelpersToClose) { 89 try { 90 helper.close(); 91 if (mTestHelper.getDatabaseName() != null) { 92 SQLiteDatabase.deleteDatabase( 93 mContext.getDatabasePath(mTestHelper.getDatabaseName())); 94 } 95 } catch (RuntimeException ex) { 96 Log.w(TAG, "Error occured when closing db helper " + helper, ex); 97 } 98 } 99 } 100 101 @Test 102 public void testLookasideDefault() throws Exception { 103 assertNotNull(mTestHelper.getWritableDatabase()); 104 verifyLookasideStats(false); 105 } 106 107 @Test 108 public void testLookasideDisabled() throws Exception { 109 mTestHelper.setLookasideConfig(0, 0); 110 assertNotNull(mTestHelper.getWritableDatabase()); 111 verifyLookasideStats(true); 112 } 113 114 @Test 115 public void testInMemoryLookasideDisabled() throws Exception { 116 TestHelper memHelper = new TestHelper(mContext); 117 mHelpersToClose.add(memHelper); 118 memHelper.setLookasideConfig(0, 0); 119 assertNotNull(memHelper.getWritableDatabase()); 120 verifyLookasideStats(SQLiteDatabaseConfiguration.MEMORY_DB_PATH, true); 121 } 122 123 @Test 124 public void testInMemoryLookasideDefault() throws Exception { 125 TestHelper memHelper = new TestHelper(mContext); 126 mHelpersToClose.add(memHelper); 127 assertNotNull(memHelper.getWritableDatabase()); 128 verifyLookasideStats(SQLiteDatabaseConfiguration.MEMORY_DB_PATH, false); 129 } 130 131 @Test 132 public void testSetLookasideConfigValidation() { 133 try { 134 mTestHelper.setLookasideConfig(-1, 0); 135 fail("Negative slot size should be rejected"); 136 } catch (IllegalArgumentException expected) { 137 } 138 try { 139 mTestHelper.setLookasideConfig(0, -10); 140 fail("Negative slot count should be rejected"); 141 } catch (IllegalArgumentException expected) { 142 } 143 try { 144 mTestHelper.setLookasideConfig(1, 0); 145 fail("Illegal config should be rejected"); 146 } catch (IllegalArgumentException expected) { 147 } 148 try { 149 mTestHelper.setLookasideConfig(0, 1); 150 fail("Illegal config should be rejected"); 151 } catch (IllegalArgumentException expected) { 152 } 153 } 154 155 private void verifyLookasideStats(boolean expectDisabled) { 156 verifyLookasideStats(mTestHelper.getDatabaseName(), expectDisabled); 157 } 158 159 private static void verifyLookasideStats(String dbName, boolean expectDisabled) { 160 boolean dbStatFound = false; 161 SQLiteDebug.PagerStats info = SQLiteDebug.getDatabaseInfo(); 162 for (SQLiteDebug.DbStats dbStat : info.dbStats) { 163 if (dbStat.dbName.endsWith(dbName)) { 164 dbStatFound = true; 165 Log.i(TAG, "Lookaside for " + dbStat.dbName + " " + dbStat.lookaside); 166 if (expectDisabled) { 167 assertTrue("lookaside slots count should be zero", dbStat.lookaside == 0); 168 } else { 169 assertTrue("lookaside slots count should be greater than zero", 170 dbStat.lookaside > 0); 171 } 172 } 173 } 174 assertTrue("No dbstat found for " + dbName, dbStatFound); 175 } 176 177 @Test 178 public void testOpenParamsConstructor() { 179 SQLiteDatabase.OpenParams params = new SQLiteDatabase.OpenParams.Builder() 180 .setJournalMode("DELETE") 181 .setSynchronousMode("OFF") 182 .build(); 183 184 TestHelper helper = new TestHelper(mContext, "openhelper_test_constructor", 1, params); 185 mHelpersToClose.add(helper); 186 187 String journalMode = DatabaseUtils 188 .stringForQuery(helper.getReadableDatabase(), "PRAGMA journal_mode", null); 189 190 assertEquals("DELETE", journalMode.toUpperCase()); 191 String syncMode = DatabaseUtils 192 .stringForQuery(helper.getReadableDatabase(), "PRAGMA synchronous", null); 193 194 assertEquals("0", syncMode); 195 } 196 197} 198