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 nsk.share.jdi.sde; 24 25 import java.io.*; 26 import java.nio.channels.FileChannel; 27 import java.util.*; 28 import com.sun.jdi.*; 29 import com.sun.jdi.event.BreakpointEvent; 30 import com.sun.jdi.event.Event; 31 import com.sun.jdi.event.StepEvent; 32 import nsk.share.ClassFileFinder; 33 import nsk.share.TestBug; 34 import nsk.share.jdi.EventHandler; 35 import nsk.share.jdi.TestDebuggerType2; 36 37 /* 38 * Class is used as base debugger for SDE tests. 39 * 40 * This class contains several methods called 'prepareDefaultPatchedClassFile_TypeXXX' which create 41 * class file with added SourceDebugExtension attribute and return debug information about created file. 42 * (this methods was moved in SDEDebugger class if similar generated class files were used in 2 or more tests) 43 * 44 * 45 */ 46 public class SDEDebugger extends TestDebuggerType2 { 47 protected static final int INIT_LINE = 32; // n.s.j.sde.TestClass1::<init> 48 protected static final int METHOD1_LINE = 43; // n.s.j.sde.TestClass1::sde_testMethod1 49 protected static final int METHOD2_LINE = 54; // n.s.j.sde.TestClass1::sde_testMethod2 50 public static String javaStratumName = "Java"; 51 52 // Set debug data for "Java" stratum for TestClass1 53 public static List<DebugLocation> javaStratumLocations_TestClass1 = new ArrayList<DebugLocation>(); 54 55 public static String javaSourceName_TestClass1 = "TestClass1.java"; 56 57 public static String javaSourcePath_TestClass1 = "nsk" + File.separator + "share" + File.separator + "jdi" 58 + File.separator + "sde" + File.separator + "TestClass1.java"; 59 60 static { 61 for (int i = 0; i < 8; i++) { javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, R, INIT_LINE + i, INIT_LINE + i))62 javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, 63 "<init>", INIT_LINE + i, INIT_LINE + i)); javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, R, METHOD1_LINE + i, METHOD1_LINE + i))64 javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, 65 "sde_testMethod1", METHOD1_LINE + i, METHOD1_LINE + i)); javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, R, METHOD2_LINE + i, METHOD2_LINE + i))66 javaStratumLocations_TestClass1.add(new DebugLocation(javaSourceName_TestClass1, javaSourcePath_TestClass1, 67 "sde_testMethod2", METHOD2_LINE + i, METHOD2_LINE + i)); 68 } 69 } 70 71 // insert debug information about "Java" stratum in the given Map<String, 72 // LocationsData> addJavaLocations(Map<String, LocationsData> testStratumData, boolean setJavaStratumDefault)73 static protected void addJavaLocations(Map<String, LocationsData> testStratumData, boolean setJavaStratumDefault) { 74 LocationsData locationsData = new LocationsData(javaStratumName); 75 76 if (setJavaStratumDefault) 77 locationsData.isDefault = true; 78 79 locationsData.paths.add(javaSourcePath_TestClass1); 80 locationsData.allLocations.addAll(javaStratumLocations_TestClass1); 81 locationsData.sourceLocations.put(javaSourceName_TestClass1, javaStratumLocations_TestClass1); 82 83 testStratumData.put(javaStratumName, locationsData); 84 85 } 86 87 // common base names for test stratum, stratum source name and stratum 88 // source path 89 public static final String testStratumName = "TestStratum"; 90 91 public static final String testStratumSourceName = "testSource"; 92 93 public static final String testStratumSourcePath = "testSourcePath"; 94 95 // Event listener thread which saves all received StepEvents 96 public class StepEventListener extends EventHandler.EventListener { 97 // is BreakpointEvent was received (debuggee should stop at breakpoint 98 // after StepEvents generation) 99 private volatile boolean breakpointEventReceived; 100 101 private List<Location> stepLocations = new ArrayList<Location>(); 102 stepLocations()103 public List<Location> stepLocations() { 104 return stepLocations; 105 } 106 clearLocations()107 public void clearLocations() { 108 stepLocations.clear(); 109 } 110 eventReceived(Event event)111 public boolean eventReceived(Event event) { 112 if (event instanceof StepEvent) { 113 StepEvent stepEvent = (StepEvent) event; 114 115 stepLocations.add(stepEvent.location()); 116 117 vm.resume(); 118 119 return true; 120 } 121 // debuggee should stop after event generation 122 else if (event instanceof BreakpointEvent) { 123 breakpointEventReceived = true; 124 vm.resume(); 125 126 return true; 127 } 128 129 return false; 130 } 131 waitBreakpointEvent()132 public void waitBreakpointEvent() { 133 while (!breakpointEventReceived) 134 Thread.yield(); 135 } 136 } 137 138 // debug information about location (implements Comparable to make possible 139 // using DebugLocation with java.util.Set) 140 public static class DebugLocation implements Comparable<DebugLocation> { DebugLocation(String sourceName, String sourcePath, String methodName, int inputLine, int outputLine)141 public DebugLocation(String sourceName, String sourcePath, String methodName, int inputLine, int outputLine) { 142 this.sourceName = sourceName; 143 this.sourcePath = sourcePath; 144 this.inputLine = inputLine; 145 this.outputLine = outputLine; 146 this.methodName = methodName; 147 } 148 149 public String sourceName; 150 151 public String sourcePath; 152 153 public String methodName; 154 155 public int inputLine; 156 157 public int outputLine; 158 toString()159 public String toString() { 160 return "Line number: " + inputLine + " SourceName: " + sourceName + " SourcePath: " + sourcePath; 161 } 162 163 // compare DebugLocation with com.sun.jdi.Location compare(Location location, String stratum)164 public boolean compare(Location location, String stratum) { 165 try { 166 if (stratum == null) { 167 return (location.lineNumber() == inputLine) && location.sourceName().equals(sourceName) 168 && location.sourcePath().equals(sourcePath); 169 } else { 170 return (location.lineNumber(stratum) == inputLine) 171 && location.sourceName(stratum).equals(sourceName) 172 && location.sourcePath(stratum).equals(sourcePath); 173 } 174 } catch (AbsentInformationException e) { 175 return false; 176 } 177 } 178 179 // used to find locations for given line isConform(String sourceName, int lineNumber)180 public boolean isConform(String sourceName, int lineNumber) { 181 boolean sourceConform = (sourceName == null ? true : this.sourceName.equals(sourceName)); 182 183 return sourceConform && (this.inputLine == lineNumber); 184 } 185 186 // implements this method to make possible using DebugLocation with java.util.Set compareTo(DebugLocation location)187 public int compareTo(DebugLocation location) { 188 return (this.sourceName.equals(location.sourceName) && this.inputLine == location.inputLine) ? 0 : 1; 189 } 190 } 191 192 // Class contains debug information about sources, paths, locations 193 // available for class 194 public static class LocationsData { LocationsData(String stratumName)195 public LocationsData(String stratumName) { 196 this.stratumName = stratumName; 197 } 198 sourceNames()199 public List<String> sourceNames() { 200 List<String> sourceNames = new ArrayList<String>(); 201 sourceNames.addAll(sourceLocations.keySet()); 202 203 return sourceNames; 204 } 205 206 public String stratumName; 207 208 // is stratum default for ReferenceType 209 public boolean isDefault; 210 211 // locations for source files 212 public Map<String, List<DebugLocation>> sourceLocations = new TreeMap<String, List<DebugLocation>>(); 213 214 // all locations for stratum 215 public List<DebugLocation> allLocations = new ArrayList<DebugLocation>(); 216 217 // all paths for stratum 218 public List<String> paths = new ArrayList<String>(); 219 } 220 locationToString(Location location, String stratum)221 static protected String locationToString(Location location, String stratum) { 222 String result; 223 224 result = "Line number: " + (stratum == null ? location.lineNumber() : location.lineNumber(stratum)); 225 226 try { 227 result += (" Source name: " + (stratum == null ? location.sourceName() : location.sourceName(stratum))); 228 } catch (AbsentInformationException e) { 229 result += (" Source name: " + " INFORMATION IS ABSENT"); 230 } 231 232 try { 233 result += (" Source path: " + (stratum == null ? location.sourcePath() : location.sourcePath(stratum))); 234 } catch (AbsentInformationException e) { 235 result += (" Source path: " + " INFORMATION IS ABSENT"); 236 } 237 238 return result; 239 } 240 241 // seach class file for given class and create copy of this class file in 242 // 'testWorkDir' directory createLocalClassfileCopy(String className)243 protected File createLocalClassfileCopy(String className) throws IOException { 244 int index = className.lastIndexOf("."); 245 246 String path; 247 248 if (index < 0) 249 path = ""; 250 else 251 path = className.substring(0, index).replace(".", "/"); 252 253 File dirs = new File(testWorkDir + "/" + path); 254 dirs.mkdirs(); 255 256 File oldFile = null; 257 { 258 java.nio.file.Path tmp = ClassFileFinder.findClassFile(className, classpath); 259 oldFile = tmp == null ? null : tmp.toFile(); 260 } 261 File newFile = copyFile(oldFile, 262 testWorkDir + "/" + className.replace(".", "/") + ".class"); 263 264 return newFile; 265 } 266 267 // create class file with multiple strata savePathcedClassFile(String className, SmapGenerator smapGenerator, String smapFileName)268 protected void savePathcedClassFile(String className, SmapGenerator smapGenerator, String smapFileName) { 269 File patchedClassFile = null; 270 271 try { 272 patchedClassFile = createLocalClassfileCopy(className); 273 } catch (IOException e) { 274 e.printStackTrace(log.getOutStream()); 275 throw new TestBug("Unexpected IO exception: " + e); 276 } 277 278 smapFileName = testWorkDir + "/" + smapFileName; 279 smapGenerator.setOutputFileName(smapFileName); 280 281 File smapFile = null; 282 283 try { 284 smapFile = smapGenerator.saveToFile(smapFileName); 285 } catch (IOException e) { 286 e.printStackTrace(log.getOutStream()); 287 throw new TestBug("Unexpected IO exception: " + e); 288 } 289 290 log.display("Add for class " + className + " following SDE: "); 291 log.display(smapGenerator.getString()); 292 293 try { 294 InstallSDE.install(patchedClassFile, smapFile, false); 295 } catch (IOException e) { 296 e.printStackTrace(log.getOutStream()); 297 throw new TestBug("Unexpected IO exception: " + e); 298 } 299 } 300 301 // common for SDE tests debuggee name debuggeeClassName()302 protected String debuggeeClassName() { 303 if (classpath == null) { 304 throw new TestBug("Debugger requires 'testClassPath' parameter"); 305 } 306 307 return SDEDebuggee.class.getName() + " -testClassPath " + testWorkDir; 308 } 309 310 // parses common for all SDE - tests parameters doInit(String args[], PrintStream out)311 protected String[] doInit(String args[], PrintStream out) { 312 args = super.doInit(args, out); 313 314 if (classpath == null) { 315 throw new TestBug("Debugger requires 'testClassPath' parameter"); 316 } 317 if (testWorkDir == null) { 318 throw new TestBug("Debugger requires 'testWorkDir' parameter"); 319 } 320 321 return args; 322 } 323 324 // single input line is mapped to the single output line, test stratum has 325 // single source prepareDefaultPatchedClassFile_Type1(String className, int testStratumCount, boolean setJavaStratumDefault)326 protected Map<String, LocationsData> prepareDefaultPatchedClassFile_Type1(String className, int testStratumCount, 327 boolean setJavaStratumDefault) { 328 /* 329 * "Java" "TestStratum" 330 * 331 * <init> 332 * 32 --> 1000, source1 333 * 33 --> 1001, source1 334 * ... 335 * ... 336 * 39 --> 1007, source1 337 * 338 * sde_testMethod1 339 * 340 * 43 --> 1100, source1 341 * 44 --> 1101, source1 342 * ... 343 * ... 344 * 50 --> 1107, source1 345 * 346 * sde_testMethod1 347 * 54 --> 1200, source1 348 * 55 --> 1201, source1 349 * ... 350 * ... 351 * 61 --> 1207, source1 352 */ 353 354 Map<String, LocationsData> testStratumData = new TreeMap<String, LocationsData>(); 355 356 String smapFileName = "TestSMAP.smap"; 357 SmapGenerator smapGenerator = new SmapGenerator(); 358 359 for (int i = 0; i < testStratumCount; i++) { 360 String stratumName = testStratumName + (i + 1); 361 362 LocationsData locationsData = new LocationsData(stratumName); 363 364 String sourceName = testStratumSourceName + (i + 1); 365 String sourcePath = testStratumSourcePath + (i + 1); 366 367 locationsData.paths.add(sourcePath); 368 369 SmapStratum smapStratum = new SmapStratum(stratumName); 370 371 List<DebugLocation> sourceLocations = new ArrayList<DebugLocation>(); 372 373 int baseLineNumber = 1000 * (i + 1); 374 375 for (int j = 0; j < 8; j++) { 376 sourceLocations.add(new DebugLocation(sourceName, sourcePath, 377 "<init>", baseLineNumber + j, INIT_LINE + j)); 378 sourceLocations.add(new DebugLocation(sourceName, sourcePath, 379 "sde_testMethod1", baseLineNumber + 100 + j, METHOD1_LINE + j)); 380 sourceLocations.add(new DebugLocation(sourceName, sourcePath, 381 "sde_testMethod2", baseLineNumber + 200 + j, METHOD2_LINE + j)); 382 } 383 384 locationsData.sourceLocations.put(sourceName, sourceLocations); 385 locationsData.allLocations.addAll(sourceLocations); 386 387 testStratumData.put(stratumName, locationsData); 388 389 smapStratum.addFile(sourceName, sourcePath); 390 391 for (DebugLocation debugLocation : sourceLocations) { 392 smapStratum.addLineData(debugLocation.inputLine, sourceName, 1, debugLocation.outputLine, 1); 393 } 394 395 // if setJavaStratumDefault == false do first test stratum default 396 if (!(setJavaStratumDefault) && (i == 0)) { 397 locationsData.isDefault = true; 398 smapGenerator.addStratum(smapStratum, true); 399 } else 400 smapGenerator.addStratum(smapStratum, false); 401 } 402 403 savePathcedClassFile(className, smapGenerator, smapFileName); 404 405 addJavaLocations(testStratumData, setJavaStratumDefault); 406 407 return testStratumData; 408 } 409 410 // single input line is mapped to the single output line, test stratum has 3 411 // sources prepareDefaultPatchedClassFile_Type2(String className, int testStratumCount)412 protected Map<String, LocationsData> prepareDefaultPatchedClassFile_Type2(String className, int testStratumCount) { 413 /* 414 * "Java" "TestStratum" 415 * 416 * <init> 417 * 32 --> 1000, source1, path1 418 * 33 --> 1001, source2, path2 419 * 34 --> 1002, source3, path3 420 * ... 421 * ... 422 * 423 * sde_testMethod1 424 * 43 --> 1100, source1, path1 425 * 44 --> 1101, source2, path2 426 * 45 --> 1102, source3, path3 427 * ... 428 * ... 429 * 430 * sde_testMethod2 431 * 54 --> 1200, source1, path1 432 * 55 --> 1201, source2, path2 433 * 56 --> 1207, source3, path3 434 * ... 435 * ... 436 */ 437 438 Map<String, LocationsData> testStratumData = new TreeMap<String, LocationsData>(); 439 440 String smapFileName = "TestSMAP.smap"; 441 SmapGenerator smapGenerator = new SmapGenerator(); 442 443 for (int i = 0; i < testStratumCount; i++) { 444 String stratumName = testStratumName + (i + 1); 445 SmapStratum smapStratum = new SmapStratum(stratumName); 446 447 LocationsData locationsData = new LocationsData(stratumName); 448 449 String sourceName1 = testStratumSourceName + (i + 1) + "_1"; 450 String sourcePath1 = testStratumSourcePath + (i + 1) + "_1"; 451 locationsData.paths.add(sourcePath1); 452 smapStratum.addFile(sourceName1, sourcePath1); 453 454 String sourceName2 = testStratumSourceName + (i + 1) + "_2"; 455 String sourcePath2 = testStratumSourcePath + (i + 1) + "_2"; 456 locationsData.paths.add(sourcePath2); 457 smapStratum.addFile(sourceName2, sourcePath2); 458 459 String sourceName3 = testStratumSourceName + (i + 1) + "_3"; 460 String sourcePath3 = testStratumSourcePath + (i + 1) + "_3"; 461 locationsData.paths.add(sourcePath3); 462 smapStratum.addFile(sourceName3, sourcePath3); 463 464 List<DebugLocation> source1Locations = new ArrayList<DebugLocation>(); 465 List<DebugLocation> source2Locations = new ArrayList<DebugLocation>(); 466 List<DebugLocation> source3Locations = new ArrayList<DebugLocation>(); 467 468 for (int j = 0; j < 8; j++) { 469 if (j % 3 == 0) { 470 source1Locations.add(new DebugLocation(sourceName1, sourcePath1, 471 "<init>", 1000 + j, INIT_LINE + j)); 472 source1Locations.add(new DebugLocation(sourceName1, sourcePath1, 473 "sde_testMethod1", 1101 + j, METHOD1_LINE + j)); 474 source1Locations.add(new DebugLocation(sourceName1, sourcePath1, 475 "sde_testMethod2", 1201 + j, METHOD2_LINE + j)); 476 } else if (j % 3 == 1) { 477 source2Locations.add(new DebugLocation(sourceName2, sourcePath2, 478 "<init>", 1000 + j, INIT_LINE + j)); 479 source2Locations.add(new DebugLocation(sourceName2, sourcePath2, 480 "sde_testMethod1", 1101 + j, METHOD1_LINE + j)); 481 source2Locations.add(new DebugLocation(sourceName2, sourcePath2, 482 "sde_testMethod2", 1201 + j, METHOD2_LINE + j)); 483 } else { 484 source3Locations.add(new DebugLocation(sourceName3, sourcePath3, 485 "<init>", 1000 + j, INIT_LINE + j)); 486 source3Locations.add(new DebugLocation(sourceName3, sourcePath3, 487 "sde_testMethod1", 1101 + j, METHOD1_LINE + j)); 488 source3Locations.add(new DebugLocation(sourceName3, sourcePath3, 489 "sde_testMethod2", 1201 + j, METHOD2_LINE + j)); 490 } 491 } 492 493 locationsData.sourceLocations.put(sourceName1, source1Locations); 494 locationsData.sourceLocations.put(sourceName2, source2Locations); 495 locationsData.sourceLocations.put(sourceName3, source3Locations); 496 497 locationsData.allLocations.addAll(source1Locations); 498 locationsData.allLocations.addAll(source2Locations); 499 locationsData.allLocations.addAll(source3Locations); 500 501 for (DebugLocation debugLocation : locationsData.allLocations) { 502 smapStratum.addLineData( 503 debugLocation.inputLine, 504 debugLocation.sourceName, 505 1, 506 debugLocation.outputLine, 507 1); 508 } 509 510 smapGenerator.addStratum(smapStratum, false); 511 512 testStratumData.put(stratumName, locationsData); 513 } 514 515 savePathcedClassFile(className, smapGenerator, smapFileName); 516 517 addJavaLocations(testStratumData, true); 518 519 return testStratumData; 520 } 521 522 // single input line is mapped to two output lines prepareDefaultPatchedClassFile_Type3(String className, int testStratumCount, boolean setJavaStratumDefault)523 protected Map<String, LocationsData> prepareDefaultPatchedClassFile_Type3(String className, int testStratumCount, 524 boolean setJavaStratumDefault) { 525 /* 526 * "Java" "TestStratum" 527 * 528 * <init> 529 * 32 --> 1001, source1 530 * 34 --> 1002, source1 531 * 36 --> 1003, source1 532 * 38 --> 1004, source1 533 * 534 * sde_testMethod1 535 * 43 --> 1101, source1 536 * 45 --> 1102, source1 537 * 47 --> 1103, source1 538 * 49 --> 1104, source1 539 * 540 * sde_testMethod2 541 * 54 --> 1201, source1 542 * 56 --> 1202, source1 543 * 58 --> 1203, source1 544 * 60 --> 1204, source1 545 */ 546 547 Map<String, LocationsData> testStratumData = new TreeMap<String, LocationsData>(); 548 549 String smapFileName = "TestSMAP.smap"; 550 SmapGenerator smapGenerator = new SmapGenerator(); 551 552 for (int i = 0; i < testStratumCount; i++) { 553 String stratumName = testStratumName + (i + 1); 554 LocationsData locationsData = new LocationsData(stratumName); 555 556 String sourceName = testStratumSourceName + (i + 1); 557 String sourcePath = testStratumSourcePath + (i + 1); 558 locationsData.paths.add(sourcePath); 559 560 SmapStratum smapStratum = new SmapStratum(stratumName); 561 562 List<DebugLocation> sourceLocations = new ArrayList<DebugLocation>(); 563 564 int baseLineNumber = 1000 * (i + 1); 565 566 for (int j = 0; j < 4; j++) { 567 sourceLocations.add(new DebugLocation(sourceName, sourcePath, 568 "<init>", baseLineNumber + j, INIT_LINE + j * 2)); 569 sourceLocations.add(new DebugLocation(sourceName, sourcePath, 570 "sde_testMethod1", baseLineNumber + 100 + j, METHOD1_LINE + j * 2)); 571 sourceLocations.add(new DebugLocation(sourceName, sourcePath, 572 "sde_testMethod2", baseLineNumber + 200 + j, METHOD2_LINE + j * 2)); 573 } 574 575 locationsData.allLocations.addAll(sourceLocations); 576 locationsData.sourceLocations.put(sourceName, sourceLocations); 577 578 testStratumData.put(stratumName, locationsData); 579 580 smapStratum.addFile(sourceName, sourcePath); 581 582 for (DebugLocation debugLocation : locationsData.allLocations) { 583 smapStratum.addLineData(debugLocation.inputLine, sourceName, 1, debugLocation.outputLine, 1); 584 } 585 586 // if setJavaStratumDefault == false do first stratum default 587 if (!setJavaStratumDefault && (i == 0)) { 588 locationsData.isDefault = true; 589 smapGenerator.addStratum(smapStratum, true); 590 } else 591 smapGenerator.addStratum(smapStratum, false); 592 } 593 594 savePathcedClassFile(className, smapGenerator, smapFileName); 595 596 addJavaLocations(testStratumData, setJavaStratumDefault); 597 598 return testStratumData; 599 } 600 601 // 3 different test stratums define disjoint locations sets prepareDefaultPatchedClassFile_Type4(String className)602 protected Map<String, LocationsData> prepareDefaultPatchedClassFile_Type4(String className) { 603 /* 604 * "Java" "TestStratum1" "TestStratum2" "TestStratum3" 605 * 606 * <init> 607 * 32 --> 1000 608 * ... 609 * ... 610 * 39 --> 1007 611 * 612 * sde_testMethod1 613 * 43 --> 1100 614 * ... 615 * ... 616 * 50 --> 1107 617 * 618 * sde_testMethod2 619 * 54 --> 1200 620 * ... 621 * ... 622 * 61 --> 1207 623 */ 624 Map<String, LocationsData> testStratumData = new TreeMap<String, LocationsData>(); 625 626 String smapFileName = "TestSMAP.smap"; 627 628 SmapGenerator smapGenerator = new SmapGenerator(); 629 630 String stratumName = testStratumName + "1"; 631 LocationsData locationsData = new LocationsData(stratumName); 632 List<DebugLocation> sourceLocations = new ArrayList<DebugLocation>(); 633 String methodName = "<init>"; 634 for (int i = 0; i < 8; i++) { 635 sourceLocations.add(new DebugLocation( 636 testStratumSourceName, testStratumSourcePath, methodName, 637 1000 + i, INIT_LINE + i)); 638 } 639 locationsData.allLocations.addAll(sourceLocations); 640 locationsData.sourceLocations.put(testStratumSourceName, sourceLocations); 641 testStratumData.put(stratumName, locationsData); 642 643 stratumName = testStratumName + "2"; 644 locationsData = new LocationsData(stratumName); 645 sourceLocations = new ArrayList<DebugLocation>(); 646 methodName = "sde_testMethod1"; 647 for (int i = 0; i < 8; i++) { 648 sourceLocations.add(new DebugLocation( 649 testStratumSourceName, testStratumSourcePath, methodName, 650 1100 + i, METHOD1_LINE + i)); 651 } 652 locationsData.allLocations.addAll(sourceLocations); 653 locationsData.sourceLocations.put(testStratumSourceName, sourceLocations); 654 testStratumData.put(stratumName, locationsData); 655 656 stratumName = testStratumName + "3"; 657 locationsData = new LocationsData(stratumName); 658 sourceLocations = new ArrayList<DebugLocation>(); 659 methodName = "sde_testMethod2"; 660 for (int i = 0; i < 8; i++) { 661 sourceLocations.add(new DebugLocation(testStratumSourceName, testStratumSourcePath, 662 methodName, 1200 + i, METHOD2_LINE + i)); 663 } 664 locationsData.allLocations.addAll(sourceLocations); 665 locationsData.sourceLocations.put(testStratumSourceName, sourceLocations); 666 testStratumData.put(stratumName, locationsData); 667 668 for (String stratum : testStratumData.keySet()) { 669 SmapStratum smapStratum = new SmapStratum(stratum); 670 smapStratum.addFile(testStratumSourceName, testStratumSourcePath); 671 672 for (DebugLocation debugLocation : testStratumData.get(stratum).allLocations) 673 smapStratum.addLineData( 674 debugLocation.inputLine, 675 debugLocation.sourceName, 676 1, 677 debugLocation.outputLine, 678 1); 679 680 smapGenerator.addStratum(smapStratum, false); 681 } 682 683 savePathcedClassFile(className, smapGenerator, smapFileName); 684 685 return testStratumData; 686 } 687 688 // single input line is mapped to the single output line, test stratum has 3 689 // sources, 690 // lines in each method has same numbers, each method has locations in 3 691 // sources prepareDefaultPatchedClassFile_Type5(String className, int testStratumCount)692 protected Map<String, LocationsData> prepareDefaultPatchedClassFile_Type5(String className, int testStratumCount) { 693 /* 694 * "Java" "TestStratum" 695 * 696 * <init> 697 * 32 --> 1000, source1, path1 698 * 33 --> 1000, source2, path2 699 * 34 --> 1000, source3, path3 700 * ... 701 * ... 702 * 703 * sde_testMethod1 704 * 43 --> 1100, source1, path1 705 * 44 --> 1100, source2, path2 706 * 45 --> 1100, source3, path3 707 * ... 708 * ... 709 * 710 * sde_testMethod2 711 * 54 --> 1200, source1, path1 712 * 55 --> 1200, source2, path2 713 * 56 --> 1200, source3, path3 714 * ... 715 * ... 716 */ 717 718 Map<String, LocationsData> testStratumData = new TreeMap<String, LocationsData>(); 719 720 String smapFileName = "TestSMAP.smap"; 721 SmapGenerator smapGenerator = new SmapGenerator(); 722 723 for (int i = 0; i < testStratumCount; i++) { 724 String stratumName = testStratumName + (i + 1); 725 SmapStratum smapStratum = new SmapStratum(stratumName); 726 727 LocationsData locationsData = new LocationsData(stratumName); 728 729 String sourceName1 = testStratumSourceName + (i + 1) + "_1"; 730 String sourcePath1 = testStratumSourcePath + (i + 1) + "_1"; 731 locationsData.paths.add(sourcePath1); 732 smapStratum.addFile(sourceName1, sourcePath1); 733 734 String sourceName2 = testStratumSourceName + (i + 1) + "_2"; 735 String sourcePath2 = testStratumSourcePath + (i + 1) + "_2"; 736 locationsData.paths.add(sourcePath2); 737 smapStratum.addFile(sourceName2, sourcePath2); 738 739 String sourceName3 = testStratumSourceName + (i + 1) + "_3"; 740 String sourcePath3 = testStratumSourcePath + (i + 1) + "_3"; 741 locationsData.paths.add(sourcePath3); 742 smapStratum.addFile(sourceName3, sourcePath3); 743 744 List<DebugLocation> source1Locations = new ArrayList<DebugLocation>(); 745 List<DebugLocation> source2Locations = new ArrayList<DebugLocation>(); 746 List<DebugLocation> source3Locations = new ArrayList<DebugLocation>(); 747 748 for (int j = 0; j < 8; j++) { 749 if (j % 3 == 0) { 750 source1Locations.add(new DebugLocation(sourceName1, sourcePath1, 751 "<init>", 1000, INIT_LINE + j)); 752 source1Locations.add(new DebugLocation(sourceName1, sourcePath1, 753 "sde_testMethod1", 1100, METHOD1_LINE + j)); 754 source1Locations.add(new DebugLocation(sourceName1, sourcePath1, 755 "sde_testMethod2", 1200, METHOD2_LINE + j)); 756 } else if (j % 3 == 1) { 757 source2Locations.add(new DebugLocation(sourceName2, sourcePath2, 758 "<init>", 1000, INIT_LINE + j)); 759 source2Locations.add(new DebugLocation(sourceName2, sourcePath2, 760 "sde_testMethod1", 1100, METHOD1_LINE + j)); 761 source2Locations.add(new DebugLocation(sourceName2, sourcePath2, 762 "sde_testMethod2", 1200, METHOD2_LINE + j)); 763 } else { 764 source3Locations.add(new DebugLocation(sourceName3, sourcePath3, 765 "<init>", 1000, INIT_LINE + j)); 766 source3Locations.add(new DebugLocation(sourceName3, sourcePath3, 767 "sde_testMethod1", 1100, METHOD1_LINE + j)); 768 source3Locations.add(new DebugLocation(sourceName3, sourcePath3, 769 "sde_testMethod2", 1200, METHOD2_LINE + j)); 770 } 771 } 772 773 locationsData.sourceLocations.put(sourceName1, source1Locations); 774 locationsData.sourceLocations.put(sourceName2, source2Locations); 775 locationsData.sourceLocations.put(sourceName3, source3Locations); 776 777 locationsData.allLocations.addAll(source1Locations); 778 locationsData.allLocations.addAll(source2Locations); 779 locationsData.allLocations.addAll(source3Locations); 780 781 for (DebugLocation debugLocation : locationsData.allLocations) { 782 smapStratum.addLineData( 783 debugLocation.inputLine, 784 debugLocation.sourceName, 785 1, 786 debugLocation.outputLine, 787 1); 788 } 789 790 smapGenerator.addStratum(smapStratum, false); 791 792 testStratumData.put(stratumName, locationsData); 793 } 794 795 savePathcedClassFile(className, smapGenerator, smapFileName); 796 797 return testStratumData; 798 } 799 copyFile(File srcFile, String newFileName)800 public static File copyFile(File srcFile, String newFileName) throws IOException { 801 FileChannel inChannel = new FileInputStream(srcFile).getChannel(); 802 803 File newFile = new File(newFileName); 804 newFile.createNewFile(); 805 FileChannel outChannel = new FileOutputStream(newFile).getChannel(); 806 807 outChannel.transferFrom(inChannel, 0, inChannel.size()); 808 809 outChannel.close(); 810 inChannel.close(); 811 812 return newFile; 813 } 814 815 // find all locations of method with given name 816 // (used to check result of 'Method.allLineLocations()') locationsOfMethod(List<DebugLocation> debugLocations, String methodName)817 static protected List<DebugLocation> locationsOfMethod(List<DebugLocation> debugLocations, String methodName) { 818 List<DebugLocation> result = new ArrayList<DebugLocation>(); 819 820 for (DebugLocation debugLocation : debugLocations) { 821 if (debugLocation.methodName.equals(methodName)) 822 result.add(debugLocation); 823 } 824 825 return result; 826 } 827 828 // find all locations for given line and source name 829 // (used to check result of 'Method.locationsOfLine()' and 830 // 'ReferenceType.locationsOfLine()') locationsOfLine(List<DebugLocation> debugLocations, String sourceName, int lineNumber)831 static protected List<DebugLocation> locationsOfLine(List<DebugLocation> debugLocations, String sourceName, 832 int lineNumber) { 833 List<DebugLocation> result = new ArrayList<DebugLocation>(); 834 835 for (DebugLocation debugLocation : debugLocations) { 836 if (debugLocation.isConform(sourceName, lineNumber)) 837 result.add(debugLocation); 838 } 839 840 return result; 841 } 842 843 // find locations unique by line number and source name 844 // (used in 'check_ReferenceType_locationsOfLine' and 845 // 'check_Method_locationsOfLine' to find all line numbers available for 846 // ReferenceType or Method) allUniqueLocations(List<DebugLocation> debugLocations)847 static protected Set<DebugLocation> allUniqueLocations(List<DebugLocation> debugLocations) { 848 Set<DebugLocation> result = new TreeSet<DebugLocation>(); 849 850 for (DebugLocation debugLocation : debugLocations) { 851 if (!result.contains(debugLocation)) { 852 result.add(debugLocation); 853 } 854 } 855 856 return result; 857 } 858 859 // check is list of Locations contains only expected locations compareLocations(List<Location> locations, List<DebugLocation> expectedLocations, String stratum)860 protected void compareLocations(List<Location> locations, List<DebugLocation> expectedLocations, String stratum) { 861 boolean success = true; 862 863 List<Location> tempLocations = new LinkedList<Location>(locations); 864 865 List<DebugLocation> tempExpectedLocations = new LinkedList<DebugLocation>(expectedLocations); 866 867 for(Iterator<Location> locationsIterator = tempLocations.iterator(); locationsIterator.hasNext();) { 868 boolean isExpected = false; 869 Location location = locationsIterator.next(); 870 871 for(Iterator<DebugLocation> expectedLocationsIterator = tempExpectedLocations.iterator(); expectedLocationsIterator.hasNext();) { 872 DebugLocation expectedLocation = expectedLocationsIterator.next(); 873 if (expectedLocation.compare(location, stratum)) { 874 isExpected = true; 875 locationsIterator.remove(); 876 expectedLocationsIterator.remove(); 877 break; 878 } 879 } 880 if (!isExpected) { 881 success = false; 882 log.complain("Location " + location + " were not found in expected locations"); 883 } 884 } 885 886 if (tempLocations.size() != 0) { 887 success = false; 888 setSuccess(false); 889 log.complain("Not all locations were found in expected"); 890 } 891 892 if (tempExpectedLocations.size() != 0) { 893 success = false; 894 setSuccess(false); 895 log.complain("Following expected locations were not found in received"); 896 for (DebugLocation expectedLocation : tempExpectedLocations) { 897 log.complain(expectedLocation.toString()); 898 } 899 } 900 901 if (!success) { 902 setSuccess(false); 903 log.complain("Expected and actual locations differ"); 904 905 log.complain("Actual locations: "); 906 for (Location location : locations) { 907 log.complain(locationToString(location, stratum)); 908 } 909 910 log.complain("Expected locations: "); 911 for (DebugLocation expectedLocation : expectedLocations) { 912 log.complain(expectedLocation.toString()); 913 } 914 } 915 } 916 917 // test all SDE related methods of ReferenceType checkReferenceType(String stratum, ReferenceType referenceType, List<String> expectedSourceNames, List<String> expectedSourcePaths, List<DebugLocation> expectedLocations)918 protected void checkReferenceType(String stratum, ReferenceType referenceType, List<String> expectedSourceNames, 919 List<String> expectedSourcePaths, List<DebugLocation> expectedLocations) { 920 log.display("Check sourceNames"); 921 check_ReferenceType_sourceNames(referenceType, stratum, expectedSourceNames); 922 log.display("Check sourcePaths"); 923 check_ReferenceType_sourcePaths(referenceType, stratum, expectedSourcePaths); 924 log.display("Check allLocations"); 925 check_ReferenceType_allLineLocations(referenceType, stratum, expectedLocations); 926 log.display("Check locationsOfLine"); 927 check_ReferenceType_locationsOfLine(referenceType, stratum, false, expectedLocations); 928 929 for (Method method : referenceType.methods()) { 930 List<DebugLocation> expectedLocationsOfMethod = locationsOfMethod(expectedLocations, method.name()); 931 932 log.display("Check allLineLocations for method '" + method.name() + "'"); 933 check_Method_allLineLocations(method, stratum, expectedLocationsOfMethod); 934 log.display("Check locationsOfLine for method '" + method.name() + "'"); 935 check_Method_locationsOfLine(method, stratum, false, expectedLocationsOfMethod); 936 } 937 } 938 939 // check is 'ReferenceType.sourceNames' returns only expected sources check_ReferenceType_sourceNames(ReferenceType referenceType, String stratum, List<String> expectedSourceNames)940 protected void check_ReferenceType_sourceNames(ReferenceType referenceType, String stratum, 941 List<String> expectedSourceNames) { 942 try { 943 if (stratum == null) { 944 String sourceName = referenceType.sourceName(); 945 String expectedSourceName = expectedSourceNames.get(0); 946 947 if (!sourceName.equals(expectedSourceName)) { 948 setSuccess(false); 949 log.complain("Unexpected result of ReferenceType.sourceName(): " + sourceName + ", expected is " 950 + expectedSourceName); 951 } 952 } else { 953 boolean success = true; 954 955 List<String> sourceNames = referenceType.sourceNames(stratum); 956 957 if (!expectedSourceNames.containsAll(sourceNames)) { 958 success = false; 959 log.complain("ReferenceType.sourceNames() returns unexpected names"); 960 } 961 962 if (!sourceNames.containsAll(expectedSourceNames)) { 963 success = false; 964 log.complain("Not all expected source names was returned by ReferenceType.sourceNames()"); 965 } 966 967 if (!success) { 968 log.complain("Expected source names:"); 969 for (String name : expectedSourceNames) 970 log.complain(name); 971 log.complain("Actual source names:"); 972 for (String name : sourceNames) 973 log.complain(name); 974 } 975 } 976 } catch (AbsentInformationException e) { 977 setSuccess(false); 978 log.complain("Unexpected exception: " + e); 979 e.printStackTrace(log.getOutStream()); 980 } 981 } 982 983 // check is 'ReferenceType.sourcePaths' returns only expected paths check_ReferenceType_sourcePaths(ReferenceType referenceType, String stratum, List<String> expectedSourcePaths)984 protected void check_ReferenceType_sourcePaths(ReferenceType referenceType, String stratum, 985 List<String> expectedSourcePaths) { 986 try { 987 boolean success = true; 988 989 List<String> sourcePaths = referenceType.sourcePaths(stratum); 990 991 if (!expectedSourcePaths.containsAll(sourcePaths)) { 992 success = false; 993 log.complain("ReferenceType.sourcePaths() returns unexpected paths"); 994 } 995 996 if (!sourcePaths.containsAll(expectedSourcePaths)) { 997 success = false; 998 log.complain("Not all expected paths was returned by ReferenceType.sourcePaths()"); 999 } 1000 1001 if (!success) { 1002 log.complain("Expected paths:"); 1003 for (String path : expectedSourcePaths) 1004 log.complain(path); 1005 log.complain("Actual paths:"); 1006 for (String path : sourcePaths) 1007 log.complain(path); 1008 } 1009 } catch (AbsentInformationException e) { 1010 setSuccess(false); 1011 log.complain("Unexpected exception: " + e); 1012 e.printStackTrace(log.getOutStream()); 1013 } 1014 } 1015 1016 // check that method 'ReferenceType.allLineLocations' returns only expected 1017 // locations check_ReferenceType_allLineLocations(ReferenceType referenceType, String stratum, List<DebugLocation> expectedLocations)1018 protected void check_ReferenceType_allLineLocations(ReferenceType referenceType, String stratum, 1019 List<DebugLocation> expectedLocations) { 1020 try { 1021 List<Location> locations = referenceType.allLineLocations(); 1022 compareLocations(locations, expectedLocations, stratum); 1023 } catch (AbsentInformationException e) { 1024 setSuccess(false); 1025 log.complain("Unexpected exception: " + e); 1026 e.printStackTrace(log.getOutStream()); 1027 } 1028 1029 } 1030 1031 // check that method 'Method.allLineLocations' returns only expected 1032 // locations check_Method_allLineLocations(Method method, String stratum, List<DebugLocation> expectedLocationsOfMethod)1033 protected void check_Method_allLineLocations(Method method, String stratum, 1034 List<DebugLocation> expectedLocationsOfMethod) { 1035 try { 1036 List<Location> methodAllLineLocations = method.allLineLocations(); 1037 compareLocations(methodAllLineLocations, expectedLocationsOfMethod, stratum); 1038 } catch (AbsentInformationException e) { 1039 setSuccess(false); 1040 log.complain("Unexpected exception: " + e); 1041 e.printStackTrace(log.getOutStream()); 1042 } 1043 } 1044 1045 // for each line available for method check result of 1046 // 'Method.locationsOfLine' check_Method_locationsOfLine(Method method, String stratum, boolean allSources, List<DebugLocation> expectedLocationsOfMethod)1047 protected void check_Method_locationsOfLine(Method method, String stratum, boolean allSources, 1048 List<DebugLocation> expectedLocationsOfMethod) { 1049 try { 1050 for (DebugLocation uniqueLocation : allUniqueLocations(expectedLocationsOfMethod)) { 1051 String sourceName = allSources ? null : uniqueLocation.sourceName; 1052 1053 List<DebugLocation> expectedLocationsOfLine = locationsOfLine( 1054 expectedLocationsOfMethod, 1055 sourceName, 1056 uniqueLocation.inputLine); 1057 1058 List<Location> locationsOfLine = (stratum == null) ? method.locationsOfLine(uniqueLocation.inputLine) 1059 : method.locationsOfLine(stratum, sourceName, uniqueLocation.inputLine); 1060 1061 compareLocations(locationsOfLine, expectedLocationsOfLine, stratum); 1062 } 1063 } catch (AbsentInformationException e) { 1064 setSuccess(false); 1065 log.complain("Unexpected exception: " + e); 1066 e.printStackTrace(log.getOutStream()); 1067 } 1068 } 1069 1070 // for each line available for ReferenceType check result of 1071 // 'ReferenceType.locationsOfLine' check_ReferenceType_locationsOfLine(ReferenceType referenceType, String stratum, boolean allSources, List<DebugLocation> expectedLocations)1072 protected void check_ReferenceType_locationsOfLine(ReferenceType referenceType, String stratum, boolean allSources, 1073 List<DebugLocation> expectedLocations) { 1074 try { 1075 for (DebugLocation uniqueLocation : allUniqueLocations(expectedLocations)) { 1076 String sourceName = allSources ? null : uniqueLocation.sourceName; 1077 1078 List<DebugLocation> expectedLocationsOfLine = locationsOfLine( 1079 expectedLocations, 1080 sourceName, 1081 uniqueLocation.inputLine); 1082 1083 List<Location> locations = (stratum == null) ? referenceType.locationsOfLine(uniqueLocation.inputLine) 1084 : referenceType.locationsOfLine(stratum, sourceName, uniqueLocation.inputLine); 1085 1086 compareLocations(locations, expectedLocationsOfLine, stratum); 1087 } 1088 } catch (AbsentInformationException e) { 1089 setSuccess(false); 1090 log.complain("Unexpected exception: " + e); 1091 e.printStackTrace(log.getOutStream()); 1092 } 1093 1094 } 1095 1096 // check that method 'ReferenceType.availableStrata' returns only expected 1097 // stratums check_ReferenceType_availableStrata(ReferenceType referenceType, List<String> expectedStrata)1098 protected void check_ReferenceType_availableStrata(ReferenceType referenceType, List<String> expectedStrata) { 1099 boolean success = true; 1100 1101 List<String> strata = referenceType.availableStrata(); 1102 1103 if (!expectedStrata.containsAll(strata)) { 1104 success = false; 1105 log.complain("ReferenceType.availableStrata() returns unexpected values"); 1106 } 1107 1108 if (!strata.containsAll(expectedStrata)) { 1109 success = false; 1110 log.complain("Not all expected stratums was returned by ReferenceType.availableStrata()"); 1111 } 1112 1113 if (!success) { 1114 log.complain("Expected stratums:"); 1115 for (String name : expectedStrata) 1116 log.complain(name); 1117 log.complain("Actual stratums:"); 1118 for (String name : strata) 1119 log.complain(name); 1120 } 1121 } 1122 1123 } 1124