1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 */
22
23/*
24 * This file is available under and governed by the GNU General Public
25 * License version 2 only, as published by the Free Software Foundation.
26 * However, the following notice accompanied the original version of this
27 * file:
28 *
29 * Written by Doug Lea with assistance from members of JCP JSR-166
30 * Expert Group and released to the public domain, as explained at
31 * http://creativecommons.org/publicdomain/zero/1.0/
32 * Other contributors include Andrew Wright, Jeffrey Hayes,
33 * Pat Fisher, Mike Judd.
34 */
35
36import static java.util.concurrent.TimeUnit.DAYS;
37import static java.util.concurrent.TimeUnit.HOURS;
38import static java.util.concurrent.TimeUnit.MICROSECONDS;
39import static java.util.concurrent.TimeUnit.MILLISECONDS;
40import static java.util.concurrent.TimeUnit.MINUTES;
41import static java.util.concurrent.TimeUnit.NANOSECONDS;
42import static java.util.concurrent.TimeUnit.SECONDS;
43
44import java.util.concurrent.CountDownLatch;
45import java.util.concurrent.TimeUnit;
46
47import junit.framework.Test;
48import junit.framework.TestSuite;
49
50public class TimeUnitTest extends JSR166TestCase {
51    public static void main(String[] args) {
52        main(suite(), args);
53    }
54
55    public static Test suite() {
56        return new TestSuite(TimeUnitTest.class);
57    }
58
59    // (loops to 88888 check increments at all time divisions.)
60
61    /**
62     * convert correctly converts sample values across the units
63     */
64    public void testConvert() {
65        for (long t = 0; t < 88888; ++t) {
66            assertEquals(t*60*60*24,
67                         SECONDS.convert(t, DAYS));
68            assertEquals(t*60*60,
69                         SECONDS.convert(t, HOURS));
70            assertEquals(t*60,
71                         SECONDS.convert(t, MINUTES));
72            assertEquals(t,
73                         SECONDS.convert(t, SECONDS));
74            assertEquals(t,
75                         SECONDS.convert(1000L*t, MILLISECONDS));
76            assertEquals(t,
77                         SECONDS.convert(1000000L*t, MICROSECONDS));
78            assertEquals(t,
79                         SECONDS.convert(1000000000L*t, NANOSECONDS));
80
81            assertEquals(1000L*t*60*60*24,
82                         MILLISECONDS.convert(t, DAYS));
83            assertEquals(1000L*t*60*60,
84                         MILLISECONDS.convert(t, HOURS));
85            assertEquals(1000L*t*60,
86                         MILLISECONDS.convert(t, MINUTES));
87            assertEquals(1000L*t,
88                         MILLISECONDS.convert(t, SECONDS));
89            assertEquals(t,
90                         MILLISECONDS.convert(t, MILLISECONDS));
91            assertEquals(t,
92                         MILLISECONDS.convert(1000L*t, MICROSECONDS));
93            assertEquals(t,
94                         MILLISECONDS.convert(1000000L*t, NANOSECONDS));
95
96            assertEquals(1000000L*t*60*60*24,
97                         MICROSECONDS.convert(t, DAYS));
98            assertEquals(1000000L*t*60*60,
99                         MICROSECONDS.convert(t, HOURS));
100            assertEquals(1000000L*t*60,
101                         MICROSECONDS.convert(t, MINUTES));
102            assertEquals(1000000L*t,
103                         MICROSECONDS.convert(t, SECONDS));
104            assertEquals(1000L*t,
105                         MICROSECONDS.convert(t, MILLISECONDS));
106            assertEquals(t,
107                         MICROSECONDS.convert(t, MICROSECONDS));
108            assertEquals(t,
109                         MICROSECONDS.convert(1000L*t, NANOSECONDS));
110
111            assertEquals(1000000000L*t*60*60*24,
112                         NANOSECONDS.convert(t, DAYS));
113            assertEquals(1000000000L*t*60*60,
114                         NANOSECONDS.convert(t, HOURS));
115            assertEquals(1000000000L*t*60,
116                         NANOSECONDS.convert(t, MINUTES));
117            assertEquals(1000000000L*t,
118                         NANOSECONDS.convert(t, SECONDS));
119            assertEquals(1000000L*t,
120                         NANOSECONDS.convert(t, MILLISECONDS));
121            assertEquals(1000L*t,
122                         NANOSECONDS.convert(t, MICROSECONDS));
123            assertEquals(t,
124                         NANOSECONDS.convert(t, NANOSECONDS));
125        }
126
127        for (TimeUnit x : TimeUnit.values()) {
128            long[] zs = {
129                0, 1, -1,
130                Integer.MAX_VALUE, Integer.MIN_VALUE,
131                Long.MAX_VALUE, Long.MIN_VALUE,
132            };
133            for (long z : zs) assertEquals(z, x.convert(z, x));
134        }
135    }
136
137    /**
138     * toNanos correctly converts sample values in different units to
139     * nanoseconds
140     */
141    public void testToNanos() {
142        for (long t = 0; t < 88888; ++t) {
143            assertEquals(t*1000000000L*60*60*24,
144                         DAYS.toNanos(t));
145            assertEquals(t*1000000000L*60*60,
146                         HOURS.toNanos(t));
147            assertEquals(t*1000000000L*60,
148                         MINUTES.toNanos(t));
149            assertEquals(1000000000L*t,
150                         SECONDS.toNanos(t));
151            assertEquals(1000000L*t,
152                         MILLISECONDS.toNanos(t));
153            assertEquals(1000L*t,
154                         MICROSECONDS.toNanos(t));
155            assertEquals(t,
156                         NANOSECONDS.toNanos(t));
157        }
158    }
159
160    /**
161     * toMicros correctly converts sample values in different units to
162     * microseconds
163     */
164    public void testToMicros() {
165        for (long t = 0; t < 88888; ++t) {
166            assertEquals(t*1000000L*60*60*24,
167                         DAYS.toMicros(t));
168            assertEquals(t*1000000L*60*60,
169                         HOURS.toMicros(t));
170            assertEquals(t*1000000L*60,
171                         MINUTES.toMicros(t));
172            assertEquals(1000000L*t,
173                         SECONDS.toMicros(t));
174            assertEquals(1000L*t,
175                         MILLISECONDS.toMicros(t));
176            assertEquals(t,
177                         MICROSECONDS.toMicros(t));
178            assertEquals(t,
179                         NANOSECONDS.toMicros(t*1000L));
180        }
181    }
182
183    /**
184     * toMillis correctly converts sample values in different units to
185     * milliseconds
186     */
187    public void testToMillis() {
188        for (long t = 0; t < 88888; ++t) {
189            assertEquals(t*1000L*60*60*24,
190                         DAYS.toMillis(t));
191            assertEquals(t*1000L*60*60,
192                         HOURS.toMillis(t));
193            assertEquals(t*1000L*60,
194                         MINUTES.toMillis(t));
195            assertEquals(1000L*t,
196                         SECONDS.toMillis(t));
197            assertEquals(t,
198                         MILLISECONDS.toMillis(t));
199            assertEquals(t,
200                         MICROSECONDS.toMillis(t*1000L));
201            assertEquals(t,
202                         NANOSECONDS.toMillis(t*1000000L));
203        }
204    }
205
206    /**
207     * toSeconds correctly converts sample values in different units to
208     * seconds
209     */
210    public void testToSeconds() {
211        for (long t = 0; t < 88888; ++t) {
212            assertEquals(t*60*60*24,
213                         DAYS.toSeconds(t));
214            assertEquals(t*60*60,
215                         HOURS.toSeconds(t));
216            assertEquals(t*60,
217                         MINUTES.toSeconds(t));
218            assertEquals(t,
219                         SECONDS.toSeconds(t));
220            assertEquals(t,
221                         MILLISECONDS.toSeconds(t*1000L));
222            assertEquals(t,
223                         MICROSECONDS.toSeconds(t*1000000L));
224            assertEquals(t,
225                         NANOSECONDS.toSeconds(t*1000000000L));
226        }
227    }
228
229    /**
230     * toMinutes correctly converts sample values in different units to
231     * minutes
232     */
233    public void testToMinutes() {
234        for (long t = 0; t < 88888; ++t) {
235            assertEquals(t*60*24,
236                         DAYS.toMinutes(t));
237            assertEquals(t*60,
238                         HOURS.toMinutes(t));
239            assertEquals(t,
240                         MINUTES.toMinutes(t));
241            assertEquals(t,
242                         SECONDS.toMinutes(t*60));
243            assertEquals(t,
244                         MILLISECONDS.toMinutes(t*1000L*60));
245            assertEquals(t,
246                         MICROSECONDS.toMinutes(t*1000000L*60));
247            assertEquals(t,
248                         NANOSECONDS.toMinutes(t*1000000000L*60));
249        }
250    }
251
252    /**
253     * toHours correctly converts sample values in different units to
254     * hours
255     */
256    public void testToHours() {
257        for (long t = 0; t < 88888; ++t) {
258            assertEquals(t*24,
259                         DAYS.toHours(t));
260            assertEquals(t,
261                         HOURS.toHours(t));
262            assertEquals(t,
263                         MINUTES.toHours(t*60));
264            assertEquals(t,
265                         SECONDS.toHours(t*60*60));
266            assertEquals(t,
267                         MILLISECONDS.toHours(t*1000L*60*60));
268            assertEquals(t,
269                         MICROSECONDS.toHours(t*1000000L*60*60));
270            assertEquals(t,
271                         NANOSECONDS.toHours(t*1000000000L*60*60));
272        }
273    }
274
275    /**
276     * toDays correctly converts sample values in different units to
277     * days
278     */
279    public void testToDays() {
280        for (long t = 0; t < 88888; ++t) {
281            assertEquals(t,
282                         DAYS.toDays(t));
283            assertEquals(t,
284                         HOURS.toDays(t*24));
285            assertEquals(t,
286                         MINUTES.toDays(t*60*24));
287            assertEquals(t,
288                         SECONDS.toDays(t*60*60*24));
289            assertEquals(t,
290                         MILLISECONDS.toDays(t*1000L*60*60*24));
291            assertEquals(t,
292                         MICROSECONDS.toDays(t*1000000L*60*60*24));
293            assertEquals(t,
294                         NANOSECONDS.toDays(t*1000000000L*60*60*24));
295        }
296    }
297
298    /**
299     * convert saturates positive too-large values to Long.MAX_VALUE
300     * and negative to LONG.MIN_VALUE
301     */
302    public void testConvertSaturate() {
303        assertEquals(Long.MAX_VALUE,
304                     NANOSECONDS.convert(Long.MAX_VALUE / 2, SECONDS));
305        assertEquals(Long.MIN_VALUE,
306                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, SECONDS));
307        assertEquals(Long.MAX_VALUE,
308                     NANOSECONDS.convert(Long.MAX_VALUE / 2, MINUTES));
309        assertEquals(Long.MIN_VALUE,
310                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, MINUTES));
311        assertEquals(Long.MAX_VALUE,
312                     NANOSECONDS.convert(Long.MAX_VALUE / 2, HOURS));
313        assertEquals(Long.MIN_VALUE,
314                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, HOURS));
315        assertEquals(Long.MAX_VALUE,
316                     NANOSECONDS.convert(Long.MAX_VALUE / 2, DAYS));
317        assertEquals(Long.MIN_VALUE,
318                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, DAYS));
319
320        for (TimeUnit x : TimeUnit.values())
321            for (TimeUnit y : TimeUnit.values()) {
322                long ratio = x.toNanos(1) / y.toNanos(1);
323                if (ratio >= 1) {
324                    assertEquals(ratio, y.convert(1, x));
325                    assertEquals(1, x.convert(ratio, y));
326                    long max = Long.MAX_VALUE/ratio;
327                    assertEquals(max * ratio, y.convert(max, x));
328                    assertEquals(-max * ratio, y.convert(-max, x));
329                    assertEquals(max, x.convert(max * ratio, y));
330                    assertEquals(-max, x.convert(-max * ratio, y));
331                    if (max < Long.MAX_VALUE) {
332                        assertEquals(Long.MAX_VALUE, y.convert(max + 1, x));
333                        assertEquals(Long.MIN_VALUE, y.convert(-max - 1, x));
334                        assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE + 1, x));
335                    }
336                    assertEquals(Long.MAX_VALUE, y.convert(Long.MAX_VALUE, x));
337                    assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE, x));
338                }
339            }
340    }
341
342    /**
343     * toNanos saturates positive too-large values to Long.MAX_VALUE
344     * and negative to LONG.MIN_VALUE
345     */
346    public void testToNanosSaturate() {
347        assertEquals(Long.MAX_VALUE,
348                     MILLISECONDS.toNanos(Long.MAX_VALUE / 2));
349        assertEquals(Long.MIN_VALUE,
350                     MILLISECONDS.toNanos(-Long.MAX_VALUE / 3));
351
352        for (TimeUnit x : TimeUnit.values()) {
353            long ratio = x.toNanos(1) / NANOSECONDS.toNanos(1);
354            if (ratio >= 1) {
355                long max = Long.MAX_VALUE/ratio;
356                for (long z : new long[] {0, 1, -1, max, -max})
357                    assertEquals(z * ratio, x.toNanos(z));
358                if (max < Long.MAX_VALUE) {
359                    assertEquals(Long.MAX_VALUE, x.toNanos(max + 1));
360                    assertEquals(Long.MIN_VALUE, x.toNanos(-max - 1));
361                    assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE + 1));
362                }
363                assertEquals(Long.MAX_VALUE, x.toNanos(Long.MAX_VALUE));
364                assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE));
365                if (max < Integer.MAX_VALUE) {
366                    assertEquals(Long.MAX_VALUE, x.toNanos(Integer.MAX_VALUE));
367                    assertEquals(Long.MIN_VALUE, x.toNanos(Integer.MIN_VALUE));
368                }
369            }
370        }
371    }
372
373    /**
374     * toMicros saturates positive too-large values to Long.MAX_VALUE
375     * and negative to LONG.MIN_VALUE
376     */
377    public void testToMicrosSaturate() {
378        for (TimeUnit x : TimeUnit.values()) {
379            long ratio = x.toNanos(1) / MICROSECONDS.toNanos(1);
380            if (ratio >= 1) {
381                long max = Long.MAX_VALUE/ratio;
382                for (long z : new long[] {0, 1, -1, max, -max})
383                    assertEquals(z * ratio, x.toMicros(z));
384                if (max < Long.MAX_VALUE) {
385                    assertEquals(Long.MAX_VALUE, x.toMicros(max + 1));
386                    assertEquals(Long.MIN_VALUE, x.toMicros(-max - 1));
387                    assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE + 1));
388                }
389                assertEquals(Long.MAX_VALUE, x.toMicros(Long.MAX_VALUE));
390                assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE));
391                if (max < Integer.MAX_VALUE) {
392                    assertEquals(Long.MAX_VALUE, x.toMicros(Integer.MAX_VALUE));
393                    assertEquals(Long.MIN_VALUE, x.toMicros(Integer.MIN_VALUE));
394                }
395            }
396        }
397    }
398
399    /**
400     * toMillis saturates positive too-large values to Long.MAX_VALUE
401     * and negative to LONG.MIN_VALUE
402     */
403    public void testToMillisSaturate() {
404        for (TimeUnit x : TimeUnit.values()) {
405            long ratio = x.toNanos(1) / MILLISECONDS.toNanos(1);
406            if (ratio >= 1) {
407                long max = Long.MAX_VALUE/ratio;
408                for (long z : new long[] {0, 1, -1, max, -max})
409                    assertEquals(z * ratio, x.toMillis(z));
410                if (max < Long.MAX_VALUE) {
411                    assertEquals(Long.MAX_VALUE, x.toMillis(max + 1));
412                    assertEquals(Long.MIN_VALUE, x.toMillis(-max - 1));
413                    assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE + 1));
414                }
415                assertEquals(Long.MAX_VALUE, x.toMillis(Long.MAX_VALUE));
416                assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE));
417                if (max < Integer.MAX_VALUE) {
418                    assertEquals(Long.MAX_VALUE, x.toMillis(Integer.MAX_VALUE));
419                    assertEquals(Long.MIN_VALUE, x.toMillis(Integer.MIN_VALUE));
420                }
421            }
422        }
423    }
424
425    /**
426     * toSeconds saturates positive too-large values to Long.MAX_VALUE
427     * and negative to LONG.MIN_VALUE
428     */
429    public void testToSecondsSaturate() {
430        for (TimeUnit x : TimeUnit.values()) {
431            long ratio = x.toNanos(1) / SECONDS.toNanos(1);
432            if (ratio >= 1) {
433                long max = Long.MAX_VALUE/ratio;
434                for (long z : new long[] {0, 1, -1, max, -max})
435                    assertEquals(z * ratio, x.toSeconds(z));
436                if (max < Long.MAX_VALUE) {
437                    assertEquals(Long.MAX_VALUE, x.toSeconds(max + 1));
438                    assertEquals(Long.MIN_VALUE, x.toSeconds(-max - 1));
439                    assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE + 1));
440                }
441                assertEquals(Long.MAX_VALUE, x.toSeconds(Long.MAX_VALUE));
442                assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE));
443                if (max < Integer.MAX_VALUE) {
444                    assertEquals(Long.MAX_VALUE, x.toSeconds(Integer.MAX_VALUE));
445                    assertEquals(Long.MIN_VALUE, x.toSeconds(Integer.MIN_VALUE));
446                }
447            }
448        }
449    }
450
451    /**
452     * toMinutes saturates positive too-large values to Long.MAX_VALUE
453     * and negative to LONG.MIN_VALUE
454     */
455    public void testToMinutesSaturate() {
456        for (TimeUnit x : TimeUnit.values()) {
457            long ratio = x.toNanos(1) / MINUTES.toNanos(1);
458            if (ratio > 1) {
459                long max = Long.MAX_VALUE/ratio;
460                for (long z : new long[] {0, 1, -1, max, -max})
461                    assertEquals(z * ratio, x.toMinutes(z));
462                assertEquals(Long.MAX_VALUE, x.toMinutes(max + 1));
463                assertEquals(Long.MIN_VALUE, x.toMinutes(-max - 1));
464                assertEquals(Long.MAX_VALUE, x.toMinutes(Long.MAX_VALUE));
465                assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE));
466                assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE + 1));
467            }
468        }
469    }
470
471    /**
472     * toHours saturates positive too-large values to Long.MAX_VALUE
473     * and negative to LONG.MIN_VALUE
474     */
475    public void testToHoursSaturate() {
476        for (TimeUnit x : TimeUnit.values()) {
477            long ratio = x.toNanos(1) / HOURS.toNanos(1);
478            if (ratio >= 1) {
479                long max = Long.MAX_VALUE/ratio;
480                for (long z : new long[] {0, 1, -1, max, -max})
481                    assertEquals(z * ratio, x.toHours(z));
482                if (max < Long.MAX_VALUE) {
483                    assertEquals(Long.MAX_VALUE, x.toHours(max + 1));
484                    assertEquals(Long.MIN_VALUE, x.toHours(-max - 1));
485                    assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE + 1));
486                }
487                assertEquals(Long.MAX_VALUE, x.toHours(Long.MAX_VALUE));
488                assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE));
489            }
490        }
491    }
492
493    /**
494     * toString returns name of unit
495     */
496    public void testToString() {
497        assertEquals("SECONDS", SECONDS.toString());
498    }
499
500    /**
501     * name returns name of unit
502     */
503    public void testName() {
504        assertEquals("SECONDS", SECONDS.name());
505    }
506
507    /**
508     * Timed wait without holding lock throws
509     * IllegalMonitorStateException
510     */
511    public void testTimedWait_IllegalMonitorException() {
512        Thread t = newStartedThread(new CheckedRunnable() {
513            public void realRun() throws InterruptedException {
514                Object o = new Object();
515                TimeUnit tu = MILLISECONDS;
516
517                try {
518                    tu.timedWait(o, LONG_DELAY_MS);
519                    threadShouldThrow();
520                } catch (IllegalMonitorStateException success) {}
521            }});
522
523        awaitTermination(t);
524    }
525
526    /**
527     * timedWait throws InterruptedException when interrupted
528     */
529    public void testTimedWait_Interruptible() {
530        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
531        Thread t = newStartedThread(new CheckedRunnable() {
532            public void realRun() throws InterruptedException {
533                Object o = new Object();
534                TimeUnit tu = MILLISECONDS;
535
536                Thread.currentThread().interrupt();
537                try {
538                    synchronized (o) {
539                        tu.timedWait(o, LONG_DELAY_MS);
540                    }
541                    shouldThrow();
542                } catch (InterruptedException success) {}
543                assertFalse(Thread.interrupted());
544
545                pleaseInterrupt.countDown();
546                try {
547                    synchronized (o) {
548                        tu.timedWait(o, LONG_DELAY_MS);
549                    }
550                    shouldThrow();
551                } catch (InterruptedException success) {}
552                assertFalse(Thread.interrupted());
553            }});
554
555        await(pleaseInterrupt);
556        assertThreadBlocks(t, Thread.State.TIMED_WAITING);
557        t.interrupt();
558        awaitTermination(t);
559    }
560
561    /**
562     * timedJoin throws InterruptedException when interrupted
563     */
564    public void testTimedJoin_Interruptible() {
565        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
566        final Thread s = newStartedThread(new CheckedInterruptedRunnable() {
567            public void realRun() throws InterruptedException {
568                Thread.sleep(LONG_DELAY_MS);
569            }});
570        final Thread t = newStartedThread(new CheckedRunnable() {
571            public void realRun() throws InterruptedException {
572                TimeUnit tu = MILLISECONDS;
573                Thread.currentThread().interrupt();
574                try {
575                    tu.timedJoin(s, LONG_DELAY_MS);
576                    shouldThrow();
577                } catch (InterruptedException success) {}
578                assertFalse(Thread.interrupted());
579
580                pleaseInterrupt.countDown();
581                try {
582                    tu.timedJoin(s, LONG_DELAY_MS);
583                    shouldThrow();
584                } catch (InterruptedException success) {}
585                assertFalse(Thread.interrupted());
586            }});
587
588        await(pleaseInterrupt);
589        assertThreadBlocks(t, Thread.State.TIMED_WAITING);
590        t.interrupt();
591        awaitTermination(t);
592        s.interrupt();
593        awaitTermination(s);
594    }
595
596    /**
597     * timedSleep throws InterruptedException when interrupted
598     */
599    public void testTimedSleep_Interruptible() {
600        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
601        Thread t = newStartedThread(new CheckedRunnable() {
602            public void realRun() throws InterruptedException {
603                TimeUnit tu = MILLISECONDS;
604                Thread.currentThread().interrupt();
605                try {
606                    tu.sleep(LONG_DELAY_MS);
607                    shouldThrow();
608                } catch (InterruptedException success) {}
609                assertFalse(Thread.interrupted());
610
611                pleaseInterrupt.countDown();
612                try {
613                    tu.sleep(LONG_DELAY_MS);
614                    shouldThrow();
615                } catch (InterruptedException success) {}
616                assertFalse(Thread.interrupted());
617            }});
618
619        await(pleaseInterrupt);
620        assertThreadBlocks(t, Thread.State.TIMED_WAITING);
621        t.interrupt();
622        awaitTermination(t);
623    }
624
625    /**
626     * a deserialized/reserialized unit is the same instance
627     */
628    public void testSerialization() throws Exception {
629        for (TimeUnit x : TimeUnit.values())
630            assertSame(x, serialClone(x));
631    }
632
633}
634