1 /* 2 * Copyright (c) 2010, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package test.javafx.concurrent; 27 28 import javafx.concurrent.Task; 29 import test.javafx.concurrent.mocks.EpicFailTask; 30 import test.javafx.concurrent.mocks.InfiniteTask; 31 import test.javafx.concurrent.mocks.RunAwayTask; 32 import test.javafx.concurrent.mocks.SimpleTask; 33 import org.junit.Before; 34 import org.junit.Test; 35 36 import static org.junit.Assert.*; 37 38 /** 39 * Tests what happens to a Task if it is canceled in each of the various 40 * states that a Task may be in. 41 */ 42 public class TaskCancelTest { 43 /** 44 * Since the InfiniteTask never ends (normally), I can test it from the 45 * ready, scheduled, running, cancelled, and failed states. I can't use 46 * it for testing what happens when the task succeeds though. 47 */ 48 private InfiniteTask task; 49 50 @Before public void setup() { 51 task = new InfiniteTask(); 52 } 53 54 /** 55 * Since the task begins in the ready state, I can just cancel it and 56 * see what happens. 57 */ 58 @Test public void cancellingA_READY_TaskShouldChangeStateTo_CANCELLED() { 59 assertTrue(task.cancel()); 60 assertEquals(Task.State.CANCELLED, task.getState()); 61 assertTrue(task.isDone()); 62 } 63 64 /** 65 * I have some cheap mechanism for simulating the scheduling of a Task 66 * (it just changes the Task state correctly). So put it in the 67 * Scheduled state and then cancel it and see what happens. 68 */ 69 @Test public void cancellingA_SCHEDULED_TaskShouldChangeStateTo_CANCELLED() { 70 task.simulateSchedule(); 71 assertTrue(task.cancel()); 72 assertEquals(Task.State.CANCELLED, task.getState()); 73 assertTrue(task.isDone()); 74 } 75 76 /** 77 * Since the task is an infinitely running task, and since there is a 78 * semaphore on the AbstractTask that tells me when certain state 79 * transitions have occurred, I can simply fire up another thread and 80 * run the infinite task, and then wait for that semaphore to trip. When 81 * it does, I know that we're running (and will never leave that state) 82 * so I can go ahead and then cancel it. 83 * 84 * @throws Exception shouldn't throw anything unless th.join fails 85 */ 86 @Test public void cancellingA_RUNNING_TaskShouldChangeStateTo_CANCELLED() throws Exception { 87 Thread th = new Thread(task); 88 th.start(); 89 task.runningSemaphore.acquire(); 90 assertTrue(task.cancel()); 91 th.join(); 92 93 assertEquals(Task.State.CANCELLED, task.getState()); 94 // TODO why is this commented out? 95 // assertNull(task.getException()); 96 assertNull(task.getValue()); 97 assertTrue(task.isDone()); 98 } 99 100 /** 101 * In this case I don't want to use the infinite task, so I'll just 102 * use a SimpleTask instead 103 */ 104 @Test public void cancellingA_SUCCEEDED_TaskShouldNotChangeTo_CANCELLED() { 105 Task t = new SimpleTask(); 106 t.run(); 107 assertFalse(t.cancel()); 108 assertEquals(Task.State.SUCCEEDED, t.getState()); 109 assertTrue(t.isDone()); 110 } 111 112 /** 113 * Although I could end up using the infinite task for this one, I'm going 114 * to go ahead and reuse the epic fail task instead 115 */ 116 @Test public void cancellingA_FAILED_TaskShouldNotChangeTo_CANCELLED() { 117 Task t = new EpicFailTask(); 118 t.run(); 119 assertFalse(t.cancel()); 120 assertEquals(Task.State.FAILED, t.getState()); 121 assertTrue(t.isDone()); 122 } 123 124 /** 125 * 126 */ 127 @Test public void aFreeRunningCancelledTaskReturnValueShouldBeIgnored() throws Exception { 128 RunAwayTask runAway = new RunAwayTask() { 129 protected void loop(int count) throws Exception { 130 } 131 }; 132 Thread th = new Thread(runAway); 133 th.start(); 134 runAway.runningSemaphore.acquire(); 135 assertTrue(runAway.cancel()); 136 runAway.stopLooping.set(true); 137 th.join(); 138 139 assertEquals(Task.State.CANCELLED, runAway.getState()); 140 // TODO why is this commented out? 141 // assertNull(task.getException()); 142 assertNull(runAway.getValue()); 143 assertTrue(runAway.isDone()); 144 } 145 }