protected void DeleteVCloudEnvironmentAsync(TestEnvironment environment)
        {
            environment.SetEnvironmentStatus(EnvironmentStatus.Disposing);
            System.Threading.Tasks.Task.Factory.StartNew
            (
               () =>
               {
                   try
                   {
                       ATFEnvironment.Log.logger.Debug(string.Format("Disposing Envrionment Id = {0}, Name= {1}", environment.EnvironmentId, environment.Name));

                       Vapp vApp = VCloud.GetVappByName(Organization, VDC, environment.Name);

                       if (vApp != null)
                       {
                           var status = VCloud.GetVAppStatus(vApp);

                           if (!(status == vAppStatus.Undeploy || status == vAppStatus.Error))
                           {
                               ATFEnvironment.Log.logger.Debug("start undeploy vApp: " + environment.Name);
                               VCloud.UndeployVapp(vApp);
                               ATFEnvironment.Log.logger.Debug("finish undeploy vApp: " + environment.Name);
                           }

                           ATFEnvironment.Log.logger.Debug("start delete vApp: " + environment.Name);
                           VCloud.DeleteVapp(vApp);
                           ATFEnvironment.Log.logger.Debug("finish delete vApp: " + environment.Name);
                       }
                   }
                   catch (Exception ex)
                   {
                       ATFEnvironment.Log.logger.Error(string.Format("Failed to dispose envrionment: {0}. Exception: {1}", environment.Name, ex.Message), ex);
                       environment.SetEnvironmentStatus(EnvironmentStatus.Discard);//here we set the environment to be discard. Because this is a async operation, it's not reasonable to throw an exception.
                   }
               }
               );
        }
        protected void DeployVCloudEnvironmentAsync(TestEnvironment environment, int timeout)
        {
            System.Threading.Tasks.Task.Factory.StartNew
            (
                () =>
                {
                    try
                    {
                        var vApp = VCloud.GetVappByName(Organization, VDC, environment.Name);

                        ATFEnvironment.Log.logger.Debug("start deploy vApp: " + environment.Name);
                        VCloud.DeployVapp(vApp, true, timeout, false);
                        ATFEnvironment.Log.logger.Debug("finish deploy vApp: " + environment.Name);
                    }
                    catch (Exception ex)
                    {
                        string errorMsg = string.Format("Failed to Deploy vApp by template: {0}", environment.Description);
                        ATFEnvironment.Log.logger.Error(errorMsg, ex);
                        environment.SetEnvironmentStatus(EnvironmentStatus.Error);//here we set the environment to be error. Because this is a async operation, it's not reasonable to throw an exception.
                    }
                }
            );
        }
        public virtual void UpdateEnvironmentConfig(TestEnvironment environment)
        {
            IList<VM> vms = null;
            try
            {
                vms = VCloud.GetVMsByVapp(Organization, VDC, environment.Name);
            }
            catch (Exception ex)
            {
                ATFEnvironment.Log.logger.Error(string.Format("Failed to get the VMs of the vAPP {0}", environment.Name), ex);
            }

            if (vms == null)
            {
                ATFEnvironment.Log.logger.Error(string.Format("No vm is found in environment {0}", environment.Name));
                return;
            }

            string xmlConfig = environment.Config;
            EnvironmentType type = EnvironmentConfigHelper.GetResidenceType(xmlConfig);
            foreach (var vm in vms)
            {
                string ip = string.Empty;
                try
                {
                    ip = vm.GetIpAddressesById().Count > 0 ? vm.GetIpAddressesById().First().Value : string.Empty;
                }
                catch(Exception ex)
                {
                    ATFEnvironment.Log.logger.Error("Could not get the IP address of the VM.", ex);
                    environment.SetEnvironmentStatus(EnvironmentStatus.Error);
                    return;
                }
                if (ip != string.Empty)
                {
                    string externalIP = string.Empty;
                    xmlConfig = EnvironmentConfigHelper.SetMachineIP(xmlConfig, type, vm.Resource.name, ip);
                    try
                    {
                        externalIP = vm.GetNetworkConnections().Count > 0 ? vm.GetNetworkConnections()[0].ExternalIpAddress : string.Empty;
                    }
                    catch (Exception ex)
                    {
                        ATFEnvironment.Log.logger.Error(string.Format("Failed to get the external IP of the VM {0}.", vm.Resource.name), ex);
                        environment.SetEnvironmentStatus(EnvironmentStatus.Error);
                        return;
                    }
                    xmlConfig = EnvironmentConfigHelper.SetMachineExternalIP(xmlConfig, type, vm.Resource.name, externalIP);
                }
                else
                {
                    string message = string.Format("Could not get the IP address for the machine {0}", vm.Resource.name);
                    ATFEnvironment.Log.logger.Error(message);
                    environment.SetEnvironmentStatus(EnvironmentStatus.Error);
                    return;
                }
            }

            environment.SetEnvironmentConfig(xmlConfig);
        }
        protected void CreateVCloudEnvironmentAsync(TestEnvironment environment, int timeout)
        {
            environment.SetEnvironmentStatus(EnvironmentStatus.Setup);
            System.Threading.Tasks.Task.Factory.StartNew
            (
                () =>
                {
                    try
                    {
                        ATFEnvironment.Log.logger.Debug(string.Format("Creating Envrionment Id = {0}, Name= {1}", environment.EnvironmentId, environment.Name));

                        ATFEnvironment.Log.logger.Info("Try to find vApp Template: " + environment.Description);
                        VappTemplate vAppTemplate = null;
                        vAppTemplate = VCloud.GetVappTemplateByName(Organization, VDC, environment.Description);

                        if (vAppTemplate == null)
                        {
                            string errorMsg = string.Format("vApp template: {0} not find", environment.Description);
                            environment.SetEnvironmentStatus(EnvironmentStatus.Error);
                            ATFEnvironment.Log.logger.Error(errorMsg);
                            throw new EnvironmentException(ModuleName, errorMsg);
                        }

                        ATFEnvironment.Log.logger.Debug("start create vApp: " + environment.Name);
                        var vApp = VCloud.CreateVappFromTemplate(Organization, VDC, environment.Description, environment.Name, timeout);
                        ATFEnvironment.Log.logger.Debug("finish create vApp: " + environment.Name);

                        ATFEnvironment.Log.logger.Debug("start deploy vApp: " + environment.Name);
                        VCloud.DeployVapp(vApp, true, timeout, false);
                        ATFEnvironment.Log.logger.Debug("start deploy vApp: " + environment.Name);
                    }
                    catch (Exception ex)
                    {
                        string errorMsg = string.Format("Failed to create vApp by template: {0}", environment.Description);
                        ATFEnvironment.Log.logger.Error(errorMsg, ex);
                        environment.SetEnvironmentStatus(EnvironmentStatus.Error);//here we set the environment to be error. Because this is a async operation, it's not reasonable to throw an exception.
                    }
                }
            );
        }
        /// <summary>
        /// Refresh environment status
        /// </summary>
        /// <param name="environment"></param>
        public virtual void RefreshEnvironmentStatus(TestEnvironment environment)
        {
            TestEnvironmentConfigHelper config = new TestEnvironmentConfigHelper(environment.Config);
            EnvironmentType type = config.Type;
            EnvironmentDeploymentType deployType = EnvironmentDeploymentType.Undefined;
            vAppStatus status = vAppStatus.Unknow;

            switch (type)
            {
                case EnvironmentType.Residence_Together:
                    deployType = config.SUTConfiguration.DeploymentType;
                    break;
                case EnvironmentType.SUTAlone:
                    deployType = config.SUTConfiguration.DeploymentType;
                    break;
                case EnvironmentType.TestAgentAlone:
                    deployType = config.TestAgentConfiguration.DeploymentType;
                    break;
            }

            switch (environment.EnvironmentStatus)
            {
                case EnvironmentStatus.New:
                    if (deployType == EnvironmentDeploymentType.ToBeCreated)
                    {
                        try
                        {
                            if (IsAllowNewVappDeploy())
                            {
                                RequestEnvironment(environment);
                            }
                        }
                        catch (Exception ex)
                        {
                            ATFEnvironment.Log.logger.Error(ex);
                        }
                    }
                    else
                    {
                        environment.SetEnvironmentStatus(EnvironmentStatus.AgentServiceInstalledAndReady);
                    }
                    break;

                case EnvironmentStatus.Setup:
                    status = vAppStatus.Unknow;
                    try
                    {
                        status = VCloud.GetVAppStatus(Organization, VDC, environment.Name);
                    }
                    catch (Exception ex)
                    {
                        ATFEnvironment.Log.logger.Error("Failed to get the status of vAPP.", ex);
                    }
                    switch (status)
                    {
                        case vAppStatus.Error:
                            environment.SetEnvironmentStatus(EnvironmentStatus.Error);
                            break;

                        case vAppStatus.Ready:
                            UpdateEnvironmentConfig(environment);
                            environment.SetEnvironmentStatus(EnvironmentStatus.MachinesReady);
                            break;

                        case vAppStatus.NotExist://Neil, sometimes the vAPP is not created yet, and request another environment with the same name will cause exception.
                            //if (IsAllowNewVappDeploy())
                            //{
                            //    RequestEnvironment(environment);
                            //}
                            break;

                        // redeploy
                        case vAppStatus.Unknow:
                        case vAppStatus.Undeploy://Neil, The deployment will be done when request the environment, here we did nothing.

                            //if (IsAllowNewVappDeploy())
                            //{
                            //    DeployVCloudEnvironmentAsync(environment, 1000 * 60 * 30);
                            //}
                            break;
                    }

                    break;

                case EnvironmentStatus.MachinesReady:

                    break;

                case EnvironmentStatus.AgentServiceInstalledAndReady:

                    break;

                case EnvironmentStatus.BuildInstalled:

                    break;

                case EnvironmentStatus.Ready:

                    break;

                case EnvironmentStatus.Error:

                    break;

                case EnvironmentStatus.Discard:
                    DisposeEnvironment(environment);
                    break;

                case EnvironmentStatus.Disposing:
                    status = vAppStatus.Unknow;
                    try
                    {
                        status = VCloud.GetVAppStatus(Organization, VDC, environment.Name);
                    }
                    catch (Exception ex)
                    {
                        ATFEnvironment.Log.logger.Error("Failed to get the status of vAPP.", ex);
                    }
                    switch (status)
                    {
                        case vAppStatus.NotExist:
                            environment.SetEnvironmentStatus(EnvironmentStatus.Disposed);
                            break;

                        case vAppStatus.Ready:
                            DisposeEnvironment(environment);
                            break;

                        case vAppStatus.Undeploy:
                            DisposeEnvironment(environment);
                            break;

                        case vAppStatus.Error:
                            DisposeEnvironment(environment);
                            break;
                    }

                    break;
            }
        }
Beispiel #6
0
        /// <summary>
        /// Install the test agent windows service on the test agent
        /// </summary>
        private static void InstallTestAgentWindowsServiceOnEnvironmentAsynchronous(TestEnvironment testEnvironment)
        {
            System.Threading.Tasks.Task.Factory.StartNew
            (
                () =>
                {
                    AutomationJob job = GetAutomationJobOfTestEnvironment(testEnvironment);
                    try
                    {
                        job.AddJobProgressInformation(string.Format("Start to install the Saber Agent Service on environment [{0}] for Job [{1}]", testEnvironment.Name, job.Name));

                        //RemoteInstallTestAgentWindowsServiceConcurrentlyAndWaitToFinish(testEnvironment);
                        if (RemoteInstallTestAgentWindowsFormAppConcurrentlyAndWaitToFinsh(testEnvironment))
                        {
                            job.AddJobProgressInformation(string.Format("The Saber Agent service has been installed on environment [{0}] for Job [{1}]", testEnvironment.Name, job.Name));
                            testEnvironment.SetEnvironmentStatus(EnvironmentStatus.AgentServiceInstalledAndReady);
                        }
                        else
                        {
                            job.AddJobProgressInformation(string.Format("The Saber Agent service failed to be installed on environment [{0}] for Job [{1}]", testEnvironment.Name, job.Name));
                            job.SetJobsStatus(JobStatus.Failed);
                        }
                    }
                    catch (Exception ex)
                    {
                        //TODO, exception handling, we may need to revert the record in DB -> reinstall the windows services.
                        ATFEnvironment.Log.logger.Error(string.Format("Error happened when install the Saber Agent service on machine [{0}]", testEnvironment.Name), ex);
                        job.SetJobsStatus(JobStatus.Failed);
                    }
                }
            );
        }
Beispiel #7
0
        /// <summary>
        /// Request the test agent environment for the job
        /// </summary>
        /// <param name="job">job</param>
        /// <param name="provider">environment provider</param>
        public void RequestTestAgentEnvironmentForJob(AutomationJob job, IEnvironmentProvider provider)
        {
            SupportedEnvironment supportEnvironment = job.GetSupportedEnv();
            AutomationTask task = JobManagement.GetAutomationTaskOfJob(job);
            string templateName = new TestEnvironmentConfigHelper(supportEnvironment.Config).TestAgentConfiguration.Name;
            string environmentName = string.Format("{0}_{1}_{2}_{3}", task.Name, job.JobId, "TestAgent", Guid.NewGuid());

            TestEnvironmentConfigHelper sutConfig = new TestEnvironmentConfigHelper(supportEnvironment.Config);

            // Get the avaliable permenent agent, typically we maintain a pool of machines act as the test agent, no need to deploy new vApps
            // If no available agents in the pool now, we'll create a new vApp from the template with name of templateName
            TestEnvironment availableReadyStaticAgent = TestEnvironment.GetAvalibleStaticTestAgent4SupportedEnvironment(supportEnvironment);
            EnvironmentDeploymentType deployType = new TestEnvironmentConfigHelper(supportEnvironment.Config).TestAgentConfiguration.DeploymentType;
            if (deployType == EnvironmentDeploymentType.Existing )
            {
                if (availableReadyStaticAgent != null)
                {
                    string info = string.Format("Find one avaliable permanent test agent [{0}:{1}] for job [{2}]", availableReadyStaticAgent.EnvironmentId, availableReadyStaticAgent.Name, job.Name);
                    availableReadyStaticAgent.SetEnvironmentStatus(EnvironmentStatus.MachinesReady);
                    ATFEnvironment.Log.logger.Info(info);
                    job.AddJobProgressInformation(info);
                    // set SUT information to test agent's config
                    // set test agent type to TestAgentAlone
                    /*
                    TestEnvironmentConfigHelper testAgentConfig = new TestEnvironmentConfigHelper(availableReadyStaticAgent.Config);
                    testAgentConfig.SUTConfiguration = sutConfig.SUTConfiguration;
                    testAgentConfig.Type = EnvironmentType.TestAgentAlone;
                    availableReadyStaticAgent.Config = testAgentConfig.ToXML();

                    info = string.Format("Change the permanent agent's status, AgentServiceInstalledAndReady -> Ocuppied");
                    ATFEnvironment.Log.logger.Info(info);
                    job.AddJobProgressInformation(info);
                    // Set this permanent agent to occuppied
                    //availableReadyStaticAgent.Status = (int)EnvironmentStatus.Ocuppied;
                    //availableReadyStaticAgent.Update();

                    TestEnvironmentConfigHelper config = new TestEnvironmentConfigHelper(availableReadyStaticAgent.Config);
                    //clear the finished job information
                    config.TestAgentConfiguration.Categories.Clear();
                    //add the jobId into the configuration file to let the Test Agent know which job the test agent is for.
                    config.TestAgentConfiguration.Categories.Add("JobId=" + job.JobId.ToString());
                    availableReadyStaticAgent.Config = config.ToXML();
                    availableReadyStaticAgent.Update();

                    //copy the config file to the test agent
                    List<Machine> testAgents = GetMachinesNeedTestAgentInstalledOn(config);
                    string ip = testAgents.Count() > 0 ? testAgents[0].ExternalIP : string.Empty;
                    string domain = config.TestAgentConfiguration.TestAgentDomainConfig.Name;
                    string administrator = config.TestAgentConfiguration.TestAgentDomainConfig.Adminstrator;
                    string password = config.TestAgentConfiguration.TestAgentDomainConfig.Password;

                    string targetPath = @"\\" + ip + @"\C$\SaberAgent";
                    string targetEnvironmentConfigFolder = targetPath + @"\Config";
                    string targetEnvironmentConfigFile = targetEnvironmentConfigFolder + @"\Environment.xml";

                    if (!NetUseHelper.NetUserMachine(ip, domain + @"\" + administrator, password))
                    {
                        ATFEnvironment.Log.logger.Error(string.Format("Net use the machine [{0}] failed.", ip));
                    }

                    Common.ScriptCommon.CMDScript.FlushDNSRemotely(ip, domain + @"\" + administrator, password);

                    if (!FileHelper.IsExistsFolder(targetEnvironmentConfigFolder))
                    {
                        FileHelper.CreateFolder(targetEnvironmentConfigFolder);
                    }

                    TXTHelper.ClearTXTContent(targetEnvironmentConfigFile);
                    TXTHelper.WriteNewLine(targetEnvironmentConfigFile, config.ToXML(), System.Text.Encoding.Default);
                    info = string.Format("Copy the file[{0}] to permanent agent", targetEnvironmentConfigFile);
                    ATFEnvironment.Log.logger.Info(info);
                    job.AddJobProgressInformation(info);
                    */
                     job.SetTestAgentEnvironment(availableReadyStaticAgent.EnvironmentId);
                }
                else
                {
                    string info = string.Format("There's no available test agents right now, please wait other tasks to free some environments.");
                    ATFEnvironment.Log.logger.Info(info);
                    job.AddJobProgressInformation(info);
                }
            }
            else
            {
                //create a new record in DB for Test Agent, and Galaxy will handle the environment later(install, config and so on)
                sutConfig.TestAgentConfiguration.DeploymentType = EnvironmentDeploymentType.ToBeCreated;
                sutConfig.Type = EnvironmentType.TestAgentAlone;
                string config = sutConfig.ToXML();
                try
                {
                    var testEnvironment = new TestEnvironment
                    {
                        ProviderId = provider.Provider.ProviderId,
                        Name = environmentName,
                        Type = provider.Provider.Name,
                        Status = (int)EnvironmentStatus.New,
                        CreateDate = DateTime.UtcNow,
                        ModifyDate = DateTime.UtcNow,
                        //Config = EnvironmentConfigHelper.SetResidenceType(supportEnvironment.Config, EnvironmentType.TestAgentAlone),
                        Config = config,
                        Description = templateName,
                    };

                    if (job.JobStatus == JobStatus.Cancelled || job.JobStatus == JobStatus.End)
                    {
                        testEnvironment.SetEnvironmentStatus(EnvironmentStatus.Discard);
                    }

                    TestEnvironment.Add(testEnvironment);

                    job.SetTestAgentEnvironment(testEnvironment.EnvironmentId);
                }
                catch (Exception ex)
                {
                    job.SetJobsStatus(JobStatus.Failed);
                    string info = string.Format("Failed to request Test Agent environment {0}, Exception: {1}", environmentName, ex.Message);
                    job.AddJobProgressInformation(info);
                    ATFEnvironment.Log.logger.Error(info, ex);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Request the sut environment for job
        /// </summary>
        /// <param name="job">job</param>
        /// <param name="provider">environment provider</param>
        public void RequestSUTEnvironmentForJob(AutomationJob job, IEnvironmentProvider provider)
        {
            SupportedEnvironment supportEnvironment = job.GetSupportedEnv();
            TestEnvironmentConfigHelper config = new TestEnvironmentConfigHelper(supportEnvironment.Config);
            string templateName = config.SUTConfiguration.Name;

            string sutConfig = string.Empty;
            if (config.Type == EnvironmentType.Residence_Seperate)
            {
                sutConfig = EnvironmentConfigHelper.SetResidenceType(supportEnvironment.Config, EnvironmentType.SUTAlone);
            }
            else if (config.Type == EnvironmentType.Residence_Together)
            {
                sutConfig = EnvironmentConfigHelper.SetResidenceType(supportEnvironment.Config, EnvironmentType.Residence_Together);
            }
            AutomationTask task = JobManagement.GetAutomationTaskOfJob(job);

            if (config.SUTConfiguration.DeploymentType == EnvironmentDeploymentType.Existing)
            {
                //Note: the existing SUT environments are distinguished by it's name, two environments with same name are considered as the same one
                var sutEnvironment = TestEnvironment.GetAvalibleStaticSUT4SupportedEnvironment(supportEnvironment);
                if (sutEnvironment == null)//wait untill another environment is freed
                {
                    string info = string.Format("There's no SUT environment in the pool available now, please wait for other tasks to free any environment.");
                    ATFEnvironment.Log.logger.Info(info);
                    job.AddJobProgressInformation(info);
                }
                else//reuse the record
                {
                    string message = string.Format("Get an available SUT environment [{0}] for the job [{1}:{2}]", sutEnvironment.Name, job.JobId, job.Name);
                    job.AddJobProgressInformation(message);
                    message = string.Format("Change environment [{0}:{1}] status from {2} to {3}", sutEnvironment.EnvironmentId, sutEnvironment.Name, sutEnvironment.Status, "MachinesReady");
                    job.AddJobProgressInformation(message);
                    sutEnvironment.SetEnvironmentStatus(EnvironmentStatus.MachinesReady);
                    job.SetSUTEnvironment(sutEnvironment.EnvironmentId);
                }
            }
            else
            {
                string environmentName = string.Format("{0}_{1}_{2}_{3}", task.Name, job.JobId, "SUT", Guid.NewGuid());
                try
                {
                    var testEnvironment = new TestEnvironment
                    {
                        ProviderId = provider.Provider.ProviderId,
                        Name = environmentName,
                        Type = provider.Provider.Name,
                        CreateDate = DateTime.UtcNow,
                        ModifyDate = DateTime.UtcNow,
                        Config = sutConfig,
                        Description = templateName,
                    };
                    if (job.JobStatus == JobStatus.Cancelled || job.JobStatus == JobStatus.End)
                        testEnvironment.SetEnvironmentStatus(EnvironmentStatus.Discard);
                    TestEnvironment.Add(testEnvironment);
                    string message = string.Format("Environment [{0}:{1} is created for job [{2}:{3}]]", testEnvironment.EnvironmentId, testEnvironment.Name, job.JobId, job.Name);
                    job.AddJobProgressInformation(message);
                    job.SetSUTEnvironment(testEnvironment.EnvironmentId);
                }
                catch (Exception ex)
                {
                    string info = string.Format("Failed to assign {0}, Exception: {1}", environmentName, ex.Message);
                    job.SetJobsStatus(JobStatus.Failed);
                    job.AddJobProgressInformation(info);
                    ATFEnvironment.Log.logger.Error(info, ex);
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Handle the test environment with machines ready, work include:
        /// 1. Install the Saber Agent services on the machines and start the services on remote machine
        /// 2. Update the environment information for the TestAgent and SUT, then the TestAgent and SUT know the details of each other(mainly IPs here)
        /// 3. Specify what kinds of works the Saber Agent services will take after it restarted. such as 
        ///   1). to tell services hosted on test agent to install the S1 build
        ///   2). to tell the services hosted on test agent to run the test case for which job
        /// 4. After that, the test environment status is AgentServiceInstalling or AgentServiceInstalledAndReady
        /// Below actions are taken by other components
        /// 5. The saber agent service on the test agent will install the S1 build, before that it'll wait the SUT to be AgentServiceInstalledAndReady
        /// 6. The saber agent service will set the environment status to be BuildInstalled
        /// 7. Then the environment manager will restart all the machines in SUT
        /// 8. After restarted, the saber agent in test agent will check all the machines in SUT are started and start to run the test cases.
        /// </summary>
        /// <param name="environment"></param>
        public void HandleTestEnvironmentWithStatusMachinesReady(TestEnvironment environment)
        {
            EnvironmentType type = EnvironmentConfigHelper.GetResidenceType(environment.Config);
            if (type == EnvironmentType.Residence_Together)
            {
                //add the jobId into the configuration file to let the Test Agent know which job the test agent is for.
                TestEnvironmentConfigHelper config = new TestEnvironmentConfigHelper(environment.Config);
                config.TestAgentConfiguration.Categories.Add(string.Format("JobId={0}", EnvironmentManager.GetAutomationJobOfTestEnvironment(environment).JobId.ToString()));
                //config.TestAgentConfiguration.Categories.Add(string.Format("mode={0}", SaberAgentMode.InstallS1Build));
                environment.SetEnvironmentConfig(config.ToXML());
                environment.SetEnvironmentStatus(EnvironmentStatus.AgentServiceInstalling);
                try
                {
                    InstallTestAgentWindowsServiceOnEnvironmentAsynchronous(environment);
                }
                catch (Exception ex)
                {
                    ATFEnvironment.Log.logger.Error(string.Format("Execption captured when install test agent windows service on environment asynchronously for environment {0}",environment.EnvironmentId), ex);
                }

                ATFEnvironment.Log.logger.Info(string.Format("Test Agents started to be installed on environment {0}", environment.Name));
                ATFEnvironment.Log.logger.Info(string.Format("Environment status changes from MachinesReady -> AgentServiceInstalling"));
            }
            else if (type == EnvironmentType.TestAgentAlone)
            {
                //to make sure in the test agent, we have the information about the SUT,
                //we'll first check whether the SUT is MachinesReady,
                //if yes, we'll copy the SUT config to the TestAgent config, then setup the Saber Agent
                //else, do nothing and wait another loop
                TestEnvironment sutEnvironment = EnvironmentManager.GetSUTEnvironmentOfTestAgentEnvironment(environment);
                if (null != sutEnvironment)
                {
                    //if the sut is machine ready or other status after machine ready
                    if (sutEnvironment.EnvironmentStatus == EnvironmentStatus.MachinesReady ||
                        sutEnvironment.EnvironmentStatus == EnvironmentStatus.AgentServiceInstalling ||
                        sutEnvironment.EnvironmentStatus == EnvironmentStatus.AgentServiceInstalledAndReady ||
                        sutEnvironment.EnvironmentStatus == EnvironmentStatus.BuildInstalled ||
                        sutEnvironment.EnvironmentStatus == EnvironmentStatus.Ready
                    )
                    {
                        //update the SUT part of the configuration of the test agent configuration.
                        //then the test agent know the detail of the SUT.
                        TestEnvironmentConfigHelper sutConfig = new TestEnvironmentConfigHelper(sutEnvironment.Config);
                        TestEnvironmentConfigHelper testAgentConfig = new TestEnvironmentConfigHelper(environment.Config);
                        testAgentConfig.SUTConfiguration = sutConfig.SUTConfiguration;
                        environment.SetEnvironmentConfig(testAgentConfig.ToXML());

                        //add the jobId into the configuration file to let the Test Agent know which job the test agent is for.
                        TestEnvironmentConfigHelper config = new TestEnvironmentConfigHelper(environment.Config);
                        config.TestAgentConfiguration.Categories.Add("JobId=" + EnvironmentManager.GetAutomationJobOfTestEnvironment(environment).JobId.ToString());
                        environment.SetEnvironmentConfig(config.ToXML());

                        //Install the Saber Agent service into the environment
                        environment.SetEnvironmentStatus(EnvironmentStatus.AgentServiceInstalling);
                        InstallTestAgentWindowsServiceOnEnvironmentAsynchronous(environment);

                        ATFEnvironment.Log.logger.Info(string.Format("Start to install Saber Agent on environment {0}", environment.Name));
                        ATFEnvironment.Log.logger.Info(string.Format("Environment status changes from MachinesReady -> AgentServiceInstalling"));
                    }
                }
            }
            else if (type == EnvironmentType.SUTAlone)//TODO, do we need to install the build on the SUT? currently we do nothing and assume that the environment is ready
            {
                TestEnvironmentConfigHelper config = new TestEnvironmentConfigHelper(environment.Config);
                config.TestAgentConfiguration.Categories.Add(string.Format("JobId={0}", EnvironmentManager.GetAutomationJobOfTestEnvironment(environment).JobId.ToString()));
                environment.SetEnvironmentConfig(config.ToXML());

                ATFEnvironment.Log.logger.Info(string.Format("Test Agents started to be installed on environment {0}", environment.Name));
                //ATFEnvironment.Log.logger.Info(string.Format("Environment status changes from {0} -> AgentServiceInstalling", environment.EnvironmentStatus));
                environment.SetEnvironmentStatus(EnvironmentStatus.AgentServiceInstalling);
                InstallTestAgentWindowsServiceOnEnvironmentAsynchronous(environment);
                ATFEnvironment.Log.logger.Info(string.Format("Test Agents have been installed on environment {0}", environment.Name));

            }
        }