/*************************************************************************** * 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.Random; import java.util.concurrent.Callable; import org.testng.annotations.Test; import com.google.gson.internal.Pair; import com.vmware.aurora.util.AuAssert; public class TestScheduler { private static final int numberOfStoredProcedures = 1000; static class DummyStoredProcedure implements Callable<Void> { private int sleepTime; // in seconds private boolean successful; DummyStoredProcedure(int sleepTime, boolean successful) { this.sleepTime = sleepTime; this.successful = successful; } @Override public Void call() throws Exception { try { Thread.sleep(sleepTime * 1000L); } catch (Exception ex) { // ignore } if(!successful) { throw new Exception("Stored procedure failed"); } return null; } } static class ProgressUpdate implements Scheduler.ProgressCallback { @Override public void progressUpdate(Callable<Void> sp, ExecutionResult result, boolean compensate, int total) { System.out.println("Finish"); } } @Test public void testBestEffort() throws InterruptedException { // In this test, all stored procedures are executed in a best-effort way, // no compensation stored procedures are executed. Scheduler.init(20, 20); Random random = new Random(); DummyStoredProcedure[] sps = new DummyStoredProcedure[numberOfStoredProcedures]; int totalFailure = 0; for (int i = 0; i < sps.length; ++i) { if (random.nextBoolean()) { sps[i] = new DummyStoredProcedure(2, true); } else { sps[i] = new DummyStoredProcedure(2, false); ++totalFailure; } } ExecutionResult[] result = Scheduler.executeStoredProcedures(Priority.BACKGROUND, sps, new ProgressUpdate()); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == (sps.length - totalFailure)); Scheduler.shutdown(true); } @Test public void testCompensation() throws InterruptedException { // In this test, dummy compensation stored procedures will be // executed if the stored procedures fail and the total number of // failed stored procedures exceeds the allowed number. Scheduler.init(20, 20); Random random = new Random(); int totalFailure = 0; @SuppressWarnings("unchecked") Pair<Callable<Void>, Callable<Void>>[] sps = new Pair[numberOfStoredProcedures]; for (int i = 0; i < sps.length; ++i) { Callable<Void> sp = null; if (random.nextBoolean()) { sp = new DummyStoredProcedure(2, true); } else { sp = new DummyStoredProcedure(2, false); ++totalFailure; } sps[i] = new Pair<Callable<Void>, Callable<Void>>(sp, sp); } Pair<ExecutionResult, ExecutionResult>[] result = Scheduler.executeStoredProcedures(Priority.INTERACTIVE, sps, 0, new ProgressUpdate()); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == 0); result = Scheduler.executeStoredProcedures(Priority.INTERACTIVE, sps, 1, new ProgressUpdate()); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == 0); result = Scheduler.executeStoredProcedures(Priority.BACKGROUND, sps, totalFailure / 2, null); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == 0); result = Scheduler.executeStoredProcedures(Priority.INTERACTIVE, sps, totalFailure - 1, new ProgressUpdate()); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == 0); result = Scheduler.executeStoredProcedures(Priority.BACKGROUND, sps, totalFailure, new ProgressUpdate()); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == (sps.length - totalFailure)); result = Scheduler.executeStoredProcedures(Priority.INTERACTIVE, sps, totalFailure + 1, null); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == (sps.length - totalFailure)); result = Scheduler.executeStoredProcedures(Priority.BACKGROUND, sps, sps.length, new ProgressUpdate()); AuAssert.check(Util.getNumberOfSuccessfulExecution(result) == (sps.length - totalFailure)); Scheduler.shutdown(true); } }