/*************************************************************************** * Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ package com.vmware.aurora.composition.concurrent; import java.util.concurrent.Callable; import org.testng.annotations.Test; import com.vmware.aurora.util.AuAssert; public class TestPriorityThreadPoolExecutor { private void sleep(int time) { if (time <= 0 ) { return; } try { Thread.sleep(time * 1000L); } catch (InterruptedException e) { // Eat the exception } } class TestCallable implements Callable<Void> { private int idx; private StringBuffer buffer; private int preSleepTime; // in seconds private int postSleepTime; // in seconds TestCallable(int idx, StringBuffer buffer, int preSleepTime, int postSleepTime) { this.idx = idx; this.buffer = buffer; this.preSleepTime = preSleepTime; this.postSleepTime = postSleepTime; } @Override public Void call() throws Exception { sleep(preSleepTime); buffer.append(Integer.toString(idx)); sleep(postSleepTime); return null; } public void setIdx(int idx) { this.idx = idx; } } @Test public void testNoWaiting() { // In this test, all tasks are executed immediately after being submitted, // no wait in queue. PriorityThreadPoolExecutor executor = new PriorityThreadPoolExecutor(2, 2); StringBuffer buffer = new StringBuffer(); TestCallable call1 = new TestCallable(1, buffer, 3, 3); executor.submit(Priority.INTERACTIVE, call1); TestCallable call2 = new TestCallable(2, buffer, 8, 2); executor.submit(Priority.BACKGROUND, call2); sleep(1); AuAssert.check(executor.executor.getActiveCount() == 2); AuAssert.check(executor.executor.getCompletedTaskCount() == 0); AuAssert.check(buffer.toString().equals("")); sleep(3); AuAssert.check(executor.executor.getActiveCount() == 2); AuAssert.check(executor.executor.getCompletedTaskCount() == 0); AuAssert.check(buffer.toString().equals("1")); sleep(3); // call1 completes AuAssert.check(executor.executor.getActiveCount() == 1); AuAssert.check(executor.executor.getCompletedTaskCount() == 1); AuAssert.check(buffer.toString().equals("1")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 1); AuAssert.check(executor.executor.getCompletedTaskCount() == 1); AuAssert.check(buffer.toString().equals("12")); sleep(3); // call2 completes AuAssert.check(executor.executor.getActiveCount() == 0); AuAssert.check(executor.executor.getCompletedTaskCount() == 2); AuAssert.check(buffer.toString().equals("12")); call1.setIdx(3); call2.setIdx(4); executor.submit(Priority.BACKGROUND, call1); executor.submit(Priority.INTERACTIVE, call2); sleep(1); AuAssert.check(executor.executor.getActiveCount() == 2); AuAssert.check(executor.executor.getCompletedTaskCount() == 2); AuAssert.check(buffer.toString().equals("12")); sleep(3); AuAssert.check(executor.executor.getActiveCount() == 2); AuAssert.check(executor.executor.getCompletedTaskCount() == 2); AuAssert.check(buffer.toString().equals("123")); sleep(3); AuAssert.check(executor.executor.getActiveCount() == 1); AuAssert.check(executor.executor.getCompletedTaskCount() == 3); AuAssert.check(buffer.toString().equals("123")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 1); AuAssert.check(executor.executor.getCompletedTaskCount() == 3); AuAssert.check(buffer.toString().equals("1234")); sleep(3); AuAssert.check(executor.executor.getActiveCount() == 0); AuAssert.check(executor.executor.getCompletedTaskCount() == 4); AuAssert.check(buffer.toString().equals("1234")); executor.shutdown(); } @Test public void testWaitingInOneQueue() { // In this test, some tasks are queued in queue for one priority. for (Priority priority : Priority.values()) { PriorityThreadPoolExecutor executor = new PriorityThreadPoolExecutor(2, 2); StringBuffer buffer = new StringBuffer(); TestCallable call1 = new TestCallable(1, buffer, 2, 2); TestCallable call2 = new TestCallable(2, buffer, 4, 2); TestCallable call3 = new TestCallable(3, buffer, 8, 2); TestCallable call4 = new TestCallable(4, buffer, 9, 2); TestCallable call5 = new TestCallable(5, buffer, 2, 3); TestCallable call6 = new TestCallable(6, buffer, 4, 3); executor.submit(priority, call1); executor.submit(priority, call2); executor.submit(priority, call3); executor.submit(priority, call4); executor.submit(priority, call5); // will wait in queue for a while executor.submit(priority, call6); // will wait in queue for a while sleep(1); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 0); AuAssert.check(buffer.toString().equals("")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 0); AuAssert.check(buffer.toString().equals("1")); sleep(2); // call1 completes AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 1); AuAssert.check(buffer.toString().equals("12")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 2); AuAssert.check(buffer.toString().equals("125")); sleep(10); AuAssert.check(executor.executor.getActiveCount() == 0); AuAssert.check(executor.executor.getCompletedTaskCount() == 6); AuAssert.check(buffer.toString().equals("125346")); executor.shutdown(); } } @Test public void testWaitingInTwoQueues() { // In this test, queues for all priorities are used. PriorityThreadPoolExecutor executor = new PriorityThreadPoolExecutor(2, 2); StringBuffer buffer = new StringBuffer(); TestCallable call1 = new TestCallable(1, buffer, 2, 1); TestCallable call2 = new TestCallable(2, buffer, 6, 4); TestCallable call3 = new TestCallable(3, buffer, 10, 2); TestCallable call4 = new TestCallable(4, buffer, 12, 1); TestCallable call5 = new TestCallable(5, buffer, 1, 2); TestCallable call6 = new TestCallable(6, buffer, 2, 2); executor.submit(Priority.BACKGROUND, call1); executor.submit(Priority.BACKGROUND, call2); executor.submit(Priority.INTERACTIVE, call3); executor.submit(Priority.INTERACTIVE, call4); executor.submit(Priority.BACKGROUND, call5); // will wait in queue for a while executor.submit(Priority.INTERACTIVE, call6); // will wait in queue for a while sleep(1); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 0); AuAssert.check(buffer.toString().equals("")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(buffer.toString().equals("1")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 1); AuAssert.check(buffer.toString().equals("15")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 2); AuAssert.check(buffer.toString().equals("152")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 4); AuAssert.check(executor.executor.getCompletedTaskCount() == 2); AuAssert.check(buffer.toString().equals("1526")); sleep(2); AuAssert.check(executor.executor.getActiveCount() == 2); AuAssert.check(executor.executor.getCompletedTaskCount() == 4); AuAssert.check(buffer.toString().equals("15263")); sleep(3); AuAssert.check(executor.executor.getActiveCount() == 0); AuAssert.check(executor.executor.getCompletedTaskCount() == 6); AuAssert.check(buffer.toString().equals("152634")); executor.shutdown(); } }