public virtual void testCompletingSuspendJobDuringAcquisition()
        {
            testRule.Deploy(SIMPLE_ASYNC_PROCESS);

            runtimeService.StartProcessInstanceByKey("simpleAsyncProcess");

            // given a waiting acquisition and a waiting suspension
            JobAcquisitionThread acquisitionThread = new JobAcquisitionThread(this);

            acquisitionThread.startAndWaitUntilControlIsReturned();

            JobSuspensionThread jobSuspensionThread = new JobSuspensionThread(this, "simpleAsyncProcess");

            jobSuspensionThread.startAndWaitUntilControlIsReturned();

            // first complete suspension:
            jobSuspensionThread.proceedAndWaitTillDone();
            acquisitionThread.proceedAndWaitTillDone();

            // then the acquisition will not Assert.Fail with optimistic locking
            Assert.IsNull(jobSuspensionThread.exception);
            Assert.IsNull(acquisitionThread.exception);
            // but the job will also not be acquired
            Assert.AreEqual(0, acquisitionThread.acquiredJobs.Size());

            //--------------------------------------------

            // given a waiting acquisition and a waiting suspension
            acquisitionThread = new JobAcquisitionThread(this);
            acquisitionThread.startAndWaitUntilControlIsReturned();

            jobSuspensionThread = new JobSuspensionThread(this, "simpleAsyncProcess");
            jobSuspensionThread.startAndWaitUntilControlIsReturned();

            // first complete acquisition:
            acquisitionThread.proceedAndWaitTillDone();
            jobSuspensionThread.proceedAndWaitTillDone();

            // then there are no optimistic locking exceptions
            Assert.IsNull(jobSuspensionThread.exception);
            Assert.IsNull(acquisitionThread.exception);
        }
        public virtual void testCompletingJobExecutionSuspendDuringExecution()
        {
            testRule.Deploy(SIMPLE_ASYNC_PROCESS);

            runtimeService.StartProcessInstanceByKey("simpleAsyncProcess");
            IJob job = managementService.CreateJobQuery().First();

            // given a waiting execution and a waiting suspension
            JobExecutionThread executionthread = new JobExecutionThread(this, job.Id);

            executionthread.startAndWaitUntilControlIsReturned();

            JobSuspensionThread jobSuspensionThread = new JobSuspensionThread(this, "simpleAsyncProcess");

            jobSuspensionThread.startAndWaitUntilControlIsReturned();

            // first complete suspension:
            jobSuspensionThread.proceedAndWaitTillDone();
            executionthread.proceedAndWaitTillDone();

            // then the execution will Assert.Fail with optimistic locking
            Assert.IsNull(jobSuspensionThread.exception);
            Assert.NotNull(executionthread.exception);

            //--------------------------------------------

            // given a waiting execution and a waiting suspension
            executionthread = new JobExecutionThread(this, job.Id);
            executionthread.startAndWaitUntilControlIsReturned();

            jobSuspensionThread = new JobSuspensionThread(this, "simpleAsyncProcess");
            jobSuspensionThread.startAndWaitUntilControlIsReturned();

            // first complete execution:
            executionthread.proceedAndWaitTillDone();
            jobSuspensionThread.proceedAndWaitTillDone();

            // then there are no optimistic locking exceptions
            Assert.IsNull(jobSuspensionThread.exception);
            Assert.IsNull(executionthread.exception);
        }