1 /* 2 * Copyright (c) 2020, 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 * @run testng AsyncShutdownNow 27 * @summary Test invoking shutdownNow with threads blocked in Future.get, 28 * invokeAll, and invokeAny 29 */ 30 31 // TODO: this test is far too slow 32 33 import java.util.List; 34 import java.util.concurrent.Callable; 35 import java.util.concurrent.CancellationException; 36 import java.util.concurrent.ExecutionException; 37 import java.util.concurrent.ExecutorService; 38 import java.util.concurrent.Executors; 39 import java.util.concurrent.ForkJoinPool; 40 import java.util.concurrent.Future; 41 import java.util.concurrent.ScheduledExecutorService; 42 import java.util.concurrent.TimeUnit; 43 44 import org.testng.annotations.AfterClass; 45 import org.testng.annotations.BeforeClass; 46 import org.testng.annotations.DataProvider; 47 import org.testng.annotations.Test; 48 import static org.testng.Assert.*; 49 50 public class AsyncShutdownNow { 51 52 // long running interruptible task 53 private static final Callable<Void> SLEEP_FOR_A_DAY = () -> { 54 Thread.sleep(86400_000); 55 return null; 56 }; 57 58 private ScheduledExecutorService scheduledExecutor; 59 60 @BeforeClass 61 public void setup() { 62 scheduledExecutor = Executors.newScheduledThreadPool(1); 63 } 64 65 @AfterClass 66 public void teardown() { 67 scheduledExecutor.shutdown(); 68 } 69 70 /** 71 * Schedule the given executor service to be shutdown abruptly after the given 72 * delay, in seconds. 73 */ 74 private void scheduleShutdownNow(ExecutorService executor, int delayInSeconds) { 75 scheduledExecutor.schedule(() -> { 76 executor.shutdownNow(); 77 return null; 78 }, delayInSeconds, TimeUnit.SECONDS); 79 } 80 81 /** 82 * The executors to test. 83 */ 84 @DataProvider(name = "executors") 85 public Object[][] executors() { 86 return new Object[][] { 87 { new ForkJoinPool() }, 88 { new ForkJoinPool(1) }, 89 }; 90 } 91 92 /** 93 * Test shutdownNow with running task and thread blocked in Future::get. 94 */ 95 @Test(dataProvider = "executors") 96 public void testFutureGet(ExecutorService executor) throws Exception { 97 System.out.format("testFutureGet: %s%n", executor); 98 scheduleShutdownNow(executor, 5); 99 try { 100 // submit long running task, the task should be cancelled 101 Future<?> future = executor.submit(SLEEP_FOR_A_DAY); 102 try { 103 future.get(); 104 assertTrue(false); 105 } catch (ExecutionException e) { 106 // expected 107 } 108 } finally { 109 executor.shutdown(); 110 } 111 } 112 113 /** 114 * Test shutdownNow with running task and thread blocked in a timed Future::get. 115 */ 116 @Test(dataProvider = "executors") 117 public void testTimedFutureGet(ExecutorService executor) throws Exception { 118 System.out.format("testTimedFutureGet: %s%n", executor); 119 scheduleShutdownNow(executor, 5); 120 try { 121 // submit long running task, the task should be cancelled 122 Future<?> future = executor.submit(SLEEP_FOR_A_DAY); 123 try { 124 future.get(1, TimeUnit.HOURS); 125 assertTrue(false); 126 } catch (ExecutionException e) { 127 // expected 128 } 129 } finally { 130 executor.shutdown(); 131 } 132 } 133 134 /** 135 * Test shutdownNow with thread blocked in invokeAll. 136 */ 137 @Test(dataProvider = "executors") 138 public void testInvokeAll(ExecutorService executor) throws Exception { 139 System.out.format("testInvokeAll: %s%n", executor); 140 scheduleShutdownNow(executor, 5); 141 try { 142 // execute long running tasks 143 List<Future<Void>> futures = executor.invokeAll(List.of(SLEEP_FOR_A_DAY, SLEEP_FOR_A_DAY)); 144 for (Future<Void> f : futures) { 145 assertTrue(f.isDone()); 146 try { 147 Object result = f.get(); 148 assertTrue(false); 149 } catch (ExecutionException | CancellationException e) { 150 // expected 151 } 152 } 153 } finally { 154 executor.shutdown(); 155 } 156 } 157 158 /** 159 * Test shutdownNow with thread blocked in invokeAny. 160 */ 161 @Test(dataProvider = "executors") 162 public void testInvokeAny(ExecutorService executor) throws Exception { 163 System.out.format("testInvokeAny: %s%n", executor); 164 scheduleShutdownNow(executor, 5); 165 try { 166 try { 167 // execute long running tasks 168 executor.invokeAny(List.of(SLEEP_FOR_A_DAY, SLEEP_FOR_A_DAY)); 169 assertTrue(false); 170 } catch (ExecutionException e) { 171 // expected 172 } 173 } finally { 174 executor.shutdown(); 175 } 176 } 177 }