public void Bug1433069TestBoundJobCommit()
        {
            void test()
            {
                using BatchClient batchCli = TestUtilities.OpenBatchClient(TestUtilities.GetCredentialsFromEnvironment());
                string jobId = Constants.DefaultConveniencePrefix + TestUtilities.GetMyName() + "-TestBoundJobCommit";

                try
                {
                    //
                    // Create the job
                    //
                    CloudJob cloudJob = batchCli.JobOperations.CreateJob(jobId, new PoolInformation());
                    cloudJob.PoolInformation = new PoolInformation()
                    {
                        PoolId = poolFixture.PoolId
                    };

                    testOutputHelper.WriteLine("Initial job schedule commit()");
                    cloudJob.Commit();

                    //Get the job
                    CloudJob refreshableJob = batchCli.JobOperations.GetJob(jobId);

                    //Update the bound job priority
                    const int          newJobPriority        = 5;
                    OnAllTasksComplete newOnAllTasksComplete = OnAllTasksComplete.NoAction;

                    testOutputHelper.WriteLine("Job priority is: {0}", refreshableJob.Priority);
                    refreshableJob.Priority           = newJobPriority;
                    refreshableJob.OnAllTasksComplete = newOnAllTasksComplete;
                    refreshableJob.Commit();

                    AssertJobCorrectness(batchCli.JobOperations, jobId, ref refreshableJob, poolFixture.PoolId, newJobPriority, null);

                    //Update the bound job pool name
                    //Must disable the job first before updating its pool
                    refreshableJob.Disable(DisableJobOption.Terminate);

                    //Wait for job to reach disabled state (could go to Disabling for a bit)
                    //TODO: Use a uBtilities wait helper here
                    DateTime jobDisabledStateWaitStartTime = DateTime.UtcNow;
                    TimeSpan jobDisabledTimeout            = TimeSpan.FromSeconds(120);
                    while (refreshableJob.State != JobState.Disabled)
                    {
                        testOutputHelper.WriteLine("Bug1433069TestBoundJobCommit: sleeping for (refreshableJob.State != JobState.Disabled)");
                        Thread.Sleep(TimeSpan.FromSeconds(10));
                        refreshableJob = batchCli.JobOperations.GetJob(jobId);

                        if (DateTime.UtcNow > jobDisabledStateWaitStartTime.Add(jobDisabledTimeout))
                        {
                            Assert.False(true, "Timed out waiting for job to go to disabled state");
                        }
                    }

                    const string newPoolId = "testPool";
                    refreshableJob.PoolInformation.PoolId = newPoolId;
                    refreshableJob.Commit();

                    AssertJobCorrectness(batchCli.JobOperations, jobId, ref refreshableJob, newPoolId, newJobPriority, null);

                    //Enable the job again
                    refreshableJob.Enable();

                    //Update the bound job constraints
                    JobConstraints newJobConstraints = new JobConstraints(TimeSpan.FromSeconds(200), 19);
                    refreshableJob.Constraints = newJobConstraints;
                    refreshableJob.Commit();

                    AssertJobCorrectness(batchCli.JobOperations, jobId, ref refreshableJob, newPoolId, newJobPriority, newJobConstraints);
                }
                finally
                {
                    batchCli.JobOperations.DeleteJob(jobId);
                }
            }

            SynchronizationContextHelper.RunTest(test, TestTimeout);
        }
        public void TestJobUpdateWithAndWithoutPoolInfo()
        {
            void test()
            {
                using BatchClient batchCli = TestUtilities.OpenBatchClient(TestUtilities.GetCredentialsFromEnvironment());
                const string testName = "TestJobUpdateWithAndWithoutPoolInfo";

                // Create a job
                string   jobId      = testName + "_" + TestUtilities.GetMyName();
                CloudJob unboundJob = batchCli.JobOperations.CreateJob();

                unboundJob.Id = jobId;

                // Use an auto pool with the job, since PoolInformation can't be updated otherwise.
                PoolSpecification poolSpec = new PoolSpecification();

                poolSpec.CloudServiceConfiguration = new CloudServiceConfiguration(PoolFixture.OSFamily, "*");

                poolSpec.TargetDedicatedComputeNodes = 0;
                poolSpec.VirtualMachineSize          = PoolFixture.VMSize;
                AutoPoolSpecification autoPoolSpec = new AutoPoolSpecification();
                string autoPoolPrefix = "UpdPIAuto_" + TestUtilities.GetMyName();

                autoPoolSpec.AutoPoolIdPrefix = autoPoolPrefix;
                const bool originalKeepAlive = false;

                autoPoolSpec.KeepAlive          = originalKeepAlive;
                autoPoolSpec.PoolLifetimeOption = PoolLifetimeOption.Job;
                autoPoolSpec.PoolSpecification  = poolSpec;
                PoolInformation poolInfo = new PoolInformation();

                poolInfo.AutoPoolSpecification = autoPoolSpec;
                unboundJob.PoolInformation     = poolInfo;

                const int originalPriority = 0;

                unboundJob.Priority = originalPriority;
                List <MetadataItem> originalMetadata = new List <MetadataItem>
                {
                    new MetadataItem("meta1", "value1"),
                    new MetadataItem("meta2", "value2")
                };

                unboundJob.Metadata = originalMetadata;

                testOutputHelper.WriteLine("Creating job {0}", jobId);
                unboundJob.Commit();

                try
                {
                    // Get bound job
                    CloudJob createdJob = batchCli.JobOperations.GetJob(jobId);

                    // Verify that we can update something besides PoolInformation without getting an error for not being in the Disabled state.
                    Assert.NotEqual(JobState.Disabled, createdJob.State);

                    int updatedPriority = originalPriority + 1;
                    List <MetadataItem> updatedMetadata = new List <MetadataItem> {
                        new MetadataItem("updatedMeta1", "value1")
                    };
                    createdJob.Priority = updatedPriority;
                    createdJob.Metadata = updatedMetadata;

                    testOutputHelper.WriteLine("Updating job {0} without altering PoolInformation", jobId);

                    createdJob.Commit();

                    // Verify update occurred
                    CloudJob updatedJob = batchCli.JobOperations.GetJob(jobId);

                    Assert.Equal(updatedPriority, updatedJob.Priority);
                    Assert.Equal(updatedJob.Metadata.Count, updatedJob.Priority);
                    Assert.Equal(updatedJob.Metadata[0].Name, updatedMetadata[0].Name);
                    Assert.Equal(updatedJob.Metadata[0].Value, updatedMetadata[0].Value);

                    // Verify that updating the PoolInformation works.
                    // PoolInformation can only be changed in the Disabled state.
                    testOutputHelper.WriteLine("Disabling job {0}", jobId);
                    updatedJob.Disable(DisableJobOption.Terminate);
                    while (updatedJob.State != JobState.Disabled)
                    {
                        Thread.Sleep(500);
                        updatedJob.Refresh();
                    }

                    Assert.Equal(JobState.Disabled, updatedJob.State);

                    bool updatedKeepAlive = !originalKeepAlive;
                    updatedJob.PoolInformation.AutoPoolSpecification.KeepAlive = updatedKeepAlive;
                    int updatedAgainPriority = updatedPriority + 1;
                    updatedJob.Priority = updatedAgainPriority;
                    testOutputHelper.WriteLine("Updating job {0} properties, including PoolInformation", jobId);
                    updatedJob.Commit();

                    CloudJob updatedPoolInfoJob = batchCli.JobOperations.GetJob(jobId);

                    Assert.Equal(updatedKeepAlive, updatedPoolInfoJob.PoolInformation.AutoPoolSpecification.KeepAlive);
                    Assert.Equal(updatedAgainPriority, updatedPoolInfoJob.Priority);
                }
                finally
                {
                    testOutputHelper.WriteLine("Deleting job {0}", jobId);
                    TestUtilities.DeleteJobIfExistsAsync(batchCli, jobId).Wait();

                    // Explicitly delete auto pool
                    foreach (CloudPool pool in batchCli.PoolOperations.ListPools(new ODATADetailLevel(filterClause: string.Format("startswith(id,'{0}')", autoPoolPrefix))))
                    {
                        testOutputHelper.WriteLine("Deleting pool {0}", pool.Id);
                        TestUtilities.DeletePoolIfExistsAsync(batchCli, pool.Id).Wait();
                    }
                }
            }

            SynchronizationContextHelper.RunTest(test, TestTimeout);
        }
        public void TestBoundJobVerbs()
        {
            void test()
            {
                using BatchClient batchCli = TestUtilities.OpenBatchClient(TestUtilities.GetCredentialsFromEnvironment());
                //Create a job

                string jobId = Constants.DefaultConveniencePrefix + TestUtilities.GetMyName() + "-TestBoundJobVerbs";

                try
                {
                    CloudJob cloudJob = batchCli.JobOperations.CreateJob(jobId, new PoolInformation());
                    cloudJob.PoolInformation = new PoolInformation()
                    {
                        PoolId = poolFixture.PoolId
                    };
                    cloudJob.Commit();

                    //Get the bound job
                    CloudJob job = batchCli.JobOperations.GetJob(jobId);

                    //Disable the job (via instance)
                    job.Disable(DisableJobOption.Terminate);

                    //Check the job state

                    CloudJob disabledJob = batchCli.JobOperations.GetJob(jobId);
                    testOutputHelper.WriteLine("DisabledJob State: {0}", disabledJob.State);
                    Assert.True(disabledJob.State == JobState.Disabled || disabledJob.State == JobState.Disabling);

                    //Enable the job (via instance)
                    job.Enable();

                    //Check the job state
                    CloudJob enabledJob = batchCli.JobOperations.GetJob(jobId);
                    testOutputHelper.WriteLine("EnabledJob state: {0}", enabledJob.State);
                    Assert.Equal(JobState.Active, JobState.Active);

                    //Disable the job (via operations)
                    batchCli.JobOperations.DisableJob(jobId, DisableJobOption.Terminate);

                    disabledJob = batchCli.JobOperations.GetJob(jobId);
                    testOutputHelper.WriteLine("DisabledJob State: {0}", disabledJob.State);
                    Assert.True(disabledJob.State == JobState.Disabled || disabledJob.State == JobState.Disabling);

                    //Enable the job (via operations)
                    batchCli.JobOperations.EnableJob(jobId);

                    //Check the job state
                    enabledJob = batchCli.JobOperations.GetJob(jobId);
                    testOutputHelper.WriteLine("EnabledJob state: {0}", enabledJob.State);
                    Assert.Equal(JobState.Active, JobState.Active);

                    //Terminate the job
                    job.Terminate("need some reason");

                    //Check the job state
                    CloudJob terminatedJob = batchCli.JobOperations.GetJob(jobId);
                    testOutputHelper.WriteLine("TerminatedJob state: {0}", terminatedJob.State);
                    Assert.True(terminatedJob.State == JobState.Terminating || terminatedJob.State == JobState.Completed);

                    if (terminatedJob.State == JobState.Terminating)
                    {
                        Thread.Sleep(TimeSpan.FromSeconds(5)); //Sleep and wait for the job to finish terminating before we issue a delete
                    }

                    //Delete the job
                    job.Delete();

                    //Check that the job doesn't exist anymore

                    try
                    {
                        testOutputHelper.WriteLine("Expected Exception: testing that job does NOT exist.");

                        CloudJob deletedJob = batchCli.JobOperations.GetJob(jobId);
                        Assert.Equal(JobState.Deleting, deletedJob.State);
                    }
                    catch (Exception e)
                    {
                        Assert.IsAssignableFrom <BatchException>(e);
                        BatchException be = e as BatchException;
                        Assert.NotNull(be.RequestInformation);
                        Assert.NotNull(be.RequestInformation.BatchError);
                        Assert.Equal(BatchErrorCodeStrings.JobNotFound, be.RequestInformation.BatchError.Code);

                        testOutputHelper.WriteLine("Job was deleted successfully");
                    }
                }
                finally
                {
                    TestUtilities.DeleteJobIfExistsAsync(batchCli, jobId).Wait();
                }
            }

            SynchronizationContextHelper.RunTest(test, TestTimeout);
        }