/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.unit_tests;

import android.app.Activity;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
import android.test.AndroidTestCase;

import junit.framework.TestCase;

/* 
 * This is a series of unit tests for database locks.
 *
 * Suppress these tests for now, since they have has inconsistent results.
 * This should be turned into a performance tracking test.
 */
@Suppress
public class DatabaseLockTest extends AndroidTestCase {

    private static final int NUM_ITERATIONS = 100;
    private static final int SLEEP_TIME = 30;
    private static final int MAX_ALLOWED_LATENCY_TIME = 30;
    private SQLiteDatabase mDatabase;
    private File mDatabaseFile;
    private AtomicInteger mCounter = new AtomicInteger();

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        File parentDir = getContext().getFilesDir();
        mDatabaseFile = new File(parentDir, "database_test.db");
        
        if (mDatabaseFile.exists()) {
            mDatabaseFile.delete();
        }
        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
        assertNotNull(mDatabase);
    }

    @Override
    protected void tearDown() throws Exception {
        mDatabase.close();
        mDatabaseFile.delete();
        super.tearDown();
    }

    /*
     * testLockFairness() tests the fairness of prioritizing multiple threads 
     * attempting to access a database concurrently.
     * This test is intended to verify that, when two threads are accessing the
     * same database at the same time with the same prioritization, neither thread 
     * is locked out and prevented from accessing the database.
     */
    @Suppress
    public void testLockFairness() {
        startDatabaseFairnessThread();
        int previous = 0;
        for (int i = 0; i < NUM_ITERATIONS; i++) { 
            mDatabase.beginTransaction();
            int val = mCounter.get();
            if (i == 0) {
                previous = val - i;
            }
            assertTrue(previous == (val - i));
            try {
                Thread.currentThread().sleep(SLEEP_TIME); 
            } catch (InterruptedException e) {
                // ignore
            }
            mDatabase.endTransaction();
        }
    }
    
    /*
     * This function is to create the second thread for testLockFairness() test.
     */
    private void startDatabaseFairnessThread() {
        Thread thread = new DatabaseFairnessThread();
        thread.start();
    }

    private class DatabaseFairnessThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < NUM_ITERATIONS; i++) {
                mDatabase.beginTransaction();
                int val = mCounter.incrementAndGet();
                try {
                    Thread.currentThread().sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    // ignore
                }
                mDatabase.endTransaction();
            }
        }
    }    
    
    /*
     * testLockLatency() tests the latency of database locks.
     * This test is intended to verify that, even when two threads are accessing
     * the same database, the locking/unlocking of the database is done within an
     * appropriate amount of time (MAX_ALLOWED_LATENCY_TIME).
     */
    @Suppress
    public void testLockLatency() {
        startDatabaseLatencyThread();
        int previous = 0;
        long sumTime = 0;
        long maxTime = 0;
        for (int i = 0; i < NUM_ITERATIONS; i++) { 
            long startTime = System.currentTimeMillis();
            mDatabase.beginTransaction();
            long endTime = System.currentTimeMillis();
            long elapsedTime = endTime - startTime;
            if (maxTime < elapsedTime) {
                maxTime = elapsedTime;
            }
            sumTime += elapsedTime;
            try {
                Thread.currentThread().sleep(SLEEP_TIME); 
            } catch (InterruptedException e) {
                // ignore
            }   
            mDatabase.endTransaction();
        }
        long averageTime = sumTime/NUM_ITERATIONS;
        Log.i("DatabaseLockLatency", "AverageTime: " + averageTime);
        Log.i("DatabaseLockLatency", "MaxTime: " + maxTime);
        assertTrue( (averageTime - SLEEP_TIME) <= MAX_ALLOWED_LATENCY_TIME);
    }
    
    /*
     * This function is to create the second thread for testLockLatency() test.
     */
    private void startDatabaseLatencyThread() {
        Thread thread = new DatabaseLatencyThread();
        thread.start();
    }

    private class DatabaseLatencyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < NUM_ITERATIONS; i++) 
            {
                mDatabase.beginTransaction();
                try {
                    Thread.currentThread().sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    // ignore
                } 
                mDatabase.endTransaction();
            }
        }
    }        
}
