19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpackage android.database;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Activity;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.sqlite.SQLiteDatabase;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.LargeTest;
2323d1b4b21c526f974a9300a24949759102c4db44Brett Chabotimport android.test.suitebuilder.annotation.Suppress;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.AndroidTestCase;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.framework.TestCase;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is a series of unit tests for database locks.
3323d1b4b21c526f974a9300a24949759102c4db44Brett Chabot *
3423d1b4b21c526f974a9300a24949759102c4db44Brett Chabot * Suppress these tests for now, since they have has inconsistent results.
3523d1b4b21c526f974a9300a24949759102c4db44Brett Chabot * This should be turned into a performance tracking test.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
3723d1b4b21c526f974a9300a24949759102c4db44Brett Chabot@Suppress
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatabaseLockTest extends AndroidTestCase {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int NUM_ITERATIONS = 100;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int SLEEP_TIME = 30;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MAX_ALLOWED_LATENCY_TIME = 30;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private SQLiteDatabase mDatabase;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private File mDatabaseFile;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AtomicInteger mCounter = new AtomicInteger();
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setUp() throws Exception {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setUp();
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        File parentDir = getContext().getFilesDir();
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabaseFile = new File(parentDir, "database_test.db");
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDatabaseFile.exists()) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabaseFile.delete();
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertNotNull(mDatabase);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void tearDown() throws Exception {
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase.close();
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabaseFile.delete();
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.tearDown();
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * testLockFairness() tests the fairness of prioritizing multiple threads
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * attempting to access a database concurrently.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This test is intended to verify that, when two threads are accessing the
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same database at the same time with the same prioritization, neither thread
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is locked out and prevented from accessing the database.
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7423d1b4b21c526f974a9300a24949759102c4db44Brett Chabot    @Suppress
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testLockFairness() {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        startDatabaseFairnessThread();
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int previous = 0;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < NUM_ITERATIONS; i++) {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.beginTransaction();
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int val = mCounter.get();
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i == 0) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                previous = val - i;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assertTrue(previous == (val - i));
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Thread.currentThread().sleep(SLEEP_TIME);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (InterruptedException e) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // ignore
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.endTransaction();
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This function is to create the second thread for testLockFairness() test.
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void startDatabaseFairnessThread() {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Thread thread = new DatabaseFairnessThread();
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        thread.start();
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class DatabaseFairnessThread extends Thread {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < NUM_ITERATIONS; i++) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.beginTransaction();
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int val = mCounter.incrementAndGet();
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Thread.currentThread().sleep(SLEEP_TIME);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // ignore
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.endTransaction();
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * testLockLatency() tests the latency of database locks.
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This test is intended to verify that, even when two threads are accessing
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same database, the locking/unlocking of the database is done within an
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appropriate amount of time (MAX_ALLOWED_LATENCY_TIME).
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12423d1b4b21c526f974a9300a24949759102c4db44Brett Chabot    @Suppress
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testLockLatency() {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        startDatabaseLatencyThread();
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int previous = 0;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long sumTime = 0;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long maxTime = 0;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < NUM_ITERATIONS; i++) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long startTime = System.currentTimeMillis();
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.beginTransaction();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long endTime = System.currentTimeMillis();
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long elapsedTime = endTime - startTime;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (maxTime < elapsedTime) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                maxTime = elapsedTime;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sumTime += elapsedTime;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Thread.currentThread().sleep(SLEEP_TIME);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (InterruptedException e) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // ignore
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.endTransaction();
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long averageTime = sumTime/NUM_ITERATIONS;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i("DatabaseLockLatency", "AverageTime: " + averageTime);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i("DatabaseLockLatency", "MaxTime: " + maxTime);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue( (averageTime - SLEEP_TIME) <= MAX_ALLOWED_LATENCY_TIME);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This function is to create the second thread for testLockLatency() test.
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void startDatabaseLatencyThread() {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Thread thread = new DatabaseLatencyThread();
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        thread.start();
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class DatabaseLatencyThread extends Thread {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < NUM_ITERATIONS; i++)
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.beginTransaction();
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Thread.currentThread().sleep(SLEEP_TIME);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // ignore
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.endTransaction();
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
176