Ejemplo n.º 1
0
        private void buttonRunPackage_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "*.dll|*.dll";
            ofd.Title  = "Select Package DLL File";
            if (ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                Job j = new Job();
                j.Properties = new SerializableDictionary <string, string>();
                j.StartDate  = DateTime.Now;
                j.Packages   = new List <ExecutablePackage>();
                FileInfo          epFile = new FileInfo(ofd.FileName);
                ExecutablePackage ep     = new ExecutablePackage();
                ep.ContentDirectory   = epFile.Directory.FullName;
                ep.JobRunnerDLLName   = epFile.Name;
                ep.JobRunnerClassName = "FILL ME IN";
                ep.Properties         = new SerializableDictionary <string, string>();
                ep.Properties.Add("ExamplePropertyKey", "ExamplePropertyValue");
                j.ISOs = new SerializableDictionary <string, string>();
                j.ISOs["ExampleISOName"] = @"c:\some\path\to.iso";
                j.Packages.Add(ep);
                FileInfo jobXMLFile = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "job.xml"));
                if (jobXMLFile.Exists)
                {
                    jobXMLFile.MoveTo(Path.Combine(jobXMLFile.Directory.FullName, Guid.NewGuid().ToString() + "job.xml"));
                }
                //save job as xml file
                using (TextWriter tw = new StreamWriter(jobXMLFile.FullName, false))
                {
                    tw.Write(j.ToXML(true));
                }
                Process.Start("notepad.exe", jobXMLFile.FullName);
            }
        }
        public void TestNullDirPathInJob()
        {
            sut.EmulateServiceStart(null);
            List <ExecutablePackage> packages = new List <ExecutablePackage>();
            ExecutablePackage        package  = new ExecutablePackage("mock.xml", null, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());

            packages.Add(package);
            Job j1 = new Job("nobuildpath", "MockVMConfig1", new SerializableDictionary <string, string>(), packages, new SerializableDictionary <string, string>());
            MessageSendRecieve msr = new MessageSendRecieve(new DirectoryInfo(inboxPath), new DirectoryInfo(outboxPath));
            DateTime           queuedJobsDateTime = DateTime.Now;
            string             job1msgID          = msr.QueueJob(j1);

            //wait for job completion
            JobCompleted jobCompleted = msr.WaitForJobCompletion(job1msgID, DEFAULT_WAIT);

            sut.EmulateServiceStop();

            Assert.That(jobCompleted, Is.Not.Null);
            Assert.That(jobCompleted.Job, Is.Not.Null);
            Assert.That(jobCompleted.Result, Is.Not.Null);
            Assert.That(jobCompleted.Result.Errors, Is.Not.Empty);
            VerifyStringInList(jobCompleted.Result.Errors, "Exception: Value cannot be null.\nParameter name: path");

            VerifyAppLogDoesNotContain(EventLogEntryType.Warning, testStart);
            VerifyAppLogDoesNotContain(EventLogEntryType.Error, testStart);
        }
Ejemplo n.º 3
0
        public void JobFailISOCopyFail()
        {
            string expectedException = "System.IO.FileNotFoundException: Could not find file";

            SerializableDictionary <string, string> isos = new SerializableDictionary <string, string>();

            isos["Main"] = "nonexistant.iso";
            ExecutablePackage        ep  = new ExecutablePackage("mock.xml", null, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
            List <ExecutablePackage> eps = new List <ExecutablePackage>();

            eps.Add(ep);

            List <FileInfo> filesToCopy = new List <FileInfo>();

            filesToCopy.Add(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestJobManager.dll")));
            JobStatus js = RunJob(filesToCopy, eps, null, isos);

            mock.VerifyEventOccured(MockEventType.UpdateStatus, expectedException, true);

            Assert.That(js.Result.Completed, Is.False);
            Assert.That(js.Result.Success, Is.False);
            Assert.That(js.Result.ExecutionResults.Count, Is.EqualTo(1));
            Assert.That(js.Result.Errors, Is.Not.Empty);

            VerifyStringInList(js.Result.Errors, expectedException);

            VerifyLogContainsString(js.Result.Logs, expectedException);
        }
Ejemplo n.º 4
0
        public void JobFailPackageThrowsException()
        {
            ExecutablePackage        ep  = new ExecutablePackage("mock.xml", null, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
            List <ExecutablePackage> eps = new List <ExecutablePackage>();

            eps.Add(ep);

            SerializableDictionary <string, string> properties = new SerializableDictionary <string, string>();

            properties["Mock_ReportSuccess"]  = "true";
            properties["Mock_StringToLog"]    = "Mock Logged String";
            properties["Mock_ThrowException"] = "Expected Exception";

            List <FileInfo> filesToCopy = new List <FileInfo>();

            filesToCopy.Add(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestJobManager.dll")));
            JobStatus js = RunJob(filesToCopy, eps, properties, null);

            mock.VerifyEventOccured(MockEventType.UpdateStatus, "Loading external test DLL: TestJobManager.dll , TestJobManager.MockJobRunner", false);
            mock.VerifyEventOccured(MockEventType.UpdateStatus, "Executing Execute() method on external DLL", false);
            mock.VerifyEventOccured(MockEventType.UpdateStatus, properties["Mock_ThrowException"], true);
            mock.VerifyEventOccured(MockEventType.UpdateStatus, properties["Mock_StringToLog"], false);

            Assert.That(js.Result.Completed, Is.False);
            Assert.That(js.Result.Success, Is.False);
            Assert.That(js.Result.ExecutionResults.Count, Is.EqualTo(1));
            Assert.That(js.Result.Errors, Is.Not.Empty);

            VerifyStringInList(js.Result.Errors, "System.Exception: " + properties["Mock_ThrowException"]);

            VerifyLogContainsString(js.Result.Logs, properties["Mock_StringToLog"]);
            VerifyLogContainsString(js.Result.Logs, properties["Mock_ThrowException"]);
        }
Ejemplo n.º 5
0
        public void TestRunMockJobSuccess2()
        {
            ExecutablePackage        ep  = new ExecutablePackage("mock.xml", null, "MockETP.dll", "MockETP.MockJobRunnerWithDependency", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
            List <ExecutablePackage> eps = new List <ExecutablePackage>();

            eps.Add(ep);

            SerializableDictionary <string, string> properties = new SerializableDictionary <string, string>();

            properties["Mock_ReportSuccess"] = "true";
            properties["Mock_StringToLog"]   = "Mock Logged String";

            List <FileInfo> filesToCopy = new List <FileInfo>();
            DirectoryInfo   mockETPDir  = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\MockETP\bin\Debug"));

            filesToCopy.AddRange(mockETPDir.GetFiles());
            //filesToCopy.Add(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\MockETP\bin\Debug\MockETP.dll")));
            JobStatus js = RunJob(filesToCopy, eps, properties, null);

            mock.VerifyEventOccured(MockEventType.UpdateStatus, "Loading external test DLL: MockETP.dll , MockETP.MockJobRunnerWithDependency", false);
            mock.VerifyEventOccured(MockEventType.UpdateStatus, "Executing Execute() method on external DLL", false);

            mock.VerifyEventOccured(MockEventType.UpdateStatus, properties["Mock_StringToLog"], false);

            Assert.That(js.Result.Success, Is.True);
            Assert.That(js.Result.SnapshotOnShutdown, Is.False);
            Assert.That(js.Result.Completed, Is.True);
            Assert.That(js.Result.Errors, Is.Empty);
            Assert.That(js.Result.CloneOnShutdown, Is.False);
            Assert.That(js.Result.Attachments, Is.Empty);
            Assert.That(js.Result.Logs, Is.Not.Empty);
            Assert.That(js.Result.ExecutionResults.Count, Is.EqualTo(1));

            VerifyLogContainsString(js.Result.Logs, properties["Mock_StringToLog"]);
        }
        public void TestNullISOs()
        {
            sut.EmulateServiceStart(null);
            DirectoryInfo tempDir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tempdll"));

            tempDir.Create();
            try
            {
                List <ExecutablePackage> packages = new List <ExecutablePackage>();
                ExecutablePackage        package  = new ExecutablePackage("mock.xml", tempDir.FullName, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
                packages.Add(package);

                Job j1 = new Job(null, "MockVMConfig1", null, packages, new SerializableDictionary <string, string>());
                MessageSendRecieve msr = new MessageSendRecieve(new DirectoryInfo(inboxPath), new DirectoryInfo(outboxPath));
                DateTime           queuedJobsDateTime = DateTime.Now;
                string             job1msgID          = msr.QueueJob(j1);

                //wait for job 1 to start
                Assert.True(WaitForVMAction(vmHash["MockVMName1"], VMActionType.Start, queuedJobsDateTime, TimeSpan.FromSeconds(5)));

                //send request for job 1
                AutomationMessage m = new AutomationMessage(new SimpleRequest(SimpleRequests.JobRequest));
                m.From = "MockVMName1";
                Job j = msr.WaitForJob(msr.Send(m), DEFAULT_WAIT);
                Assert.That(j, Is.Not.Null);
                Assert.That(j.JobID, Is.EqualTo(j1.JobID));

                //send finished for job 1
                DateTime  finishedSentDateTime = DateTime.Now;
                JobResult jr = new JobResult();
                jr.Completed = true;
                ExecutionResult er = new ExecutionResult();
                er.Success = true;
                jr.ExecutionResults.Add(er);
                msr.ReportJobStatus(new JobCompleted(j1, jr));

                //wait for job completion
                JobCompleted jobCompleted = msr.WaitForJobCompletion(job1msgID, DEFAULT_WAIT);

                sut.EmulateServiceStop();

                VerifyAppLogDoesNotContain(EventLogEntryType.Warning, testStart);
                VerifyAppLogDoesNotContain(EventLogEntryType.Error, testStart);

                Assert.That(jobCompleted, Is.Not.Null);
                Assert.That(jobCompleted.Job, Is.Not.Null);
                Assert.That(jobCompleted.Result, Is.Not.Null);
                Assert.That(jobCompleted.Result.Errors, Is.Empty);
                Assert.That(jobCompleted.Result.Success, Is.True);
                Assert.That(jobCompleted.Result.Completed, Is.True);
            }
            finally
            {
                tempDir.Delete(true);
            }
        }
        public void RunDependentJob()
        {
            sut.EmulateServiceStart(null);
            DirectoryInfo tempDir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tempdll"));

            tempDir.Create();
            try
            {
                List <ExecutablePackage> packages = new List <ExecutablePackage>();
                ExecutablePackage        package  = new ExecutablePackage("mock.xml", tempDir.FullName, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
                packages.Add(package);
                Job j1 = new Job("nobuildpath", "MockVMConfig1", new SerializableDictionary <string, string>(), packages, new SerializableDictionary <string, string>());
                Job j2 = new Job("nobuildpath", "MockVMConfig2", new SerializableDictionary <string, string>(), packages, new SerializableDictionary <string, string>());
                j2.DependsOnJobIds.Add(j1.JobID);
                MessageSendRecieve msr = new MessageSendRecieve(new DirectoryInfo(inboxPath), new DirectoryInfo(outboxPath));
                DateTime           queuedJobsDateTime = DateTime.Now;
                string             job2msgID          = msr.QueueJob(j2);
                string             job1msgID          = msr.QueueJob(j1);
                //wait for job 1 to start
                Assert.True(WaitForVMAction(vmHash["MockVMName1"], VMActionType.Start, queuedJobsDateTime, TimeSpan.FromSeconds(10)));
                //send request for job 1
                AutomationMessage m = new AutomationMessage(new SimpleRequest(SimpleRequests.JobRequest));
                m.From = "MockVMName1";
                Job j = msr.WaitForJob(msr.Send(m), DEFAULT_WAIT);
                Assert.That(j, Is.Not.Null);
                //send finished for job 1
                DateTime finishedSentDateTime = DateTime.Now;
                msr.ReportJobStatus(new JobCompleted(j1, new JobResult()));
                //wait for job 2 to start
                Assert.True(WaitForVMAction(vmHash["MockVMName2"], VMActionType.Start, finishedSentDateTime, TimeSpan.FromSeconds(10)));
                //send request for job 2
                m      = new AutomationMessage(new SimpleRequest(SimpleRequests.JobRequest));
                m.From = "MockVMName2";
                j      = msr.WaitForJob(msr.Send(m), DEFAULT_WAIT);
                Assert.That(j, Is.Not.Null);
                //send finished for job2
                msr.ReportJobStatus(new JobCompleted(j2, new JobResult()));

                Assert.That(msr.WaitForJobCompletion(job1msgID, DEFAULT_WAIT), Is.Not.Null);
                Assert.That(msr.WaitForJobCompletion(job2msgID, DEFAULT_WAIT), Is.Not.Null);

                sut.EmulateServiceStop();

                VerifyAppLogDoesNotContain(EventLogEntryType.Warning, testStart);
                VerifyAppLogDoesNotContain(EventLogEntryType.Error, testStart);

                VerifyMockVMActionInvoked(vmHash["MockVMName1"], VMActionType.RevertToNamedSnapshot, "Snapshot1");
                VerifyMockVMActionInvoked(vmHash["MockVMName2"], VMActionType.RevertToNamedSnapshot, "Snapshot2");
            }
            finally
            {
                tempDir.Delete(true);
            }
        }
Ejemplo n.º 8
0
        public void JobFailMissingDLL()
        {
            ExecutablePackage        ep  = new ExecutablePackage("mock.xml", null, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
            List <ExecutablePackage> eps = new List <ExecutablePackage>();

            eps.Add(ep);

            JobStatus js = RunJob(null, eps, null, null);

            mock.VerifyEventOccured(MockEventType.UpdateStatus, "System.IO.FileNotFoundException: Could not load file", true);

            Assert.That(js.Result.Completed, Is.False);
            Assert.That(js.Result.Success, Is.False);
            Assert.That(js.Result.ExecutionResults.Count, Is.EqualTo(1));
            Assert.That(js.Result.Errors, Is.Not.Empty);

            VerifyStringInList(js.Result.Errors, "System.IO.FileNotFoundException: Could not load file");
        }
Ejemplo n.º 9
0
        public void JobFailWrongClassName()
        {
            ExecutablePackage        ep  = new ExecutablePackage("mock.xml", null, "TestJobManager.dll", "TestJobManager.InvalidName", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
            List <ExecutablePackage> eps = new List <ExecutablePackage>();

            eps.Add(ep);

            List <FileInfo> filesToCopy = new List <FileInfo>();

            filesToCopy.Add(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestJobManager.dll")));
            JobStatus js = RunJob(filesToCopy, eps, null, null);

            mock.VerifyEventOccured(MockEventType.UpdateStatus, "System.Exception: method/class not found", true);

            Assert.That(js.Result.Completed, Is.False);
            Assert.That(js.Result.Success, Is.False);
            Assert.That(js.Result.ExecutionResults.Count, Is.EqualTo(1));
            Assert.That(js.Result.Errors, Is.Not.Empty);

            VerifyStringInList(js.Result.Errors, "System.Exception: method/class not found");
        }
Ejemplo n.º 10
0
        public void JobFailTestDLLDirectoryLocked()
        {
            DirectoryInfo testdllDir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestDLL"));

            testdllDir.Create();
            FileInfo   tempFile = new FileInfo(Path.Combine(testdllDir.FullName, "temp.txt"));
            FileStream fs       = new FileStream(tempFile.FullName, FileMode.Create, FileAccess.ReadWrite, FileShare.None);

            try
            {
                string expectedException = "System.IO.IOException: The process cannot access the file 'temp.txt' because it is being used by another process.";

                ExecutablePackage        ep  = new ExecutablePackage("mock.xml", null, "TestJobManager.dll", "TestJobManager.MockJobRunner", new SerializableDictionary <string, string>(), new SerializableDictionary <string, string>());
                List <ExecutablePackage> eps = new List <ExecutablePackage>();
                eps.Add(ep);

                List <FileInfo> filesToCopy = new List <FileInfo>();
                filesToCopy.Add(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestJobManager.dll")));
                JobStatus js = RunJob(filesToCopy, eps, null, null);

                mock.VerifyEventOccured(MockEventType.UpdateStatus, expectedException, true);

                Assert.That(js.Result.Completed, Is.False);
                Assert.That(js.Result.Success, Is.False);
                Assert.That(js.Result.ExecutionResults.Count, Is.EqualTo(1));
                Assert.That(js.Result.Errors, Is.Not.Empty);

                VerifyStringInList(js.Result.Errors, expectedException);

                VerifyLogContainsString(js.Result.Logs, expectedException);
            }
            finally
            {
                fs.Close();
                tempFile.Delete();
                testdllDir.Delete(true);
            }
        }
Ejemplo n.º 11
0
        private void buttonDetail_Click(object sender, EventArgs e)
        {
            if (listViewStatus.SelectedItems.Count > 0)
            {
                ListViewItem item = listViewStatus.SelectedItems[0];
                if (item.Tag != null && item.Tag is FullJob)
                {
                    FullJob fj = (FullJob)item.Tag;
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("Started: " + fj.Job.StartDate);
                    sb.AppendLine("Configuration: " + fj.Job.Configuration);
                    sb.AppendLine("VM: " + fj.Status.VMPath);
                    sb.AppendLine("Job ID: " + fj.Job.JobID);
                    sb.AppendLine("JobXML: " + fj.Job.JobXML);
                    sb.AppendLine("SequenceXML: " + fj.Job.SequenceXML);
                    sb.AppendLine("ConfigXML: " + fj.Job.ConfigurationXML);
                    sb.AppendLine("Packages (" + fj.Job.Packages.Count + "):");
                    for (int i = 0; i < fj.Job.Packages.Count; i++)
                    {
                        ExecutablePackage ep = fj.Job.Packages[i];
                        sb.AppendLine("PackageXML: " + ep.PackageXML);
                        sb.AppendLine("  DLL: " + ep.JobRunnerDLLName);
                        if (ep.Properties.Count > 0)
                        {
                            sb.AppendLine("  Package Properties:");
                            foreach(string key in ep.Properties.Keys)
                            {
                                sb.AppendLine("    " + key + ": " + ep.Properties[key]);
                            }
                        }
                        if (fj.Status.Result != null && fj.Status.Result.ExecutionResults.Count > i)
                        {
                            ExecutionResult er = fj.Status.Result.ExecutionResults[i];
                            sb.AppendLine("  Success: " + er.Success);
                            sb.AppendLine("  Attachments (" + er.Attachments.Count + "):");
                            foreach (FileData fd in er.Attachments)
                            {
                                sb.AppendLine("    Name: " + fd.Name);
                            }
                            sb.AppendLine("  Errors (" + er.Errors.Count + "):");
                            foreach (string error in er.Errors)
                            {
                                sb.AppendLine("    " + error);
                            }
                        }
                    }
                    sb.AppendLine("State: " + fj.Status.State);
                    sb.AppendLine("Last State Change: " + fj.Status.LastStateChange);
                    if (fj.Status.Result != null)
                    {
                        sb.AppendLine("Completed: " + fj.Status.Result.Completed);
                        sb.AppendLine("Success: " + fj.Status.Result.Success);
                        sb.AppendLine("SnapshotOnShutdown: " + fj.Status.Result.SnapshotOnShutdown);
                        if (fj.Status.Result.SnapshotOnShutdown)
                        {
                            sb.AppendLine("SnapshotName: " + fj.Status.Result.SnapshotName);
                            sb.AppendLine("SnapshotDesc: " + fj.Status.Result.SnapshotDesc);
                        }
                        sb.AppendLine("Log Files (" + fj.Status.Result.Logs.Count + "):");
                        foreach (FileData fd in fj.Status.Result.Logs)
                        {
                            sb.AppendLine("  Name: " + fd.Name);
                        }
                    }
                    if (fj.Job.Properties != null && fj.Job.Properties.Count > 0)
                    {
                        sb.AppendLine("Properties:");
                        foreach (string key in fj.Job.Properties.Keys)
                        {
                            sb.AppendLine(key + ": " + fj.Job.Properties[key]);
                        }
                    }

                    //sb.AppendLine(Utility.DumpObject(fj.Job, 0, typeof(ExecutablePackage), typeof(IEnumerable<ExecutablePackage>)));
                    MessageBox.Show(sb.ToString());
                    //MessageBox.Show(Utility.DumpObject(js, 0, typeof(JobResult), typeof(List<FileData>), typeof(List<ExecutionResult>), typeof(ExecutionResult)));
                }
            }
        }
Ejemplo n.º 12
0
        public void Run()
        {
            try
            {
                FileInfo mapNetBatchFile = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "map.bat"));
                //if the network drive is disconected, then we will be unable to get to the server inbox, in which case we should try to remap
                if (!AppConfig.ServerInbox.Exists && mapNetBatchFile.Exists)
                {
                    using (System.Diagnostics.Process p = new System.Diagnostics.Process())
                    {
                        p.StartInfo.WorkingDirectory = mapNetBatchFile.Directory.FullName;
                        p.StartInfo.FileName         = mapNetBatchFile.Name;
                        p.StartInfo.CreateNoWindow   = true;
                        p.StartInfo.UseShellExecute  = true;
                        p.Start();
                        p.WaitForExit();
                    }
                }
                int       packageToRun = 0;
                JobResult result       = new JobResult();
                result.Completed = true;

                //string sendQueueName = @"FormatName:DIRECT=OS:hammerbuildvm\Private$\jobmanager";
                //string sendQueueName = @"FormatName:DIRECT=OS:ryanadams2\Private$\test2";
                //jci.LogString("Connecting to Job Manager receive queue (" + sendQueueName + ")");
                MessageSendRecieve msr = new MessageSendRecieve(AppConfig.ServerInbox, AppConfig.ServerOutbox);
                //jci.LogString("Permission = " + msr.RemoteMessageQueue.AccessMode.ToString());

                //look for an existing job to run/continue before getting a new job from the server
                FileInfo jobXML = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "job.xml"));
                if (jobXML.Exists)
                {
                    using (TextReader tr = new StreamReader(jobXML.FullName))
                    {
                        j = XMLSerializable.FromXML <Job>(tr.ReadToEnd());
                        if (j.Properties.ContainsKey("PackageToRun"))
                        {
                            packageToRun = Int32.Parse(j.Properties["PackageToRun"]);
                        }
                    }
                    try
                    {
                        //rename the job file so the next run doesn't automatically use it.  The job.xml file will be put back
                        //as part of jci.StartupOnNextRun if it is meant to be continued after a restart
                        string lastFile = jobXML.FullName + ".old";
                        if (File.Exists(lastFile))
                        {
                            File.Delete(lastFile);
                        }
                        File.Move(jobXML.FullName, lastFile);
                    }
                    catch (Exception ex)
                    {
                        //if the delete fails lets log it, but it isn't critical so let's eat the exception
                        LogString("Could not delete existing job.xml file: " + ex.ToString());
                    }
                    //look for an existing JobResult to pull in
                    FileInfo jobResultXML = new FileInfo(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml"));
                    if (jobResultXML.Exists)
                    {
                        try
                        {
                            using (TextReader tr = new StreamReader(jobResultXML.FullName))
                            {
                                result = XMLSerializable.FromXML <JobResult>(tr.ReadToEnd());
                            }
                        }
                        catch (Exception ex)
                        {
                            //log, but eat it
                            LogString(ex.ToString());
                        }
                    }
                }
                else
                {
                    LogString("Requesting Jobs from Job Manager");
                    string messageID = msr.RequestJob();
                    LogString("Sent request with message id: " + messageID);

                    LogString("Waiting for Job response from Job Manager");
                    j = msr.WaitForJob(messageID, DEFAULT_JOB_WAIT);
                    if (j == null)
                    {
                        LogString("No Jobs Available");
                        return;
                    }
                    try
                    {
                        LogString("Found Job: " + j.JobID);

                        if (baseDir.Exists)
                        {
                            baseDir.Delete(true);
                            //TODO wait for files to be deleted?
                        }
                        baseDir.Create();

                        List <string> keys = new List <string>(j.ISOs.Keys);
                        foreach (string isoName in keys)
                        {
                            FileInfo isoPath  = new FileInfo(j.ISOs[isoName]);
                            string   destPath = Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, isoPath.Name);
                            LogString("Copying ISO from \"" + isoPath.Directory.FullName + "\" to \"" + destPath + "\"");
                            isoPath.CopyTo(destPath);
                            j.ISOs[isoName] = destPath;
                        }

                        if (j.Properties == null)
                        {
                            j.Properties = new SerializableDictionary <string, string>();
                        }
                    }
                    catch (Exception ex)
                    {
                        LogString(ex.ToString());
                        result.Completed = false;
                        ExecutionResult er = new ExecutionResult(ex.ToString(), null);
                        result.ExecutionResults.Add(er);
                        Logger.Instance.Pause();
                        result.Logs.Add(FileData.FromFile(new FileInfo(Logger.Instance.FileName)));
                        Logger.Instance.Resume();
                        LogString("Sending Job Result");
                        msr.ReportJobStatus(new JobCompleted(j, result));
                        LogString("Job Result Sent");
                        return;
                    }
                }
                if (j.Packages.Count == 0)
                {
                    Logger.Instance.Pause();
                    result.Logs.Add(FileData.FromFile(new FileInfo(Logger.Instance.FileName)));
                    Logger.Instance.Resume();
                }
                while (packageToRun < j.Packages.Count)
                {
                    runningPackageDir = new DirectoryInfo(Path.Combine(baseDir.FullName, packageToRun.ToString()));

                    ExecutablePackage ep = j.Packages[packageToRun];
                    runningPackage = ep;
                    ExecutionResult er = new ExecutionResult();
                    try
                    {
                        if (!ep.ContentDirectory.ToLower().Equals(runningPackageDir.FullName.ToLower()))
                        {
                            if (runningPackageDir.Exists)
                            {
                                runningPackageDir.Delete(true);
                            }
                            runningPackageDir.Create();

                            LogString("Copying data from \"" + ep.ContentDirectory + "\" to \"" + runningPackageDir.FullName + "\"");
                            DirectoryData.FromDirectory(new DirectoryInfo(ep.ContentDirectory)).DumpContentsToDir(runningPackageDir);
                            ep.ContentDirectory = runningPackageDir.FullName;
                        }
                        LogString("Loading external test DLL: " + ep.JobRunnerDLLName + " , " + ep.JobRunnerClassName);
                        JobRunner jr = LoadJobRunner(ep.JobRunnerClassName, Path.Combine(runningPackageDir.FullName, ep.JobRunnerDLLName));

                        LogString("Executing Execute() method on external DLL");

                        er = jr.Execute(this);
                    }
                    catch (Exception ex)
                    {
                        LogString(ex.ToString());
                        result.Completed = false;
                        er = new ExecutionResult(ex.ToString(), null);
                    }

                    Logger.Instance.Pause();
                    result.Logs.Add(FileData.FromFile(new FileInfo(Logger.Instance.FileName)));
                    Logger.Instance.Resume();

                    if (er != null)
                    {
                        result.ExecutionResults.Add(er);
                    }

                    //lets save the current job result
                    using (TextWriter tw = new StreamWriter(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml"), false))
                    {
                        tw.Write(result.ToXML());
                    }

                    if (er == null)
                    {
                        //The automation is likely not finished, the computer is likely going to reboot and
                        //we want this execution to continue after reboot so we should exit now instead of going to the next package.
                        //the executable package should have already called startuponnextrun
                        return;
                    }


                    if (!er.Success)
                    {
                        //stop on first error
                        break;
                    }

                    packageToRun++;
                    j.Properties["PackageToRun"] = packageToRun.ToString();
                    if (er.Success && er.RestartAfter)
                    {
                        StartupOnNextRun();
                        LogString("Restarting ...");
                        system.Shutdown(true);
                        return;
                    }
                }
                LogString("Sending Job Result");
                msr.ReportJobStatus(new JobCompleted(j, result));
                LogString("Job Result Sent");
                //cleanup
                if (File.Exists(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml")))
                {
                    File.Delete(Path.Combine(Utilities.ExecutingAssembly.Directory.FullName, "jobresult.xml"));
                }
                if (ShutdownOnCompletion)
                {
                    LogString("Shuting Down ...");
                    system.Shutdown(false);

                    //so, lets exit the program
                    System.Windows.Forms.Application.Exit();
                }
            }
            catch (ThreadAbortException)
            {
                //eat it, get out right away.  Program is exiting or user has stopped automation
                return;
            }
            catch (Exception e)
            {
                LogString("Exception in thread: " + e.ToString());
                return;
            }
        }