/*
* Copyright 2008-2010 LinkedIn, Inc
*
* 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 voldemort.server.protocol.admin;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import junit.framework.TestCase;
import voldemort.common.service.SchedulerService;
import voldemort.utils.SystemTime;
/**
* Test {@link voldemort.server.protocol.admin.AsyncOperationService}
*/
public class AsyncOperationTest extends TestCase {
public void testAsyncOperationService() throws Exception {
SchedulerService schedulerService = new SchedulerService(2, SystemTime.INSTANCE);
AsyncOperationService asyncOperationService = new AsyncOperationService(schedulerService,
10);
final AtomicBoolean op0Complete = new AtomicBoolean(false);
final AtomicBoolean op1Complete = new AtomicBoolean(false);
final CountDownLatch op0Latch = new CountDownLatch(1);
final CountDownLatch op1Latch = new CountDownLatch(1);
int op0 = asyncOperationService.getUniqueRequestId();
asyncOperationService.submitOperation(op0, new AsyncOperation(op0, "op0") {
@Override
public void operate() throws Exception {
Thread.sleep(500);
op0Latch.countDown();
op0Complete.set(true);
}
@Override
public void stop() {
}
});
int op1 = asyncOperationService.getUniqueRequestId();
asyncOperationService.submitOperation(op1, new AsyncOperation(op1, "op1") {
@Override
public void operate() throws Exception {
op1Complete.set(true);
op1Latch.countDown();
}
@Override
public void stop() {
}
});
op1Latch.await();
List<Integer> opList = asyncOperationService.getAsyncOperationList(false);
assertFalse("doesn't list completed operations", opList.contains(1));
assertTrue("lists a pending operation", opList.contains(0));
opList = asyncOperationService.getAsyncOperationList(true);
assertTrue("lists all operations", opList.containsAll(Arrays.asList(0, 1)));
op0Latch.await();
assertTrue("operation 0 finished", op0Complete.get());
assertTrue("operation 1 finished", op1Complete.get());
}
public void testAsyncOperationCache() throws Exception {
Map<Integer, AsyncOperation> operations = Collections.synchronizedMap(new AsyncOperationCache(2));
final CountDownLatch countDownLatch = new CountDownLatch(1);
AsyncOperation completeLater = new AsyncOperation(0, "test") {
@Override
public void stop() {}
@Override
public void operate() {
try {
Thread.sleep(500);
countDownLatch.countDown();
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
ExecutorService executorService = Executors.newFixedThreadPool(5);
AsyncOperation completeNow = new AsyncOperation(1, "test") {
@Override
public void stop() {}
@Override
public void operate() {}
};
AsyncOperation completeSoon = new AsyncOperation(2, "test") {
@Override
public void stop() {}
@Override
public void operate() {
try {
Thread.sleep(250);
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
operations.put(0, completeLater);
operations.put(1, completeNow);
operations.put(2, completeSoon);
executorService.submit(completeLater);
executorService.submit(completeNow);
executorService.submit(completeSoon);
assertTrue("Handles overflow okay", operations.containsKey(0) && operations.containsKey(1)
&& operations.containsKey(2));
countDownLatch.await();
for(int i = 3; i < 32; i++) {
AsyncOperation asyncOperation = new AsyncOperation(i, "test") {
@Override
public void stop() {}
@Override
public void operate() {}
};
operations.put(i, asyncOperation);
}
// Commented out as it's brittle and leads to frequent test failures
// assertFalse("Actually does LRU heuristics",
// operations.containsKey(0));
}
}