/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
 * @test TestMaxMinHeapFreeRatioFlags
 * @key gc
 * @summary Verify that heap size changes according to max and min heap free ratios.
 * @library /testlibrary
 * @modules java.base/jdk.internal.misc
 *          java.management
 * @build TestMaxMinHeapFreeRatioFlags
 * @run driver/timeout=240 TestMaxMinHeapFreeRatioFlags
 */

import java.util.LinkedList;
import java.util.Arrays;
import java.util.Collections;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.ProcessTools;
import jdk.test.lib.Utils;
import jdk.test.lib.HeapRegionUsageTool;
import sun.misc.Unsafe;

public class TestMaxMinHeapFreeRatioFlags {

    public static final long M = 1024 * 1024;
    public static final long MAX_HEAP_SIZE = 200 * M;
    public static final long HEAP_SIZE = 10 * M;
    public static final long MAX_NEW_SIZE = 20 * M;
    public static final long NEW_SIZE = 5 * M;

    public static void main(String args[]) throws Exception {
        LinkedList<String> options = new LinkedList<>(
                Arrays.asList(Utils.getFilteredTestJavaOpts("-XX:[^ ]*HeapFreeRatio","-XX:\\+ExplicitGCInvokesConcurrent"))
        );

        negativeTest(20, false, 10, true, options);
        negativeTest(100, true, 0, false, options);
        negativeTest(101, false, 50, false, options);
        negativeTest(49, true, 102, true, options);
        negativeTest(-1, false, 50, false, options);
        negativeTest(50, true, -1, true, options);

        positiveTest(10, false, 90, false, true, options);
        positiveTest(10, true, 80, false, true, options);
        positiveTest(20, false, 70, true, true, options);
        positiveTest(25, true, 65, true, true, options);
        positiveTest(40, false, 50, false, true, options);
    }

    /**
     * Verify that heap size will be changed to conform
     * min and max heap free ratios.
     *
     * @param minRatio value of MinHeapFreeRatio option
     * @param useXminf used Xminf option instead of MinHeapFreeRatio
     * @param maxRatio value of MaxHeapFreeRatio option
     * @param useXmaxf used Xmaxf option instead of MaxHeapFreeRatio
     * @param options additional options for JVM
     */
    public static void positiveTest(int minRatio, boolean useXminf,
            int maxRatio, boolean useXmaxf, boolean shrinkHeapInSteps,
            LinkedList<String> options) throws Exception {

        LinkedList<String> vmOptions = new LinkedList<>(options);
        Collections.addAll(vmOptions,
                (useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
                (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
                "-Xmx" + MAX_HEAP_SIZE,
                "-Xms" + HEAP_SIZE,
                "-XX:NewSize=" + NEW_SIZE,
                "-XX:MaxNewSize=" + MAX_NEW_SIZE,
                "-XX:" + (shrinkHeapInSteps ? '+' : '-') + "ShrinkHeapInSteps",
                RatioVerifier.class.getName(),
                Integer.toString(minRatio),
                Integer.toString(maxRatio),
                Boolean.toString(shrinkHeapInSteps)
        );

        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
        analyzer.shouldHaveExitValue(0);
    }

    /**
     * Verify that VM will fail to start with specified ratios.
     *
     * @param minRatio value of MinHeapFreeRatio option
     * @param useXminf used Xminf option instead of MinHeapFreeRatio
     * @param maxRatio value of MaxHeapFreeRatio option
     * @param useXmaxf used Xmaxf option instead of MaxHeapFreeRatio
     * @param options additional options for JVM
     */
    public static void negativeTest(int minRatio, boolean useXminf,
            int maxRatio, boolean useXmaxf,
            LinkedList<String> options) throws Exception {

        LinkedList<String> vmOptions = new LinkedList<>(options);
        Collections.addAll(vmOptions,
                (useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
                (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
                "-version"
        );
        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
        OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
        analyzer.shouldHaveExitValue(1);
        analyzer.shouldContain("Error: Could not create the Java Virtual Machine.");
    }

    /**
     * RatioVerifier will be executed in the tested VM.
     * It will check that real heap usage after collection lies between MinHeapFreeRatio and MaxHeapFreeRatio.
     */
    public static class RatioVerifier {

        private static final Unsafe unsafe = Utils.getUnsafe();

        // Size of byte array that will be allocated
        public static final int CHUNK_SIZE = 1024;
        // Length of byte array, that will be added to "garbage" list.
        public static final int ARRAY_LENGTH = CHUNK_SIZE - Unsafe.ARRAY_BYTE_BASE_OFFSET;
        // Amount of tries to force heap shrinking/expansion using GC
        public static final int GC_TRIES = 10;

        // Value that will be added/substracted from expected min/max heap free ratio
        // during memory allocation to make sure that specified limit will be exceeded.
        public static final double OVERLOAD = 0.05;
        // Acceptable heap free ratio limit exceedance: verification will fail if
        // actual ratio is lower than expected min heap free ratio - VARIANCE or
        // higher than expected max heap free ratio + VARIANCE.
        public static final double VARIANCE = 0.025;

        public static LinkedList<Object> garbage = new LinkedList<>();

        public static void main(String args[]) throws Exception {
            if (args.length != 3) {
                throw new IllegalArgumentException("Expected 3 args: <minRatio> <maxRatio> <shrinkHeapInSteps>");
            }
            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.PSOld) {
                System.out.println("Test is not applicable to parallel GC");
                return;
            }

            double minRatio = Integer.valueOf(args[0]) / 100.0;
            double maxRatio = Integer.valueOf(args[1]) / 100.0;
            boolean shrinkHeapInSteps = Boolean.valueOf(args[2]);

            long maxHeapSize = getMax();
            int gcTries = (shrinkHeapInSteps ? GC_TRIES : 1);

            // Initial checks. This also links up everything in these helper methods,
            // in case it brings more garbage.
            forceGC(gcTries);
            verifyRatio(minRatio, maxRatio);

            // commit 0.5 of total heap size to have enough space
            // to both shink and expand
            while (getCommitted() < maxHeapSize / 2) {
                garbage.add(new byte[ARRAY_LENGTH]);
            }

            forceGC(gcTries);
            // Verify that current heap free ratio lies between specified limits
            verifyRatio(minRatio, maxRatio);

            // Estimate how much memory we have to allocate to force expansion
            long memoryToFill = (long) (getCommitted() * (1 - minRatio + OVERLOAD))
                    - getUsed();

            long previouslyCommitted = getCommitted();

            while (memoryToFill > 0) {
                garbage.add(new byte[CHUNK_SIZE]);
                memoryToFill -= CHUNK_SIZE;
            }

            forceGC(gcTries);
            // Verify that after memory allocation heap free ratio is still conforming specified limits
            verifyRatio(minRatio, maxRatio);
            // Verify that heap was actually expanded
            if (previouslyCommitted >= getCommitted()) {
                throw new RuntimeException("Heap was not expanded.");
            }

            // Estimate how much memory we have to free to force shrinking
            long memoryToFree = getUsed()
                    - (long) (getCommitted() * (1 - maxRatio - OVERLOAD));

            previouslyCommitted = getCommitted();

            while (memoryToFree > 0 && garbage.size() > 0) {
                garbage.remove(garbage.size() - 1);
                memoryToFree -= CHUNK_SIZE;
            }

            forceGC(gcTries);
            // Verify that heap free ratio is still conforming specified limits
            verifyRatio(minRatio, maxRatio);
            // Verify that heap was actually shrinked
            if (previouslyCommitted <= getCommitted()) {
                throw new RuntimeException("Heap was not shrinked.");
            }
        }

        public static void forceGC(int gcTries) {
            for (int i = 0; i < gcTries; i++) {
                System.gc();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ie) {
                }
            }
        }

        /**
         * Verify that heap free ratio is conforming specified limits.
         * Actual heap free ratio may be very close to one of specified limits,
         * but exceed for more then VARIANCE.
         * Verification will also pass if actual ratio is not conforming limits,
         * but it is not possible to shrink/expand heap.
         */
        public static void verifyRatio(double minRatio, double maxRatio) {
            double ratio = getHeapFreeRatio();
            System.out.println(minRatio + " " + ratio + " " + maxRatio);
            if (minRatio - ratio > VARIANCE
                    && getCommitted() < getMax()) {
                throw new RuntimeException("Current heap free ratio is lower than "
                        + "MinHeapFreeRatio (" + ratio + " vs " + minRatio + ").");
            }
            if (ratio - maxRatio > VARIANCE
                    && getUsed() > getInit()) {
                throw new RuntimeException("Current heap free ratio is higher than "
                        + "MaxHeapFreeRatio (" + ratio + " vs " + maxRatio + ").");
            }
        }

        /*
         * Obtain information about heap size.
         *
         * For G1 information summed up for all type of regions,
         * because tested options affect overall heap sizing.
         *
         * For all other GCs return information only for old gen.
         */
        public static long getMax() {
            return HeapRegionUsageTool.getOldUsage().getMax();
        }

        public static long getInit() {
            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
                return HeapRegionUsageTool.getEdenUsage().getInit()
                        + HeapRegionUsageTool.getSurvivorUsage().getInit()
                        + HeapRegionUsageTool.getOldUsage().getInit();
            } else {
                return HeapRegionUsageTool.getOldUsage().getInit();
            }
        }

        public static long getUsed() {
            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
                return HeapRegionUsageTool.getEdenUsage().getUsed()
                        + HeapRegionUsageTool.getSurvivorUsage().getUsed()
                        + HeapRegionUsageTool.getOldUsage().getUsed();
            } else {
                return HeapRegionUsageTool.getOldUsage().getUsed();
            }
        }

        public static long getCommitted() {
            if (GCTypes.OldGCType.getOldGCType() == GCTypes.OldGCType.G1) {
                return HeapRegionUsageTool.getEdenUsage().getCommitted()
                        + HeapRegionUsageTool.getSurvivorUsage().getCommitted()
                        + HeapRegionUsageTool.getOldUsage().getCommitted();
            } else {
                return HeapRegionUsageTool.getOldUsage().getCommitted();
            }
        }

        public static long getFree() {
            return getCommitted() - getUsed();
        }

        public static double getHeapFreeRatio() {
            return getFree() / (double) getCommitted();
        }
    }
}
