You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Injection.java 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 1998-2002 PARC Inc. All rights reserved.
  3. *
  4. * Use and copying of this software and preparation of derivative works based
  5. * upon this software are permitted. Any distribution of this software or
  6. * derivative works must comply with all applicable United States export
  7. * control laws.
  8. *
  9. * This software is made available AS IS, and PARC Inc. makes no
  10. * warranty about the software, its performance or its conformity to any
  11. * specification.
  12. */
  13. import java.io.*;
  14. /**
  15. * Demonstrate technique of fault-injection
  16. * as coordinated by test driver.
  17. * @author Wes Isberg
  18. */
  19. aspect InjectingIOException {
  20. // article page 43 - fault injection
  21. // START-SAMPLE testing-inoculated-injectIOException Inject IOException on test driver command
  22. /** the test starts when the driver starts executing */
  23. pointcut testEntryPoint(TestDriver driver) :
  24. target(driver) && execution(* TestDriver.startTest());
  25. /**
  26. * The fault may be injected at the execution of any
  27. * (non-static) PrinterStream method that throws an IOException
  28. */
  29. pointcut testCheckPoint(PrinterStream stream) : target(stream)
  30. && execution(public * PrinterStream+.*(..) throws IOException);
  31. /**
  32. * After the method returns normally, query the
  33. * test driver to see if we should instead throw
  34. * an exception ("inject" the fault).
  35. */
  36. after (TestDriver driver, PrinterStream stream) returning
  37. throws IOException :
  38. cflowbelow(testEntryPoint(driver))
  39. && testCheckPoint(stream) {
  40. IOException e = driver.createException(stream);
  41. if (null != e) {
  42. System.out.println("InjectingIOException - injecting " + e);
  43. throw e;
  44. }
  45. }
  46. /* Comment on the after advice IOException declaration:
  47. "throws IOException" is a declaration of the advice,
  48. not the pointcut.
  49. Since the advice might throw the injected fault, it
  50. must declare that it throws IOException. When advice declares
  51. exceptions thrown, the compiler will emit an error if any
  52. join point is not also declared to throw an IOException.
  53. In this case, the testCheckPoint pointcut only picks out
  54. methods that throw IOException, so the compile will not
  55. signal any errors.
  56. */
  57. // END-SAMPLE testing-inoculated-injectIOException
  58. }
  59. /** this runs the test case */
  60. public class Injection {
  61. /** Run three print jobs, two as a test and one normally */
  62. public static void main(String[] args) throws Exception {
  63. Runnable r = new Runnable() {
  64. public void run() {
  65. try { new TestDriver().startTest(); }
  66. catch (IOException e) {
  67. System.err.println("got expected injected error " + e.getMessage());
  68. }
  69. }
  70. };
  71. System.out.println("Injection.main() - starting separate test thread");
  72. Thread t = new Thread(r);
  73. t.start();
  74. System.out.println("Injection.main() - running test in this thread");
  75. r.run();
  76. t.join();
  77. System.out.println("Injection.main() - running job normally, not by TestDriver");
  78. new PrintJob().runPrintJob();
  79. }
  80. }
  81. /** handle starting of test and determining whether to inject failure */
  82. class TestDriver {
  83. /** start a new test */
  84. public void startTest() throws IOException {
  85. new PrintJob().runPrintJob();
  86. }
  87. /** this implementation always injects a failure */
  88. public IOException createException(PrinterStream p) {
  89. return new IOException(""+p);
  90. }
  91. }
  92. //--------------------------------------- target classes
  93. class PrintJob {
  94. /** this job writes to the printer stream */
  95. void runPrintJob() throws IOException {
  96. new PrinterStream().write();
  97. }
  98. }
  99. class PrinterStream {
  100. /** this printer stream writes without exception */
  101. public void write() throws IOException {
  102. System.err.println("PrinterStream.write() - not throwing exception");
  103. }
  104. }