1 /*
   2  * Copyright (c) 2009, 2010, 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 
  24 /*
  25  * @test
  26  * @bug 6911256 6964740
  27  * @summary Tests of generated TWR code.
  28  */
  29 
  30 import java.util.List;
  31 import java.util.ArrayList;
  32 
  33 public class TwrTests {
  34     public static void main(String[] args) {
  35         testCreateFailure1();
  36         testCreateFailure2();
  37         testCreateFailure2Nested();
  38         testCreateFailure3();
  39         testCreateFailure3Nested();
  40         testCreateFailure4();
  41         testCreateFailure4Nested();
  42         testCreateFailure5();
  43         testCreateFailure5Nested();
  44 
  45         testCreateSuccess1();
  46         testCreateSuccess2();
  47         testCreateSuccess2Nested();
  48         testCreateSuccess3();
  49         testCreateSuccess3Nested();
  50         testCreateSuccess4();
  51         testCreateSuccess4Nested();
  52         testCreateSuccess5();
  53         testCreateSuccess5Nested();
  54     }
  55 
  56     /*
  57      * The following tests simulate a creation failure of every possible
  58      * resource in an TWR block, and check to make sure that the failure
  59      * prevents creation of subsequent resources, and that all created
  60      * resources are properly closed, even if one or more of the close
  61      * attempts fails.
  62      */
  63 
  64     public static void testCreateFailure1() {
  65         int creationFailuresDetected = 0;
  66         List<Integer> closedList = new ArrayList<Integer>(0);
  67         try (Resource r0 = createResource(0, 0, 0, closedList)) {
  68             throw new AssertionError("Resource creation succeeded");
  69         } catch (Resource.CreateFailException e) {
  70             creationFailuresDetected++;
  71             if (e.resourceId() != 0) {
  72                 throw new AssertionError("Wrong resource creation "
  73                                          + e.resourceId() + " failed");
  74             }
  75         } catch (Resource.CloseFailException e) {
  76             throw new AssertionError("Unexpected CloseFailException: " + e.resourceId());
  77         }
  78         checkForSingleCreationFailure(creationFailuresDetected);
  79         checkClosedList(closedList, 0);
  80     }
  81 
  82     public static void testCreateFailure2() {
  83         for (int createFailureId = 0; createFailureId < 2; createFailureId++) {
  84             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
  85                 int creationFailuresDetected = 0;
  86                 List<Integer> closedList = new ArrayList<Integer>();
  87                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList);
  88                      Resource r1 = createResource(1, createFailureId, bitMap, closedList)) {
  89                     throw new AssertionError("Entire resource creation succeeded");
  90                 } catch (Resource.CreateFailException e) {
  91                     creationFailuresDetected++;
  92                     checkCreateFailureId(e.resourceId(), createFailureId);
  93                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
  94                 } catch (Resource.CloseFailException e) {
  95                     throw new AssertionError("Secondary exception suppression failed");
  96                 }
  97                 checkForSingleCreationFailure(creationFailuresDetected);
  98                 checkClosedList(closedList, createFailureId);
  99             }
 100         }
 101     }
 102 
 103     public static void testCreateFailure2Nested() {
 104         for (int createFailureId = 0; createFailureId < 2; createFailureId++) {
 105             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 106                 int creationFailuresDetected = 0;
 107                 List<Integer> closedList = new ArrayList<Integer>();
 108                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList)) {
 109                     try(Resource r1 = createResource(1, createFailureId, bitMap, closedList)) {
 110                         throw new AssertionError("Entire resource creation succeeded");
 111                     }
 112                 } catch (Resource.CreateFailException e) {
 113                     creationFailuresDetected++;
 114                     checkCreateFailureId(e.resourceId(), createFailureId);
 115                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 116                 } catch (Resource.CloseFailException e) {
 117                     throw new AssertionError("Secondary exception suppression failed");
 118                 }
 119                 checkForSingleCreationFailure(creationFailuresDetected);
 120                 checkClosedList(closedList, createFailureId);
 121             }
 122         }
 123     }
 124 
 125     public static void testCreateFailure3() {
 126         for (int createFailureId = 0; createFailureId < 3; createFailureId++) {
 127             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 128                 int creationFailuresDetected = 0;
 129                 List<Integer> closedList = new ArrayList<Integer>();
 130                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList);
 131                      Resource r1 = createResource(1, createFailureId, bitMap, closedList);
 132                      Resource r2 = createResource(2, createFailureId, bitMap, closedList)) {
 133                     throw new AssertionError("Entire resource creation succeeded");
 134                 } catch (Resource.CreateFailException e) {
 135                     creationFailuresDetected++;
 136                     checkCreateFailureId(e.resourceId(), createFailureId);
 137                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 138                 } catch (Resource.CloseFailException e) {
 139                     throw new AssertionError("Secondary exception suppression failed:" + e);
 140                 }
 141                 checkForSingleCreationFailure(creationFailuresDetected);
 142                 checkClosedList(closedList, createFailureId);
 143             }
 144         }
 145     }
 146 
 147     public static void testCreateFailure3Nested() {
 148         for (int createFailureId = 0; createFailureId < 3; createFailureId++) {
 149             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 150                 int creationFailuresDetected = 0;
 151                 List<Integer> closedList = new ArrayList<Integer>();
 152                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList)) {
 153                     try (Resource r1 = createResource(1, createFailureId, bitMap, closedList)) {
 154                         try (Resource r2 = createResource(2, createFailureId, bitMap, closedList)) {
 155                             throw new AssertionError("Entire resource creation succeeded");
 156                         }
 157                     }
 158                 } catch (Resource.CreateFailException e) {
 159                     creationFailuresDetected++;
 160                     checkCreateFailureId(e.resourceId(), createFailureId);
 161                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 162                 } catch (Resource.CloseFailException e) {
 163                     throw new AssertionError("Secondary exception suppression failed:" + e);
 164                 }
 165                 checkForSingleCreationFailure(creationFailuresDetected);
 166                 checkClosedList(closedList, createFailureId);
 167             }
 168         }
 169     }
 170 
 171     public static void testCreateFailure4() {
 172         for (int createFailureId = 0; createFailureId < 4; createFailureId++) {
 173             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 174                 int creationFailuresDetected = 0;
 175                 List<Integer> closedList = new ArrayList<Integer>();
 176                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList);
 177                      Resource r1 = createResource(1, createFailureId, bitMap, closedList);
 178                      Resource r2 = createResource(2, createFailureId, bitMap, closedList);
 179                      Resource r3 = createResource(3, createFailureId, bitMap, closedList)) {
 180                     throw new AssertionError("Entire resource creation succeeded");
 181                 } catch (Resource.CreateFailException e) {
 182                     creationFailuresDetected++;
 183                     checkCreateFailureId(e.resourceId(), createFailureId);
 184                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 185                 } catch (Resource.CloseFailException e) {
 186                     throw new AssertionError("Secondary exception suppression failed:" + e);
 187                 }
 188                 checkForSingleCreationFailure(creationFailuresDetected);
 189                 checkClosedList(closedList, createFailureId);
 190             }
 191         }
 192     }
 193 
 194     public static void testCreateFailure4Nested() {
 195         for (int createFailureId = 0; createFailureId < 4; createFailureId++) {
 196             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 197                 int creationFailuresDetected = 0;
 198                 List<Integer> closedList = new ArrayList<Integer>();
 199                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList)) {
 200                     try (Resource r1 = createResource(1, createFailureId, bitMap, closedList)) {
 201                         try (Resource r2 = createResource(2, createFailureId, bitMap, closedList)) {
 202                             try (Resource r3 = createResource(3, createFailureId, bitMap, closedList)) {
 203                                 throw new AssertionError("Entire resource creation succeeded");
 204                             }
 205                         }
 206                     }
 207                 } catch (Resource.CreateFailException e) {
 208                     creationFailuresDetected++;
 209                     checkCreateFailureId(e.resourceId(), createFailureId);
 210                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 211                 } catch (Resource.CloseFailException e) {
 212                     throw new AssertionError("Secondary exception suppression failed:" + e);
 213                 }
 214                 checkForSingleCreationFailure(creationFailuresDetected);
 215                 checkClosedList(closedList, createFailureId);
 216             }
 217         }
 218     }
 219 
 220     public static void testCreateFailure5() {
 221         for (int createFailureId = 0; createFailureId < 5; createFailureId++) {
 222             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 223                 int creationFailuresDetected = 0;
 224                 List<Integer> closedList = new ArrayList<Integer>();
 225                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList);
 226                      Resource r1 = createResource(1, createFailureId, bitMap, closedList);
 227                      Resource r2 = createResource(2, createFailureId, bitMap, closedList);
 228                      Resource r3 = createResource(3, createFailureId, bitMap, closedList);
 229                      Resource r4 = createResource(4, createFailureId, bitMap, closedList)) {
 230                     throw new AssertionError("Entire resource creation succeeded");
 231                 } catch (Resource.CreateFailException e) {
 232                     creationFailuresDetected++;
 233                     checkCreateFailureId(e.resourceId(), createFailureId);
 234                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 235                 } catch (Resource.CloseFailException e) {
 236                     throw new AssertionError("Secondary exception suppression failed:" + e);
 237                 }
 238                 checkForSingleCreationFailure(creationFailuresDetected);
 239                 checkClosedList(closedList, createFailureId);
 240             }
 241         }
 242     }
 243 
 244     public static void testCreateFailure5Nested() {
 245         for (int createFailureId = 0; createFailureId < 5; createFailureId++) {
 246             for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) {
 247                 int creationFailuresDetected = 0;
 248                 List<Integer> closedList = new ArrayList<Integer>();
 249                 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList)) {
 250                     try (Resource r1 = createResource(1, createFailureId, bitMap, closedList)) {
 251                         try (Resource r2 = createResource(2, createFailureId, bitMap, closedList)) {
 252                             try (Resource r3 = createResource(3, createFailureId, bitMap, closedList)) {
 253                                 try (Resource r4 = createResource(4, createFailureId, bitMap, closedList)) {
 254                                     throw new AssertionError("Entire resource creation succeeded");
 255                                 }
 256                             }
 257                         }
 258                     }
 259                 } catch (Resource.CreateFailException e) {
 260                     creationFailuresDetected++;
 261                     checkCreateFailureId(e.resourceId(), createFailureId);
 262                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 263                 } catch (Resource.CloseFailException e) {
 264                     throw new AssertionError("Secondary exception suppression failed:" + e);
 265                 }
 266                 checkForSingleCreationFailure(creationFailuresDetected);
 267                 checkClosedList(closedList, createFailureId);
 268             }
 269         }
 270     }
 271 
 272     /**
 273      * Create a resource with the specified ID. The ID must be less than createFailureId.
 274      * A subsequent attempt to close the resource will fail iff the corresponding bit
 275      * is set in closeFailureBitMap.  When an attempt is made to close this resource,
 276      * its ID will be added to closedList, regardless of whether the attempt succeeds.
 277      *
 278      * @param id the ID of this resource
 279      * @param createFailureId the ID of the resource whose creation will fail
 280      * @param closeFailureBitMap a bit vector describing which resources should throw an
 281      *        exception when close is attempted
 282      * @param closedList a list on which to record resource close attempts
 283      * @throws AssertionError if no attempt should be made to create this resource
 284      */
 285     private static Resource createResource(int id,
 286                                            int createFailureId,
 287                                            int closeFailureBitMap,
 288                                            List<Integer> closedList) throws Resource.CreateFailException {
 289         if (id > createFailureId)
 290             throw new AssertionError("Resource " + id + " shouldn't be created");
 291         boolean createSucceeds = id != createFailureId;
 292         boolean closeSucceeds = (closeFailureBitMap & (1 << id)) == 0;
 293         return new Resource(id, createSucceeds, closeSucceeds, closedList);
 294     }
 295 
 296 
 297     /**
 298      * Check that an observed creation failure has the expected resource ID.
 299      *
 300      * @param foundId the ID of the resource whose creation failed
 301      * @param expectedId the ID of the resource whose creation should have failed
 302      */
 303     private static void checkCreateFailureId(int foundId, int expectedId) {
 304         if (foundId != expectedId)
 305             throw new AssertionError("Wrong resource creation failed. Found ID "
 306                                      + foundId + " expected " + expectedId);
 307     }
 308 
 309     /**
 310      * Check for proper suppressed exceptions in proper order.
 311      *
 312      * @param suppressedExceptions the suppressed exceptions array returned by
 313      *        getSuppressedExceptions()
 314      * @bitmap a bitmap indicating which suppressed exceptions are expected.
 315      *         Bit i is set iff id should throw a CloseFailException.
 316      */
 317     private static void checkSuppressedExceptions(Throwable[] suppressedExceptions, int bitMap) {
 318         if (suppressedExceptions.length != Integer.bitCount(bitMap))
 319             throw new AssertionError("Expected " + Integer.bitCount(bitMap)
 320                                      + " suppressed exceptions, got " +  suppressedExceptions.length);
 321 
 322         int prevCloseFailExceptionId = Integer.MAX_VALUE;
 323         for (Throwable t : suppressedExceptions) {
 324             int id = ((Resource.CloseFailException) t).resourceId();
 325             if ((1 << id  & bitMap) == 0)
 326                 throw new AssertionError("Unexpected suppressed CloseFailException: " + id);
 327             if (id > prevCloseFailExceptionId)
 328                 throw new AssertionError("Suppressed CloseFailException" + id
 329                                          + " followed " + prevCloseFailExceptionId);
 330         }
 331     }
 332 
 333     /**
 334      * Check that exactly one resource creation failed.
 335      *
 336      * @param numCreationFailuresDetected the number of creation failures detected
 337      */
 338     private static void checkForSingleCreationFailure(int numCreationFailuresDetected) {
 339         if (numCreationFailuresDetected != 1)
 340             throw new AssertionError("Wrong number of creation failures: "
 341                                      + numCreationFailuresDetected);
 342     }
 343 
 344     /**
 345      * Check that a close was attempted on every resourced that was successfully opened,
 346      * and that the close attempts occurred in the proper order.
 347      *
 348      * @param closedList the resource IDs of the close attempts, in the order they occurred
 349      * @param the ID of the resource whose creation failed.  Close attempts should occur
 350      *        for all previous resources, in reverse order.
 351      */
 352     private static void checkClosedList(List<Integer> closedList, int createFailureId) {
 353         List<Integer> expectedList = new ArrayList<Integer>(createFailureId);
 354         for (int i = createFailureId - 1; i >= 0; i--)
 355             expectedList.add(i);
 356         if (!closedList.equals(expectedList))
 357             throw new AssertionError("Closing sequence " + closedList + " != " + expectedList);
 358     }
 359 
 360     /*
 361      * The following tests simulate the creation of several resources, followed
 362      * by success or failure of forward processing.  They test that all resources
 363      * are properly closed, even if one or more of the close attempts fails.
 364      */
 365 
 366     public static void testCreateSuccess1() {
 367         for (int bitMap = 0, n = 1 << 1; bitMap < n; bitMap++) {
 368             for (int failure = 0; failure < 2; failure++) {
 369                 List<Integer> closedList = new ArrayList<Integer>();
 370                 try (Resource r0 = createResource(0, bitMap, closedList)) {
 371                     if (failure != 0)
 372                         throw new MyKindOfException();
 373                 } catch (Resource.CreateFailException e) {
 374                     throw new AssertionError(
 375                                              "Resource creation failed: " + e.resourceId());
 376                 } catch (MyKindOfException e) {
 377                     if (failure == 0)
 378                         throw new AssertionError("Unexpected MyKindOfException");
 379                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 380                 } catch (Resource.CloseFailException e) {
 381                     if (failure == 1)
 382                         throw new AssertionError("Secondary exception suppression failed");
 383                     int id = e.resourceId();
 384                     if (bitMap == 0)
 385                         throw new AssertionError("Unexpected CloseFailException: " + id);
 386                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 387                     if (1 << id != highestCloseFailBit) {
 388                         throw new AssertionError("CloseFailException: got id " + id
 389                                                  + ", expected lg(" + highestCloseFailBit +")");
 390                     }
 391                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 392                 }
 393                 checkClosedList(closedList, 1);
 394             }
 395         }
 396     }
 397 
 398     public static void testCreateSuccess2() {
 399         for (int bitMap = 0, n = 1 << 2; bitMap < n; bitMap++) {
 400             for (int failure = 0; failure < 2; failure++) {
 401                 List<Integer> closedList = new ArrayList<Integer>();
 402                 try (Resource r0 = createResource(0, bitMap, closedList);
 403                      Resource r1 = createResource(1, bitMap, closedList)) {
 404                     if (failure != 0)
 405                         throw new MyKindOfException();
 406                 } catch (Resource.CreateFailException e) {
 407                     throw new AssertionError(
 408                                              "Resource creation failed: " + e.resourceId());
 409                 } catch (MyKindOfException e) {
 410                     if (failure == 0)
 411                         throw new AssertionError("Unexpected MyKindOfException");
 412                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 413                 } catch (Resource.CloseFailException e) {
 414                     if (failure == 1)
 415                         throw new AssertionError("Secondary exception suppression failed");
 416                     int id = e.resourceId();
 417                     if (bitMap == 0)
 418                         throw new AssertionError("Unexpected CloseFailException: " + id);
 419                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 420                     if (1 << id != highestCloseFailBit) {
 421                         throw new AssertionError("CloseFailException: got id " + id
 422                                                  + ", expected lg(" + highestCloseFailBit +")");
 423                     }
 424                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 425                 }
 426                 checkClosedList(closedList, 2);
 427             }
 428         }
 429     }
 430 
 431     public static void testCreateSuccess2Nested() {
 432         for (int bitMap = 0, n = 1 << 2; bitMap < n; bitMap++) {
 433             for (int failure = 0; failure < 2; failure++) {
 434                 List<Integer> closedList = new ArrayList<Integer>();
 435                 try (Resource r0 = createResource(0, bitMap, closedList)) {
 436                     try (Resource r1 = createResource(1, bitMap, closedList)) {
 437                         if (failure != 0)
 438                             throw new MyKindOfException();
 439                     }
 440                 } catch (Resource.CreateFailException e) {
 441                     throw new AssertionError(
 442                                              "Resource creation failed: " + e.resourceId());
 443                 } catch (MyKindOfException e) {
 444                     if (failure == 0)
 445                         throw new AssertionError("Unexpected MyKindOfException");
 446                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 447                 } catch (Resource.CloseFailException e) {
 448                     if (failure == 1)
 449                         throw new AssertionError("Secondary exception suppression failed");
 450                     int id = e.resourceId();
 451                     if (bitMap == 0)
 452                         throw new AssertionError("Unexpected CloseFailException: " + id);
 453                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 454                     if (1 << id != highestCloseFailBit) {
 455                         throw new AssertionError("CloseFailException: got id " + id
 456                                                  + ", expected lg(" + highestCloseFailBit +")");
 457                     }
 458                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 459                 }
 460                 checkClosedList(closedList, 2);
 461             }
 462         }
 463     }
 464 
 465     public static void testCreateSuccess3() {
 466         for (int bitMap = 0, n = 1 << 3; bitMap < n; bitMap++) {
 467             for (int failure = 0; failure < 2; failure++) {
 468                 List<Integer> closedList = new ArrayList<Integer>();
 469                 try (Resource r0 = createResource(0, bitMap, closedList);
 470                      Resource r1 = createResource(1, bitMap, closedList);
 471                      Resource r2 = createResource(2, bitMap, closedList)) {
 472                     if (failure != 0)
 473                         throw new MyKindOfException();
 474                 } catch (Resource.CreateFailException e) {
 475                     throw new AssertionError(
 476                                              "Resource creation failed: " + e.resourceId());
 477                 } catch (MyKindOfException e) {
 478                     if (failure == 0)
 479                         throw new AssertionError("Unexpected MyKindOfException");
 480                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 481                 } catch (Resource.CloseFailException e) {
 482                     if (failure == 1)
 483                         throw new AssertionError("Secondary exception suppression failed");
 484                     int id = e.resourceId();
 485                     if (bitMap == 0)
 486                         throw new AssertionError("Unexpected CloseFailException: " + id);
 487                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 488                     if (1 << id != highestCloseFailBit) {
 489                         throw new AssertionError("CloseFailException: got id " + id
 490                                                  + ", expected lg(" + highestCloseFailBit +")");
 491                     }
 492                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 493                 }
 494                 checkClosedList(closedList, 3);
 495             }
 496         }
 497     }
 498 
 499     public static void testCreateSuccess3Nested() {
 500         for (int bitMap = 0, n = 1 << 3; bitMap < n; bitMap++) {
 501             for (int failure = 0; failure < 2; failure++) {
 502                 List<Integer> closedList = new ArrayList<Integer>();
 503                 try (Resource r0 = createResource(0, bitMap, closedList)) {
 504                     try (Resource r1 = createResource(1, bitMap, closedList)) {
 505                         try (Resource r2 = createResource(2, bitMap, closedList)) {
 506                             if (failure != 0)
 507                                 throw new MyKindOfException();
 508                         }
 509                     }
 510                 } catch (Resource.CreateFailException e) {
 511                     throw new AssertionError(
 512                                              "Resource creation failed: " + e.resourceId());
 513                 } catch (MyKindOfException e) {
 514                     if (failure == 0)
 515                         throw new AssertionError("Unexpected MyKindOfException");
 516                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 517                 } catch (Resource.CloseFailException e) {
 518                     if (failure == 1)
 519                         throw new AssertionError("Secondary exception suppression failed");
 520                     int id = e.resourceId();
 521                     if (bitMap == 0)
 522                         throw new AssertionError("Unexpected CloseFailException: " + id);
 523                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 524                     if (1 << id != highestCloseFailBit) {
 525                         throw new AssertionError("CloseFailException: got id " + id
 526                                                  + ", expected lg(" + highestCloseFailBit +")");
 527                     }
 528                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 529                 }
 530                 checkClosedList(closedList, 3);
 531             }
 532         }
 533     }
 534 
 535     public static void testCreateSuccess4() {
 536         for (int bitMap = 0, n = 1 << 4; bitMap < n; bitMap++) {
 537             for (int failure = 0; failure < 2; failure++) {
 538                 List<Integer> closedList = new ArrayList<Integer>();
 539                 try (Resource r0 = createResource(0, bitMap, closedList);
 540                      Resource r1 = createResource(1, bitMap, closedList);
 541                      Resource r2 = createResource(2, bitMap, closedList);
 542                      Resource r3 = createResource(3, bitMap, closedList)) {
 543                     if (failure != 0)
 544                         throw new MyKindOfException();
 545                 } catch (Resource.CreateFailException e) {
 546                     throw new AssertionError(
 547                                              "Resource creation failed: " + e.resourceId());
 548                 } catch (MyKindOfException e) {
 549                     if (failure == 0)
 550                         throw new AssertionError("Unexpected MyKindOfException");
 551                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 552                 } catch (Resource.CloseFailException e) {
 553                     if (failure == 1)
 554                         throw new AssertionError("Secondary exception suppression failed");
 555                     int id = e.resourceId();
 556                     if (bitMap == 0)
 557                         throw new AssertionError("Unexpected CloseFailException: " + id);
 558                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 559                     if (1 << id != highestCloseFailBit) {
 560                         throw new AssertionError("CloseFailException: got id " + id
 561                                                  + ", expected lg(" + highestCloseFailBit +")");
 562                     }
 563                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 564                 }
 565                 checkClosedList(closedList, 4);
 566             }
 567         }
 568     }
 569 
 570     public static void testCreateSuccess4Nested() {
 571         for (int bitMap = 0, n = 1 << 4; bitMap < n; bitMap++) {
 572             for (int failure = 0; failure < 2; failure++) {
 573                 List<Integer> closedList = new ArrayList<Integer>();
 574                 try (Resource r0 = createResource(0, bitMap, closedList)) {
 575                     try (Resource r1 = createResource(1, bitMap, closedList)) {
 576                         try (Resource r2 = createResource(2, bitMap, closedList)) {
 577                             try (Resource r3 = createResource(3, bitMap, closedList)) {
 578                                 if (failure != 0)
 579                                     throw new MyKindOfException();
 580                             }
 581                         }
 582                     }
 583                 } catch (Resource.CreateFailException e) {
 584                     throw new AssertionError(
 585                                              "Resource creation failed: " + e.resourceId());
 586                 } catch (MyKindOfException e) {
 587                     if (failure == 0)
 588                         throw new AssertionError("Unexpected MyKindOfException");
 589                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 590                 } catch (Resource.CloseFailException e) {
 591                     if (failure == 1)
 592                         throw new AssertionError("Secondary exception suppression failed");
 593                     int id = e.resourceId();
 594                     if (bitMap == 0)
 595                         throw new AssertionError("Unexpected CloseFailException: " + id);
 596                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 597                     if (1 << id != highestCloseFailBit) {
 598                         throw new AssertionError("CloseFailException: got id " + id
 599                                                  + ", expected lg(" + highestCloseFailBit +")");
 600                     }
 601                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 602                 }
 603                 checkClosedList(closedList, 4);
 604             }
 605         }
 606     }
 607 
 608     public static void testCreateSuccess5() {
 609         for (int bitMap = 0, n = 1 << 5; bitMap < n; bitMap++) {
 610             for (int failure = 0; failure < 2; failure++) {
 611                 List<Integer> closedList = new ArrayList<Integer>();
 612                 try (Resource r0 = createResource(0, bitMap, closedList);
 613                      Resource r1 = createResource(1, bitMap, closedList);
 614                      Resource r2 = createResource(2, bitMap, closedList);
 615                      Resource r3 = createResource(3, bitMap, closedList);
 616                      Resource r4 = createResource(4, bitMap, closedList)) {
 617                     if (failure != 0)
 618                         throw new MyKindOfException();
 619                 } catch (Resource.CreateFailException e) {
 620                     throw new AssertionError("Resource creation failed: " + e.resourceId());
 621                 } catch (MyKindOfException e) {
 622                     if (failure == 0)
 623                         throw new AssertionError("Unexpected MyKindOfException");
 624                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 625                 } catch (Resource.CloseFailException e) {
 626                     if (failure == 1)
 627                         throw new AssertionError("Secondary exception suppression failed");
 628                     int id = e.resourceId();
 629                     if (bitMap == 0)
 630                         throw new AssertionError("Unexpected CloseFailException: " + id);
 631                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 632                     if (1 << id != highestCloseFailBit) {
 633                         throw new AssertionError("CloseFailException: got id " + id
 634                                                  + ", expected lg(" + highestCloseFailBit +")");
 635                     }
 636                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 637                 }
 638                 checkClosedList(closedList, 5);
 639             }
 640         }
 641     }
 642 
 643     public static void testCreateSuccess5Nested() {
 644         for (int bitMap = 0, n = 1 << 5; bitMap < n; bitMap++) {
 645             for (int failure = 0; failure < 2; failure++) {
 646                 List<Integer> closedList = new ArrayList<Integer>();
 647                 try (Resource r0 = createResource(0, bitMap, closedList)) {
 648                     try (Resource r1 = createResource(1, bitMap, closedList)) {
 649                         try (Resource r2 = createResource(2, bitMap, closedList)) {
 650                             try (Resource r3 = createResource(3, bitMap, closedList)) {
 651                                 try (Resource r4 = createResource(4, bitMap, closedList)) {
 652                                     if (failure != 0)
 653                                         throw new MyKindOfException();
 654                                 }
 655                             }
 656                         }
 657                     }
 658                 } catch (Resource.CreateFailException e) {
 659                     throw new AssertionError("Resource creation failed: " + e.resourceId());
 660                 } catch (MyKindOfException e) {
 661                     if (failure == 0)
 662                         throw new AssertionError("Unexpected MyKindOfException");
 663                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
 664                 } catch (Resource.CloseFailException e) {
 665                     if (failure == 1)
 666                         throw new AssertionError("Secondary exception suppression failed");
 667                     int id = e.resourceId();
 668                     if (bitMap == 0)
 669                         throw new AssertionError("Unexpected CloseFailException: " + id);
 670                     int highestCloseFailBit = Integer.highestOneBit(bitMap);
 671                     if (1 << id != highestCloseFailBit) {
 672                         throw new AssertionError("CloseFailException: got id " + id
 673                                                  + ", expected lg(" + highestCloseFailBit +")");
 674                     }
 675                     checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
 676                 }
 677                 checkClosedList(closedList, 5);
 678             }
 679         }
 680     }
 681 
 682     private static Resource createResource(int id,
 683                                            int closeFailureBitMap,
 684                                            List<Integer> closedList) throws Resource.CreateFailException {
 685         boolean closeSucceeds = (closeFailureBitMap & (1 << id)) == 0;
 686         return new Resource(id, true, closeSucceeds, closedList);
 687     }
 688 
 689     private static class MyKindOfException extends Exception {
 690     }
 691 }
 692 
 693 class Resource implements AutoCloseable {
 694     /** A number identifying this resource */
 695     private final int resourceId;
 696 
 697     /** Whether the close call on this resource should succeed or fail */
 698     private final boolean closeSucceeds;
 699 
 700     /** When resource is closed, it records its ID in this list */
 701     private final List<Integer> closedList;
 702 
 703     Resource(int resourceId, boolean createSucceeds, boolean closeSucceeds,
 704              List<Integer> closedList) throws CreateFailException {
 705         if (!createSucceeds)
 706             throw new CreateFailException(resourceId);
 707         this.resourceId = resourceId;
 708         this.closeSucceeds = closeSucceeds;
 709         this.closedList = closedList;
 710     }
 711 
 712     public void close() throws CloseFailException {
 713         closedList.add(resourceId);
 714         if (!closeSucceeds)
 715             throw new CloseFailException(resourceId);
 716     }
 717 
 718     public static class ResourceException extends RuntimeException {
 719         private final int resourceId;
 720 
 721         public ResourceException(int resourceId) {
 722             super("Resource ID = " + resourceId);
 723             this.resourceId = resourceId;
 724         }
 725 
 726         public int resourceId() {
 727             return resourceId;
 728         }
 729     }
 730 
 731     public static class CreateFailException extends ResourceException {
 732         public CreateFailException(int resourceId) {
 733             super(resourceId);
 734         }
 735     }
 736 
 737     public static class CloseFailException extends ResourceException {
 738         public CloseFailException(int resourceId) {
 739             super(resourceId);
 740         }
 741     }
 742 }