View Javadoc
1   package org.junit.tests.experimental.rules;
2   
3   import static org.hamcrest.CoreMatchers.containsString;
4   import static org.junit.Assert.assertEquals;
5   import static org.junit.Assert.assertThat;
6   
7   import java.io.File;
8   import java.io.IOException;
9   import java.io.InterruptedIOException;
10  import java.io.RandomAccessFile;
11  import java.nio.ByteBuffer;
12  import java.nio.channels.FileChannel;
13  import java.util.Random;
14  import java.util.concurrent.TimeUnit;
15  import java.util.concurrent.locks.ReentrantLock;
16  
17  import org.junit.After;
18  import org.junit.Before;
19  import org.junit.Rule;
20  import org.junit.Test;
21  import org.junit.rules.TemporaryFolder;
22  import org.junit.rules.TestRule;
23  import org.junit.rules.Timeout;
24  import org.junit.runner.JUnitCore;
25  import org.junit.runner.Result;
26  import org.junit.runner.notification.Failure;
27  
28  public class TimeoutRuleTest {
29      private static final ReentrantLock run1Lock = new ReentrantLock();
30  
31      private static volatile boolean run4done = false;
32  
33      public abstract static class AbstractTimeoutTest {
34          public static final StringBuffer logger = new StringBuffer();
35  
36          @Rule
37          public final TemporaryFolder tmpFile = new TemporaryFolder();
38  
39          @Test
40          public void run1() throws InterruptedException {
41              logger.append("run1");
42              TimeoutRuleTest.run1Lock.lockInterruptibly();
43              TimeoutRuleTest.run1Lock.unlock();
44          }
45  
46          @Test
47          public void run2() throws InterruptedException {
48              logger.append("run2");
49              Thread.currentThread().join();
50          }
51  
52          @Test
53          public synchronized void run3() throws InterruptedException {
54              logger.append("run3");
55              wait();
56          }
57  
58          @Test
59          public void run4() {
60              logger.append("run4");
61              while (!run4done) {
62              }
63          }
64  
65          @Test
66          public void run5() throws IOException {
67              logger.append("run5");
68              Random rnd = new Random();
69              byte[] data = new byte[1024];
70              File tmp = tmpFile.newFile();
71              while (true) {
72                  RandomAccessFile randomAccessFile = new RandomAccessFile(tmp, "rw");
73                  try {
74                      FileChannel channel = randomAccessFile.getChannel();
75                      rnd.nextBytes(data);
76                      ByteBuffer buffer = ByteBuffer.wrap(data);
77                      // Interrupted thread closes channel and throws ClosedByInterruptException.
78                      channel.write(buffer);
79                  } finally {
80                      randomAccessFile.close();
81                  }
82                  tmp.delete();
83              }
84          }
85  
86          @Test
87          public void run6() throws InterruptedIOException {
88              logger.append("run6");
89              // Java IO throws InterruptedIOException only on SUN machines.
90              throw new InterruptedIOException();
91          }
92      }
93  
94      public static class HasGlobalLongTimeout extends AbstractTimeoutTest {
95  
96          @Rule
97          public final TestRule globalTimeout = Timeout.millis(200);
98      }
99  
100     public static class HasGlobalTimeUnitTimeout extends AbstractTimeoutTest {
101 
102         @Rule
103         public final TestRule globalTimeout = new Timeout(200, TimeUnit.MILLISECONDS);
104     }
105     
106     public static class HasNullTimeUnit {
107 
108         @Rule
109         public final TestRule globalTimeout = new Timeout(200, null);
110         
111         @Test
112         public void wouldPass() {
113         }
114     }
115 
116     @Before
117     public void before() {
118         run4done = false;
119         run1Lock.lock();
120     }
121 
122     @After
123     public void after() {
124         // set run4done to make sure that the thread won't continue at run4()
125         run4done = true;
126         run1Lock.unlock();
127     }
128 
129     @Test
130     public void timeUnitTimeout() {
131         HasGlobalTimeUnitTimeout.logger.setLength(0);
132         Result result = JUnitCore.runClasses(HasGlobalTimeUnitTimeout.class);
133         assertEquals(6, result.getFailureCount());
134         assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run1"));
135         assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run2"));
136         assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run3"));
137         assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run4"));
138         assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run5"));
139         assertThat(HasGlobalTimeUnitTimeout.logger.toString(), containsString("run6"));
140     }
141 
142     @Test
143     public void longTimeout() {
144         HasGlobalLongTimeout.logger.setLength(0);
145         Result result = JUnitCore.runClasses(HasGlobalLongTimeout.class);
146         assertEquals(6, result.getFailureCount());
147         assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run1"));
148         assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run2"));
149         assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run3"));
150         assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run4"));
151         assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run5"));
152         assertThat(HasGlobalLongTimeout.logger.toString(), containsString("run6"));
153     }
154 
155     @Test
156     public void nullTimeUnit() {
157         Result result = JUnitCore.runClasses(HasNullTimeUnit.class);
158         assertEquals(1, result.getFailureCount());
159         Failure failure = result.getFailures().get(0);
160         assertThat(failure.getException().getMessage(),
161                 containsString("Invalid parameters for Timeout"));
162         Throwable cause = failure.getException().getCause();
163         assertThat(cause.getMessage(), containsString("TimeUnit cannot be null"));
164     }
165 }