/*
 * Copyright (C) 2007 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.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import android.test.suitebuilder.annotation.Suppress;
import dalvik.system.VMRuntime;
import junit.framework.TestCase;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.Random;


public class HeapTest extends TestCase {

    private static final String TAG = "HeapTest";

    /**
     * Returns a WeakReference to an object that has no
     * other references.  This is done in a separate method
     * to ensure that the Object's address isn't sitting in
     * a stale local register.
     */
    private WeakReference<Object> newRef() {
        return new WeakReference<Object>(new Object());
    }

    /**
     * Allocates the specified number of bytes. This is done in a separate method
     * to ensure that the Object's address isn't sitting in a stale local register.
     */
    private void allocateMemory(int size) {
        byte[] b = new byte[size];
    }

    @MediumTest
    public void testMinimumHeapSize() throws Exception {
        VMRuntime r = VMRuntime.getRuntime();
        final boolean RUN_FLAKY = false;

        long origSize = r.getMinimumHeapSize();
        if (RUN_FLAKY) {
            /* Check that the default value is zero.  This will break if anyone
             * in this process sets the minimum heap size to a positive value
             * before calling this test.
             */
            assertTrue(origSize == 0);
        }

        long size = 4 * 1024 * 1024;
        long oldSize = r.setMinimumHeapSize(size);
        assertTrue(oldSize == origSize);

        long newSize = r.getMinimumHeapSize();
        /* This will fail if the maximum heap size (-Xmx) is smaller than 4MB.
         */
        assertTrue(newSize == size);

        /* Make sure that getting the size doesn't change anything.
         */
        newSize = r.getMinimumHeapSize();
        assertTrue(newSize == size);

        /* This test is flaky; if the heap is already large and fragmented,
         * it can fail.  It can also fail if another thread causes a GC
         * at the wrong time.
         */
        if (RUN_FLAKY) {
            /* Increase the minimum size, allocate a big object, and make sure that
             * a GC didn't happen.
             */
            WeakReference ref = newRef();
            assertNotNull(ref.get());

            r.setMinimumHeapSize(8 * 1024 * 1024);
            allocateMemory(4 * 1024 * 1024);

            /* If a GC happened, this reference will be null.
             */
            assertNotNull(ref.get());
        }

        /* Restore the original setting.
         */
        r.setMinimumHeapSize(origSize);
        newSize = r.getMinimumHeapSize();
        assertTrue(newSize == origSize);

        /* Clean up any large stuff we've allocated,
         * and re-establish the normal utilization ratio.
         */
        Runtime.getRuntime().gc();
    }

    private static void makeRefs(Object objects[], SoftReference<Object> refs[]) {
        for (int i = 0; i < objects.length; i++) {
            objects[i] = (Object) new byte[8 * 1024];
            refs[i] = new SoftReference<Object>(objects[i]);
        }
    }

    private static <T> int checkRefs(SoftReference<T> refs[], int last) {
        int i;
        int numCleared = 0;
        for (i = 0; i < refs.length; i++) {
            Object o = refs[i].get();
            if (o == null) {
                numCleared++;
            }
        }
        if (numCleared != last) {
            Log.i(TAG, "****** " + numCleared + "/" + i + " cleared ******");
        }
        return numCleared;
    }

    private static void clearRefs(Object objects[], int skip) {
        for (int i = 0; i < objects.length; i += skip) {
            objects[i] = null;
        }
    }

    private static void clearRefs(Object objects[]) {
        clearRefs(objects, 1);
    }

    private static <T> void checkRefs(T objects[], SoftReference<T> refs[]) {
        boolean ok = true;

        for (int i = 0; i < objects.length; i++) {
            if (refs[i].get() != objects[i]) {
                ok = false;
            }
        }
        if (!ok) {
            throw new RuntimeException("Test failed: soft refs not cleared");
        }
    }

    @MediumTest
    public void testGcSoftRefs() throws Exception {
        final int NUM_REFS = 128;

        Object objects[] = new Object[NUM_REFS];
        SoftReference<Object> refs[] = new SoftReference[objects.length];

        /* Create a bunch of objects and a parallel array
         * of SoftReferences.
         */
        makeRefs(objects, refs);
        Runtime.getRuntime().gc();

        /* Let go of some of the hard references to the objects so that
         * the references can be cleared.
         */
        clearRefs(objects, 3);

        /* Collect all softly-reachable objects.
         */
        VMRuntime.getRuntime().gcSoftReferences();
        Runtime.getRuntime().runFinalization();

        /* Make sure that the objects were collected.
         */
        checkRefs(objects, refs);

        /* Remove more hard references and re-check.
         */
        clearRefs(objects, 2);
        VMRuntime.getRuntime().gcSoftReferences();
        Runtime.getRuntime().runFinalization();
        checkRefs(objects, refs);

        /* Remove the rest of the references and re-check.
         */
        /* Remove more hard references and re-check.
         */
        clearRefs(objects);
        VMRuntime.getRuntime().gcSoftReferences();
        Runtime.getRuntime().runFinalization();
        checkRefs(objects, refs);
    }

    public void xxtestSoftRefPartialClean() throws Exception {
        final int NUM_REFS = 128;

        Object objects[] = new Object[NUM_REFS];
        SoftReference<Object> refs[] = new SoftReference[objects.length];

        /* Create a bunch of objects and a parallel array
        * of SoftReferences.
        */
        makeRefs(objects, refs);
        Runtime.getRuntime().gc();

        /* Let go of the hard references to the objects so that
        * the references can be cleared.
        */
        clearRefs(objects);

        /* Start creating a bunch of temporary and permanent objects
        * to drive GC.
        */
        final int NUM_OBJECTS = 64 * 1024;
        Object junk[] = new Object[NUM_OBJECTS];
        Random random = new Random();

        int i = 0;
        int mod = 0;
        int totalSize = 0;
        int cleared = -1;
        while (i < junk.length && totalSize < 8 * 1024 * 1024) {
            int r = random.nextInt(64 * 1024) + 128;
            Object o = (Object) new byte[r];
            if (++mod % 16 == 0) {
                junk[i++] = o;
                totalSize += r * 4;
            }
            cleared = checkRefs(refs, cleared);
        }
    }

    private static void makeRefs(Object objects[], WeakReference<Object> refs[]) {
        for (int i = 0; i < objects.length; i++) {
            objects[i] = new Object();
            refs[i] = new WeakReference<Object>(objects[i]);
        }
    }

    private static <T> void checkRefs(T objects[], WeakReference<T> refs[]) {
        boolean ok = true;

        for (int i = 0; i < objects.length; i++) {
            if (refs[i].get() != objects[i]) {
                ok = false;
            }
        }
        if (!ok) {
            throw new RuntimeException("Test failed: " +
                    "weak refs not cleared");
        }
    }

    @MediumTest
    public void testWeakRefs() throws Exception {
        final int NUM_REFS = 16;

        Object objects[] = new Object[NUM_REFS];
        WeakReference<Object> refs[] = new WeakReference[objects.length];

        /* Create a bunch of objects and a parallel array
        * of WeakReferences.
        */
        makeRefs(objects, refs);
        Runtime.getRuntime().gc();
        checkRefs(objects, refs);

        /* Clear out every other strong reference.
        */
        for (int i = 0; i < objects.length; i += 2) {
            objects[i] = null;
        }
        Runtime.getRuntime().gc();
        checkRefs(objects, refs);

        /* Clear out the rest of them.
        */
        for (int i = 0; i < objects.length; i++) {
            objects[i] = null;
        }
        Runtime.getRuntime().gc();
        checkRefs(objects, refs);
    }

    private static void makeRefs(Object objects[], PhantomReference<Object> refs[],
            ReferenceQueue<Object> queue) {
        for (int i = 0; i < objects.length; i++) {
            objects[i] = new Object();
            refs[i] = new PhantomReference<Object>(objects[i], queue);
        }
    }

    static <T> void checkRefs(T objects[], PhantomReference<T> refs[],
            ReferenceQueue<T> queue) {
        boolean ok = true;

        /* Make sure that the reference that should be on
        * the queue are marked as enqueued.  Once we
        * pull them off the queue, they will no longer
        * be marked as enqueued.
        */
        for (int i = 0; i < objects.length; i++) {
            if (objects[i] == null && refs[i] != null) {
                if (!refs[i].isEnqueued()) {
                    ok = false;
                }
            }
        }
        if (!ok) {
            throw new RuntimeException("Test failed: " +
                    "phantom refs not marked as enqueued");
        }

        /* Make sure that all of the references on the queue
        * are supposed to be there.
        */
        PhantomReference<T> ref;
        while ((ref = (PhantomReference<T>) queue.poll()) != null) {
            /* Find the list index that corresponds to this reference.
            */
            int i;
            for (i = 0; i < objects.length; i++) {
                if (refs[i] == ref) {
                    break;
                }
            }
            if (i == objects.length) {
                throw new RuntimeException("Test failed: " +
                        "unexpected ref on queue");
            }
            if (objects[i] != null) {
                throw new RuntimeException("Test failed: " +
                        "reference enqueued for strongly-reachable " +
                        "object");
            }
            refs[i] = null;

            /* TODO: clear doesn't do much, since we're losing the
            * strong ref to the ref object anyway.  move the ref
            * into another list.
            */
            ref.clear();
        }

        /* We've visited all of the enqueued references.
        * Make sure that there aren't any other references
        * that should have been enqueued.
        *
        * NOTE: there is a race condition here;  this assumes
        * that the VM has serviced all outstanding reference
        * enqueue() calls.
        */
        for (int i = 0; i < objects.length; i++) {
            if (objects[i] == null && refs[i] != null) {
//                System.out.println("HeapTest/PhantomRefs: refs[" + i +
//                        "] should be enqueued");
                ok = false;
            }
        }
        if (!ok) {
            throw new RuntimeException("Test failed: " +
                    "phantom refs not enqueued");
        }
    }

    @MediumTest
    public void testPhantomRefs() throws Exception {
        final int NUM_REFS = 16;

        Object objects[] = new Object[NUM_REFS];
        PhantomReference<Object> refs[] = new PhantomReference[objects.length];
        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();

        /* Create a bunch of objects and a parallel array
        * of PhantomReferences.
        */
        makeRefs(objects, refs, queue);
        Runtime.getRuntime().gc();
        checkRefs(objects, refs, queue);

        /* Clear out every other strong reference.
        */
        for (int i = 0; i < objects.length; i += 2) {
            objects[i] = null;
        }
        // System.out.println("HeapTest/PhantomRefs: cleared evens");
        Runtime.getRuntime().gc();
        Runtime.getRuntime().runFinalization();
        checkRefs(objects, refs, queue);

        /* Clear out the rest of them.
        */
        for (int i = 0; i < objects.length; i++) {
            objects[i] = null;
        }
        // System.out.println("HeapTest/PhantomRefs: cleared all");
        Runtime.getRuntime().gc();
        Runtime.getRuntime().runFinalization();
        checkRefs(objects, refs, queue);
    }

    private static int sNumFinalized = 0;
    private static final Object sLock = new Object();

    private static class FinalizableObject {
        protected void finalize() {
            // System.out.println("gc from finalize()");
            Runtime.getRuntime().gc();
            synchronized (sLock) {
                sNumFinalized++;
            }
        }
    }

    private static void makeRefs(FinalizableObject objects[],
            WeakReference<FinalizableObject> refs[]) {
        for (int i = 0; i < objects.length; i++) {
            objects[i] = new FinalizableObject();
            refs[i] = new WeakReference<FinalizableObject>(objects[i]);
        }
    }

    @LargeTest
    public void testWeakRefsAndFinalizers() throws Exception {
        final int NUM_REFS = 16;

        FinalizableObject objects[] = new FinalizableObject[NUM_REFS];
        WeakReference<FinalizableObject> refs[] = new WeakReference[objects.length];
        int numCleared;

        /* Create a bunch of objects and a parallel array
        * of WeakReferences.
        */
        makeRefs(objects, refs);
        Runtime.getRuntime().gc();
        checkRefs(objects, refs);

        /* Clear out every other strong reference.
        */
        sNumFinalized = 0;
        numCleared = 0;
        for (int i = 0; i < objects.length; i += 2) {
            objects[i] = null;
            numCleared++;
        }
        // System.out.println("HeapTest/WeakRefsAndFinalizers: cleared evens");
        Runtime.getRuntime().gc();
        Runtime.getRuntime().runFinalization();
        checkRefs(objects, refs);
        if (sNumFinalized != numCleared) {
            throw new RuntimeException("Test failed: " +
                    "expected " + numCleared + " finalizations, saw " +
                    sNumFinalized);
        }

        /* Clear out the rest of them.
        */
        sNumFinalized = 0;
        numCleared = 0;
        for (int i = 0; i < objects.length; i++) {
            if (objects[i] != null) {
                objects[i] = null;
                numCleared++;
            }
        }
        // System.out.println("HeapTest/WeakRefsAndFinalizers: cleared all");
        Runtime.getRuntime().gc();
        Runtime.getRuntime().runFinalization();
        checkRefs(objects, refs);
        if (sNumFinalized != numCleared) {
            throw new RuntimeException("Test failed: " +
                    "expected " + numCleared + " finalizations, saw " +
                    sNumFinalized);
        }
    }

    @MediumTest
    public void testOomeLarge() throws Exception {
        /* Just shy of the typical max heap size so that it will actually
         * try to allocate it instead of short-circuiting.
         */
        final int SIXTEEN_MB = (16 * 1024 * 1024 - 32);

        Boolean sawEx = false;
        byte a[];

        try {
            a = new byte[SIXTEEN_MB];
        } catch (OutOfMemoryError oom) {
            //Log.i(TAG, "HeapTest/OomeLarge caught " + oom);
            sawEx = true;
        }

        if (!sawEx) {
            throw new RuntimeException("Test failed: " +
                    "OutOfMemoryError not thrown");
        }
    }

    //See bug 1308253 for reasons.
    @Suppress
    public void disableTestOomeSmall() throws Exception {
        final int SIXTEEN_MB = (16 * 1024 * 1024);
        final int LINK_SIZE = 6 * 4; // estimated size of a LinkedList's node

        Boolean sawEx = false;

        LinkedList<Object> list = new LinkedList<Object>();

        /* Allocate progressively smaller objects to fill up the entire heap.
         */
        int objSize = 1 * 1024 * 1024;
        while (objSize >= LINK_SIZE) {
            try {
                for (int i = 0; i < SIXTEEN_MB / objSize; i++) {
                    list.add((Object)new byte[objSize]);
                }
            } catch (OutOfMemoryError oom) {
                sawEx = true;
            }

            if (!sawEx) {
                throw new RuntimeException("Test failed: " +
                        "OutOfMemoryError not thrown while filling heap");
            }
            sawEx = false;

            objSize = (objSize * 4) / 5;
        }
    }

    @SmallTest
    public void testExternalOomeLarge() {
        /* Just shy of the typical max heap size so that it will actually
         * try to allocate it instead of short-circuiting.
         */
        final int HUGE_SIZE = (16 * 1024 * 1024 - 32);

        assertFalse(VMRuntime.getRuntime().trackExternalAllocation(HUGE_SIZE));
    }

    /**
     * "Allocates" external memory in progressively smaller chunks until there's
     * only roughly 16 bytes left.
     *
     * @return the number of bytes allocated
     */
    private long allocateMaxExternal() {
        final VMRuntime runtime = VMRuntime.getRuntime();
        final int SIXTEEN_MB = (16 * 1024 * 1024);
        final int MIN_SIZE = 16;
        long totalAllocated = 0;
        boolean success;

        success = false;
        try {
            /* "Allocate" progressively smaller chunks to "fill up" the entire heap.
             */
            int objSize = 1 * 1024 * 1024;
            while (objSize >= MIN_SIZE) {
                boolean sawFailure = false;
                for (int i = 0; i < SIXTEEN_MB / objSize; i++) {
                    if (runtime.trackExternalAllocation(objSize)) {
                        totalAllocated += objSize;
                    } else {
                        sawFailure = true;
                        break;
                    }
                }

                if (!sawFailure) {
                    throw new RuntimeException("Test failed: " +
                            "no failure while filling heap");
                }

                objSize = (objSize * 4) / 5;
            }
            success = true;
        } finally {
            if (!success) {
                runtime.trackExternalFree(totalAllocated);
                totalAllocated = 0;
            }
        }
        return totalAllocated;
    }

    public void xxtest00ExternalOomeSmall() {
        VMRuntime.getRuntime().trackExternalFree(allocateMaxExternal());
    }

    /**
     * Allocates as much external memory as possible, then allocates from the heap
     * until an OOME is caught.
     *
     * It's nice to run this test while the real heap is small, hence the '00' in its
     * name to force it to run before testOomeSmall().
     */
    public void xxtest00CombinedOomeSmall() {
        long totalAllocated = 0;
        boolean sawEx = false;
        try {
            totalAllocated = allocateMaxExternal();
            LinkedList<Object> list = new LinkedList<Object>();
            try {
                while (true) {
                    list.add((Object)new byte[8192]);
                }
                /*NOTREACHED*/
            } catch (OutOfMemoryError oom) {
                sawEx = true;
            }
        } finally {
            VMRuntime.getRuntime().trackExternalFree(totalAllocated);
        }
        assertTrue(sawEx);
    }

    //TODO: test external alloc debugging/inspection
}
