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.database.sqlite.SQLiteDatabase;
2023d1b4b21c526f974a9300a24949759102c4db44Brett Chabotimport android.test.suitebuilder.annotation.Suppress;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.AndroidTestCase;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is a series of unit tests for database locks.
2823d1b4b21c526f974a9300a24949759102c4db44Brett Chabot *
2923d1b4b21c526f974a9300a24949759102c4db44Brett Chabot * Suppress these tests for now, since they have has inconsistent results.
3023d1b4b21c526f974a9300a24949759102c4db44Brett Chabot * This should be turned into a performance tracking test.
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
3223d1b4b21c526f974a9300a24949759102c4db44Brett Chabot@Suppress
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DatabaseLockTest extends AndroidTestCase {
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int NUM_ITERATIONS = 100;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int SLEEP_TIME = 30;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MAX_ALLOWED_LATENCY_TIME = 30;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private SQLiteDatabase mDatabase;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private File mDatabaseFile;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AtomicInteger mCounter = new AtomicInteger();
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setUp() throws Exception {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setUp();
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        File parentDir = getContext().getFilesDir();
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabaseFile = new File(parentDir, "database_test.db");
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDatabaseFile.exists()) {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabaseFile.delete();
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertNotNull(mDatabase);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void tearDown() throws Exception {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabase.close();
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDatabaseFile.delete();
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.tearDown();
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * testLockFairness() tests the fairness of prioritizing multiple threads
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * attempting to access a database concurrently.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This test is intended to verify that, when two threads are accessing the
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same database at the same time with the same prioritization, neither thread
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is locked out and prevented from accessing the database.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6923d1b4b21c526f974a9300a24949759102c4db44Brett Chabot    @Suppress
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testLockFairness() {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        startDatabaseFairnessThread();
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int previous = 0;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < NUM_ITERATIONS; i++) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.beginTransaction();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int val = mCounter.get();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i == 0) {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                previous = val - i;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assertTrue(previous == (val - i));
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Thread.currentThread().sleep(SLEEP_TIME);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (InterruptedException e) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // ignore
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.endTransaction();
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This function is to create the second thread for testLockFairness() test.
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void startDatabaseFairnessThread() {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Thread thread = new DatabaseFairnessThread();
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        thread.start();
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class DatabaseFairnessThread extends Thread {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < NUM_ITERATIONS; i++) {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.beginTransaction();
1025a05c23f3d6a1a895bf5917aacd8bd9a5302ba00Jeff Brown                mCounter.incrementAndGet();
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1045a05c23f3d6a1a895bf5917aacd8bd9a5302ba00Jeff Brown                    Thread.sleep(SLEEP_TIME);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // ignore
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.endTransaction();
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * testLockLatency() tests the latency of database locks.
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This test is intended to verify that, even when two threads are accessing
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same database, the locking/unlocking of the database is done within an
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appropriate amount of time (MAX_ALLOWED_LATENCY_TIME).
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11923d1b4b21c526f974a9300a24949759102c4db44Brett Chabot    @Suppress
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testLockLatency() {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        startDatabaseLatencyThread();
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long sumTime = 0;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long maxTime = 0;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < NUM_ITERATIONS; i++) {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long startTime = System.currentTimeMillis();
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.beginTransaction();
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long endTime = System.currentTimeMillis();
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long elapsedTime = endTime - startTime;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (maxTime < elapsedTime) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                maxTime = elapsedTime;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sumTime += elapsedTime;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
1345a05c23f3d6a1a895bf5917aacd8bd9a5302ba00Jeff Brown                Thread.sleep(SLEEP_TIME);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (InterruptedException e) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // ignore
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDatabase.endTransaction();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long averageTime = sumTime/NUM_ITERATIONS;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i("DatabaseLockLatency", "AverageTime: " + averageTime);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i("DatabaseLockLatency", "MaxTime: " + maxTime);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue( (averageTime - SLEEP_TIME) <= MAX_ALLOWED_LATENCY_TIME);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This function is to create the second thread for testLockLatency() test.
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void startDatabaseLatencyThread() {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Thread thread = new DatabaseLatencyThread();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        thread.start();
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class DatabaseLatencyThread extends Thread {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < NUM_ITERATIONS; i++)
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.beginTransaction();
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1615a05c23f3d6a1a895bf5917aacd8bd9a5302ba00Jeff Brown                    Thread.sleep(SLEEP_TIME);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // ignore
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDatabase.endTransaction();
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
170