1 /**
   2  *  @test
   3  *  @bug 4390869
   4  *  @bug 4460328
   5  *  @summary Test the new SourceDebugExtension facility
   6  *
   7  *  @author Robert Field
   8  *
   9  *  @library ..
  10  *  @modules jdk.jdi
  11  *  @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE
  12  *  @run compile MangleTest.java
  13  *  @run compile -g onion/pickle/Mangle.java
  14  *  @run driver MangleTest
  15  */
  16 import com.sun.jdi.*;
  17 import com.sun.jdi.event.*;
  18 import com.sun.jdi.request.*;
  19 
  20 import java.util.*;
  21 import java.io.File;
  22 
  23 public class MangleTest extends TestScaffold {
  24     static final String op = "onion" + File.separator + "pickle" + File.separator;
  25     ReferenceType targetClass;
  26 
  27     MangleTest (String args[]) {
  28         super(args);
  29     }
  30 
  31     public static void main(String[] args)      throws Exception {
  32         testSetUp();
  33         new MangleTest(args).startTests();
  34     }
  35 
  36     /********** test set-up **********/
  37 
  38     static void testSetUp() throws Exception {
  39         InstallSDE.install(new File(System.getProperty("test.classes", "."),
  40                                     op + "Mangle.class"),
  41                            new File(System.getProperty("test.src", "."),
  42                                     "Mangle.sde"));
  43     }
  44 
  45     /********** test assist **********/
  46 
  47     void checkLocation(Location loc, String label,
  48                        String expectedSourceName,
  49                        String expectedSourcePath,
  50                        int expectedLinenumber) throws Exception {
  51         String sourceName = loc.sourceName();
  52         if (sourceName.equals(expectedSourceName)) {
  53             println(label + " sourceName: " + sourceName);
  54         } else {
  55             failure("FAIL: " + label +
  56                     " expected sourceName " + expectedSourceName +
  57                     " got - " + sourceName);
  58         }
  59 
  60         String sourcePath = loc.sourcePath();
  61         if (sourcePath.equals(expectedSourcePath)) {
  62             println(label + " sourcePath: " + sourcePath);
  63         } else {
  64             failure("FAIL: " + label +
  65                     " expected sourcePath " + expectedSourcePath +
  66                     " got - " + sourcePath);
  67         }
  68 
  69         int ln = loc.lineNumber();
  70         if (ln == expectedLinenumber) {
  71             println(label + " line number: " + ln);
  72         } else {
  73             failure("FAIL: " + label +
  74                     " expected line number " + expectedLinenumber +
  75                     " got - " + ln);
  76         }
  77     }
  78 
  79     void checkLocation(String stratum, Location loc, String label,
  80                        String expectedSourceName,
  81                        String expectedSourcePath,
  82                        int expectedLinenumber) throws Exception {
  83         String sourceName = loc.sourceName(stratum);
  84         if (sourceName.equals(expectedSourceName)) {
  85             println(label + "(" + stratum + ")" +
  86                     " sourceName: " + sourceName);
  87         } else {
  88             failure("FAIL: " + label + "(" + stratum + ")" +
  89                     " expected sourceName " + expectedSourceName +
  90                     " got " + sourceName);
  91         }
  92 
  93         String sourcePath = loc.sourcePath(stratum);
  94         if (sourcePath.equals(expectedSourcePath)) {
  95             println(label + "(" + stratum + ")" +
  96                     " sourcePath: " + sourcePath);
  97         } else {
  98             failure("FAIL: " + label + "(" + stratum + ")" +
  99                     " expected sourcePath " + expectedSourcePath +
 100                     " got " + sourcePath);
 101         }
 102 
 103         int ln = loc.lineNumber(stratum);
 104         if (ln == expectedLinenumber) {
 105             println(label + "(" + stratum + ")" +
 106                     " line number: " + ln);
 107         } else {
 108             failure("FAIL: " + label + "(" + stratum + ")" +
 109                     " expected line number " + expectedLinenumber +
 110                     " got " + ln);
 111         }
 112     }
 113 
 114     Location getLoc(int index, List locList) {
 115         return ((Location)(locList.get(index)));
 116     }
 117 
 118     void lineMatch(int index, String stratum, Location loc, int line) {
 119         int gotLine = loc.lineNumber(stratum);
 120         if (gotLine != line) {
 121             failure("FAIL: index=" + index +
 122                     " " + stratum + " line=" + gotLine +
 123                     " expected: " + line);
 124         }
 125     }
 126 
 127     void lineMatch(int index, Location loc,
 128                    int javaLine, int xyzLine, int ratsLine) {
 129         lineMatch(index, "Java", loc, javaLine);
 130         lineMatch(index, "XYZ", loc, xyzLine);
 131         lineMatch(index, "Rats", loc, ratsLine);
 132     }
 133 
 134     List listWith(String s1) {
 135         List result = new ArrayList();
 136         result.add(s1);
 137         return result;
 138     }
 139 
 140     List listWith(String s1, String s2) {
 141         List result = new ArrayList();
 142         result.add(s1);
 143         result.add(s2);
 144         return result;
 145     }
 146 
 147 
 148     /********** test core **********/
 149 
 150     protected void runTests() throws Exception {
 151         /*
 152          * Get to the top of main()
 153          * to determine targetClass
 154          */
 155         BreakpointEvent bpe = startToMain("onion.pickle.Mangle");
 156         targetClass = bpe.location().declaringType();
 157 
 158         // ref type source name
 159         String sourceName = targetClass.sourceName();
 160         if (sourceName.equals("Mangle.xyz")) {
 161             println("ref type sourceName: " + sourceName);
 162         } else {
 163             failure("FAIL: unexpected ref type sourceName - " + sourceName);
 164         }
 165 
 166         // ref type source names /paths
 167         List sourceNames;
 168         sourceNames = targetClass.sourceNames("Java");
 169         if (sourceNames.equals(listWith("Mangle.java"))) {
 170             println("ref type Java sourceNames: " + sourceNames);
 171         } else {
 172             failure("FAIL: unexpected ref type Java sourceNames - " +
 173                     sourceNames);
 174         }
 175         sourceNames = targetClass.sourceNames("XYZ");
 176         if (sourceNames.equals(listWith("Mangle.xyz", "Incl.xyz"))) {
 177             println("ref type XYZ sourceNames: " + sourceNames);
 178         } else {
 179             failure("FAIL: unexpected ref type XYZ sourceNames - " +
 180                     sourceNames);
 181         }
 182         sourceNames = targetClass.sourceNames(null);
 183         if (sourceNames.equals(listWith("Mangle.xyz", "Incl.xyz"))) {
 184             println("ref type null sourceNames: " + sourceNames);
 185         } else {
 186             failure("FAIL: unexpected ref type null sourceNames - " +
 187                     sourceNames);
 188         }
 189         sourceNames = targetClass.sourceNames("Rats");
 190         if (sourceNames.equals(listWith("Mangle.rats", "Incl.rats"))) {
 191             println("ref type Rats sourceNames: " + sourceNames);
 192         } else {
 193             failure("FAIL: unexpected ref type Rats sourceNames - " +
 194                     sourceNames);
 195         }
 196         List sourcePaths;
 197         sourcePaths = targetClass.sourcePaths("Java");
 198         if (sourcePaths.equals(listWith(op + "Mangle.java"))) {
 199             println("ref type Java sourcePaths: " + sourcePaths);
 200         } else {
 201             failure("FAIL: unexpected ref type Java sourcePaths - " +
 202                     sourcePaths);
 203         }
 204         sourcePaths = targetClass.sourcePaths("XYZ");
 205         if (sourcePaths.equals(listWith("database14", op + "Incl.xyz"))) {
 206             println("ref type XYZ sourcePaths: " + sourcePaths);
 207         } else {
 208             failure("FAIL: unexpected ref type XYZ sourcePaths - " +
 209                     sourcePaths);
 210         }
 211         sourcePaths = targetClass.sourcePaths(null);
 212         if (sourcePaths.equals(listWith("database14", op + "Incl.xyz"))) {
 213             println("ref type null sourcePaths: " + sourcePaths);
 214         } else {
 215             failure("FAIL: unexpected ref type null sourcePaths - " +
 216                     sourcePaths);
 217         }
 218         sourcePaths = targetClass.sourcePaths("Rats");
 219         if (sourcePaths.equals(listWith(op + "Mangle.rats",
 220                                         "bleep:bleep:Incl.rats"))) {
 221             println("ref type Rats sourcePaths: " + sourcePaths);
 222         } else {
 223             failure("FAIL: unexpected ref type Rats sourcePaths - " +
 224                     sourcePaths);
 225         }
 226 
 227         Method main = findMethod(targetClass, "main",
 228                                  "([Ljava/lang/String;)V");
 229         List allLines = main.allLineLocations();
 230         List javaLines = main.allLineLocations("Java", null);
 231         List bogusLines = main.allLineLocations("bogus", null);
 232         List nullLines = main.allLineLocations(null, null);
 233         List xyzLines = main.allLineLocations("XYZ", null);
 234         List ratsLines = main.allLineLocations("Rats", null);
 235 
 236         List tl = new ArrayList(allLines);
 237         tl.removeAll(xyzLines);
 238         if (tl.isEmpty() && allLines.size() == xyzLines.size()) {
 239             println("allLineLocations() is OK");
 240         } else {
 241             failure("FAIL: allLineLocations() wrong - " + allLines);
 242         }
 243 
 244         tl = new ArrayList(bogusLines);
 245         tl.removeAll(xyzLines);
 246         if (tl.isEmpty() && bogusLines.size() == xyzLines.size()) {
 247             println("allLineLocations(\"bogus\") is OK");
 248         } else {
 249             failure("FAIL: allLineLocations(\"bogus\") wrong - " + bogusLines);
 250         }
 251 
 252         tl = new ArrayList(nullLines);
 253         tl.removeAll(xyzLines);
 254         if (tl.isEmpty() && nullLines.size() == xyzLines.size()) {
 255             println("allLineLocations(null) is OK");
 256         } else {
 257             failure("FAIL: allLineLocations(null) wrong - " + nullLines);
 258         }
 259 
 260         if (!javaLines.get(0).equals(ratsLines.get(0))) {
 261             failure("FAIL: locations should match - " + javaLines.get(0));
 262         }
 263         if (javaLines.get(0).equals(xyzLines.get(0))) {
 264             failure("FAIL: locations should not match - " +
 265                     javaLines.get(0));
 266         }
 267         if (!javaLines.get(1).equals(ratsLines.get(1))) {
 268             failure("FAIL: locations should match - " + javaLines.get(1));
 269         }
 270         if (!javaLines.get(1).equals(xyzLines.get(0))) {
 271             failure("FAIL: locations should match - " + javaLines.get(1));
 272         }
 273         if (javaLines.get(2).equals(ratsLines.get(1))) {
 274             failure("FAIL: locations should not match - " +
 275                     javaLines.get(1));
 276         }
 277         if (xyzLines.contains(javaLines.get(0))) {
 278             failure("FAIL: xyz locations should not match - " +
 279                     javaLines.get(0));
 280         }
 281         if (xyzLines.contains(javaLines.get(2))) {
 282             failure("FAIL: xyz locations should not match - " +
 283                     javaLines.get(2));
 284         }
 285         if (xyzLines.contains(javaLines.get(6))) {
 286             failure("FAIL: xyz locations should not match - " +
 287                     javaLines.get(6));
 288         }
 289 
 290         if (ratsLines.contains(javaLines.get(2))) {
 291             failure("FAIL: rats locations should not match - " +
 292                     javaLines.get(2));
 293         }
 294         if (ratsLines.contains(javaLines.get(4))) {
 295             failure("FAIL: rats locations should not match - " +
 296                     javaLines.get(4));
 297         }
 298         if (ratsLines.contains(javaLines.get(5))) {
 299             failure("FAIL: rats locations should not match - " +
 300                     javaLines.get(5));
 301         }
 302 
 303         println("*** Java");
 304         for (Iterator it = javaLines.iterator(); it.hasNext(); ) {
 305             Location loc = (Location)it.next();
 306             print("" + loc.lineNumber("Java") + " - ");
 307             print(loc.sourceName("XYZ") + " : ");
 308             print("" + loc.lineNumber("XYZ") + " ... ");
 309             print(loc.sourceName("Rats") + " : ");
 310             println("" + loc.lineNumber("Rats"));
 311         }
 312 
 313         println("*** XYZ");
 314         for (Iterator it = xyzLines.iterator(); it.hasNext(); ) {
 315             Location loc = (Location)it.next();
 316             print("" + loc.lineNumber("Java") + " - ");
 317             print(loc.sourceName("XYZ") + " : ");
 318             print("" + loc.lineNumber("XYZ") + " ... ");
 319             print(loc.sourceName("Rats") + " : ");
 320             println("" + loc.lineNumber("Rats"));
 321         }
 322 
 323         println("*** Rats");
 324         for (Iterator it = ratsLines.iterator(); it.hasNext(); ) {
 325             Location loc = (Location)it.next();
 326             print("" + loc.lineNumber("Java") + " - ");
 327             print(loc.sourceName("XYZ") + " : ");
 328             print("" + loc.lineNumber("XYZ") + " ... ");
 329             print(loc.sourceName("Rats") + " : ");
 330             println("" + loc.lineNumber("Rats"));
 331         }
 332 
 333         checkLocation(getLoc(0, javaLines), "0",
 334                       "Incl.xyz",
 335                       op + "Incl.xyz", 200);
 336         checkLocation(null, getLoc(0, javaLines), "0",
 337                       "Incl.xyz",
 338                       op + "Incl.xyz", 200);
 339         checkLocation("bogus", getLoc(0, javaLines), "0",
 340                       "Incl.xyz",
 341                       op + "Incl.xyz", 200);
 342         checkLocation("Java", getLoc(0, javaLines), "0",
 343                       "Mangle.java",
 344                       op + "Mangle.java", 4);
 345         checkLocation("XYZ", getLoc(0, javaLines), "0",
 346                       "Incl.xyz",
 347                       op + "Incl.xyz", 200);
 348         checkLocation("Rats", getLoc(0, javaLines), "0",
 349                       "Mangle.rats",
 350                       op + "Mangle.rats", 1000);
 351 
 352         checkLocation(getLoc(3, javaLines), "3",
 353                       "Mangle.xyz",
 354                       "database14", 210);
 355         checkLocation(null, getLoc(3, javaLines), "3",
 356                       "Mangle.xyz",
 357                       "database14", 210);
 358         checkLocation("bogus", getLoc(3, javaLines), "3",
 359                       "Mangle.xyz",
 360                       "database14", 210);
 361         checkLocation("Java", getLoc(3, javaLines), "3",
 362                       "Mangle.java",
 363                       op + "Mangle.java", 7);
 364         checkLocation("XYZ", getLoc(3, javaLines), "3",
 365                       "Mangle.xyz",
 366                       "database14", 210);
 367         checkLocation("Rats", getLoc(3, javaLines), "3",
 368                       "Incl.rats",
 369                       "bleep:bleep:Incl.rats", 1112);
 370 
 371         checkLocation(getLoc(6, javaLines), "6",
 372                       "Mangle.xyz",
 373                       "database14", 218);
 374         checkLocation(null, getLoc(6, javaLines), "6",
 375                       "Mangle.xyz",
 376                       "database14", 218);
 377         checkLocation("bogus", getLoc(6, javaLines), "6",
 378                       "Mangle.xyz",
 379                       "database14", 218);
 380         checkLocation("Java", getLoc(6, javaLines), "6",
 381                       "Mangle.java",
 382                       op + "Mangle.java", 10);
 383         checkLocation("XYZ", getLoc(6, javaLines), "6",
 384                       "Mangle.xyz",
 385                       "database14", 218);
 386         checkLocation("Rats", getLoc(6, javaLines), "6",
 387                       "Incl.rats",
 388                       "bleep:bleep:Incl.rats", 1112);
 389 
 390         lineMatch(0, getLoc(0, javaLines), 4, 200, 1000);
 391         lineMatch(1, getLoc(1, javaLines), 5, 200, 1111);
 392         lineMatch(2, getLoc(2, javaLines), 6, 200, 1111);
 393         lineMatch(3, getLoc(3, javaLines), 7, 210, 1112);
 394         lineMatch(4, getLoc(4, javaLines), 8, 217, 1112);
 395         lineMatch(5, getLoc(5, javaLines), 9, 218, 1112);
 396         lineMatch(6, getLoc(6, javaLines), 10, 218, 1112);
 397 
 398         /*
 399          * resume the target listening for events
 400          */
 401         listenUntilVMDisconnect();
 402 
 403         /*
 404          * deal with results of test
 405          * if anything has called failure("foo") testFailed will be true
 406          */
 407         if (!testFailed) {
 408             println("MangleTest: passed");
 409         } else {
 410             throw new Exception("MangleTest: failed");
 411         }
 412     }
 413 }