1 /* 2 * Copyright (c) 2012, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 // this test has been disabled because of timeout issues. 27 // see JDK-8006746 28 29 package org.openjdk.tests.vm; 30 31 import java.util.*; 32 33 import org.testng.ITestResult; 34 import org.testng.annotations.Test; 35 import org.testng.annotations.DataProvider; 36 import org.testng.annotations.AfterMethod; 37 import org.testng.annotations.AfterSuite; 38 39 import org.openjdk.tests.separate.*; 40 import org.openjdk.tests.separate.Compiler; 41 42 import org.openjdk.tests.shapegen.Hierarchy; 43 import org.openjdk.tests.shapegen.HierarchyGenerator; 44 import org.openjdk.tests.shapegen.ClassCase; 45 46 import static org.testng.Assert.*; 47 import static org.openjdk.tests.separate.SourceModel.*; 48 import static org.openjdk.tests.separate.SourceModel.Class; 49 import static org.openjdk.tests.separate.SourceModel.Method; 50 import static org.openjdk.tests.separate.SourceModel.Type; 51 52 public class FDSeparateCompilationTest extends TestHarness { 53 54 private static String EMPTY = "\"\""; 55 FDSeparateCompilationTest()56 public FDSeparateCompilationTest() { 57 super(false, true); 58 } 59 60 @DataProvider(name = "allShapes", parallel = true) hierarchyGenerator()61 public Object[][] hierarchyGenerator() { 62 ArrayList<Object[]> allCases = new ArrayList<>(); 63 64 HierarchyGenerator hg = new HierarchyGenerator(); 65 for (Object x : hg.getOK()) { 66 allCases.add(new Object[]{x}); 67 } 68 for (Object x : hg.getErr()) { 69 allCases.add(new Object[]{x}); 70 } 71 return allCases.toArray(new Object[0][]); 72 } 73 74 // The expected value obtained when invoking the method from the specified 75 // class. If returns null, then an AbstractMethodError is expected. getExpectedResult(ClassCase cc)76 private static String getExpectedResult(ClassCase cc) { 77 Set<ClassCase> provs = cc.get_mprov(); 78 if (cc.get_mres() != null) { 79 return cc.get_mres().getName(); 80 } else if (provs != null && provs.size() == 1) { 81 ClassCase cand = provs.iterator().next(); 82 switch (cand.kind) { 83 case CCONCRETE: 84 case IDEFAULT: 85 return cand.getName(); 86 case CNONE: 87 case IVAC: 88 return getExpectedResult(cand); 89 } 90 } 91 return null; 92 } 93 94 private static final ConcreteMethod canonicalMethod = new ConcreteMethod( 95 "String", "m", "returns " + EMPTY + ";", AccessFlag.PUBLIC); 96 97 @Test(enabled = false, groups = "vm", dataProvider = "allShapes") separateCompilationTest(Hierarchy hs)98 public void separateCompilationTest(Hierarchy hs) { 99 ClassCase cc = hs.root; 100 Type type = sourceTypeFrom(hs.root); 101 102 Class specimen = null; 103 if (type instanceof Class) { 104 Class ctype = (Class)type; 105 if (ctype.isAbstract()) { 106 specimen = new Class("Test" + ctype.getName(), ctype); 107 } else { 108 specimen = ctype; 109 } 110 } else { 111 specimen = new Class("Test" + type.getName(), (Interface)type); 112 } 113 114 String value = getExpectedResult(cc); 115 if (value != null) { 116 assertInvokeVirtualEquals(value, specimen, canonicalMethod, EMPTY); 117 } else { 118 assertThrows(AbstractMethodError.class, specimen, 119 canonicalMethod, EMPTY); 120 } 121 } 122 123 @AfterMethod printCaseError(ITestResult result)124 public void printCaseError(ITestResult result) { 125 if (result.getStatus() == ITestResult.FAILURE) { 126 Hierarchy hs = (Hierarchy)result.getParameters()[0]; 127 System.out.println("Separate compilation case " + hs); 128 printCaseDetails(hs); 129 } 130 } 131 132 @AfterSuite cleanupCompilerCache()133 public void cleanupCompilerCache() { 134 Compiler.purgeCache(); 135 } 136 printCaseDetails(Hierarchy hs)137 private void printCaseDetails(Hierarchy hs) { 138 String exp = getExpectedResult(hs.root); 139 for (String s : hs.getDescription()) { 140 System.out.println(" " + s); 141 } 142 if (exp != null) { 143 System.out.println(" Expected \"" + exp + "\""); 144 } else { 145 System.out.println(" Expected AbstractMethodError"); 146 } 147 } 148 sourceTypeFrom(ClassCase cc)149 private Type sourceTypeFrom(ClassCase cc) { 150 Type type = null; 151 152 if (cc.isInterface()) { 153 Interface iface = new Interface(cc.getName()); 154 for (ClassCase scc : cc.getInterfaces()) { 155 Interface supertype = (Interface)sourceTypeFrom(scc); 156 iface.addSuperType(supertype); 157 } 158 type = iface; 159 } else { 160 Class cls = new Class(cc.getName()); 161 if (cc.hasSuperclass()) { 162 Class superc = (Class)sourceTypeFrom(cc.getSuperclass()); 163 cls.setSuperClass(superc); 164 } 165 for (ClassCase scc : cc.getInterfaces()) { 166 Interface supertype = (Interface)sourceTypeFrom(scc); 167 cls.addSuperType(supertype); 168 } 169 if (cc.isAbstract()) { 170 cls.getAccessFlags().add(AccessFlag.ABSTRACT); 171 } 172 type = cls; 173 } 174 Method method = methodFrom(cc); 175 if (method != null) { 176 type.addMethod(method); 177 } 178 return type; 179 } 180 methodFrom(ClassCase cc)181 private Method methodFrom(ClassCase cc) { 182 switch (cc.kind) { 183 case IVAC: 184 case CNONE: return null; 185 case IPRESENT: 186 case CABSTRACT: 187 return new AbstractMethod("String", "m", AccessFlag.PUBLIC); 188 case IDEFAULT: 189 return new DefaultMethod( 190 "String", "m", "return \"" + cc.getName() + "\";"); 191 case CCONCRETE: 192 return new ConcreteMethod( 193 "String", "m", "return \"" + cc.getName() + "\";", 194 AccessFlag.PUBLIC); 195 default: 196 fail("Unknown method type in class"); 197 return null; 198 } 199 } 200 } 201