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 }