/*******************************************************************************
 *  Copyright (c) 2003, 2018 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM - Initial API and implementation
 *     Stephan Wahlbrink  - Test fix for bug 200997.
 *     Dmitry Karasik - Test cases for bug 255384
 *     Jan Koehnlein - Test case for bug 60964 (454698)
 *     Alexander Kurtakov <akurtako@redhat.com> - bug 458490
 *     Thirumala Reddy Mutchukota (thirumala@google.com) -
 *     		Bug 105821, Support for Job#join with timeout and progress monitor
 *******************************************************************************/
package org.eclipse.core.tests.runtime.jobs;

import org.eclipse.core.internal.jobs.JobManager;
import org.eclipse.core.internal.jobs.Worker;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.core.tests.harness.*;
import org.junit.Assert;

/**
 * Tests the implemented get/set methods of the abstract class Job
 */
public class JobTest extends AbstractJobTest {
	protected Job longJob;
	protected Job shortJob;
	private FussyProgressProvider progressProvider;

	public JobTest(String name) {
		super(name);
	}

	//see bug #43591
	public void _testDone() {
		//calling the done method on a job that is not executing asynchronously should have no effect

		shortJob.done(Status.OK_STATUS);
		assertTrue("1.0", shortJob.getResult() == null);

		shortJob.done(Status.CANCEL_STATUS);
		assertTrue("2.0", shortJob.getResult() == null);

		//calling the done method after the job is scheduled
		shortJob.schedule();
		shortJob.done(Status.CANCEL_STATUS);
		waitForState(shortJob, Job.NONE);

		//the done call should be ignored, and the job should finish execution normally
		assertTrue("3.0", shortJob.getResult().getSeverity() == IStatus.OK);

		shortJob.done(Status.CANCEL_STATUS);
		assertTrue("4.0", shortJob.getResult().getSeverity() == IStatus.OK);

		//calling the done method before a job is canceled
		longJob.schedule();
		waitForState(longJob, Job.RUNNING);
		longJob.done(Status.OK_STATUS);
		longJob.cancel();
		waitForState(longJob, Job.NONE);

		//the done call should be ignored, and the job status should still be canceled
		assertTrue("5.0", longJob.getResult().getSeverity() == IStatus.CANCEL);

		longJob.done(Status.OK_STATUS);
		assertTrue("6.0", longJob.getResult().getSeverity() == IStatus.CANCEL);

	}

	private void cancel(Job[] jobs) {
		for (Job job : jobs) {
			job.cancel();
		}
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		shortJob = new TestJob("Short Test Job", 100, 10);
		longJob = new TestJob("Long Test Job", 1000000, 10);
		progressProvider = new FussyProgressProvider();
		Job.getJobManager().setProgressProvider(progressProvider);
	}

	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
		Job.getJobManager().setProgressProvider(null);
		waitForState(shortJob, Job.NONE);
		waitForState(longJob, Job.NONE);
	}

	//see bug #43566
	public void testAsynchJob() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START};

		//execute a job asynchronously and check the result
		AsynchTestJob main = new AsynchTestJob("Test Asynch Finish", status, 0);

		assertTrue("1.0", main.getThread() == null);
		assertTrue("2.0", main.getResult() == null);
		//schedule the job to run
		main.schedule();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);
		assertTrue("3.0", main.getState() == Job.RUNNING);
		//the asynchronous process that assigns the thread the job is going to run in has not been started yet
		//the job is running in the thread provided to it by the manager
		assertTrue("3.1" + main.getThread().getName(), main.getThread() instanceof Worker);

		status[0] = TestBarrier.STATUS_START;
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_START);

		//the asynchronous process has been started, but the set thread method has not been called yet
		assertTrue("3.2", main.getThread() instanceof Worker);

		status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;

		//make sure the job has set the thread it is going to run in
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);

		assertTrue("3.3", status[0] == TestBarrier.STATUS_RUNNING);
		assertTrue("3.4", main.getThread() instanceof AsynchExecThread);

		//let the job run
		status[0] = TestBarrier.STATUS_WAIT_FOR_DONE;
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);
		waitForState(main, Job.NONE);

		//after the job is finished, the thread should be reset
		assertTrue("4.0", main.getState() == Job.NONE);
		assertTrue("4.1", main.getResult().getSeverity() == IStatus.OK);
		assertTrue("4.2", main.getThread() == null);

		//reset status
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;

		//schedule the job to run again
		main.schedule();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);
		assertTrue("5.0", main.getState() == Job.RUNNING);

		//the asynchronous process that assigns the thread the job is going to run in has not been started yet
		//job is running in the thread provided by the manager
		assertTrue("5.1", main.getThread() instanceof Worker);

		status[0] = TestBarrier.STATUS_START;
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_START);

		//the asynchronous process has been started, but the set thread method has not been called yet
		assertTrue("5.2", main.getThread() instanceof Worker);

		status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;

		//make sure the job has set the thread it is going to run in
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);

		assertTrue("5.3", status[0] == TestBarrier.STATUS_RUNNING);
		assertTrue("5.4", main.getThread() instanceof AsynchExecThread);

		//cancel the job, then let the job get the cancellation request
		main.cancel();
		status[0] = TestBarrier.STATUS_WAIT_FOR_DONE;
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);
		waitForState(main, Job.NONE);

		//thread should be reset to null after cancellation
		assertTrue("6.0", main.getState() == Job.NONE);
		assertTrue("6.1", main.getResult().getSeverity() == IStatus.CANCEL);
		assertTrue("6.2", main.getThread() == null);
	}

	public void testAsynchJobComplex() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START};

		//test the interaction of several asynchronous jobs
		AsynchTestJob[] jobs = new AsynchTestJob[5];

		for (int i = 0; i < jobs.length; i++) {
			jobs[i] = new AsynchTestJob("TestJob" + (i + 1), status, i);
			assertTrue("1." + i, jobs[i].getThread() == null);
			assertTrue("2." + i, jobs[i].getResult() == null);
			jobs[i].schedule();
			//status[i] = TestBarrier.STATUS_START;
		}
		//all the jobs should be running at the same time
		waitForStart(jobs, status);

		//every job should now be waiting for the STATUS_START flag
		for (int i = 0; i < status.length; i++) {
			assertTrue("3." + i, jobs[i].getState() == Job.RUNNING);
			assertTrue("4." + i, jobs[i].getThread() instanceof Worker);
			status[i] = TestBarrier.STATUS_START;
		}

		for (int i = 0; i < status.length; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_WAIT_FOR_START);
		}

		//every job should now be waiting for the STATUS_WAIT_FOR_RUN flag
		for (int i = 0; i < status.length; i++) {
			assertTrue("5. " + i, jobs[i].getThread() instanceof Worker);
			status[i] = TestBarrier.STATUS_WAIT_FOR_RUN;
		}

		//wait until all jobs are in the running state
		for (int i = 0; i < status.length; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_RUNNING);
		}

		//let the jobs execute
		for (int i = 0; i < status.length; i++) {
			assertTrue("6. " + i, jobs[i].getThread() instanceof AsynchExecThread);
			status[i] = TestBarrier.STATUS_WAIT_FOR_DONE;
		}

		for (int i = 0; i < status.length; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_DONE);
		}

		//the status for every job should be STATUS_OK
		//the threads should have been reset to null
		for (int i = 0; i < status.length; i++) {
			assertEquals("7." + i, TestBarrier.STATUS_DONE, status[i]);
			assertEquals("8." + i, Job.NONE, jobs[i].getState());
			assertEquals("9." + i, IStatus.OK, jobs[i].getResult().getSeverity());
			assertNull("10." + i, jobs[i].getThread());
		}
	}

	public void testAsynchJobConflict() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START};

		//test the interaction of several asynchronous jobs when a conflicting rule is assigned to some of them
		AsynchTestJob[] jobs = new AsynchTestJob[5];

		ISchedulingRule rule = new IdentityRule();

		for (int i = 0; i < jobs.length; i++) {
			jobs[i] = new AsynchTestJob("TestJob" + (i + 1), status, i);
			assertTrue("1." + i, jobs[i].getThread() == null);
			assertTrue("2." + i, jobs[i].getResult() == null);
			if (i < 2) {
				jobs[i].schedule();
			} else if (i > 2) {
				jobs[i].setRule(rule);
			} else {
				jobs[i].setRule(rule);
				jobs[i].schedule();
			}

		}

		//these 3 jobs should be waiting for the STATUS_START flag
		for (int i = 0; i < 3; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_RUNNING);
			assertTrue("3." + i, jobs[i].getState() == Job.RUNNING);
			assertTrue("4." + i, jobs[i].getThread() instanceof Worker);
			status[i] = TestBarrier.STATUS_START;
		}

		//the first 3 jobs should be running at the same time
		for (int i = 0; i < 3; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_WAIT_FOR_START);
		}

		//the 3 jobs should now be waiting for the STATUS_WAIT_FOR_RUN flag
		for (int i = 0; i < 3; i++) {
			assertTrue("5. " + i, jobs[i].getThread() instanceof Worker);
			status[i] = TestBarrier.STATUS_WAIT_FOR_RUN;
		}

		//wait until jobs block on running state
		for (int i = 0; i < 3; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_RUNNING);
		}

		//schedule the 2 remaining jobs
		jobs[3].schedule();
		jobs[4].schedule();

		//the 2 newly scheduled jobs should be waiting since they conflict with the third job
		//no threads were assigned to them yet
		assertEquals("6.1", Job.WAITING, jobs[3].getState());
		assertNull("6.2", jobs[3].getThread());
		assertEquals("6.3", Job.WAITING, jobs[4].getState());
		assertNull("6.4", jobs[4].getThread());

		//let the two non-conflicting jobs execute together
		for (int i = 0; i < 2; i++) {
			assertTrue("7. " + i, jobs[i].getThread() instanceof AsynchExecThread);
			status[i] = TestBarrier.STATUS_WAIT_FOR_DONE;
		}
		//wait until the non-conflicting jobs are done
		TestBarrier.waitForStatus(status, 1, TestBarrier.STATUS_DONE);

		//the third job should still be in the running state
		assertEquals("8.1", Job.RUNNING, jobs[2].getState());
		//the 2 conflicting jobs should still be in the waiting state
		assertEquals("8.2", Job.WAITING, jobs[3].getState());
		assertEquals("8.3", Job.WAITING, jobs[4].getState());

		//let the third job finish execution
		assertTrue("8.4", jobs[2].getThread() instanceof AsynchExecThread);
		status[2] = TestBarrier.STATUS_WAIT_FOR_DONE;

		//wait until the third job is done
		TestBarrier.waitForStatus(status, 2, TestBarrier.STATUS_DONE);

		//the fourth job should now start running, the fifth job should still be waiting
		TestBarrier.waitForStatus(status, 3, TestBarrier.STATUS_RUNNING);
		assertEquals("9.1", Job.RUNNING, jobs[3].getState());
		assertEquals("9.2", Job.WAITING, jobs[4].getState());

		//let the fourth job run, the fifth job is still waiting
		status[3] = TestBarrier.STATUS_START;
		assertEquals("9.3", Job.WAITING, jobs[4].getState());
		TestBarrier.waitForStatus(status, 3, TestBarrier.STATUS_WAIT_FOR_START);
		status[3] = TestBarrier.STATUS_WAIT_FOR_RUN;
		assertEquals("9.4", Job.WAITING, jobs[4].getState());
		TestBarrier.waitForStatus(status, 3, TestBarrier.STATUS_RUNNING);
		assertEquals("9.5", Job.WAITING, jobs[4].getState());

		//cancel the fifth job, finish the fourth job
		jobs[4].cancel();
		assertTrue("9.6", jobs[3].getThread() instanceof AsynchExecThread);
		status[3] = TestBarrier.STATUS_WAIT_FOR_DONE;

		//wait until the fourth job is done
		TestBarrier.waitForStatus(status, 3, TestBarrier.STATUS_DONE);

		//the status for the first 4 jobs should be STATUS_OK
		//the threads should have been reset to null
		for (int i = 0; i < status.length - 1; i++) {
			assertEquals("10." + i, TestBarrier.STATUS_DONE, status[i]);
			assertEquals("11." + i, Job.NONE, jobs[i].getState());
			assertEquals("12." + i, IStatus.OK, jobs[i].getResult().getSeverity());
			assertNull("13." + i, jobs[i].getThread());
		}

		//the fifth job should have null as its status (it never finished running)
		//the thread for it should have also been reset
		assertEquals("14.1", TestBarrier.STATUS_WAIT_FOR_START, status[4]);
		assertEquals("14.2", Job.NONE, jobs[4].getState());
		assertNull("14.3", jobs[4].getResult());
		assertNull("14.4", jobs[4].getThread());
	}

	/**
	 * Tests cancelation of a job from the aboutToRun job event.
	 * See bug 70434 for details.
	 */
	public void testCancelFromAboutToRun() {
		final int[] doneCount = new int[] {0};
		final int[] runningCount = new int[] {0};
		TestJob job = new TestJob("testCancelFromAboutToRun", 0, 0);
		job.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void aboutToRun(IJobChangeEvent event) {
				event.getJob().cancel();
			}

			@Override
			public void done(IJobChangeEvent event) {
				doneCount[0]++;
			}

			@Override
			public void running(IJobChangeEvent event) {
				runningCount[0]++;
			}
		});
		job.schedule();
		try {
			job.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
			fail("0.99 " + e.getMessage());
		}
		assertEquals("1.0", 0, job.getRunCount());
		assertEquals("1.1", 1, doneCount[0]);
		assertEquals("1.2", 0, runningCount[0]);
	}

	/**
	 * Basic test of {@link Job#shouldRun()}.
	 */
	public void testShouldRun() {
		class ShouldRunJob extends Job {
			public ShouldRunJob() {
				super("ShouldRunJob");
			}

			int runCount = 0;

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				++runCount;
				return Status.OK_STATUS;
			}

			@Override
			public boolean shouldRun() {
				return false;
			}
		}
		ShouldRunJob j = new ShouldRunJob();
		j.schedule();
		try {
			j.join();
		} catch (InterruptedException e) {
			fail("0.99", e);
		}

		//ensure the job never ran
		assertEquals(0, j.runCount);

	}

	/**
	 * Test of an ill-behaving {@link Job#shouldRun()}.
	 */
	public void testShouldRunFailure() {
		class ShouldRunJob extends Job {
			public ShouldRunJob() {
				super("ShouldRunJob");
			}

			int runCount = 0;

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				++runCount;
				return Status.OK_STATUS;
			}

			@Override
			public boolean shouldRun() {
				throw new RuntimeException("Exception thrown on purpose as part of a test");
			}
		}
		ShouldRunJob j = new ShouldRunJob();
		j.schedule();
		waitForState(j, Job.NONE);

		//ensure the job never ran
		assertEquals(0, j.runCount);

	}

	/**
	 * Tests canceling a job from the shouldRun method. See bug 255384.
	 */
	public void testCancelShouldRun() {
		final String[] failure = new String[1];
		final Job j = new Job("Test") {
			volatile int runningCount = 0;
			boolean cancelled;

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				if (++runningCount > 1) {
					failure[0] = "Multiple running at once!";
				}
				try {
					Thread.sleep(500);
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (--runningCount != 0) {
						failure[0] = "Multiple were running at once!";
					}
				}
				return Status.OK_STATUS;
			}

			@Override
			public boolean belongsTo(Object family) {
				return JobTest.this == family;
			}

			@Override
			public boolean shouldRun() {
				if (!cancelled) {
					cancelled = true;
					this.sleep();
					this.cancel();
					this.schedule();
					try {
						Thread.sleep(500);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				return true;
			}
		};
		j.schedule();
		try {
			Thread.sleep(1000);
			Job.getJobManager().join(this, null);
		} catch (OperationCanceledException e) {
			fail("4.99", e);
		} catch (InterruptedException e) {
			fail("4.99", e);
		}
		assertNull(failure[0], failure[0]);
	}

	/**
	 * Tests the hook method {@link Job#canceling}.
	 */
	public void testCanceling() {
		final TestBarrier barrier = new TestBarrier();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
		final int[] canceling = new int[] {0};
		Job job = new Job("Testing#testCanceling") {
			@Override
			protected void canceling() {
				canceling[0]++;
			}

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
				barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
				return Status.OK_STATUS;
			}
		};
		//schedule the job and wait on the barrier until it is running
		job.schedule();
		barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
		assertTrue("1.0", canceling[0] == 0);
		job.cancel();
		assertTrue("1.1", canceling[0] == 1);
		job.cancel();
		assertTrue("1.2", canceling[0] == 1);
		//let the job finish
		barrier.setStatus(TestBarrier.STATUS_RUNNING);
		waitForState(job, Job.NONE);
	}

	/**
	 * Tests the hook method {@link Job#canceling}.
	 */
	public void testCancelingByMonitor() {
		final TestBarrier barrier = new TestBarrier();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
		final int[] canceling = new int[] {0};
		final IProgressMonitor[] jobmonitor = new IProgressMonitor[1];
		Job job = new Job("Testing#testCancelingByMonitor") {
			@Override
			protected void canceling() {
				canceling[0]++;
			}

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				jobmonitor[0] = monitor;
				barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
				barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
				return Status.OK_STATUS;
			}
		};
		//run test twice to ensure job is left in a clean state after first cancelation
		for (int i = 0; i < 2; i++) {
			canceling[0] = 0;
			//schedule the job and wait on the barrier until it is running
			job.schedule();
			barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
			assertEquals(Integer.toString(i) + ".1.0", 0, canceling[0]);
			jobmonitor[0].setCanceled(true);
			assertEquals(Integer.toString(i) + ".1.1", 1, canceling[0]);
			jobmonitor[0].setCanceled(true);
			assertEquals(Integer.toString(i) + ".1.2", 1, canceling[0]);
			//let the job finish
			barrier.setStatus(TestBarrier.STATUS_RUNNING);
			waitForState(job, Job.NONE);
		}
	}

	public void testCancelAboutToSchedule() {
		final boolean[] failure = new boolean[1];
		final Job j = new Job("testCancelAboutToSchedule") {
			volatile int runningCount = 0;

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				if (++runningCount > 1) {
					failure[0] = true;
				}
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					if (--runningCount != 0) {
						failure[0] = true;
					}
				}
				return Status.OK_STATUS;
			}

			@Override
			public boolean belongsTo(Object family) {
				return JobTest.this == family;
			}
		};
		JobChangeAdapter listener = new JobChangeAdapter() {
			boolean canceled = false;

			@Override
			public void scheduled(IJobChangeEvent event) {
				if (event.getJob().belongsTo(JobTest.this) && !canceled) {
					canceled = true;
					j.cancel();
					j.schedule();
					try {
						Thread.sleep(100);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		};
		Job.getJobManager().addJobChangeListener(listener);
		try {
			j.schedule();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				fail("4.99", e);
			}
			try {
				Job.getJobManager().join(this, null);
			} catch (OperationCanceledException e) {
				fail("4.99", e);
			} catch (InterruptedException e) {
				fail("4.99", e);
			}
			assertFalse("1.0", failure[0]);
		} finally {
			Job.getJobManager().removeJobChangeListener(listener);
		}
	}

	public void testGetName() {
		assertTrue("1.0", shortJob.getName().equals("Short Test Job"));
		assertTrue("1.1", longJob.getName().equals("Long Test Job"));

		//try creating a job with a null name
		try {
			new TestJob(null);
			fail("2.0");
		} catch (RuntimeException e) {
			//should fail
		}
	}

	public void testGetPriority() {
		//set priorities to all allowed options
		//check if getPriority() returns proper result

		int[] priority = {Job.SHORT, Job.LONG, Job.INTERACTIVE, Job.BUILD, Job.DECORATE};

		for (int i = 0; i < priority.length; i++) {
			shortJob.setPriority(priority[i]);
			assertTrue("1." + i, shortJob.getPriority() == priority[i]);
		}
	}

	public void testGetProperty() {
		QualifiedName n1 = new QualifiedName("org.eclipse.core.tests.runtime", "p1");
		QualifiedName n2 = new QualifiedName("org.eclipse.core.tests.runtime", "p2");
		assertNull("1.0", shortJob.getProperty(n1));
		shortJob.setProperty(n1, null);
		assertNull("1.1", shortJob.getProperty(n1));
		shortJob.setProperty(n1, shortJob);
		assertTrue("1.2", shortJob.getProperty(n1) == shortJob);
		assertNull("1.3", shortJob.getProperty(n2));
		shortJob.setProperty(n1, "hello");
		assertEquals("1.4", "hello", shortJob.getProperty(n1));
		shortJob.setProperty(n1, null);
		assertNull("1.5", shortJob.getProperty(n1));
		assertNull("1.6", shortJob.getProperty(n2));
	}

	public void testGetResult() {
		//execute a short job
		assertTrue("1.0", shortJob.getResult() == null);
		shortJob.schedule();
		waitForState(shortJob, Job.NONE);
		assertTrue("1.1", shortJob.getResult().getSeverity() == IStatus.OK);

		//cancel a long job
		waitForState(longJob, Job.NONE);
		longJob.schedule();
		waitForState(longJob, Job.RUNNING);
		longJob.cancel();
		waitForState(longJob, Job.NONE);
		assertTrue("2.0", longJob.getResult().getSeverity() == IStatus.CANCEL);
	}

	public void testGetRule() {
		//set several rules for the job, check if getRule returns the rule that was set
		//no rule was set yet
		assertTrue("1.0", shortJob.getRule() == null);

		shortJob.setRule(new IdentityRule());
		assertTrue("1.1", (shortJob.getRule() instanceof IdentityRule));

		ISchedulingRule rule = new PathRule("/testGetRule");
		shortJob.setRule(rule);
		assertTrue("1.2", shortJob.getRule() == rule);

		shortJob.setRule(null);
		assertTrue("1.3", shortJob.getRule() == null);
	}

	public void testGetThread() {
		//check that getThread returns the thread that was passed in setThread, when the job is not running
		//if the job is scheduled, only jobs that return the asynch_exec status will run in the indicated thread

		//main is not running now
		assertTrue("1.0", shortJob.getThread() == null);

		Thread t = new Thread();
		shortJob.setThread(t);
		assertTrue("1.1", shortJob.getThread() == t);

		shortJob.setThread(new Thread());
		assertTrue("1.2", shortJob.getThread() != t);

		shortJob.setThread(null);
		assertTrue("1.3", shortJob.getThread() == null);
	}

	public void testIsBlocking() {
		IdentityRule rule = new IdentityRule();
		TestJob high = new TestJob("TestIsBlocking.long", 10000, 100);
		high.setRule(rule);
		high.setPriority(Job.LONG);
		TestJob medium = new TestJob("TestIsBlocking.build", 10000, 100);
		medium.setRule(rule);
		medium.setPriority(Job.BUILD);
		TestJob low = new TestJob("TestIsBlocking.decorate", 10000, 100);
		low.setRule(rule);
		low.setPriority(Job.DECORATE);

		//start the build job, and make sure it is not blocking
		medium.schedule();
		waitForState(medium, Job.RUNNING);
		assertTrue("1.0", !medium.isBlocking());
		//schedule a lower priority job, and it should still not be blocking
		low.schedule();
		assertTrue("1.1", !medium.isBlocking());
		//schedule a higher priority job - now it should be blocking
		high.schedule();
		//wait for the high priority job to become blocked
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			//ignore
		}
		assertTrue("1.2", medium.isBlocking());

		//cancel everything
		Job[] jobs = new Job[] {high, medium, low};
		cancel(jobs);
		waitForState(jobs, Job.NONE);

		//a higher priority system job should not be blocking
		high.setSystem(true);
		medium.schedule();
		waitForState(medium, Job.RUNNING);
		high.schedule();
		assertTrue("2.0", !medium.isBlocking());

		//clean up
		cancel(jobs);
		waitForState(jobs, Job.NONE);
	}

	// @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=60964
	public void testIsBlocking2() throws InterruptedException {
		final IJobManager manager = Job.getJobManager();
		final ISchedulingRule rule = new IdentityRule();
		Thread thread = new Thread("testIsBlocking2") {
			@Override
			public void run() {
				try {
					manager.beginRule(rule, null);
				} finally {
					manager.endRule(rule);
				}
			}
		};
		try {
			manager.beginRule(rule, null);
			thread.start();
			while (thread.getState() != Thread.State.WAITING) {
				Thread.sleep(50);
			}
			assertTrue(manager.currentJob().isBlocking());
		} finally {
			manager.endRule(rule);
			thread.join();
		}
	}

	public void testIsSystem() {
		//reset the system parameter several times
		shortJob.setUser(false);
		shortJob.setSystem(false);
		assertTrue("1.0", !shortJob.isUser());
		assertTrue("1.1", !shortJob.isSystem());
		shortJob.setSystem(true);
		assertTrue("1.2", !shortJob.isUser());
		assertTrue("1.3", shortJob.isSystem());
		shortJob.setSystem(false);
		assertTrue("1.4", !shortJob.isUser());
		assertTrue("1.5", !shortJob.isSystem());
	}

	public void testIsUser() {
		//reset the user parameter several times
		shortJob.setUser(false);
		shortJob.setSystem(false);
		assertTrue("1.0", !shortJob.isUser());
		assertTrue("1.1", !shortJob.isSystem());
		shortJob.setUser(true);
		assertTrue("1.2", shortJob.isUser());
		assertTrue("1.3", !shortJob.isSystem());
		shortJob.setUser(false);
		assertTrue("1.4", !shortJob.isUser());
		assertTrue("1.5", !shortJob.isSystem());
	}

	public void testJoin() {
		longJob.schedule(100000);
		//create a thread that will join the test job
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				longJob.join();
			} catch (InterruptedException e) {
				Assert.fail("0.99");
			}
			status[0] = TestBarrier.STATUS_DONE;
		});
		t.start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_START);
		assertEquals("1.0", TestBarrier.STATUS_START, status[0]);
		//putting the job to sleep should not affect the join call
		longJob.sleep();
		//give a chance for the sleep to take effect
		sleep(100);
		assertEquals("1.0", TestBarrier.STATUS_START, status[0]);
		//similarly waking the job up should not affect the join
		longJob.wakeUp(100000);
		sleep(100);
		assertEquals("1.0", TestBarrier.STATUS_START, status[0]);

		//finally canceling the job will cause the join to return
		longJob.cancel();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);
	}

	public void testJoinWithTimeout() {
		longJob.schedule();
		final long timeout = 1000;
		final long duration[] = {-1};
		// Create a thread that will join the test job
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				long start = System.currentTimeMillis();
				longJob.join(timeout, null);
				duration[0] = System.currentTimeMillis() - start;
			} catch (InterruptedException e1) {
				Assert.fail("0.88");
			} catch (OperationCanceledException e2) {
				Assert.fail("0.99");
			}
			status[0] = TestBarrier.STATUS_DONE;
		});
		t.start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_START);
		assertEquals("1.0", TestBarrier.STATUS_START, status[0]);
		int i = 0;
		for (; i < 11; i++) {
			if (status[0] == TestBarrier.STATUS_DONE) {
				// Verify that the join call is blocked for at least for the duration of given timeout
				assertTrue("2.0 duration: " + duration + " timeout: " + timeout, duration[0] >= timeout);
				break;
			}
			sleep(100);
		}
		// Verify that the join call is finished with in reasonable time of 1100 ms (given timeout + 100ms)
		assertTrue("3.0", i < 11);
		// Verify that the join call is still running
		assertEquals("4.0", Job.RUNNING, longJob.getState());
		// Finally cancel the job
		longJob.cancel();
		waitForCompletion(longJob);
	}

	public void testJoinWithProgressMonitor() {
		shortJob.schedule(100000);
		// Create a progress monitor for the join call
		final FussyProgressMonitor monitor = new FussyProgressMonitor();
		// Create a thread that will join the test job
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				shortJob.join(0, monitor);
			} catch (InterruptedException e1) {
				Assert.fail("0.88");
			} catch (OperationCanceledException e2) {
				Assert.fail("0.99");
			}
			status[0] = TestBarrier.STATUS_DONE;
		});
		t.start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_START);
		assertEquals("1.0", TestBarrier.STATUS_START, status[0]);
		// Wakeup the job to get the join call to complete
		shortJob.wakeUp();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);
		monitor.sanityCheck();
	}

	public void testJoinWithCancelingMonitor() {
		longJob.schedule();
		// Create a progress monitor for the join call
		final FussyProgressMonitor monitor = new FussyProgressMonitor();
		// Create a thread that will join the test job
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				longJob.join(0, monitor);
			} catch (InterruptedException e1) {
				Assert.fail("0.88");
			} catch (OperationCanceledException e2) {
				// expected
			}
			status[0] = TestBarrier.STATUS_DONE;
		});
		t.start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_START);
		assertEquals("1.0", TestBarrier.STATUS_START, status[0]);

		// Cancel the monitor that is attached to the join call
		monitor.setCanceled(true);
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);
		monitor.sanityCheck();
		// Verify that the join call is still running
		assertEquals("2.0", Job.RUNNING, longJob.getState());
		// Finally cancel the job
		longJob.cancel();
		waitForCompletion(longJob);
	}

	public void testJoinInterruptNonUIThread() throws InterruptedException {
		final Job job = new TestJob("job", 1000, 100);
		Thread t = new Thread(() -> {
			job.schedule();
			try {
				job.join();
			} catch (InterruptedException e) {
				job.cancel();
			}
		});
		t.start();
		// make sure the job is running before we interrupt the thread
		waitForState(job, Job.RUNNING);
		t.interrupt();
		job.join();
		assertTrue("Thread not interrupted", job.getResult() == Status.CANCEL_STATUS);
	}

	public void testJoinInterruptUIThread() throws InterruptedException {
		final Job job = new TestJob("job", 1000, 100);
		Thread t = new Thread(() -> {
			job.schedule();
			try {
				job.join();
			} catch (InterruptedException e) {
				job.cancel();
			}
		});
		try {
			Job.getJobManager().setLockListener(new LockListener() {
				@Override
				public boolean canBlock() {
					// pretend to be the UI thread
					return false;
				}
			});
			t.start();
			// make sure the job is running before we interrupt the thread
			waitForState(job, Job.RUNNING);
			t.interrupt();
			job.join();
			assertTrue("Thread interrupted", job.getResult() == Status.OK_STATUS);
		} finally {
			Job.getJobManager().setLockListener(null);
		}
	}

	/**
	 * Asserts that the LockListener is called correctly during invocation of
	 * {@link Job#join()}.
	 * See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=195839.
	 */
	public void testJoinLockListener() {
		Job testJob = new TestJob("testJoinLockListener", 5, 500);
		TestLockListener lockListener = new TestLockListener();
		try {
			Job.getJobManager().setLockListener(lockListener);
			testJob.join();
		} catch (OperationCanceledException e) {
			fail("4.99", e);
		} catch (InterruptedException e) {
			fail("4.99", e);
		} finally {
			Job.getJobManager().setLockListener(null);
		}
		lockListener.assertNotWaiting("1.0");
	}

	/**
	 * Tests a job change listener that throws an exception.
	 * This would previously cause join attempts on that job to
	 * hang indefinitely because they would miss the notification
	 * required to end the join.
	 */
	public void testJoinFailingListener() {
		shortJob.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				throw new RuntimeException("This exception thrown on purpose as part of a test");
			}
		});
		final int[] status = new int[1];
		//create a thread that will join the job
		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				shortJob.join();
			} catch (InterruptedException e) {
				Assert.fail("0.99");
			}
			status[0] = TestBarrier.STATUS_DONE;
		});
		//schedule the job and then fork the thread to join it
		shortJob.schedule();
		t.start();
		//wait until the join succeeds
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);
	}

	/**
	 * Tests that a job joining itself is an error.
	 */
	public void testJoinSelf() {
		final Exception[] failure = new Exception[1];
		Job selfJoiner = new Job("testJoinSelf") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					this.join();
				} catch (RuntimeException e) {
					failure[0] = e;
				} catch (InterruptedException e) {
					failure[0] = e;
				}
				return Status.OK_STATUS;
			}
		};
		selfJoiner.schedule();
		try {
			selfJoiner.join();
		} catch (InterruptedException e) {
			fail("Unexpected interrupt");
		}
		assertTrue("1.0", failure[0] != null);
	}

	/**
	 * This is a regression test for bug 60323. If a job change listener
	 * removed itself from the listener list during the done() change event,
	 * then anyone joining on that job would hang forever.
	 */
	public void testJoinRemoveListener() {
		final IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				shortJob.removeJobChangeListener(this);
			}
		};
		shortJob.addJobChangeListener(listener);
		final int[] status = new int[1];
		//create a thread that will join the job
		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				shortJob.join();
			} catch (InterruptedException e) {
				Assert.fail("0.99");
			}
			status[0] = TestBarrier.STATUS_DONE;
		});
		//schedule the job and then fork the thread to join it
		shortJob.schedule();
		t.start();
		//wait until the join succeeds
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);
	}

	/*
	 * Test that a canceled job is rescheduled
	 */
	public void testRescheduleCancel() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START};
		Job job = new Job("Testing") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					monitor.beginTask("Testing", 1);
					status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
					TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
					monitor.worked(1);
				} finally {
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		//schedule the job, cancel it, then reschedule
		job.schedule();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		job.cancel();
		job.schedule();
		//let the first iteration of the job finish
		status[0] = TestBarrier.STATUS_RUNNING;
		//wait until the job runs again
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		//let the job finish
		status[0] = TestBarrier.STATUS_RUNNING;
		waitForState(job, Job.NONE);
	}

	/*
	 * Test that multiple reschedules of the same job while it is running
	 * only remembers the last reschedule request
	 */
	public void testRescheduleComplex() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START};
		final int[] runCount = new int[] {0};
		Job job = new Job("Testing") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					monitor.beginTask("Testing", 1);
					status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
					TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
					monitor.worked(1);
				} finally {
					runCount[0]++;
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		//schedule the job, reschedule when it is running
		job.schedule();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		//the last schedule value should win
		job.schedule(1000000);
		job.schedule(3000);
		job.schedule(200000000);
		job.schedule();
		status[0] = TestBarrier.STATUS_RUNNING;
		//wait until the job runs again
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		assertEquals("1.0", 1, runCount[0]);
		//let the job finish
		status[0] = TestBarrier.STATUS_RUNNING;
		waitForState(job, Job.NONE);
		assertEquals("1.0", 2, runCount[0]);
	}

	/*
	 * Reschedule a running job with a delay
	 */
	public void testRescheduleDelay() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START};
		final int[] runCount = new int[] {0};
		Job job = new Job("Testing") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					monitor.beginTask("Testing", 1);
					status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
					TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
					monitor.worked(1);
				} finally {
					runCount[0]++;
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		//schedule the job, reschedule when it is running
		job.schedule();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		job.schedule(1000000);
		status[0] = TestBarrier.STATUS_RUNNING;
		//now wait until the job is scheduled again and put to sleep
		waitForState(job, Job.SLEEPING);
		assertEquals("1.0", 1, runCount[0]);

		//reschedule the job while it is sleeping
		job.schedule();
		//wake up the currently sleeping job
		job.wakeUp();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		status[0] = TestBarrier.STATUS_RUNNING;
		//make sure the job was not rescheduled while the executing job was sleeping
		waitForState(job, Job.NONE);
		assertTrue("1.0", job.getState() == Job.NONE);
		assertEquals("1.0", 2, runCount[0]);
	}

	/*
	 * Schedule a simple job that repeats several times from within the run method.
	 */
	public void testRescheduleRepeat() {
		final int[] count = new int[] {0};
		final int REPEATS = 10;
		Job job = new Job("testRescheduleRepeat") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				count[0]++;
				schedule();
				return Status.OK_STATUS;
			}

			@Override
			public boolean shouldSchedule() {
				return count[0] < REPEATS;
			}
		};
		job.schedule();
		int timeout = 0;
		while (timeout++ < 100 && count[0] < REPEATS) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				//ignore
			}
		}
		assertTrue("1.0", timeout < 100);
		assertEquals("1.1", REPEATS, count[0]);
	} /*
		* Schedule a simple job that repeats several times from within the run method.
		*/

	public void testRescheduleRepeatWithDelay() {
		final int[] count = new int[] {0};
		final int REPEATS = 10;
		Job job = new Job("testRescheduleRepeat") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				count[0]++;
				schedule(10);
				return Status.OK_STATUS;
			}

			@Override
			public boolean shouldSchedule() {
				return count[0] < REPEATS;
			}
		};
		job.schedule();
		int timeout = 0;
		while (timeout++ < 100 && count[0] < REPEATS) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				//ignore
			}
		}
		assertTrue("1.0", timeout < 100);
		assertEquals("1.1", REPEATS, count[0]);
	}

	/*
	 * Schedule a job to run, and then reschedule it
	 */
	public void testRescheduleSimple() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START};
		Job job = new Job("testRescheduleSimple") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					monitor.beginTask("Testing", 1);
					status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
					TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
					monitor.worked(1);
				} finally {
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		//schedule the job, reschedule when it is running
		job.schedule();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		job.schedule();
		status[0] = TestBarrier.STATUS_RUNNING;
		//wait until the job runs again
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		//let the job finish
		status[0] = TestBarrier.STATUS_RUNNING;
		waitForState(job, Job.NONE);

		//the job should only run once the second time around
		job.schedule();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_WAIT_FOR_RUN);
		//let the job finish
		status[0] = TestBarrier.STATUS_RUNNING;
		//wait until the job truly finishes and has a chance to be rescheduled (it shouldn't reschedule)
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			//ignore
		}
		waitForState(job, Job.NONE);
	}

	/*
	 * Reschedule a waiting job.
	 */
	public void testRescheduleWaiting() {
		final int[] status = {TestBarrier.STATUS_WAIT_FOR_START, TestBarrier.STATUS_WAIT_FOR_START};
		final int[] runCount = new int[] {0};
		final ISchedulingRule rule = new IdentityRule();
		Job first = new Job("Testing1") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					monitor.beginTask("Testing", 1);
					status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
					TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);
					monitor.worked(1);
				} finally {
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		Job second = new Job("Testing2") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					monitor.beginTask("Testing", 1);
					status[1] = TestBarrier.STATUS_WAIT_FOR_RUN;
					TestBarrier.waitForStatus(status, 1, TestBarrier.STATUS_RUNNING);
					monitor.worked(1);
				} finally {
					runCount[0]++;
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		//set the same rule for both jobs so that the second job would have to wait
		first.setRule(rule);
		first.schedule();
		second.setRule(rule);
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_RUN);
		second.schedule();
		waitForState(second, Job.WAITING);
		//reschedule the second job while it is waiting
		second.schedule();
		//let the first job finish
		status[0] = TestBarrier.STATUS_RUNNING;
		//the second job will start
		TestBarrier.waitForStatus(status, 1, TestBarrier.STATUS_WAIT_FOR_RUN);
		//let the second job finish
		status[1] = TestBarrier.STATUS_RUNNING;

		//make sure the second job was not rescheduled
		waitForState(second, Job.NONE);
		assertEquals("2.0", Job.NONE, second.getState());
		assertEquals("2.1", 1, runCount[0]);
	}

	/*
	 * see bug #43458
	 */
	public void testSetPriority() {
		int[] wrongPriority = {1000, -Job.DECORATE, 25, 0, 5, Job.INTERACTIVE - Job.BUILD};

		for (int i = 0; i < wrongPriority.length; i++) {
			//set priority to non-existent type
			try {
				shortJob.setPriority(wrongPriority[i]);
				fail("1." + (i + 1));
			} catch (RuntimeException e) {
				//should fail
			}
		}
	}

	/**
	 * Tests the API methods Job.setProgressGroup
	 */
	public void testSetProgressGroup() {
		final TestBarrier barrier = new TestBarrier();
		Job job = new Job("testSetProgressGroup") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_RUNNING);
				barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				if (monitor.isCanceled()) {
					return Status.CANCEL_STATUS;
				}
				return Status.OK_STATUS;
			}
		};
		//null group
		try {
			job.setProgressGroup(null, 5);
			fail("1.0");
		} catch (RuntimeException e) {
			//should fail
		}
		IProgressMonitor group = Job.getJobManager().createProgressGroup();
		group.beginTask("Group task name", 10);
		job.setProgressGroup(group, 5);

		//ignore changes to group while waiting or running
		job.schedule(100);
		job.setProgressGroup(group, 0);
		//wait until job starts and try to set the progress group
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
		job.setProgressGroup(group, 0);

		//ensure cancelation still works
		job.cancel();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
		waitForState(job, Job.NONE);
		assertEquals("1.0", IStatus.CANCEL, job.getResult().getSeverity());
		group.done();
	}

	/*
	 * see bug #43459
	 */
	public void testSetRule() {
		//setting a scheduling rule for a job after it was already scheduled should throw an exception
		shortJob.setRule(new IdentityRule());
		assertTrue("1.0", shortJob.getRule() instanceof IdentityRule);
		shortJob.schedule(1000000);
		try {
			shortJob.setRule(new PathRule("/testSetRule"));
			fail("1.1");
		} catch (RuntimeException e) {
			//should fail
		}

		//wake up the sleeping job
		shortJob.wakeUp();

		//setting the rule while running should fail
		try {
			shortJob.setRule(new PathRule("/testSetRule/B"));
			fail("2.0");
		} catch (RuntimeException e1) {
			//should fail
		}

		try {
			//wait for the job to complete
			shortJob.join();
		} catch (InterruptedException e2) {
			//ignore
		}

		//after the job has finished executing, the scheduling rule for it can once again be reset
		shortJob.setRule(new PathRule("/testSetRule/B/C/D"));
		assertTrue("1.2", shortJob.getRule() instanceof PathRule);
		shortJob.setRule(null);
		assertTrue("1.3", shortJob.getRule() == null);
	}

	public void testSetThread() {
		//setting the thread of a job that is not an asynchronous job should not affect the actual thread the job will run in
		assertTrue("0.0", longJob.getThread() == null);

		longJob.setThread(Thread.currentThread());
		assertTrue("1.0", longJob.getThread() == Thread.currentThread());
		longJob.schedule();
		waitForState(longJob, Job.RUNNING);

		//the setThread method should have no effect on jobs that execute normally
		assertTrue("2.0", longJob.getThread() != Thread.currentThread());

		longJob.cancel();
		waitForState(longJob, Job.NONE);

		//the thread should reset to null when the job finishes execution
		assertTrue("3.0", longJob.getThread() == null);

		longJob.setThread(null);
		assertTrue("4.0", longJob.getThread() == null);

		longJob.schedule();
		waitForState(longJob, Job.RUNNING);

		//the thread that the job is executing in is not the one that was set
		assertTrue("5.0 (state=" + JobManager.printState(longJob.getState()) + ')', longJob.getThread() != null);
		longJob.cancel();
		waitForState(longJob, Job.NONE);

		//thread should reset to null after execution of job
		assertTrue("6.0", longJob.getThread() == null);

		Thread t = new Thread();
		longJob.setThread(t);
		assertTrue("7.0", longJob.getThread() == t);
		longJob.schedule();
		waitForState(longJob, Job.RUNNING);

		//the thread that the job is executing in is not the one that it was set to
		assertTrue("8.0", longJob.getThread() != t);
		longJob.cancel();
		waitForState(longJob, Job.NONE);

		//execution thread should reset to null after job is finished
		assertTrue("9.0", longJob.getThread() == null);

		//when the state is changed to RUNNING, the thread should not be null
		final Thread[] thread = new Thread[1];
		IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void running(IJobChangeEvent event) {
				thread[0] = event.getJob().getThread();
			}
		};
		longJob.addJobChangeListener(listener);
		longJob.schedule();
		waitForState(longJob, Job.RUNNING);
		longJob.cancel();
		longJob.removeJobChangeListener(listener);
		assertNotNull("10.0", thread[0]);
	}

	/**
	 * Several jobs were scheduled to run.
	 * Pause this thread until all the jobs start running.
	 */
	private void waitForStart(Job[] jobs, int[] status) {
		for (int i = 0; i < jobs.length; i++) {
			TestBarrier.waitForStatus(status, i, TestBarrier.STATUS_RUNNING);
		}
	}

	/**
	 * A job has been scheduled.  Pause this thread so that a worker thread
	 * has a chance to pick up the new job.
	 */
	private void waitForState(Job job, int state) {
		int i = 0;
		while (job.getState() != state) {
			try {
				Thread.yield();
				Thread.sleep(100);
				Thread.yield();
			} catch (InterruptedException e) {
				//ignore
			}
			//sanity test to avoid hanging tests
			assertTrue("Timeout waiting for job to change state.", i++ < 100);
		}
	}

	private void waitForState(Job[] jobs, int state) {
		for (Job job : jobs) {
			waitForState(job, state);
		}
	}

	/**
	 * A job was scheduled to run.  Pause this thread so that a worker thread
	 * has a chance to finish the job
	 */
	//	private void waitForEnd(Job job) {
	//		int i = 0;
	//		while(job.getState() != Job.NONE) {
	//			try {
	//				Thread.sleep(100);
	//			} catch (InterruptedException e) {
	//
	//			}
	//
	//			//sanity test to avoid hanging tests
	//			assertTrue("Timeout waiting for job to end", i++ < 1000);
	//		}
	//	}
}
