1 /* 2 * Copyright (C) 2009 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 android.database; 18 19 import android.database.sqlite.SQLiteDatabase; 20 import android.test.suitebuilder.annotation.Suppress; 21 import android.util.Log; 22 import java.io.File; 23 import java.util.concurrent.atomic.AtomicInteger; 24 import android.test.AndroidTestCase; 25 26 /* 27 * This is a series of unit tests for database locks. 28 * 29 * Suppress these tests for now, since they have has inconsistent results. 30 * This should be turned into a performance tracking test. 31 */ 32 @Suppress 33 public class DatabaseLockTest extends AndroidTestCase { 34 35 private static final int NUM_ITERATIONS = 100; 36 private static final int SLEEP_TIME = 30; 37 private static final int MAX_ALLOWED_LATENCY_TIME = 30; 38 private SQLiteDatabase mDatabase; 39 private File mDatabaseFile; 40 private AtomicInteger mCounter = new AtomicInteger(); 41 42 @Override 43 protected void setUp() throws Exception { 44 super.setUp(); 45 File parentDir = getContext().getFilesDir(); 46 mDatabaseFile = new File(parentDir, "database_test.db"); 47 48 if (mDatabaseFile.exists()) { 49 mDatabaseFile.delete(); 50 } 51 mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null); 52 assertNotNull(mDatabase); 53 } 54 55 @Override 56 protected void tearDown() throws Exception { 57 mDatabase.close(); 58 mDatabaseFile.delete(); 59 super.tearDown(); 60 } 61 62 /* 63 * testLockFairness() tests the fairness of prioritizing multiple threads 64 * attempting to access a database concurrently. 65 * This test is intended to verify that, when two threads are accessing the 66 * same database at the same time with the same prioritization, neither thread 67 * is locked out and prevented from accessing the database. 68 */ 69 @Suppress 70 public void testLockFairness() { 71 startDatabaseFairnessThread(); 72 int previous = 0; 73 for (int i = 0; i < NUM_ITERATIONS; i++) { 74 mDatabase.beginTransaction(); 75 int val = mCounter.get(); 76 if (i == 0) { 77 previous = val - i; 78 } 79 assertTrue(previous == (val - i)); 80 try { 81 Thread.currentThread().sleep(SLEEP_TIME); 82 } catch (InterruptedException e) { 83 // ignore 84 } 85 mDatabase.endTransaction(); 86 } 87 } 88 89 /* 90 * This function is to create the second thread for testLockFairness() test. 91 */ 92 private void startDatabaseFairnessThread() { 93 Thread thread = new DatabaseFairnessThread(); 94 thread.start(); 95 } 96 97 private class DatabaseFairnessThread extends Thread { 98 @Override 99 public void run() { 100 for (int i = 0; i < NUM_ITERATIONS; i++) { 101 mDatabase.beginTransaction(); 102 mCounter.incrementAndGet(); 103 try { 104 Thread.sleep(SLEEP_TIME); 105 } catch (InterruptedException e) { 106 // ignore 107 } 108 mDatabase.endTransaction(); 109 } 110 } 111 } 112 113 /* 114 * testLockLatency() tests the latency of database locks. 115 * This test is intended to verify that, even when two threads are accessing 116 * the same database, the locking/unlocking of the database is done within an 117 * appropriate amount of time (MAX_ALLOWED_LATENCY_TIME). 118 */ 119 @Suppress 120 public void testLockLatency() { 121 startDatabaseLatencyThread(); 122 long sumTime = 0; 123 long maxTime = 0; 124 for (int i = 0; i < NUM_ITERATIONS; i++) { 125 long startTime = System.currentTimeMillis(); 126 mDatabase.beginTransaction(); 127 long endTime = System.currentTimeMillis(); 128 long elapsedTime = endTime - startTime; 129 if (maxTime < elapsedTime) { 130 maxTime = elapsedTime; 131 } 132 sumTime += elapsedTime; 133 try { 134 Thread.sleep(SLEEP_TIME); 135 } catch (InterruptedException e) { 136 // ignore 137 } 138 mDatabase.endTransaction(); 139 } 140 long averageTime = sumTime/NUM_ITERATIONS; 141 Log.i("DatabaseLockLatency", "AverageTime: " + averageTime); 142 Log.i("DatabaseLockLatency", "MaxTime: " + maxTime); 143 assertTrue( (averageTime - SLEEP_TIME) <= MAX_ALLOWED_LATENCY_TIME); 144 } 145 146 /* 147 * This function is to create the second thread for testLockLatency() test. 148 */ 149 private void startDatabaseLatencyThread() { 150 Thread thread = new DatabaseLatencyThread(); 151 thread.start(); 152 } 153 154 private class DatabaseLatencyThread extends Thread { 155 @Override 156 public void run() { 157 for (int i = 0; i < NUM_ITERATIONS; i++) 158 { 159 mDatabase.beginTransaction(); 160 try { 161 Thread.sleep(SLEEP_TIME); 162 } catch (InterruptedException e) { 163 // ignore 164 } 165 mDatabase.endTransaction(); 166 } 167 } 168 } 169 } 170