/* * Copyright (c) 2007, 2018, 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. */ package nsk.share.jdi.sde; import java.io.*; import java.nio.channels.FileChannel; import java.util.*; import com.sun.jdi.*; import com.sun.jdi.event.BreakpointEvent; import com.sun.jdi.event.Event; import com.sun.jdi.event.StepEvent; import nsk.share.ClassFileFinder; import nsk.share.TestBug; import nsk.share.jdi.EventHandler; import nsk.share.jdi.TestDebuggerType2; /* * Class is used as base debugger for SDE tests. * * This class contains several methods called 'prepareDefaultPatchedClassFile_TypeXXX' which create * class file with added SourceDebugExtension attribute and return debug information about created file. * (this methods was moved in SDEDebugger class if similar generated class files were used in 2 or more tests) * * */ public class SDEDebugger extends TestDebuggerType2 { protected static final int INIT_LINE = 32; // n.s.j.sde.TestClass1:: protected static final int METHOD1_LINE = 43; // n.s.j.sde.TestClass1::sde_testMethod1 protected static final int METHOD2_LINE = 54; // n.s.j.sde.TestClass1::sde_testMethod2 public static String javaStratumName = "Java"; // Set debug data for "Java" stratum for TestClass1 public static List javaStratumLocations_TestClass1 = new ArrayList(); public static String javaSourceName_TestClass1 = "TestClass1.java"; public static String javaSourcePath_TestClass1 = "nsk" + File.separator + "share" + File.separator + "jdi" + File.separator + "sde" + File.separator + "TestClass1.java"; static { for (int i = 0; i < 8; i++) { javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, "", INIT_LINE + i, INIT_LINE + i)); javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, "sde_testMethod1", METHOD1_LINE + i, METHOD1_LINE + i)); javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, "sde_testMethod2", METHOD2_LINE + i, METHOD2_LINE + i)); } } // insert debug information about "Java" stratum in the given Map static protected void addJavaLocations(Map testStratumData, boolean setJavaStratumDefault) { LocationsData locationsData = new LocationsData(javaStratumName); if (setJavaStratumDefault) locationsData.isDefault = true; locationsData.paths.add(javaSourcePath_TestClass1); locationsData.allLocations.addAll(javaStratumLocations_TestClass1); locationsData.sourceLocations.put(javaSourceName_TestClass1, javaStratumLocations_TestClass1); testStratumData.put(javaStratumName, locationsData); } // common base names for test stratum, stratum source name and stratum // source path public static final String testStratumName = "TestStratum"; public static final String testStratumSourceName = "testSource"; public static final String testStratumSourcePath = "testSourcePath"; // Event listener thread which saves all received StepEvents public class StepEventListener extends EventHandler.EventListener { // is BreakpointEvent was received (debuggee should stop at breakpoint // after StepEvents generation) private volatile boolean breakpointEventReceived; private List stepLocations = new ArrayList(); public List stepLocations() { return stepLocations; } public void clearLocations() { stepLocations.clear(); } public boolean eventReceived(Event event) { if (event instanceof StepEvent) { StepEvent stepEvent = (StepEvent) event; stepLocations.add(stepEvent.location()); vm.resume(); return true; } // debuggee should stop after event generation else if (event instanceof BreakpointEvent) { breakpointEventReceived = true; vm.resume(); return true; } return false; } public void waitBreakpointEvent() { while (!breakpointEventReceived) Thread.yield(); } } // debug information about location (implements Comparable to make possible // using DebugLocation with java.util.Set) public static class DebugLocation implements Comparable { public DebugLocation(String sourceName, String sourcePath, String methodName, int inputLine, int outputLine) { this.sourceName = sourceName; this.sourcePath = sourcePath; this.inputLine = inputLine; this.outputLine = outputLine; this.methodName = methodName; } public String sourceName; public String sourcePath; public String methodName; public int inputLine; public int outputLine; public String toString() { return "Line number: " + inputLine + " SourceName: " + sourceName + " SourcePath: " + sourcePath; } // compare DebugLocation with com.sun.jdi.Location public boolean compare(Location location, String stratum) { try { if (stratum == null) { return (location.lineNumber() == inputLine) && location.sourceName().equals(sourceName) && location.sourcePath().equals(sourcePath); } else { return (location.lineNumber(stratum) == inputLine) && location.sourceName(stratum).equals(sourceName) && location.sourcePath(stratum).equals(sourcePath); } } catch (AbsentInformationException e) { return false; } } // used to find locations for given line public boolean isConform(String sourceName, int lineNumber) { boolean sourceConform = (sourceName == null ? true : this.sourceName.equals(sourceName)); return sourceConform && (this.inputLine == lineNumber); } // implements this method to make possible using DebugLocation with java.util.Set public int compareTo(DebugLocation location) { return (this.sourceName.equals(location.sourceName) && this.inputLine == location.inputLine) ? 0 : 1; } } // Class contains debug information about sources, paths, locations // available for class public static class LocationsData { public LocationsData(String stratumName) { this.stratumName = stratumName; } public List sourceNames() { List sourceNames = new ArrayList(); sourceNames.addAll(sourceLocations.keySet()); return sourceNames; } public String stratumName; // is stratum default for ReferenceType public boolean isDefault; // locations for source files public Map> sourceLocations = new TreeMap>(); // all locations for stratum public List allLocations = new ArrayList(); // all paths for stratum public List paths = new ArrayList(); } static protected String locationToString(Location location, String stratum) { String result; result = "Line number: " + (stratum == null ? location.lineNumber() : location.lineNumber(stratum)); try { result += (" Source name: " + (stratum == null ? location.sourceName() : location.sourceName(stratum))); } catch (AbsentInformationException e) { result += (" Source name: " + " INFORMATION IS ABSENT"); } try { result += (" Source path: " + (stratum == null ? location.sourcePath() : location.sourcePath(stratum))); } catch (AbsentInformationException e) { result += (" Source path: " + " INFORMATION IS ABSENT"); } return result; } // seach class file for given class and create copy of this class file in // 'testWorkDir' directory protected File createLocalClassfileCopy(String className) throws IOException { int index = className.lastIndexOf("."); String path; if (index < 0) path = ""; else path = className.substring(0, index).replace(".", "/"); File dirs = new File(testWorkDir + "/" + path); dirs.mkdirs(); File oldFile = null; { java.nio.file.Path tmp = ClassFileFinder.findClassFile(className, classpath); oldFile = tmp == null ? null : tmp.toFile(); } File newFile = copyFile(oldFile, testWorkDir + "/" + className.replace(".", "/") + ".class"); return newFile; } // create class file with multiple strata protected void savePathcedClassFile(String className, SmapGenerator smapGenerator, String smapFileName) { File patchedClassFile = null; try { patchedClassFile = createLocalClassfileCopy(className); } catch (IOException e) { e.printStackTrace(log.getOutStream()); throw new TestBug("Unexpected IO exception: " + e); } smapFileName = testWorkDir + "/" + smapFileName; smapGenerator.setOutputFileName(smapFileName); File smapFile = null; try { smapFile = smapGenerator.saveToFile(smapFileName); } catch (IOException e) { e.printStackTrace(log.getOutStream()); throw new TestBug("Unexpected IO exception: " + e); } log.display("Add for class " + className + " following SDE: "); log.display(smapGenerator.getString()); try { InstallSDE.install(patchedClassFile, smapFile, false); } catch (IOException e) { e.printStackTrace(log.getOutStream()); throw new TestBug("Unexpected IO exception: " + e); } } // common for SDE tests debuggee name protected String debuggeeClassName() { if (classpath == null) { throw new TestBug("Debugger requires 'testClassPath' parameter"); } return SDEDebuggee.class.getName() + " -testClassPath " + testWorkDir; } // parses common for all SDE - tests parameters protected String[] doInit(String args[], PrintStream out) { args = super.doInit(args, out); if (classpath == null) { throw new TestBug("Debugger requires 'testClassPath' parameter"); } if (testWorkDir == null) { throw new TestBug("Debugger requires 'testWorkDir' parameter"); } return args; } // single input line is mapped to the single output line, test stratum has // single source protected Map prepareDefaultPatchedClassFile_Type1(String className, int testStratumCount, boolean setJavaStratumDefault) { /* * "Java" "TestStratum" * * * 32 --> 1000, source1 * 33 --> 1001, source1 * ... * ... * 39 --> 1007, source1 * * sde_testMethod1 * * 43 --> 1100, source1 * 44 --> 1101, source1 * ... * ... * 50 --> 1107, source1 * * sde_testMethod1 * 54 --> 1200, source1 * 55 --> 1201, source1 * ... * ... * 61 --> 1207, source1 */ Map testStratumData = new TreeMap(); String smapFileName = "TestSMAP.smap"; SmapGenerator smapGenerator = new SmapGenerator(); for (int i = 0; i < testStratumCount; i++) { String stratumName = testStratumName + (i + 1); LocationsData locationsData = new LocationsData(stratumName); String sourceName = testStratumSourceName + (i + 1); String sourcePath = testStratumSourcePath + (i + 1); locationsData.paths.add(sourcePath); SmapStratum smapStratum = new SmapStratum(stratumName); List sourceLocations = new ArrayList(); int baseLineNumber = 1000 * (i + 1); for (int j = 0; j < 8; j++) { sourceLocations.add(new DebugLocation(sourceName, sourcePath, "", baseLineNumber + j, INIT_LINE + j)); sourceLocations.add(new DebugLocation(sourceName, sourcePath, "sde_testMethod1", baseLineNumber + 100 + j, METHOD1_LINE + j)); sourceLocations.add(new DebugLocation(sourceName, sourcePath, "sde_testMethod2", baseLineNumber + 200 + j, METHOD2_LINE + j)); } locationsData.sourceLocations.put(sourceName, sourceLocations); locationsData.allLocations.addAll(sourceLocations); testStratumData.put(stratumName, locationsData); smapStratum.addFile(sourceName, sourcePath); for (DebugLocation debugLocation : sourceLocations) { smapStratum.addLineData(debugLocation.inputLine, sourceName, 1, debugLocation.outputLine, 1); } // if setJavaStratumDefault == false do first test stratum default if (!(setJavaStratumDefault) && (i == 0)) { locationsData.isDefault = true; smapGenerator.addStratum(smapStratum, true); } else smapGenerator.addStratum(smapStratum, false); } savePathcedClassFile(className, smapGenerator, smapFileName); addJavaLocations(testStratumData, setJavaStratumDefault); return testStratumData; } // single input line is mapped to the single output line, test stratum has 3 // sources protected Map prepareDefaultPatchedClassFile_Type2(String className, int testStratumCount) { /* * "Java" "TestStratum" * * * 32 --> 1000, source1, path1 * 33 --> 1001, source2, path2 * 34 --> 1002, source3, path3 * ... * ... * * sde_testMethod1 * 43 --> 1100, source1, path1 * 44 --> 1101, source2, path2 * 45 --> 1102, source3, path3 * ... * ... * * sde_testMethod2 * 54 --> 1200, source1, path1 * 55 --> 1201, source2, path2 * 56 --> 1207, source3, path3 * ... * ... */ Map testStratumData = new TreeMap(); String smapFileName = "TestSMAP.smap"; SmapGenerator smapGenerator = new SmapGenerator(); for (int i = 0; i < testStratumCount; i++) { String stratumName = testStratumName + (i + 1); SmapStratum smapStratum = new SmapStratum(stratumName); LocationsData locationsData = new LocationsData(stratumName); String sourceName1 = testStratumSourceName + (i + 1) + "_1"; String sourcePath1 = testStratumSourcePath + (i + 1) + "_1"; locationsData.paths.add(sourcePath1); smapStratum.addFile(sourceName1, sourcePath1); String sourceName2 = testStratumSourceName + (i + 1) + "_2"; String sourcePath2 = testStratumSourcePath + (i + 1) + "_2"; locationsData.paths.add(sourcePath2); smapStratum.addFile(sourceName2, sourcePath2); String sourceName3 = testStratumSourceName + (i + 1) + "_3"; String sourcePath3 = testStratumSourcePath + (i + 1) + "_3"; locationsData.paths.add(sourcePath3); smapStratum.addFile(sourceName3, sourcePath3); List source1Locations = new ArrayList(); List source2Locations = new ArrayList(); List source3Locations = new ArrayList(); for (int j = 0; j < 8; j++) { if (j % 3 == 0) { source1Locations.add(new DebugLocation(sourceName1, sourcePath1, "", 1000 + j, INIT_LINE + j)); source1Locations.add(new DebugLocation(sourceName1, sourcePath1, "sde_testMethod1", 1101 + j, METHOD1_LINE + j)); source1Locations.add(new DebugLocation(sourceName1, sourcePath1, "sde_testMethod2", 1201 + j, METHOD2_LINE + j)); } else if (j % 3 == 1) { source2Locations.add(new DebugLocation(sourceName2, sourcePath2, "", 1000 + j, INIT_LINE + j)); source2Locations.add(new DebugLocation(sourceName2, sourcePath2, "sde_testMethod1", 1101 + j, METHOD1_LINE + j)); source2Locations.add(new DebugLocation(sourceName2, sourcePath2, "sde_testMethod2", 1201 + j, METHOD2_LINE + j)); } else { source3Locations.add(new DebugLocation(sourceName3, sourcePath3, "", 1000 + j, INIT_LINE + j)); source3Locations.add(new DebugLocation(sourceName3, sourcePath3, "sde_testMethod1", 1101 + j, METHOD1_LINE + j)); source3Locations.add(new DebugLocation(sourceName3, sourcePath3, "sde_testMethod2", 1201 + j, METHOD2_LINE + j)); } } locationsData.sourceLocations.put(sourceName1, source1Locations); locationsData.sourceLocations.put(sourceName2, source2Locations); locationsData.sourceLocations.put(sourceName3, source3Locations); locationsData.allLocations.addAll(source1Locations); locationsData.allLocations.addAll(source2Locations); locationsData.allLocations.addAll(source3Locations); for (DebugLocation debugLocation : locationsData.allLocations) { smapStratum.addLineData( debugLocation.inputLine, debugLocation.sourceName, 1, debugLocation.outputLine, 1); } smapGenerator.addStratum(smapStratum, false); testStratumData.put(stratumName, locationsData); } savePathcedClassFile(className, smapGenerator, smapFileName); addJavaLocations(testStratumData, true); return testStratumData; } // single input line is mapped to two output lines protected Map prepareDefaultPatchedClassFile_Type3(String className, int testStratumCount, boolean setJavaStratumDefault) { /* * "Java" "TestStratum" * * * 32 --> 1001, source1 * 34 --> 1002, source1 * 36 --> 1003, source1 * 38 --> 1004, source1 * * sde_testMethod1 * 43 --> 1101, source1 * 45 --> 1102, source1 * 47 --> 1103, source1 * 49 --> 1104, source1 * * sde_testMethod2 * 54 --> 1201, source1 * 56 --> 1202, source1 * 58 --> 1203, source1 * 60 --> 1204, source1 */ Map testStratumData = new TreeMap(); String smapFileName = "TestSMAP.smap"; SmapGenerator smapGenerator = new SmapGenerator(); for (int i = 0; i < testStratumCount; i++) { String stratumName = testStratumName + (i + 1); LocationsData locationsData = new LocationsData(stratumName); String sourceName = testStratumSourceName + (i + 1); String sourcePath = testStratumSourcePath + (i + 1); locationsData.paths.add(sourcePath); SmapStratum smapStratum = new SmapStratum(stratumName); List sourceLocations = new ArrayList(); int baseLineNumber = 1000 * (i + 1); for (int j = 0; j < 4; j++) { sourceLocations.add(new DebugLocation(sourceName, sourcePath, "", baseLineNumber + j, INIT_LINE + j * 2)); sourceLocations.add(new DebugLocation(sourceName, sourcePath, "sde_testMethod1", baseLineNumber + 100 + j, METHOD1_LINE + j * 2)); sourceLocations.add(new DebugLocation(sourceName, sourcePath, "sde_testMethod2", baseLineNumber + 200 + j, METHOD2_LINE + j * 2)); } locationsData.allLocations.addAll(sourceLocations); locationsData.sourceLocations.put(sourceName, sourceLocations); testStratumData.put(stratumName, locationsData); smapStratum.addFile(sourceName, sourcePath); for (DebugLocation debugLocation : locationsData.allLocations) { smapStratum.addLineData(debugLocation.inputLine, sourceName, 1, debugLocation.outputLine, 1); } // if setJavaStratumDefault == false do first stratum default if (!setJavaStratumDefault && (i == 0)) { locationsData.isDefault = true; smapGenerator.addStratum(smapStratum, true); } else smapGenerator.addStratum(smapStratum, false); } savePathcedClassFile(className, smapGenerator, smapFileName); addJavaLocations(testStratumData, setJavaStratumDefault); return testStratumData; } // 3 different test stratums define disjoint locations sets protected Map prepareDefaultPatchedClassFile_Type4(String className) { /* * "Java" "TestStratum1" "TestStratum2" "TestStratum3" * * * 32 --> 1000 * ... * ... * 39 --> 1007 * * sde_testMethod1 * 43 --> 1100 * ... * ... * 50 --> 1107 * * sde_testMethod2 * 54 --> 1200 * ... * ... * 61 --> 1207 */ Map testStratumData = new TreeMap(); String smapFileName = "TestSMAP.smap"; SmapGenerator smapGenerator = new SmapGenerator(); String stratumName = testStratumName + "1"; LocationsData locationsData = new LocationsData(stratumName); List sourceLocations = new ArrayList(); String methodName = ""; for (int i = 0; i < 8; i++) { sourceLocations.add(new DebugLocation( testStratumSourceName, testStratumSourcePath, methodName, 1000 + i, INIT_LINE + i)); } locationsData.allLocations.addAll(sourceLocations); locationsData.sourceLocations.put(testStratumSourceName, sourceLocations); testStratumData.put(stratumName, locationsData); stratumName = testStratumName + "2"; locationsData = new LocationsData(stratumName); sourceLocations = new ArrayList(); methodName = "sde_testMethod1"; for (int i = 0; i < 8; i++) { sourceLocations.add(new DebugLocation( testStratumSourceName, testStratumSourcePath, methodName, 1100 + i, METHOD1_LINE + i)); } locationsData.allLocations.addAll(sourceLocations); locationsData.sourceLocations.put(testStratumSourceName, sourceLocations); testStratumData.put(stratumName, locationsData); stratumName = testStratumName + "3"; locationsData = new LocationsData(stratumName); sourceLocations = new ArrayList(); methodName = "sde_testMethod2"; for (int i = 0; i < 8; i++) { sourceLocations.add(new DebugLocation(testStratumSourceName, testStratumSourcePath, methodName, 1200 + i, METHOD2_LINE + i)); } locationsData.allLocations.addAll(sourceLocations); locationsData.sourceLocations.put(testStratumSourceName, sourceLocations); testStratumData.put(stratumName, locationsData); for (String stratum : testStratumData.keySet()) { SmapStratum smapStratum = new SmapStratum(stratum); smapStratum.addFile(testStratumSourceName, testStratumSourcePath); for (DebugLocation debugLocation : testStratumData.get(stratum).allLocations) smapStratum.addLineData( debugLocation.inputLine, debugLocation.sourceName, 1, debugLocation.outputLine, 1); smapGenerator.addStratum(smapStratum, false); } savePathcedClassFile(className, smapGenerator, smapFileName); return testStratumData; } // single input line is mapped to the single output line, test stratum has 3 // sources, // lines in each method has same numbers, each method has locations in 3 // sources protected Map prepareDefaultPatchedClassFile_Type5(String className, int testStratumCount) { /* * "Java" "TestStratum" * * * 32 --> 1000, source1, path1 * 33 --> 1000, source2, path2 * 34 --> 1000, source3, path3 * ... * ... * * sde_testMethod1 * 43 --> 1100, source1, path1 * 44 --> 1100, source2, path2 * 45 --> 1100, source3, path3 * ... * ... * * sde_testMethod2 * 54 --> 1200, source1, path1 * 55 --> 1200, source2, path2 * 56 --> 1200, source3, path3 * ... * ... */ Map testStratumData = new TreeMap(); String smapFileName = "TestSMAP.smap"; SmapGenerator smapGenerator = new SmapGenerator(); for (int i = 0; i < testStratumCount; i++) { String stratumName = testStratumName + (i + 1); SmapStratum smapStratum = new SmapStratum(stratumName); LocationsData locationsData = new LocationsData(stratumName); String sourceName1 = testStratumSourceName + (i + 1) + "_1"; String sourcePath1 = testStratumSourcePath + (i + 1) + "_1"; locationsData.paths.add(sourcePath1); smapStratum.addFile(sourceName1, sourcePath1); String sourceName2 = testStratumSourceName + (i + 1) + "_2"; String sourcePath2 = testStratumSourcePath + (i + 1) + "_2"; locationsData.paths.add(sourcePath2); smapStratum.addFile(sourceName2, sourcePath2); String sourceName3 = testStratumSourceName + (i + 1) + "_3"; String sourcePath3 = testStratumSourcePath + (i + 1) + "_3"; locationsData.paths.add(sourcePath3); smapStratum.addFile(sourceName3, sourcePath3); List source1Locations = new ArrayList(); List source2Locations = new ArrayList(); List source3Locations = new ArrayList(); for (int j = 0; j < 8; j++) { if (j % 3 == 0) { source1Locations.add(new DebugLocation(sourceName1, sourcePath1, "", 1000, INIT_LINE + j)); source1Locations.add(new DebugLocation(sourceName1, sourcePath1, "sde_testMethod1", 1100, METHOD1_LINE + j)); source1Locations.add(new DebugLocation(sourceName1, sourcePath1, "sde_testMethod2", 1200, METHOD2_LINE + j)); } else if (j % 3 == 1) { source2Locations.add(new DebugLocation(sourceName2, sourcePath2, "", 1000, INIT_LINE + j)); source2Locations.add(new DebugLocation(sourceName2, sourcePath2, "sde_testMethod1", 1100, METHOD1_LINE + j)); source2Locations.add(new DebugLocation(sourceName2, sourcePath2, "sde_testMethod2", 1200, METHOD2_LINE + j)); } else { source3Locations.add(new DebugLocation(sourceName3, sourcePath3, "", 1000, INIT_LINE + j)); source3Locations.add(new DebugLocation(sourceName3, sourcePath3, "sde_testMethod1", 1100, METHOD1_LINE + j)); source3Locations.add(new DebugLocation(sourceName3, sourcePath3, "sde_testMethod2", 1200, METHOD2_LINE + j)); } } locationsData.sourceLocations.put(sourceName1, source1Locations); locationsData.sourceLocations.put(sourceName2, source2Locations); locationsData.sourceLocations.put(sourceName3, source3Locations); locationsData.allLocations.addAll(source1Locations); locationsData.allLocations.addAll(source2Locations); locationsData.allLocations.addAll(source3Locations); for (DebugLocation debugLocation : locationsData.allLocations) { smapStratum.addLineData( debugLocation.inputLine, debugLocation.sourceName, 1, debugLocation.outputLine, 1); } smapGenerator.addStratum(smapStratum, false); testStratumData.put(stratumName, locationsData); } savePathcedClassFile(className, smapGenerator, smapFileName); return testStratumData; } public static File copyFile(File srcFile, String newFileName) throws IOException { FileChannel inChannel = new FileInputStream(srcFile).getChannel(); File newFile = new File(newFileName); newFile.createNewFile(); FileChannel outChannel = new FileOutputStream(newFile).getChannel(); outChannel.transferFrom(inChannel, 0, inChannel.size()); outChannel.close(); inChannel.close(); return newFile; } // find all locations of method with given name // (used to check result of 'Method.allLineLocations()') static protected List locationsOfMethod(List debugLocations, String methodName) { List result = new ArrayList(); for (DebugLocation debugLocation : debugLocations) { if (debugLocation.methodName.equals(methodName)) result.add(debugLocation); } return result; } // find all locations for given line and source name // (used to check result of 'Method.locationsOfLine()' and // 'ReferenceType.locationsOfLine()') static protected List locationsOfLine(List debugLocations, String sourceName, int lineNumber) { List result = new ArrayList(); for (DebugLocation debugLocation : debugLocations) { if (debugLocation.isConform(sourceName, lineNumber)) result.add(debugLocation); } return result; } // find locations unique by line number and source name // (used in 'check_ReferenceType_locationsOfLine' and // 'check_Method_locationsOfLine' to find all line numbers available for // ReferenceType or Method) static protected Set allUniqueLocations(List debugLocations) { Set result = new TreeSet(); for (DebugLocation debugLocation : debugLocations) { if (!result.contains(debugLocation)) { result.add(debugLocation); } } return result; } // check is list of Locations contains only expected locations protected void compareLocations(List locations, List expectedLocations, String stratum) { boolean success = true; List tempLocations = new LinkedList(locations); List tempExpectedLocations = new LinkedList(expectedLocations); for(Iterator locationsIterator = tempLocations.iterator(); locationsIterator.hasNext();) { boolean isExpected = false; Location location = locationsIterator.next(); for(Iterator expectedLocationsIterator = tempExpectedLocations.iterator(); expectedLocationsIterator.hasNext();) { DebugLocation expectedLocation = expectedLocationsIterator.next(); if (expectedLocation.compare(location, stratum)) { isExpected = true; locationsIterator.remove(); expectedLocationsIterator.remove(); break; } } if (!isExpected) { success = false; log.complain("Location " + location + " were not found in expected locations"); } } if (tempLocations.size() != 0) { success = false; setSuccess(false); log.complain("Not all locations were found in expected"); } if (tempExpectedLocations.size() != 0) { success = false; setSuccess(false); log.complain("Following expected locations were not found in received"); for (DebugLocation expectedLocation : tempExpectedLocations) { log.complain(expectedLocation.toString()); } } if (!success) { setSuccess(false); log.complain("Expected and actual locations differ"); log.complain("Actual locations: "); for (Location location : locations) { log.complain(locationToString(location, stratum)); } log.complain("Expected locations: "); for (DebugLocation expectedLocation : expectedLocations) { log.complain(expectedLocation.toString()); } } } // test all SDE related methods of ReferenceType protected void checkReferenceType(String stratum, ReferenceType referenceType, List expectedSourceNames, List expectedSourcePaths, List expectedLocations) { log.display("Check sourceNames"); check_ReferenceType_sourceNames(referenceType, stratum, expectedSourceNames); log.display("Check sourcePaths"); check_ReferenceType_sourcePaths(referenceType, stratum, expectedSourcePaths); log.display("Check allLocations"); check_ReferenceType_allLineLocations(referenceType, stratum, expectedLocations); log.display("Check locationsOfLine"); check_ReferenceType_locationsOfLine(referenceType, stratum, false, expectedLocations); for (Method method : referenceType.methods()) { List expectedLocationsOfMethod = locationsOfMethod(expectedLocations, method.name()); log.display("Check allLineLocations for method '" + method.name() + "'"); check_Method_allLineLocations(method, stratum, expectedLocationsOfMethod); log.display("Check locationsOfLine for method '" + method.name() + "'"); check_Method_locationsOfLine(method, stratum, false, expectedLocationsOfMethod); } } // check is 'ReferenceType.sourceNames' returns only expected sources protected void check_ReferenceType_sourceNames(ReferenceType referenceType, String stratum, List expectedSourceNames) { try { if (stratum == null) { String sourceName = referenceType.sourceName(); String expectedSourceName = expectedSourceNames.get(0); if (!sourceName.equals(expectedSourceName)) { setSuccess(false); log.complain("Unexpected result of ReferenceType.sourceName(): " + sourceName + ", expected is " + expectedSourceName); } } else { boolean success = true; List sourceNames = referenceType.sourceNames(stratum); if (!expectedSourceNames.containsAll(sourceNames)) { success = false; log.complain("ReferenceType.sourceNames() returns unexpected names"); } if (!sourceNames.containsAll(expectedSourceNames)) { success = false; log.complain("Not all expected source names was returned by ReferenceType.sourceNames()"); } if (!success) { log.complain("Expected source names:"); for (String name : expectedSourceNames) log.complain(name); log.complain("Actual source names:"); for (String name : sourceNames) log.complain(name); } } } catch (AbsentInformationException e) { setSuccess(false); log.complain("Unexpected exception: " + e); e.printStackTrace(log.getOutStream()); } } // check is 'ReferenceType.sourcePaths' returns only expected paths protected void check_ReferenceType_sourcePaths(ReferenceType referenceType, String stratum, List expectedSourcePaths) { try { boolean success = true; List sourcePaths = referenceType.sourcePaths(stratum); if (!expectedSourcePaths.containsAll(sourcePaths)) { success = false; log.complain("ReferenceType.sourcePaths() returns unexpected paths"); } if (!sourcePaths.containsAll(expectedSourcePaths)) { success = false; log.complain("Not all expected paths was returned by ReferenceType.sourcePaths()"); } if (!success) { log.complain("Expected paths:"); for (String path : expectedSourcePaths) log.complain(path); log.complain("Actual paths:"); for (String path : sourcePaths) log.complain(path); } } catch (AbsentInformationException e) { setSuccess(false); log.complain("Unexpected exception: " + e); e.printStackTrace(log.getOutStream()); } } // check that method 'ReferenceType.allLineLocations' returns only expected // locations protected void check_ReferenceType_allLineLocations(ReferenceType referenceType, String stratum, List expectedLocations) { try { List locations = referenceType.allLineLocations(); compareLocations(locations, expectedLocations, stratum); } catch (AbsentInformationException e) { setSuccess(false); log.complain("Unexpected exception: " + e); e.printStackTrace(log.getOutStream()); } } // check that method 'Method.allLineLocations' returns only expected // locations protected void check_Method_allLineLocations(Method method, String stratum, List expectedLocationsOfMethod) { try { List methodAllLineLocations = method.allLineLocations(); compareLocations(methodAllLineLocations, expectedLocationsOfMethod, stratum); } catch (AbsentInformationException e) { setSuccess(false); log.complain("Unexpected exception: " + e); e.printStackTrace(log.getOutStream()); } } // for each line available for method check result of // 'Method.locationsOfLine' protected void check_Method_locationsOfLine(Method method, String stratum, boolean allSources, List expectedLocationsOfMethod) { try { for (DebugLocation uniqueLocation : allUniqueLocations(expectedLocationsOfMethod)) { String sourceName = allSources ? null : uniqueLocation.sourceName; List expectedLocationsOfLine = locationsOfLine( expectedLocationsOfMethod, sourceName, uniqueLocation.inputLine); List locationsOfLine = (stratum == null) ? method.locationsOfLine(uniqueLocation.inputLine) : method.locationsOfLine(stratum, sourceName, uniqueLocation.inputLine); compareLocations(locationsOfLine, expectedLocationsOfLine, stratum); } } catch (AbsentInformationException e) { setSuccess(false); log.complain("Unexpected exception: " + e); e.printStackTrace(log.getOutStream()); } } // for each line available for ReferenceType check result of // 'ReferenceType.locationsOfLine' protected void check_ReferenceType_locationsOfLine(ReferenceType referenceType, String stratum, boolean allSources, List expectedLocations) { try { for (DebugLocation uniqueLocation : allUniqueLocations(expectedLocations)) { String sourceName = allSources ? null : uniqueLocation.sourceName; List expectedLocationsOfLine = locationsOfLine( expectedLocations, sourceName, uniqueLocation.inputLine); List locations = (stratum == null) ? referenceType.locationsOfLine(uniqueLocation.inputLine) : referenceType.locationsOfLine(stratum, sourceName, uniqueLocation.inputLine); compareLocations(locations, expectedLocationsOfLine, stratum); } } catch (AbsentInformationException e) { setSuccess(false); log.complain("Unexpected exception: " + e); e.printStackTrace(log.getOutStream()); } } // check that method 'ReferenceType.availableStrata' returns only expected // stratums protected void check_ReferenceType_availableStrata(ReferenceType referenceType, List expectedStrata) { boolean success = true; List strata = referenceType.availableStrata(); if (!expectedStrata.containsAll(strata)) { success = false; log.complain("ReferenceType.availableStrata() returns unexpected values"); } if (!strata.containsAll(expectedStrata)) { success = false; log.complain("Not all expected stratums was returned by ReferenceType.availableStrata()"); } if (!success) { log.complain("Expected stratums:"); for (String name : expectedStrata) log.complain(name); log.complain("Actual stratums:"); for (String name : strata) log.complain(name); } } }