1 /* 2 * Copyright (c) 2009, 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 27 * @summary Tests of generated ARM code. 28 */ 29 30 import java.util.List; 31 import java.util.ArrayList; 32 33 public class ArmTests { 34 public static void main(String[] args) { 35 testCreateFailure1(); 36 testCreateFailure2(); 37 testCreateFailure3(); 38 testCreateFailure4(); 39 testCreateFailure5(); 40 41 testCreateSuccess1(); 42 testCreateSuccess2(); 43 testCreateSuccess3(); 44 testCreateSuccess4(); 45 testCreateSuccess5(); 46 } 47 48 /* 49 * The following tests simulate a creation failure of every possible 50 * resource in an ARM block, and check to make sure that the failure 51 * prevents creation of subsequent resources, and that all created 52 * resources are properly closed, even if one or more of the close 53 * attempts fails. 54 */ 55 56 public static void testCreateFailure1() { 57 int creationFailuresDetected = 0; 58 List<Integer> closedList = new ArrayList<Integer>(0); 59 try (Resource r0 = createResource(0, 0, 0, closedList)) { 60 throw new AssertionError("Resource creation succeeded"); 61 } catch (Resource.CreateFailException e) { 62 creationFailuresDetected++; 63 if (e.resourceId() != 0) { 64 throw new AssertionError("Wrong resource creation " 65 + e.resourceId() + " failed"); 66 } 67 } catch (Resource.CloseFailException e) { 68 throw new AssertionError("Unexpected CloseFailException: " + e.resourceId()); 69 } 70 checkForSingleCreationFailure(creationFailuresDetected); 71 checkClosedList(closedList, 0); 72 } 73 74 public static void testCreateFailure2() { 75 for (int createFailureId = 0; createFailureId < 2; createFailureId++) { 76 for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) { 77 int creationFailuresDetected = 0; 78 List<Integer> closedList = new ArrayList<Integer>(); 79 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList); 80 Resource r1 = createResource(1, createFailureId, bitMap, closedList)) { 81 throw new AssertionError("Entire resource creation succeeded"); 82 } catch (Resource.CreateFailException e) { 83 creationFailuresDetected++; 84 checkCreateFailureId(e.resourceId(), createFailureId); 85 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 86 } catch (Resource.CloseFailException e) { 87 throw new AssertionError("Secondary exception suppression failed"); 88 } 89 checkForSingleCreationFailure(creationFailuresDetected); 90 checkClosedList(closedList, createFailureId); 91 } 92 } 93 } 94 95 public static void testCreateFailure3() { 96 for (int createFailureId = 0; createFailureId < 3; createFailureId++) { 97 for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) { 98 int creationFailuresDetected = 0; 99 List<Integer> closedList = new ArrayList<Integer>(); 100 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList); 101 Resource r1 = createResource(1, createFailureId, bitMap, closedList); 102 Resource r2 = createResource(2, createFailureId, bitMap, closedList)) { 103 throw new AssertionError("Entire resource creation succeeded"); 104 } catch (Resource.CreateFailException e) { 105 creationFailuresDetected++; 106 checkCreateFailureId(e.resourceId(), createFailureId); 107 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 108 } catch (Resource.CloseFailException e) { 109 throw new AssertionError("Secondary exception suppression failed:" + e); 110 } 111 checkForSingleCreationFailure(creationFailuresDetected); 112 checkClosedList(closedList, createFailureId); 113 } 114 } 115 } 116 117 public static void testCreateFailure4() { 118 for (int createFailureId = 0; createFailureId < 4; createFailureId++) { 119 for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) { 120 int creationFailuresDetected = 0; 121 List<Integer> closedList = new ArrayList<Integer>(); 122 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList); 123 Resource r1 = createResource(1, createFailureId, bitMap, closedList); 124 Resource r2 = createResource(2, createFailureId, bitMap, closedList); 125 Resource r3 = createResource(3, createFailureId, bitMap, closedList)) { 126 throw new AssertionError("Entire resource creation succeeded"); 127 } catch (Resource.CreateFailException e) { 128 creationFailuresDetected++; 129 checkCreateFailureId(e.resourceId(), createFailureId); 130 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 131 } catch (Resource.CloseFailException e) { 132 throw new AssertionError("Secondary exception suppression failed:" + e); 133 } 134 checkForSingleCreationFailure(creationFailuresDetected); 135 checkClosedList(closedList, createFailureId); 136 } 137 } 138 } 139 140 public static void testCreateFailure5() { 141 for (int createFailureId = 0; createFailureId < 5; createFailureId++) { 142 for (int bitMap = 0, n = 1 << createFailureId; bitMap < n; bitMap++) { 143 int creationFailuresDetected = 0; 144 List<Integer> closedList = new ArrayList<Integer>(); 145 try (Resource r0 = createResource(0, createFailureId, bitMap, closedList); 146 Resource r1 = createResource(1, createFailureId, bitMap, closedList); 147 Resource r2 = createResource(2, createFailureId, bitMap, closedList); 148 Resource r3 = createResource(3, createFailureId, bitMap, closedList); 149 Resource r4 = createResource(4, createFailureId, bitMap, closedList)) { 150 throw new AssertionError("Entire resource creation succeeded"); 151 } catch (Resource.CreateFailException e) { 152 creationFailuresDetected++; 153 checkCreateFailureId(e.resourceId(), createFailureId); 154 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 155 } catch (Resource.CloseFailException e) { 156 throw new AssertionError("Secondary exception suppression failed:" + e); 157 } 158 checkForSingleCreationFailure(creationFailuresDetected); 159 checkClosedList(closedList, createFailureId); 160 } 161 } 162 } 163 164 /** 165 * Create a resource with the specified ID. The ID must be less than createFailureId. 166 * A subsequent attempt to close the resource will fail iff the corresponding bit 167 * is set in closeFailureBitMap. When an attempt is made to close this resource, 168 * its ID will be added to closedList, regardless of whether the attempt succeeds. 169 * 170 * @param id the ID of this resource 171 * @param createFailureId the ID of the resource whose creation will fail 172 * @param closeFailureBitMap a bit vector describing which resources should throw an 173 * exception when close is attempted 174 * @param closedList a list on which to record resource close attempts 175 * @throws AssertionError if no attempt should be made to create this resource 176 */ 177 private static Resource createResource(int id, 178 int createFailureId, 179 int closeFailureBitMap, 180 List<Integer> closedList) throws Resource.CreateFailException { 181 if (id > createFailureId) 182 throw new AssertionError("Resource " + id + " shouldn't be created"); 183 boolean createSucceeds = id != createFailureId; 184 boolean closeSucceeds = (closeFailureBitMap & (1 << id)) == 0; 185 return new Resource(id, createSucceeds, closeSucceeds, closedList); 186 } 187 188 189 /** 190 * Check that an observed creation failure has the expected resource ID. 191 * 192 * @param foundId the ID of the resource whose creation failed 193 * @param expectedId the ID of the resource whose creation should have failed 194 */ 195 private static void checkCreateFailureId(int foundId, int expectedId) { 196 if (foundId != expectedId) 197 throw new AssertionError("Wrong resource creation failed. Found ID " 198 + foundId + " expected " + expectedId); 199 } 200 201 /** 202 * Check for proper suppressed exceptions in proper order. 203 * 204 * @param suppressedExceptions the suppressed exceptions array returned by 205 * getSuppressedExceptions() 206 * @bitmap a bitmap indicating which suppressed exceptions are expected. 207 * Bit i is set iff id should throw a CloseFailException. 208 */ 209 private static void checkSuppressedExceptions(Throwable[] suppressedExceptions, int bitMap) { 210 if (suppressedExceptions.length != Integer.bitCount(bitMap)) 211 throw new AssertionError("Expected " + Integer.bitCount(bitMap) 212 + " suppressed exceptions, got " + suppressedExceptions.length); 213 214 int prevCloseFailExceptionId = Integer.MAX_VALUE; 215 for (Throwable t : suppressedExceptions) { 216 int id = ((Resource.CloseFailException) t).resourceId(); 217 if ((1 << id & bitMap) == 0) 218 throw new AssertionError("Unexpected suppressed CloseFailException: " + id); 219 if (id > prevCloseFailExceptionId) 220 throw new AssertionError("Suppressed CloseFailException" + id 221 + " followed " + prevCloseFailExceptionId); 222 } 223 } 224 225 /** 226 * Check that exactly one resource creation failed. 227 * 228 * @param numCreationFailuresDetected the number of creation failures detected 229 */ 230 private static void checkForSingleCreationFailure(int numCreationFailuresDetected) { 231 if (numCreationFailuresDetected != 1) 232 throw new AssertionError("Wrong number of creation failures: " 233 + numCreationFailuresDetected); 234 } 235 236 /** 237 * Check that a close was attempted on every resourced that was successfully opened, 238 * and that the close attempts occurred in the proper order. 239 * 240 * @param closedList the resource IDs of the close attempts, in the order they occurred 241 * @param the ID of the resource whose creation failed. Close attempts should occur 242 * for all previous resources, in reverse order. 243 * 244 */ 245 private static void checkClosedList(List<Integer> closedList, int createFailureId) { 246 List<Integer> expectedList = new ArrayList<Integer>(createFailureId); 247 for (int i = createFailureId - 1; i >= 0; i--) 248 expectedList.add(i); 249 if (!closedList.equals(expectedList)) 250 throw new AssertionError("Closing sequence " + closedList + " != " + expectedList); 251 } 252 253 /* 254 * The following tests simulate the creation of several resources, followed 255 * by success or failure of forward processing. They test that all resources 256 * are properly closed, even if one or more of the close attempts fails. 257 */ 258 259 public static void testCreateSuccess1() { 260 for (int bitMap = 0, n = 1 << 1; bitMap < n; bitMap++) { 261 for (int failure = 0; failure < 2; failure++) { 262 List<Integer> closedList = new ArrayList<Integer>(); 263 try (Resource r0 = createResource(0, bitMap, closedList)) { 264 if (failure != 0) 265 throw new MyKindOfException(); 266 } catch (Resource.CreateFailException e) { 267 throw new AssertionError( 268 "Resource creation failed: " + e.resourceId()); 269 } catch (MyKindOfException e) { 270 if (failure == 0) 271 throw new AssertionError("Unexpected MyKindOfException"); 272 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 273 } catch (Resource.CloseFailException e) { 274 if (failure == 1) 275 throw new AssertionError("Secondary exception suppression failed"); 276 int id = e.resourceId(); 277 if (bitMap == 0) 278 throw new AssertionError("Unexpected CloseFailException: " + id); 279 int highestCloseFailBit = Integer.highestOneBit(bitMap); 280 if (1 << id != highestCloseFailBit) { 281 throw new AssertionError("CloseFailException: got id " + id 282 + ", expected lg(" + highestCloseFailBit +")"); 283 } 284 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); 285 } 286 checkClosedList(closedList, 1); 287 } 288 } 289 } 290 291 public static void testCreateSuccess2() { 292 for (int bitMap = 0, n = 1 << 2; bitMap < n; bitMap++) { 293 for (int failure = 0; failure < 2; failure++) { 294 List<Integer> closedList = new ArrayList<Integer>(); 295 try (Resource r0 = createResource(0, bitMap, closedList); 296 Resource r1 = createResource(1, bitMap, closedList)) { 297 if (failure != 0) 298 throw new MyKindOfException(); 299 } catch (Resource.CreateFailException e) { 300 throw new AssertionError( 301 "Resource creation failed: " + e.resourceId()); 302 } catch (MyKindOfException e) { 303 if (failure == 0) 304 throw new AssertionError("Unexpected MyKindOfException"); 305 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 306 } catch (Resource.CloseFailException e) { 307 if (failure == 1) 308 throw new AssertionError("Secondary exception suppression failed"); 309 int id = e.resourceId(); 310 if (bitMap == 0) 311 throw new AssertionError("Unexpected CloseFailException: " + id); 312 int highestCloseFailBit = Integer.highestOneBit(bitMap); 313 if (1 << id != highestCloseFailBit) { 314 throw new AssertionError("CloseFailException: got id " + id 315 + ", expected lg(" + highestCloseFailBit +")"); 316 } 317 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); 318 } 319 checkClosedList(closedList, 2); 320 } 321 } 322 } 323 324 public static void testCreateSuccess3() { 325 for (int bitMap = 0, n = 1 << 3; bitMap < n; bitMap++) { 326 for (int failure = 0; failure < 2; failure++) { 327 List<Integer> closedList = new ArrayList<Integer>(); 328 try (Resource r0 = createResource(0, bitMap, closedList); 329 Resource r1 = createResource(1, bitMap, closedList); 330 Resource r2 = createResource(2, bitMap, closedList)) { 331 if (failure != 0) 332 throw new MyKindOfException(); 333 } catch (Resource.CreateFailException e) { 334 throw new AssertionError( 335 "Resource creation failed: " + e.resourceId()); 336 } catch (MyKindOfException e) { 337 if (failure == 0) 338 throw new AssertionError("Unexpected MyKindOfException"); 339 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 340 } catch (Resource.CloseFailException e) { 341 if (failure == 1) 342 throw new AssertionError("Secondary exception suppression failed"); 343 int id = e.resourceId(); 344 if (bitMap == 0) 345 throw new AssertionError("Unexpected CloseFailException: " + id); 346 int highestCloseFailBit = Integer.highestOneBit(bitMap); 347 if (1 << id != highestCloseFailBit) { 348 throw new AssertionError("CloseFailException: got id " + id 349 + ", expected lg(" + highestCloseFailBit +")"); 350 } 351 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); 352 } 353 checkClosedList(closedList, 3); 354 } 355 } 356 } 357 358 public static void testCreateSuccess4() { 359 for (int bitMap = 0, n = 1 << 4; bitMap < n; bitMap++) { 360 for (int failure = 0; failure < 2; failure++) { 361 List<Integer> closedList = new ArrayList<Integer>(); 362 try (Resource r0 = createResource(0, bitMap, closedList); 363 Resource r1 = createResource(1, bitMap, closedList); 364 Resource r2 = createResource(2, bitMap, closedList); 365 Resource r3 = createResource(3, bitMap, closedList)) { 366 if (failure != 0) 367 throw new MyKindOfException(); 368 } catch (Resource.CreateFailException e) { 369 throw new AssertionError( 370 "Resource creation failed: " + e.resourceId()); 371 } catch (MyKindOfException e) { 372 if (failure == 0) 373 throw new AssertionError("Unexpected MyKindOfException"); 374 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 375 } catch (Resource.CloseFailException e) { 376 if (failure == 1) 377 throw new AssertionError("Secondary exception suppression failed"); 378 int id = e.resourceId(); 379 if (bitMap == 0) 380 throw new AssertionError("Unexpected CloseFailException: " + id); 381 int highestCloseFailBit = Integer.highestOneBit(bitMap); 382 if (1 << id != highestCloseFailBit) { 383 throw new AssertionError("CloseFailException: got id " + id 384 + ", expected lg(" + highestCloseFailBit +")"); 385 } 386 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); 387 } 388 checkClosedList(closedList, 4); 389 } 390 } 391 } 392 393 public static void testCreateSuccess5() { 394 for (int bitMap = 0, n = 1 << 5; bitMap < n; bitMap++) { 395 for (int failure = 0; failure < 2; failure++) { 396 List<Integer> closedList = new ArrayList<Integer>(); 397 try (Resource r0 = createResource(0, bitMap, closedList); 398 Resource r1 = createResource(1, bitMap, closedList); 399 Resource r2 = createResource(2, bitMap, closedList); 400 Resource r3 = createResource(3, bitMap, closedList); 401 Resource r4 = createResource(4, bitMap, closedList)) { 402 if (failure != 0) 403 throw new MyKindOfException(); 404 } catch (Resource.CreateFailException e) { 405 throw new AssertionError("Resource creation failed: " + e.resourceId()); 406 } catch (MyKindOfException e) { 407 if (failure == 0) 408 throw new AssertionError("Unexpected MyKindOfException"); 409 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap); 410 } catch (Resource.CloseFailException e) { 411 if (failure == 1) 412 throw new AssertionError("Secondary exception suppression failed"); 413 int id = e.resourceId(); 414 if (bitMap == 0) 415 throw new AssertionError("Unexpected CloseFailException: " + id); 416 int highestCloseFailBit = Integer.highestOneBit(bitMap); 417 if (1 << id != highestCloseFailBit) { 418 throw new AssertionError("CloseFailException: got id " + id 419 + ", expected lg(" + highestCloseFailBit +")"); 420 } 421 checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit); 422 } 423 checkClosedList(closedList, 5); 424 } 425 } 426 } 427 428 private static Resource createResource(int id, 429 int closeFailureBitMap, 430 List<Integer> closedList) throws Resource.CreateFailException { 431 boolean closeSucceeds = (closeFailureBitMap & (1 << id)) == 0; 432 return new Resource(id, true, closeSucceeds, closedList); 433 } 434 435 private static class MyKindOfException extends Exception { 436 } 437 } 438 439 class Resource implements AutoCloseable { 440 /** A number identifying this resource */ 441 private final int resourceId; 442 443 /** Whether the close call on this resource should succeed or fail */ 444 private final boolean closeSucceeds; 445 446 /** When resource is closed, it records its ID in this list */ 447 private final List<Integer> closedList; 448 449 Resource(int resourceId, boolean createSucceeds, boolean closeSucceeds, 450 List<Integer> closedList) throws CreateFailException { 451 if (!createSucceeds) 452 throw new CreateFailException(resourceId); 453 this.resourceId = resourceId; 454 this.closeSucceeds = closeSucceeds; 455 this.closedList = closedList; 456 } 457 458 public void close() throws CloseFailException { 459 closedList.add(resourceId); 460 if (!closeSucceeds) 461 throw new CloseFailException(resourceId); 462 } 463 464 public static class ResourceException extends RuntimeException { 465 private final int resourceId; 466 467 public ResourceException(int resourceId) { 468 super("Resource ID = " + resourceId); 469 this.resourceId = resourceId; 470 } 471 472 public int resourceId() { 473 return resourceId; 474 } 475 } 476 477 public static class CreateFailException extends ResourceException { 478 public CreateFailException(int resourceId) { 479 super(resourceId); 480 } 481 } 482 483 public static class CloseFailException extends ResourceException { 484 public CloseFailException(int resourceId) { 485 super(resourceId); 486 } 487 } 488 }