/*
 * Copyright (c) 2013, 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.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.Scanner;

import com.oracle.java.testlibrary.Asserts;
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.JDKToolLauncher;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.ProcessTools;

/*
 * @test
 * @bug 6313383
 * @key regression
 * @summary Regression test for hprof export issue due to large heaps (>2G)
 * @library /testlibrary
 * @build com.oracle.java.testlibrary.* JMapHProfLargeHeapProc
 * @run main JMapHProfLargeHeapTest
 */

public class JMapHProfLargeHeapTest {
    private static final String HEAP_DUMP_FILE_NAME = "heap.hprof";
    private static final String HPROF_HEADER_1_0_1 = "JAVA PROFILE 1.0.1";
    private static final String HPROF_HEADER_1_0_2 = "JAVA PROFILE 1.0.2";
    private static final long M = 1024L;
    private static final long G = 1024L * M;

    public static void main(String[] args) throws Exception {
        // If we are on MacOSX, test if JMap tool is signed, otherwise return
        // since test will fail with privilege error.
        if (Platform.isOSX()) {
            String jmapToolPath = JDKToolFinder.getTestJDKTool("jmap");
            ProcessBuilder codesignProcessBuilder = new ProcessBuilder(
                    "codesign", "-v", jmapToolPath);
            Process codesignProcess = codesignProcessBuilder.start();
            OutputAnalyzer analyser = new OutputAnalyzer(codesignProcess);
            try {
                analyser.shouldNotContain("code object is not signed at all");
                System.out.println("Signed jmap found at: " + jmapToolPath);
            } catch (Exception e) {
                // Abort since we can't know if the test will work
                System.out
                        .println("Test aborted since we are on MacOSX and the jmap tool is not signed.");
                return;
            }
        }

        // Small heap 22 megabytes, should create 1.0.1 file format
        testHProfFileFormat("-Xmx1g", 22 * M, HPROF_HEADER_1_0_1);

        /**
         * This test was deliberately commented out since the test system lacks
         * support to handle the requirements for this kind of heap size in a
         * good way. If or when it becomes possible to run this kind of tests in
         * the test environment the test should be enabled again.
         * */
        // Large heap 2,2 gigabytes, should create 1.0.2 file format
        // testHProfFileFormat("-Xmx4g", 2 * G + 2 * M, HPROF_HEADER_1_0_2);
    }

    private static void testHProfFileFormat(String vmArgs, long heapSize,
            String expectedFormat) throws Exception, IOException,
            InterruptedException, FileNotFoundException {
        ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(
                vmArgs, "JMapHProfLargeHeapProc", String.valueOf(heapSize));
        procBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
        Process largeHeapProc = procBuilder.start();

        try (Scanner largeHeapScanner = new Scanner(
                largeHeapProc.getInputStream());) {
            String pidstring = null;
            while ((pidstring = largeHeapScanner.findInLine("PID\\[[0-9].*\\]")) == null) {
                Thread.sleep(500);
            }
            int pid = Integer.parseInt(pidstring.substring(4,
                    pidstring.length() - 1));
            System.out.println("Extracted pid: " + pid);

            JDKToolLauncher jMapLauncher = JDKToolLauncher
                    .createUsingTestJDK("jmap");
            jMapLauncher.addToolArg("-dump:format=b,file=" + pid + "-"
                    + HEAP_DUMP_FILE_NAME);
            jMapLauncher.addToolArg(String.valueOf(pid));

            ProcessBuilder jMapProcessBuilder = new ProcessBuilder(
                    jMapLauncher.getCommand());
            System.out.println("jmap command: "
                    + Arrays.toString(jMapLauncher.getCommand()));

            Process jMapProcess = jMapProcessBuilder.start();
            OutputAnalyzer analyzer = new OutputAnalyzer(jMapProcess);
            analyzer.shouldHaveExitValue(0);
            analyzer.shouldContain(pid + "-" + HEAP_DUMP_FILE_NAME);
            analyzer.shouldContain("Heap dump file created");

            largeHeapProc.getOutputStream().write('\n');

            File dumpFile = new File(pid + "-" + HEAP_DUMP_FILE_NAME);
            Asserts.assertTrue(dumpFile.exists(), "Heap dump file not found.");

            try (Reader reader = new BufferedReader(new FileReader(dumpFile))) {
                CharBuffer buf = CharBuffer.allocate(expectedFormat.length());
                reader.read(buf);
                buf.clear();
                Asserts.assertEQ(buf.toString(), expectedFormat,
                        "Wrong file format. Expected '" + expectedFormat
                                + "', but found '" + buf.toString() + "'");
            }

            System.out.println("Success!");

        } finally {
            largeHeapProc.destroyForcibly();
        }
    }
}
