blob: 11ded95c57a32e72c6d8f4e07f4532df7a053b49 [file] [log] [blame]
/*
* Copyright (C) The Android Open Source Project
*
* 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.android.globalsearch;
import junit.framework.TestCase;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Tests for {@link PerTagExecutor}.
*/
public class PerTagExecutorTest extends TestCase {
private ExecutorService mExecutor;
@Override
protected void setUp() throws Exception {
super.setUp();
mExecutor = new ThreadPoolExecutor(4, 4,
100, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public void testLimit() throws Exception {
PerTagExecutor tagExecutor = new PerTagExecutor(mExecutor, 2);
TRunnable a1 = new TRunnable();
TRunnable a2 = new TRunnable();
TRunnable a3 = new TRunnable();
TRunnable b1 = new TRunnable();
assertFalse(tagExecutor.execute("a", a1));
assertFalse(tagExecutor.execute("a", a2));
assertTrue(tagExecutor.execute("a", a3));
assertFalse(tagExecutor.execute("b", b1));
mExecutor.shutdown();
mExecutor.awaitTermination(1, TimeUnit.SECONDS);
assertTrue(a1.hasRun());
assertTrue(a2.hasRun());
assertFalse(a3.hasRun());
assertTrue(b1.hasRun());
}
public void testPendingRuns() throws Exception {
PerTagExecutor tagExecutor = new PerTagExecutor(mExecutor, 2);
TRunnable a1 = new TRunnable();
TRunnable a2 = new TRunnable();
TRunnable a3 = new TRunnable();
tagExecutor.execute("a", a1);
tagExecutor.execute("a", a2);
tagExecutor.execute("a", a3);
// let a1 finish, should trigger a3 to run
synchronized (a1) {
a1.notify();
}
mExecutor.shutdown();
mExecutor.awaitTermination(1, TimeUnit.SECONDS);
assertTrue(a1.hasRun());
assertTrue(a2.hasRun());
assertTrue(a3.hasRun());
}
public void testPendingRuns_intermediateDropped() throws Exception {
PerTagExecutor tagExecutor = new PerTagExecutor(mExecutor, 2);
TRunnable a1 = new TRunnable();
TRunnable a2 = new TRunnable();
TRunnable a3 = new TRunnable();
TRunnable a4 = new TRunnable();
tagExecutor.execute("a", a1);
tagExecutor.execute("a", a2);
tagExecutor.execute("a", a3);
tagExecutor.execute("a", a4);
// let a1 finish, should trigger a3 to run
synchronized (a1) {
a1.notify();
}
mExecutor.shutdown();
mExecutor.awaitTermination(1, TimeUnit.SECONDS);
assertTrue(a1.hasRun());
assertTrue(a2.hasRun());
assertFalse("pending a3 should have been dropped when a4 was executed.", a3.hasRun());
assertTrue(a4.hasRun());
}
/**
* A runnable that knows when it has been run, and waits until notified to finish.
*/
private static class TRunnable implements Runnable {
boolean mRun = false;
public synchronized void run() {
mRun = true;
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public boolean hasRun() {
return mRun;
}
}
}