1 /* 2 * Copyright (c) 2007, 2018, 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 package vm.oom; 24 25 import nsk.share.TestFailure; 26 import nsk.share.test.*; 27 import nsk.share.gc.*; 28 import java.util.List; 29 import java.util.ArrayList; 30 import vm.share.stack.StackUtils; 31 32 public abstract class OOMTraceTest extends GCTestBase { 33 protected abstract OutOfMemoryError createOOM(); 34 private List<StackTraceElement> expectedTrace = new ArrayList<StackTraceElement>(); 35 private boolean expectOOM = true; 36 private Stresser stresser; 37 38 protected void initExpectedTrace() { 39 addExpectedTraceElement(OOMTraceTest.class.getName(), "run", false); 40 addExpectedTraceElement(OOMTraceTest.class.getName(), "run1", false); 41 addExpectedTraceElement(null, "createOOM", false); 42 } 43 44 protected void addExpectedTraceElement(String className, String methodName, boolean nativeMethod) { 45 StackUtils.addExpectedTraceElement(expectedTrace, className, methodName, nativeMethod); 46 } 47 48 /** 49 * Verify that all elements from expectedTrace occur somewhere 50 * in the stack trace. 51 */ 52 protected void checkExpectedTraceElements(StackTraceElement[] elements) { 53 try { 54 if (expectedTrace.size() == 0) 55 return; 56 log.info("Expected part of stack trace:"); 57 StackUtils.printStackTrace(log, expectedTrace); 58 int i = StackUtils.findMatch(elements, expectedTrace.get(expectedTrace.size() - 1)); 59 if (i == -1) 60 throw new TestFailure("Expected element not found: " + StackUtils.strStackTraceElement(expectedTrace.get(0))); 61 log.info("Found first expected element at index " + i); 62 StackUtils.checkMatches(elements, expectedTrace, i); 63 } catch (TestFailure e) { 64 throw e; 65 } 66 } 67 68 protected boolean isAlwaysOOM() { 69 return expectOOM; 70 } 71 72 protected void dontExpectOOM() { 73 expectOOM = false; 74 } 75 76 protected boolean continueExecution() { 77 return stresser.continueExecution(); 78 } 79 80 protected void checkOOM(OutOfMemoryError oom) { 81 log.info("Checking stack trace."); 82 StackTraceElement[] elements = oom.getStackTrace(); 83 log.info("Actual stack trace:"); 84 StackUtils.printStackTrace(log, elements); 85 checkExpectedTraceElements(elements); 86 checkStackTraceElements(elements); 87 } 88 89 protected void checkStackTraceElements(StackTraceElement[] elements) { 90 if (elements == null) 91 throw new TestFailure("OutOfMemoryError has null stack trace"); 92 if (elements.length == 0) 93 throw new TestFailure("OutOfMemoryError has stack trace of length 0"); 94 if (elements.length == 1) 95 throw new TestFailure("OutOfMemoryError has stack trace of length 1"); 96 } 97 98 public void run1() { 99 OutOfMemoryError oom = createOOM(); 100 if (oom == null) { 101 if (isAlwaysOOM()) 102 throw new TestFailure("No OOM is obtained."); 103 else { 104 log.info("OOM is not obtained, skipping"); 105 return; 106 } 107 } 108 log.info("OutOfMemoryError is obtained:"); 109 log.info(oom); 110 checkOOM(oom); 111 log.info("Verification of OOM passed"); 112 } 113 114 public void run() { 115 initExpectedTrace(); 116 117 stresser = new Stresser(runParams.getStressOptions()); 118 stresser.start(runParams.getIterations()); 119 120 while (stresser.iteration()) { 121 run1(); 122 } 123 124 stresser.finish(); 125 126 log.info("TEST PASSED"); 127 } 128 }