1 /*
2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package gc.arguments;
25 
26 /*
27  * @test TestVerifyBeforeAndAfterGCFlags
28  * @key gc
29  * @bug 8000831
30  * @summary Runs an simple application (GarbageProducer) with various
31          combinations of -XX:{+|-}Verify{After|Before}GC flags and checks that
32          output contain or doesn't contain expected patterns
33  * @requires vm.gc != "Z" & vm.gc != "Shenandoah"
34  * @modules java.base/jdk.internal.misc
35  * @modules java.management
36  * @library /test/lib
37  * @library /
38  * @run driver gc.arguments.TestVerifyBeforeAndAfterGCFlags
39  */
40 
41 import java.util.ArrayList;
42 import java.util.Collections;
43 
44 import jdk.test.lib.Utils;
45 import jdk.test.lib.process.OutputAnalyzer;
46 import jdk.test.lib.process.ProcessTools;
47 
48 public class TestVerifyBeforeAndAfterGCFlags {
49 
50     // VerifyBeforeGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand code cache ]
51     public static final String VERIFY_BEFORE_GC_PATTERN = "Verifying Before GC";
52     // VerifyBeforeGC: VerifyBeforeGC: VerifyBeforeGC:
53     public static final String VERIFY_BEFORE_GC_CORRUPTED_PATTERN = "VerifyBeforeGC:(?!\\[Verifying[^]]+\\])";
54 
55     // VerifyAfterGC:[Verifying threads heap tenured eden syms strs zone dict metaspace chunks hand code cache ]
56     public static final String VERIFY_AFTER_GC_PATTERN = "Verifying After GC";
57     // VerifyAfterGC: VerifyAfterGC: VerifyAfterGC:
58     public static final String VERIFY_AFTER_GC_CORRUPTED_PATTERN = "VerifyAfterGC:(?!\\[Verifying[^]]+\\])";
59 
main(String args[])60     public static void main(String args[]) throws Exception {
61         String[] filteredOpts = Utils.getFilteredTestJavaOpts(
62                                     new String[] { "-Xlog:gc+verify=debug",
63                                                    "-XX:+UseGCLogFileRotation",
64                                                    "-XX:-DisplayVMOutput",
65                                                    "VerifyBeforeGC",
66                                                    "VerifyAfterGC" });
67         testVerifyFlags(false, false, filteredOpts);
68         testVerifyFlags(true,  true,  filteredOpts);
69         testVerifyFlags(true,  false, filteredOpts);
70         testVerifyFlags(false, true,  filteredOpts);
71     }
72 
testVerifyFlags(boolean verifyBeforeGC, boolean verifyAfterGC, String[] opts)73     public static void testVerifyFlags(boolean verifyBeforeGC,
74                                        boolean verifyAfterGC,
75                                        String[] opts) throws Exception {
76         ArrayList<String> vmOpts = new ArrayList<>();
77         if (opts != null && (opts.length > 0)) {
78             Collections.addAll(vmOpts, opts);
79         }
80         Collections.addAll(vmOpts, new String[] {
81                                        "-Xlog:gc+verify=debug",
82                                        "-Xmx5m",
83                                        "-Xms5m",
84                                        "-Xmn3m",
85                                        "-XX:+UnlockDiagnosticVMOptions",
86                                        (verifyBeforeGC ? "-XX:+VerifyBeforeGC"
87                                                        : "-XX:-VerifyBeforeGC"),
88                                        (verifyAfterGC ? "-XX:+VerifyAfterGC"
89                                                       : "-XX:-VerifyAfterGC"),
90                                        GarbageProducer.class.getName() });
91         ProcessBuilder procBuilder =
92             GCArguments.createJavaProcessBuilder(vmOpts.toArray(
93                                                      new String[vmOpts.size()]));
94         OutputAnalyzer analyzer = new OutputAnalyzer(procBuilder.start());
95 
96         analyzer.shouldHaveExitValue(0);
97         analyzer.shouldNotMatch(VERIFY_BEFORE_GC_CORRUPTED_PATTERN);
98         analyzer.shouldNotMatch(VERIFY_AFTER_GC_CORRUPTED_PATTERN);
99 
100         if (verifyBeforeGC) {
101             analyzer.shouldMatch(VERIFY_BEFORE_GC_PATTERN);
102         } else {
103             analyzer.shouldNotMatch(VERIFY_BEFORE_GC_PATTERN);
104         }
105 
106         if (verifyAfterGC) {
107             analyzer.shouldMatch(VERIFY_AFTER_GC_PATTERN);
108         } else {
109             analyzer.shouldNotMatch(VERIFY_AFTER_GC_PATTERN);
110         }
111     }
112 
113     public static class GarbageProducer {
114         static long[][] garbage = new long[10][];
115 
main(String args[])116         public static void main(String args[]) {
117             int j = 0;
118             for(int i = 0; i<1000; i++) {
119                 garbage[j] = new long[10000];
120                 j = (j+1)%garbage.length;
121             }
122         }
123     }
124 }
125