public PnPAppConfigManager(string sqlConnectionString, string configurationName) { //System.Diagnostics.Debugger.Launch(); // let's find the right id based on the name using (TestModelContainer context = new TestModelContainer(sqlConnectionString)) { var configuration = context.TestConfigurationSet.Where(s => s.Name.Equals(configurationName, StringComparison.InvariantCultureIgnoreCase)).First(); if (configuration != null) { this.configurationId = configuration.Id; } else { throw new Exception(String.Format("Test configuration with name {0} was not found", configurationName)); } } this.sqlConnectionString = sqlConnectionString; }
public string GetConfigurationElement(string element) { using (TestModelContainer context = new TestModelContainer(sqlConnectionString)) { TestConfiguration testConfig = context.TestConfigurationSet.Find(configurationId); if (testConfig == null) { throw new Exception(String.Format("Test configuration with ID {0} was not found", configurationId)); } if (element.Equals("PnPBranch", StringComparison.InvariantCultureIgnoreCase)) { return(testConfig.Branch); } else if (element.Equals("PnPBuild", StringComparison.InvariantCultureIgnoreCase)) { return(testConfig.VSBuildConfiguration); } return(""); } }
/// <summary> /// Default constructor /// </summary> /// <param name="parameters">Dictionary with parameter values</param> public TestManager(Dictionary <string, string> parameters) { //System.Diagnostics.Debugger.Launch(); loggerParameters = parameters; // validate is we've the needed params if (String.IsNullOrEmpty(GetParameter("PnPSQLConnectionString")) || String.IsNullOrEmpty(GetParameter("PnPConfigurationToTest"))) { throw new ArgumentException("Requested parameters (PnPSQLConnectionString and PnPConfigurationToTest) are not defined"); } // we pass the connection string as base64 encoded + replaced "=" with " to avoid problems with the default implementation of the VSTestLogger interface context = new TestModelContainer(Base64Decode(GetParameter("PnPSQLConnectionString")).Replace(""", "\"")); // find the used configuration string configurationToTest = GetParameter("PnPConfigurationToTest"); testConfiguration = context.TestConfigurationSet.Where(s => s.Name.Equals(configurationToTest, StringComparison.InvariantCultureIgnoreCase)).First(); if (testConfiguration == null) { throw new Exception(String.Format("Test configuration with name {0} was not found", configurationToTest)); } }
/// <summary> /// Execute MSBuild run, collect the console output and store it in the database. /// </summary> /// <param name="pnpConfigurationToTest">Configuration to run</param> /// <param name="sqlConnectionString">Connection string to PnP Test Automation database that contains the configuration</param> /// <param name="buildTarget">Build file (.targets)</param> public void Execute(string pnpConfigurationToTest, string sqlConnectionString, string buildTarget) { // Prep an entity framework connection string and create a dbcontext connectionString = String.Format("metadata=res://*/SQL.TestModel.csdl|res://*/SQL.TestModel.ssdl|res://*/SQL.TestModel.msl;provider=System.Data.SqlClient;provider connection string=\"{0}\"", sqlConnectionString); context = new TestModelContainer(connectionString); string msBuildExe = ConfigurationManager.AppSettings[Constants.settingMSBuildExe].ToString(); if (String.IsNullOrEmpty(msBuildExe)) { msBuildExe = @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"; } // Create process var proc = new Process(); proc.StartInfo.FileName = msBuildExe; proc.StartInfo.Arguments = String.Format("/property:PnPConfigurationToTest={0};PnPSQLConnectionString=\"metadata=res://*/SQL.TestModel.csdl|res://*/SQL.TestModel.ssdl|res://*/SQL.TestModel.msl;provider=System.Data.SqlClient;provider connection string="{1}"\" \"{2}\"", pnpConfigurationToTest, sqlConnectionString, buildTarget); // set up output redirection proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.EnableRaisingEvents = true; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.UseShellExecute = false; // see below for output handler proc.ErrorDataReceived += proc_DataReceived; proc.OutputDataReceived += proc_DataReceived; proc.Start(); proc.BeginErrorReadLine(); proc.BeginOutputReadLine(); // wait for process to terminate gracefully...if not terminated after the defined timespan kill the process and all childprocesses spawned from this process int maxRunTimeInMinutes; if (!Int32.TryParse(ConfigurationManager.AppSettings[Constants.settingMaxRunTimeInMinutes], out maxRunTimeInMinutes)) { maxRunTimeInMinutes = 180; } WriteLine(String.Format("Starting MSBuild with a max run time of {0} minutes", maxRunTimeInMinutes)); if (!proc.WaitForExit(Convert.ToInt32(new TimeSpan(0, maxRunTimeInMinutes, 0).TotalMilliseconds))) { try { WriteLine("[IMPORTANT] Started killing of the MSBuild process and it's child processes due to exceeded run time"); // kill vstest.console process if it's availabe var vsTestProcesses = Process.GetProcessesByName("vstest.console"); if (vsTestProcesses.Length > 0) { for (int i = 0; i < vsTestProcesses.Length; i++) { KillAllProcessesSpawnedBy(Convert.ToUInt32(vsTestProcesses[i].Id)); WriteLine(string.Format("Killing {0}", vsTestProcesses[i].ProcessName)); vsTestProcesses[i].Kill(); } } // kill all the processes spawned by this process KillAllProcessesSpawnedBy(Convert.ToUInt32(proc.Id)); // kill this process as it has been running too long WriteLine(string.Format("Killing {0}", proc.ProcessName)); proc.Kill(); WriteLine("[IMPORTANT] Termination done!"); } catch { } } // persist the log file TestRun run = context.TestRunSet.Find(this.testRunId); run.MSBuildLog = sb.ToString(); // If the run did not finish by now then something went wrong if (run.Status != RunStatus.Done) { run.Status = RunStatus.Failed; } // Persist the changes SaveChanges(); }
public void GenerateAppConfig(string appConfigFolder) { using (TestModelContainer context = new TestModelContainer(sqlConnectionString)) { TestConfiguration testConfig = context.TestConfigurationSet.Find(configurationId); if (testConfig == null) { throw new Exception(String.Format("Test configuration with ID {0} was not found", configurationId)); } string appConfigFile = Path.Combine(appConfigFolder, "app.config"); // If there's already an app.config file then delete it if (File.Exists(appConfigFile)) { File.Delete(appConfigFile); } // Generate app.config XML file using (XmlWriter writer = XmlWriter.Create(appConfigFile)) { writer.WriteStartElement("configuration"); writer.WriteStartElement("appSettings"); // These app settings property value pairs are always present WriteProperty(writer, "SPOTenantUrl", testConfig.TenantUrl); WriteProperty(writer, "SPODevSiteUrl", testConfig.TestSiteUrl); if (testConfig.Type == TestConfigurationType.SharePoint2013 || testConfig.Type == TestConfigurationType.SharePoint2016) { WriteProperty(writer, "SPOCredentialManagerLabel", testConfig.TestAuthentication.CredentialManagerLabel); if (!testConfig.TestAuthentication.AppOnly) { if (!String.IsNullOrEmpty(testConfig.TestAuthentication.CredentialManagerLabel)) { NetworkCredential cred = CredentialManager.GetCredential(testConfig.TestAuthentication.CredentialManagerLabel); if (cred.UserName.IndexOf("\\") > 0) { string[] userParts = cred.UserName.Split('\\'); WriteProperty(writer, "OnPremUserName", userParts[1]); WriteProperty(writer, "OnPremDomain", userParts[0]); } else { throw new ArgumentException(String.Format("Username {0} stored in credential manager value {1} needs to be formatted as domain\\user", cred.UserName, testConfig.TestAuthentication.CredentialManagerLabel)); } } else { WriteProperty(writer, "OnPremUserName", testConfig.TestAuthentication.User); WriteProperty(writer, "OnPremDomain", testConfig.TestAuthentication.Domain); WriteProperty(writer, "OnPremPassword", testConfig.TestAuthentication.Password); } } else // App-Only { WriteProperty(writer, "AppId", testConfig.TestAuthentication.AppId); WriteProperty(writer, "AppSecret", testConfig.TestAuthentication.AppSecret); } // dump additional properties foreach (var testConfigurationProperty in testConfig.TestConfigurationProperties) { WriteProperty(writer, testConfigurationProperty.Name, testConfigurationProperty.Value); } // dump "special" additional properties WriteProperty(writer, "TestAutomationDatabaseConnectionString", GetConnectionString(sqlConnectionString)); } else // Online { WriteProperty(writer, "SPOCredentialManagerLabel", testConfig.TestAuthentication.CredentialManagerLabel); if (!testConfig.TestAuthentication.AppOnly) { // System.Diagnostics.Debugger.Launch(); // Always output the username since some tests depend on this if (!String.IsNullOrEmpty(testConfig.TestAuthentication.CredentialManagerLabel)) { NetworkCredential cred = CredentialManager.GetCredential(testConfig.TestAuthentication.CredentialManagerLabel); WriteProperty(writer, "SPOUserName", cred.UserName); } else { WriteProperty(writer, "SPOUserName", testConfig.TestAuthentication.User); WriteProperty(writer, "SPOPassword", testConfig.TestAuthentication.Password); } } else // App-Only { WriteProperty(writer, "AppId", testConfig.TestAuthentication.AppId); WriteProperty(writer, "AppSecret", testConfig.TestAuthentication.AppSecret); } // dump additional properties foreach (var testConfigurationProperty in testConfig.TestConfigurationProperties) { WriteProperty(writer, testConfigurationProperty.Name, testConfigurationProperty.Value); } // dump "special" additional properties WriteProperty(writer, "TestAutomationDatabaseConnectionString", GetConnectionString(sqlConnectionString)); } writer.WriteEndElement(); //appSettings writer.WriteStartElement("system.diagnostics"); writer.WriteStartElement("sharedListeners"); writer.WriteStartElement("add"); writer.WriteAttributeString("name", "console"); writer.WriteAttributeString("type", "System.Diagnostics.ConsoleTraceListener"); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteStartElement("sources"); writer.WriteStartElement("source"); writer.WriteAttributeString("name", "OfficeDevPnP.Core"); writer.WriteAttributeString("switchValue", "Verbose"); writer.WriteStartElement("listeners"); writer.WriteStartElement("add"); writer.WriteAttributeString("name", "console"); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteStartElement("trace"); writer.WriteAttributeString("indentsize", "0"); writer.WriteAttributeString("autoflush", "true"); writer.WriteStartElement("listeners"); writer.WriteStartElement("add"); writer.WriteAttributeString("name", "console"); } } }