blob: 9e20c854d9648cf6aa7850fea6453b9e95ac7b2c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.tests.runtime.jobs;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.tests.harness.TestBarrier;
/**
* Make sure that IProgressMonitor's blocked/unblocked is invoked.
*/
public class Bug_311756 extends AbstractJobManagerTest {
int UNSET = -1;
int CLEARED = 0;
int BLOCKED = 1;
/**
* Tests that the progress monitor blocked state is cleared in the normal case
* that the rule becomes available after being blocked.
*/
public void testBlockingAndUnblockingMonitor() throws Exception {
final int[] blocked = new int[] {UNSET};
ProgressMonitorWrapper wrapper = new ProgressMonitorWrapper(new NullProgressMonitor()) {
@Override
public void setBlocked(IStatus reason) {
super.setBlocked(reason);
blocked[0] = BLOCKED;
}
@Override
public void clearBlocked() {
super.clearBlocked();
if (blocked[0] == BLOCKED)
blocked[0] = CLEARED;
}
};
final TestBarrier barrier = new TestBarrier(TestBarrier.STATUS_START);
IdentityRule rule = new IdentityRule();
Job conflicting = new Job("Conflicting") {
@Override
protected IStatus run(IProgressMonitor monitor) {
barrier.setStatus(TestBarrier.STATUS_RUNNING);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
fail("4.99", e);
}
return Status.OK_STATUS;
}
};
conflicting.setRule(rule);
conflicting.schedule();
barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
try {
Job.getJobManager().beginRule(rule, wrapper);
} finally {
Job.getJobManager().endRule(rule);
}
assertEquals(blocked[0] == UNSET ? "setBlocked never called" : "clearBlocked never called", CLEARED, blocked[0]);
}
/**
* Tests that the progress monitor blocked state is cleared in the case that a rule
* is transferring to the waiting job while blocked.
*/
public void testBlockingAndUnblockingMonitorUsingTransfer() throws Exception {
final int[] blocked = new int[] {UNSET};
final ProgressMonitorWrapper wrapper = new ProgressMonitorWrapper(new NullProgressMonitor()) {
@Override
public void setBlocked(IStatus reason) {
super.setBlocked(reason);
blocked[0] = BLOCKED;
}
@Override
public void clearBlocked() {
super.clearBlocked();
if (blocked[0] == BLOCKED)
blocked[0] = CLEARED;
}
};
final TestBarrier barrier = new TestBarrier(TestBarrier.STATUS_START);
final IdentityRule rule = new IdentityRule();
final Thread[] destinationThread = new Thread[1];
Job conflicting = new Job("Conflicting") {
@Override
protected IStatus run(IProgressMonitor monitor) {
barrier.setStatus(TestBarrier.STATUS_RUNNING);
barrier.waitForStatus(TestBarrier.STATUS_BLOCKED);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
fail("4.99", e);
}
getJobManager().transferRule(rule, destinationThread[0]);
return Status.OK_STATUS;
}
};
Job transferTo = new Job("TransferTo") {
@Override
protected IStatus run(IProgressMonitor monitor) {
destinationThread[0] = getThread();
barrier.setStatus(TestBarrier.STATUS_BLOCKED);
getJobManager().beginRule(rule, wrapper);
getJobManager().endRule(rule);
return Status.OK_STATUS;
}
};
conflicting.setRule(rule);
conflicting.schedule();
barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
transferTo.schedule();
waitForCompletion(conflicting);
waitForCompletion(transferTo);
assertEquals(blocked[0] == UNSET ? "setBlocked never called" : "clearBlocked never called", CLEARED, blocked[0]);
}
/**
* Tests that the progress monitor blocked state is cleared in the case that a rule
* becomes available to a yielded job while it is blocked.
*/
public void testBlockingAndUnblockingMonitorUsingYield() throws Exception {
final int[] blocked = new int[] {-1};
final ProgressMonitorWrapper wrapper = new ProgressMonitorWrapper(new NullProgressMonitor()) {
@Override
public void setBlocked(IStatus reason) {
super.setBlocked(reason);
blocked[0] = BLOCKED;
}
@Override
public void clearBlocked() {
super.clearBlocked();
if (blocked[0] == BLOCKED)
blocked[0] = CLEARED;
}
};
final TestBarrier barrier = new TestBarrier(TestBarrier.STATUS_START);
IdentityRule rule = new IdentityRule();
Job conflicting = new Job("Conflicting") {
@Override
protected IStatus run(IProgressMonitor monitor) {
barrier.setStatus(TestBarrier.STATUS_RUNNING);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
fail("4.99", e);
}
Job j = null;
while (j == null)
j = yieldRule(wrapper);
return Status.OK_STATUS;
}
};
conflicting.setRule(rule);
conflicting.schedule();
barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
try {
Job.getJobManager().beginRule(rule, null);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
fail("4.99", e);
}
} finally {
Job.getJobManager().endRule(rule);
}
conflicting.join();
assertEquals(blocked[0] == UNSET ? "setBlocked never called" : "clearBlocked never called", CLEARED, blocked[0]);
}
/**
* Tests that the progress monitor blocked state is cleared in the case that a rule
* is transferred back to a yielded job while it is blocked.
*/
public void testBlockingAndUnblockingMonitorUsingYieldAndTransfer() throws Exception {
final int[] blocked = new int[] {-1};
final ProgressMonitorWrapper wrapper = new ProgressMonitorWrapper(new NullProgressMonitor()) {
@Override
public void setBlocked(IStatus reason) {
super.setBlocked(reason);
blocked[0] = BLOCKED;
}
@Override
public void clearBlocked() {
super.clearBlocked();
if (blocked[0] == BLOCKED)
blocked[0] = CLEARED;
}
};
final TestBarrier barrier = new TestBarrier(TestBarrier.STATUS_START);
IdentityRule rule = new IdentityRule();
Job conflicting = new Job("Conflicting") {
@Override
protected IStatus run(IProgressMonitor monitor) {
barrier.setStatus(TestBarrier.STATUS_RUNNING);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
fail("4.99", e);
}
Job j = null;
while (j == null)
j = yieldRule(wrapper);
return Status.OK_STATUS;
}
};
conflicting.setRule(rule);
conflicting.schedule();
barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
Job.getJobManager().beginRule(rule, null);
Job.getJobManager().transferRule(rule, conflicting.getThread());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
fail("4.99", e);
}
conflicting.join();
assertEquals(blocked[0] == UNSET ? "setBlocked never called" : "clearBlocked never called", CLEARED, blocked[0]);
}
}