diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8546df3898..cfe4393e8b 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,6 +6,6 @@ Please Make sure these boxes are checked before submitting your pull request - T
- [ ] Proper Jira ticket - Number, Link in pull request description.
- [ ] The PR can is merged on your machine without any conflicts.
- [ ] The PR can is built on your machine without any (new) warnings.
-- [ ] The PR passed sanity tests by you / QA / DevTest / Good Samaritain.
+- [ ] The PR passed sanity tests by you / QA / DevTest / Good Samaritan.
- [ ] Add unit tests with new features.
-- [ ] If you added any dependency to the POM - Please update @YafimK
+- [ ] If you added any dependency to the POM - Please update grount
diff --git a/.gitignore b/.gitignore
index b277c21ced..51138e47cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,11 +38,9 @@ Ankh.NoLoad
#Tooling
_ReSharper*/
*.resharper
-[Tt]est[Rr]esult*
*.sass-cache
#Project files
-[Bb]uild/
#Subversion files
.svn
@@ -74,9 +72,9 @@ local.properties
#Intellij files
-/.idea/**
.idea/
hp-application-automation-tools-plugin.iml
+*.iml
#Visual studio 14 files
HpToolsLauncher/.vs/
@@ -112,13 +110,17 @@ src/main/resources/LRAnalysisLauncher.exe
# Intellij specific
.iml
target/
-.idea/
# java script
node/
-node_modules/
+node_modules
/hp-application-automation-tools-plugin.iml
/node/
/node_modules/
.sonarlint/
+# jenkins instance folder generated by mvn run:hpi
+work
+work1
+nga/
+**/resources/**/*Gherkin*.xml
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
new file mode 100644
index 0000000000..a65d82e1b6
--- /dev/null
+++ b/.mvn/extensions.xml
@@ -0,0 +1,7 @@
+
+
+ io.jenkins.tools.incrementals
+ git-changelist-maven-extension
+ 1.3
+
+
diff --git a/.mvn/maven.config b/.mvn/maven.config
new file mode 100644
index 0000000000..2a0299c486
--- /dev/null
+++ b/.mvn/maven.config
@@ -0,0 +1,2 @@
+-Pconsume-incrementals
+-Pmight-produce-incrementals
diff --git a/.run/Jenkins debug.run.xml b/.run/Jenkins debug.run.xml
new file mode 100644
index 0000000000..9b3a07f547
--- /dev/null
+++ b/.run/Jenkins debug.run.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HpToolsAborter/Program.cs b/HpToolsAborter/Program.cs
index 64cab146ad..8f9fd7fc43 100644
--- a/HpToolsAborter/Program.cs
+++ b/HpToolsAborter/Program.cs
@@ -1,28 +1,43 @@
-//© Copyright 2013 Hewlett-Packard Development Company, L.P.
-//Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-//and associated documentation files (the "Software"), to deal in the Software without restriction,
-//including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-//and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-//subject to the following conditions:
-
-//The above copyright notice and this permission notice shall be included in all copies or
-//substantial portions of the Software.
-
-//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-//INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-//PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-//LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-//TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-//OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Management;
using System.Diagnostics;
using System.IO;
using HpToolsLauncher;
+using System.Runtime.InteropServices;
namespace HpToolsAborter
{
@@ -73,6 +88,7 @@ static void Main(string[] args)
{
KillQtpAutomationProcess();
KillLoadRunnerAutomationProcess();
+ KillParallelRunnerAutomationProcesses();
}
if (runType=="Alm")
@@ -117,6 +133,49 @@ private static void KillLoadRunnerAutomationProcess()
}
+ private static void KillParallelRunnerAutomationProcess(Process parallelRunner)
+ {
+ if(parallelRunner != null)
+ {
+ List children = new List();
+ GetProcessChildren(parallelRunner.Id, children);
+
+ foreach(var child in children)
+ {
+ var proc = Process.GetProcessById(child.ID);
+
+ if(proc != null)
+ {
+ KillProcess(proc);
+ }
+ }
+
+ KillProcess(parallelRunner);
+ }
+ }
+
+ private static void KillParallelRunnerAutomationProcesses()
+ {
+ Process[] paralelRunnerProcesses = Process.GetProcessesByName("ParallelRunner");
+
+ // kill every parallel runner process
+ foreach(var proc in paralelRunnerProcesses)
+ {
+ // we are sending SIGINT as ParallelRunner will handle this message
+ // gracefully and will set the test status to aborted
+ bool closed = SendSigIntToProcess(proc);
+
+ // let's give SIGINT a chance to execute
+ proc.WaitForExit(500);
+
+ // if ctr-c has failed, just kill the process...
+ if (!closed || !proc.HasExited)
+ {
+ KillParallelRunnerAutomationProcess(proc);
+ }
+ }
+ }
+
private static void KillQtpAutomationProcess()
{
@@ -135,6 +194,7 @@ private static void KillQtpAutomationProcess()
foreach (var child in children)
{
var proc = Process.GetProcessById(child.ID);
+
if (proc != null)
{
KillProcess(proc);
@@ -146,6 +206,14 @@ private static void KillQtpAutomationProcess()
private static void KillQtpAutomationFromAlm()
{
var remoteAgent = Process.GetProcessesByName("AQTRmtAgent").FirstOrDefault();
+ var almProcesses = Process.GetProcessesByName("HP.ALM.Lab.Agent.RemoteService");
+ foreach(var almProcess in almProcesses)
+ {
+ if(almProcess != null)
+ {
+ KillProcess(almProcess);
+ }
+ }
if (remoteAgent != null)
{
@@ -169,11 +237,9 @@ private static void KillQtpAutomationFromAlm()
}
}
- private static void KillServiceTestFromAlm()
+ public static void KillServiceTestFromAlm()
{
-
var dllHostProcesses = Process.GetProcessesByName("dllhost");
-
foreach (var dllhostProcess in dllHostProcesses)
{
List children = new List();
@@ -186,7 +252,6 @@ private static void KillServiceTestFromAlm()
{
var process = Process.GetProcessById(internalExecuterData.ID);
KillProcess(process);
-
KillProcess(dllhostProcess);
break;
}
@@ -210,7 +275,7 @@ private static void KillProcessAndChildren(int pid)
Process proc = Process.GetProcessById(pid);
proc.Kill();
}
- catch (ArgumentException ex)
+ catch (ArgumentException)
{
// Process already exited.
}
@@ -247,6 +312,65 @@ private static void KillProcess(Process process)
}
}
+ private static bool SendSigIntToProcess(Process process)
+ {
+ const int waitMs = 500;
+
+ // we can only be attached to one console at a time
+ if (!FreeConsole())
+ return false;
+
+ // try to attach the console to the process
+ // that we want to send the signal to
+ if (!AttachConsole((uint)process.Id))
+ return false;
+
+ // disable the ctrl handler for our process
+ // so we do not close ourselvles
+ if (!SetConsoleCtrlHandler(null, true))
+ {
+ FreeConsole();
+ AllocConsole();
+
+ return false;
+ }
+
+ // Now generate the event and free the console
+ // that we have attached ourselvles to
+ if (GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0))
+ {
+ process.WaitForExit(waitMs);
+ }
+
+ // free the console for the process that we have attached to
+ FreeConsole();
+
+ // alloc a new console for current process
+ // as we might need to display something
+ AllocConsole();
+
+ SetConsoleCtrlHandler(null, false);
+
+ return true;
+ }
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern bool AttachConsole(uint dwProcessId);
+
+ [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
+ static extern bool FreeConsole();
+
+ [DllImport("kernel32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
+
+ public delegate bool HandlerRoutine(CtrlTypes CtrlType);
+
+ [DllImport("kernel32")]
+ public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
+
+ [DllImport("kernel32")]
+ static extern bool AllocConsole();
}
public class ProcessData
@@ -261,4 +385,13 @@ public ProcessData(int id, string name)
public string Name { get; private set; }
}
+ enum CtrlTypes : uint
+ {
+ CTRL_C_EVENT = 0,
+ CTRL_BREAK_EVENT,
+ CTRL_CLOSE_EVENT,
+ CTRL_LOGOFF_EVENT = 5,
+ CTRL_SHUTDOWN_EVENT
+ }
+
}
diff --git a/HpToolsAborter/Properties/AssemblyInfo.cs b/HpToolsAborter/Properties/AssemblyInfo.cs
index d35670bcec..8135c3c008 100644
--- a/HpToolsAborter/Properties/AssemblyInfo.cs
+++ b/HpToolsAborter/Properties/AssemblyInfo.cs
@@ -1,19 +1,34 @@
-//© Copyright 2013 Hewlett-Packard Development Company, L.P.
-//Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-//and associated documentation files (the "Software"), to deal in the Software without restriction,
-//including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-//and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-//subject to the following conditions:
-
-//The above copyright notice and this permission notice shall be included in all copies or
-//substantial portions of the Software.
-
-//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-//INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-//PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-//LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-//TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-//OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System.Reflection;
using System.Runtime.CompilerServices;
diff --git a/HpToolsLauncher/Common/McConnectionInfo.cs b/HpToolsLauncher/Common/McConnectionInfo.cs
new file mode 100644
index 0000000000..097c72f241
--- /dev/null
+++ b/HpToolsLauncher/Common/McConnectionInfo.cs
@@ -0,0 +1,554 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.ComponentModel;
+using System.Linq;
+using System.Net.Sockets;
+using HpToolsLauncher.Properties;
+using HpToolsLauncher.Utils;
+using Mercury.TD.Client.Ota.QC9;
+
+namespace HpToolsLauncher
+{
+ public class McConnectionInfo
+ {
+ private const string EQ = "=";
+ private const string SEMI_COLON = ";";
+ private const string YES = "Yes";
+ private const string NO = "No";
+ private const string SYSTEM = "System";
+ private const string HTTP = "Http";
+ private const string HTTPS = "Https";
+ private const string PORT_8080 = "8080";
+ private const string PORT_443 = "443";
+ private const string CLIENT = "client";
+ private const string SECRET = "secret";
+ private const string TENANT = "tenant";
+ private const int ZERO = 0;
+ private const int ONE = 1;
+ private static readonly char[] SLASH = new char[] { '/' };
+ private static readonly char[] COLON = new char[] { ':' };
+ private static readonly char[] DBL_QUOTE = new char[] { '"' };
+
+ private const string MOBILEHOSTADDRESS = "MobileHostAddress";
+ private const string MOBILEUSESSL = "MobileUseSSL";
+ private const string MOBILEUSERNAME = "MobileUserName";
+ private const string MOBILEPASSWORD = "MobilePassword";
+ private const string MOBILETENANTID = "MobileTenantId";
+ private const string MOBILEEXECTOKEN = "MobileExecToken";
+ private const string DIGITALLABTYPE = "DigitalLabType";
+ private const string MOBILEUSEPROXY = "MobileUseProxy";
+ private const string MOBILEPROXYTYPE = "MobileProxyType";
+ private const string MOBILEPROXYSETTING_ADDRESS = "MobileProxySetting_Address";
+ private const string MOBILEPROXYSETTING_AUTHENTICATION = "MobileProxySetting_Authentication";
+ private const string MOBILEPROXYSETTING_USERNAME = "MobileProxySetting_UserName";
+ private const string MOBILEPROXYSETTING_PASSWORD = "MobileProxySetting_Password";
+
+ // auth types for MC
+ public enum AuthType
+ {
+ [Description("Username Password")]
+ UsernamePassword,
+ [Description("Access Key")]
+ AuthToken
+ }
+
+ public enum DigitalLabType
+ {
+ UFT = 0,
+ Lite = 1,
+ ValueEdge = 2
+ }
+
+ public struct AuthTokenInfo
+ {
+ public string ClientId { get; set; }
+ public string SecretKey { get; set; }
+ }
+
+ private bool _useSSL;
+ private bool _useProxy;
+ private bool _useProxyAuth;
+
+ // if token auth was specified this is populated
+ private AuthTokenInfo _token;
+ private string _execToken;
+ private AuthType _authType = AuthType.UsernamePassword;
+ private DigitalLabType _labType = DigitalLabType.UFT;
+
+ public string UserName { get; set; }
+ public string Password { get; set; }
+
+ public string ExecToken
+ {
+ get
+ {
+ return _execToken;
+ }
+ set
+ {
+ if (value == null)
+ {
+ _execToken = null;
+ _token.ClientId = _token.SecretKey = null;
+ }
+ else
+ {
+ _execToken = value.Trim().Trim(DBL_QUOTE);
+ _token = ParseExecToken();
+ }
+ }
+ }
+
+ public AuthType MobileAuthType
+ {
+ get
+ {
+ return _authType;
+ }
+ private set
+ {
+ _authType = value;
+ }
+ }
+
+ public DigitalLabType LabType
+ {
+ get
+ {
+ return _labType;
+ }
+ }
+
+ public string HostAddress { get; set; }
+ public string HostPort { get; set; }
+ public string TenantId { get; set; }
+ public bool UseSSL { get { return _useSSL; } set { _useSSL = value; } }
+ public int UseSslAsInt { get { return _useSSL ? ONE : ZERO; } }
+ public bool UseProxy { get { return _useProxy; } set { _useProxy = value; } }
+ public int UseProxyAsInt { get { return _useProxy ? ONE : ZERO; } }
+ public int ProxyType { get; set; }
+ public string ProxyAddress { get; set; }
+ public int ProxyPort { get; set; }
+ public bool UseProxyAuth { get; set; }
+ public int UseProxyAuthAsInt { get { return _useProxyAuth ? ONE : ZERO; } }
+ public string ProxyUserName { get; set; }
+ public string ProxyPassword { get; set; }
+
+ public McConnectionInfo()
+ {
+ HostPort = PORT_8080;
+ UserName =
+ ExecToken =
+ Password =
+ HostAddress =
+ TenantId =
+ ProxyAddress =
+ ProxyUserName =
+ ProxyPassword = string.Empty;
+ }
+
+ public McConnectionInfo(JavaProperties ciParams) : this()
+ {
+ if (ciParams.ContainsKey(MOBILEHOSTADDRESS))
+ {
+ //ssl
+ if (ciParams.ContainsKey(MOBILEUSESSL))
+ {
+ string strUseSSL = ciParams[MOBILEUSESSL];
+ if (!string.IsNullOrEmpty(strUseSSL))
+ {
+ int intUseSSL;
+ int.TryParse(ciParams[MOBILEUSESSL], out intUseSSL);
+ _useSSL = intUseSSL == ONE;
+ }
+ }
+
+ string mcServerUrl = ciParams[MOBILEHOSTADDRESS].Trim();
+ if (string.IsNullOrEmpty(mcServerUrl))
+ {
+ throw new NoMcConnectionException();
+ }
+ //url is something like http://xxx.xxx.xxx.xxx:8080
+ string[] arr = mcServerUrl.Split(COLON, StringSplitOptions.RemoveEmptyEntries);
+ if (arr.Length == 1)
+ {
+ if (arr[0].Trim().In(true, HTTP, HTTPS))
+ throw new ArgumentException(string.Format(Resources.McInvalidUrl, mcServerUrl));
+ HostAddress = arr[0].TrimEnd(SLASH);
+ HostPort = _useSSL ? PORT_443 : PORT_8080;
+ }
+ else if (arr.Length == 2)
+ {
+ if (arr[0].Trim().In(true, HTTP, HTTPS))
+ {
+ HostAddress = arr[1].Trim(SLASH);
+ HostPort = _useSSL ? PORT_443 : PORT_8080;
+ }
+ else
+ {
+ HostAddress = arr[0].Trim(SLASH);
+ HostPort = arr[1].Trim();
+ }
+ }
+ else if (arr.Length == 3)
+ {
+ HostAddress = arr[1].Trim(SLASH);
+ HostPort = arr[2].Trim();
+ }
+
+ if (HostAddress.Trim() == string.Empty)
+ {
+ throw new ArgumentException(Resources.McEmptyHostAddress);
+ }
+
+ //mc username
+ if (ciParams.ContainsKey(MOBILEUSERNAME))
+ {
+ string mcUsername = ciParams[MOBILEUSERNAME];
+ if (!string.IsNullOrEmpty(mcUsername))
+ {
+ UserName = mcUsername;
+ }
+ }
+
+ //mc password
+ if (ciParams.ContainsKey(MOBILEPASSWORD))
+ {
+ string mcPassword = ciParams[MOBILEPASSWORD];
+ if (!string.IsNullOrEmpty(mcPassword))
+ {
+ Password = Encrypter.Decrypt(mcPassword);
+ }
+ }
+
+ //mc tenantId
+ if (ciParams.ContainsKey(MOBILETENANTID))
+ {
+ string mcTenantId = ciParams[MOBILETENANTID];
+ if (!string.IsNullOrEmpty(mcTenantId))
+ {
+ TenantId = mcTenantId;
+ }
+ }
+
+ //mc exec token
+ if (ciParams.ContainsKey(MOBILEEXECTOKEN))
+ {
+ var mcExecToken = ciParams[MOBILEEXECTOKEN];
+ if (!string.IsNullOrEmpty(mcExecToken))
+ {
+ ExecToken = Encrypter.Decrypt(mcExecToken);
+ }
+ }
+
+ if (ciParams.ContainsKey(DIGITALLABTYPE))
+ {
+ var dlLabType = ciParams[DIGITALLABTYPE];
+ if (!string.IsNullOrEmpty(dlLabType))
+ {
+ Enum.TryParse(dlLabType, true, out _labType);
+ }
+ }
+
+ //Proxy enabled flag
+ if (ciParams.ContainsKey(MOBILEUSEPROXY))
+ {
+ string useProxy = ciParams[MOBILEUSEPROXY];
+ if (!string.IsNullOrEmpty(useProxy))
+ {
+ int useProxyAsInt = int.Parse(useProxy);
+ _useProxy = useProxyAsInt == ONE;
+ }
+ }
+
+ //Proxy type
+ if (ciParams.ContainsKey(MOBILEPROXYTYPE))
+ {
+ string proxyType = ciParams[MOBILEPROXYTYPE];
+ if (!string.IsNullOrEmpty(proxyType))
+ {
+ ProxyType = int.Parse(proxyType);
+ }
+ }
+
+ //proxy address
+ string proxyAddress = ciParams.GetOrDefault(MOBILEPROXYSETTING_ADDRESS);
+ if (!string.IsNullOrEmpty(proxyAddress))
+ {
+ // data is something like "16.105.9.23:8080"
+ string[] arrProxyAddress = proxyAddress.Split(new char[] { ':' });
+ if (arrProxyAddress.Length == 2)
+ {
+ ProxyAddress = arrProxyAddress[0];
+ ProxyPort = int.Parse(arrProxyAddress[1]);
+ }
+ }
+
+
+ //Proxy authentication
+ if (ciParams.ContainsKey(MOBILEPROXYSETTING_AUTHENTICATION))
+ {
+ string proxyAuth = ciParams[MOBILEPROXYSETTING_AUTHENTICATION];
+ if (!string.IsNullOrEmpty(proxyAuth))
+ {
+ int useProxyAuthAsInt = int.Parse(proxyAuth);
+ _useProxyAuth = useProxyAuthAsInt == ONE;
+ }
+ }
+
+ //Proxy username
+ if (ciParams.ContainsKey(MOBILEPROXYSETTING_USERNAME))
+ {
+ string proxyUsername = ciParams[MOBILEPROXYSETTING_USERNAME];
+ if (!string.IsNullOrEmpty(proxyUsername))
+ {
+ ProxyUserName = proxyUsername;
+ }
+ }
+
+ //Proxy password
+ if (ciParams.ContainsKey(MOBILEPROXYSETTING_PASSWORD))
+ {
+ string proxyPassword = ciParams[MOBILEPROXYSETTING_PASSWORD];
+ if (!string.IsNullOrEmpty(proxyPassword))
+ {
+ ProxyPassword = Encrypter.Decrypt(proxyPassword);
+ }
+ }
+ }
+ else
+ {
+ throw new NoMcConnectionException();
+ }
+ }
+
+ ///
+ /// Parses the execution token and separates into three parts: clientId, secretKey and tenantId
+ ///
+ ///
+ ///
+ private AuthTokenInfo ParseExecToken()
+ {
+ // exec token consists of three parts:
+ // 1. client id
+ // 2. secret key
+ // 3. optionally tenant id
+ // separator is ;
+ // key-value pairs are separated with =
+
+ // e.g., "client=oauth2-QHxvc8bOSz4lwgMqts2w@microfocus.com; secret=EHJp8ea6jnVNqoLN6HkD; tenant=999999999;"
+ // "client=oauth2-OuV8k3snnGp9vJugC1Zn@microfocus.com; secret=6XSquF1FUD4CyQM7fb0B; tenant=999999999;"
+ // "client=oauth2-OuV8k3snnGp9vJugC1Zn@microfocus.com; secret=6XSquF1FUD7CyQM7fb0B; tenant=999999999;"
+ var ret = new AuthTokenInfo();
+ if (_execToken.Length == 0) return ret; // empty string was given as token, may semnalize that it wasn't specified
+
+ var tokens = _execToken.Split(SEMI_COLON.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
+
+ if (tokens.Length != 3) throw new ArgumentException(Resources.McInvalidToken);
+ if (!tokens.All(token => token.Contains(EQ)))
+ throw new ArgumentException(string.Format(Resources.McMalformedTokenInvalidKeyValueSeparator, EQ));
+
+ // key-values are separated by =, we need its value, the key is known
+ foreach (var token in tokens)
+ {
+ var parts = token.Split(EQ.ToCharArray());
+
+ if (parts.Length != 2)
+ throw new ArgumentException(Resources.McMalformedTokenMissingKeyValuePair);
+
+ var key = parts[0].Trim();
+ var value = parts[1].Trim();
+
+ if (CLIENT.EqualsIgnoreCase(key))
+ {
+ ret.ClientId = value;
+ }
+ else if (SECRET.EqualsIgnoreCase(key))
+ {
+ ret.SecretKey = value;
+ }
+ else if (TENANT.EqualsIgnoreCase(key))
+ {
+ TenantId = value;
+ }
+ else
+ {
+ throw new ArgumentException(string.Format(Resources.McMalformedTokenInvalidKey, key));
+ }
+ }
+
+ _authType = AuthType.AuthToken;
+ return ret;
+ }
+
+ ///
+ /// Returns the parsed tokens from the execution token.
+ ///
+ ///
+ public AuthTokenInfo GetAuthToken()
+ {
+ return _token;
+ }
+
+ public override string ToString()
+ {
+ string strUseSsl = string.Format("UseSSL: {0}", UseSslAsInt == ONE ? YES : NO);
+ string strUserNameOrClientId = string.Empty;
+ if (MobileAuthType == AuthType.AuthToken)
+ {
+ strUserNameOrClientId = string.Format("ClientId: {0}", _token.ClientId);
+ }
+ else if (MobileAuthType == AuthType.UsernamePassword)
+ {
+ strUserNameOrClientId = string.Format("Username: {0}", UserName);
+ }
+ string strTenantId = TenantId.IsNullOrWhiteSpace() ? string.Empty : string.Format(", TenantId: {0}", TenantId);
+ string strProxy = string.Format("UseProxy: {0}", UseProxyAsInt == ONE ? YES : NO);
+ if (UseProxy)
+ {
+ strProxy += string.Format(", ProxyType: {0}", ProxyType == ONE ? SYSTEM : HTTP);
+ if (!ProxyAddress.IsNullOrWhiteSpace())
+ {
+ strProxy += string.Format(", ProxyAddress: {0}", ProxyAddress);
+ if (ProxyPort > 0)
+ {
+ strProxy += string.Format(", ProxyPort: {0}", ProxyPort);
+ }
+ }
+ strProxy += string.Format(", ProxyAuth: {0}", _useProxyAuth ? YES : NO);
+ if (_useProxy && !ProxyUserName.IsNullOrWhiteSpace())
+ {
+ strProxy += string.Format(", ProxyUserName: {0}", ProxyUserName);
+ }
+ }
+ return string.Format("HostAddress: {0}, Port: {1}, AuthType: {2}, {3}{4}, {5}, {6}", HostAddress, HostPort, MobileAuthType, strUserNameOrClientId, strTenantId, strUseSsl, strProxy);
+ }
+ }
+
+ public class NoMcConnectionException : Exception
+ {
+ }
+
+ public class CloudBrowser
+ {
+ private const string EQ = "=";
+ private const string SEMI_COLON = ";";
+ private const string URL = "url";
+ private const string TYPE = "type";
+ private const string _OS = "os";
+ private const string VERSION = "version";
+ private const string REGION = "region";
+
+ private static readonly char[] DBL_QUOTE = new char[] { '"' };
+
+ private string _url;
+ private string _os;
+ private string _type;
+ private string _version;
+ private string _location;
+ public CloudBrowser(string url, string os, string type, string version, string location)
+ {
+ _url = url;
+ _os = os;
+ _type = type;
+ _version = version;
+ _location = location;
+ }
+ public string Url { get { return _url; } }
+ public string OS { get { return _os; } }
+ public string Browser { get { return _type;} }
+ public string Version { get { return _version; } }
+ public string Region { get { return _location; } }
+
+ public static bool TryParse(string strCloudBrowser, out CloudBrowser cloudBrowser)
+ {
+ cloudBrowser = null;
+ try
+ {
+ string[] arrKeyValPairs = strCloudBrowser.Trim().Trim(DBL_QUOTE).Split(SEMI_COLON.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
+ string url = null, os = null, type = null, version = null, region = null;
+
+ // key-values are separated by =, we need its value, the key is known
+ foreach (var pair in arrKeyValPairs)
+ {
+ string[] arrKVP = pair.Split(EQ.ToCharArray(), 2);
+
+ if (arrKVP.Length < 2)
+ continue;
+
+ var key = arrKVP[0].Trim();
+ var value = arrKVP[1].Trim();
+ switch (key.ToLower())
+ {
+ case URL:
+ url = value; break;
+ case _OS:
+ os = value; break;
+ case TYPE:
+ type = value; break;
+ case VERSION:
+ version = value; break;
+ case REGION:
+ region = value; break;
+ default:
+ break;
+ }
+ }
+ cloudBrowser = new CloudBrowser(url, os, type, version, region);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteErrLine(ex.Message);
+ return false;
+ }
+ }
+ }
+
+ public class DigitalLab
+ {
+ private McConnectionInfo _connInfo;
+ private string _mobileInfo;
+ private CloudBrowser _cloudBrowser;
+ public DigitalLab(McConnectionInfo mcConnInfo, string mobileInfo, CloudBrowser cloudBrowser)
+ {
+ _connInfo = mcConnInfo;
+ _mobileInfo = mobileInfo;
+ _cloudBrowser = cloudBrowser;
+ }
+ public McConnectionInfo ConnectionInfo { get { return _connInfo; } }
+ public string MobileInfo { get { return _mobileInfo; } }
+ public CloudBrowser CloudBrowser { get { return _cloudBrowser; } }
+ }
+}
diff --git a/HpToolsLauncher/Common/WinUserNativeMethods.cs b/HpToolsLauncher/Common/WinUserNativeMethods.cs
new file mode 100644
index 0000000000..d28102a84a
--- /dev/null
+++ b/HpToolsLauncher/Common/WinUserNativeMethods.cs
@@ -0,0 +1,100 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace HpToolsLauncher
+{
+ public static class WinUserNativeMethods
+ {
+ private static class EncodeUtilsWrap
+ {
+ [DllImport("EncodeUtilsWrap", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void UnprotectBSTRFromBase64([MarshalAs(UnmanagedType.BStr)] string input, [MarshalAs(UnmanagedType.BStr)] out string result, [MarshalAs(UnmanagedType.Bool)] bool bCrypt);
+
+ [DllImport("EncodeUtilsWrap", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ProtectBSTRToBase64([MarshalAs(UnmanagedType.BStr)] string input, [MarshalAs(UnmanagedType.BStr)] out string result, [MarshalAs(UnmanagedType.Bool)] bool bCrypt);
+ }
+
+ private static class EncodeUtilsWrapD
+ {
+ [DllImport("EncodeUtilsWrapD", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void UnprotectBSTRFromBase64([MarshalAs(UnmanagedType.BStr)] string input, [MarshalAs(UnmanagedType.BStr)] out string result, [MarshalAs(UnmanagedType.Bool)] bool bCrypt);
+
+ [DllImport("EncodeUtilsWrapD", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void ProtectBSTRToBase64([MarshalAs(UnmanagedType.BStr)] string input, [MarshalAs(UnmanagedType.BStr)] out string result, [MarshalAs(UnmanagedType.Bool)] bool bCrypt);
+ }
+
+ public static string ProtectBSTRToBase64(string clearData)
+ {
+ string result = null;
+
+ try
+ {
+ EncodeUtilsWrap.ProtectBSTRToBase64(clearData, out result, true);
+ }
+ catch (DllNotFoundException)
+ {
+ try
+ {
+ EncodeUtilsWrapD.ProtectBSTRToBase64(clearData, out result, true);
+ }
+ catch (DllNotFoundException)
+ {
+
+ }
+ }
+
+ return result;
+ }
+
+ public static string UnprotectBSTRFromBase64(string protectedData)
+ {
+ if (string.IsNullOrEmpty(protectedData))
+ return string.Empty;
+
+ string result = null;
+
+ try
+ {
+ EncodeUtilsWrap.UnprotectBSTRFromBase64(protectedData, out result, true);
+ }
+ catch (DllNotFoundException)
+ {
+ EncodeUtilsWrapD.UnprotectBSTRFromBase64(protectedData, out result, true);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/HpToolsLauncher/ConsoleQuickEdit.cs b/HpToolsLauncher/ConsoleQuickEdit.cs
index f837d389e7..bd79301146 100644
--- a/HpToolsLauncher/ConsoleQuickEdit.cs
+++ b/HpToolsLauncher/ConsoleQuickEdit.cs
@@ -1,7 +1,36 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
using System.Runtime.InteropServices;
namespace HpToolsLauncher
@@ -24,7 +53,7 @@ public class ConsoleQuickEdit
private static bool SetNewConsoleMode(IntPtr consoleHandle, uint consoleMode)
{
-// set the new mode
+ // set the new mode
if (!SetConsoleMode(consoleHandle, consoleMode))
{
// ERROR: Unable to set console mode
diff --git a/HpToolsLauncher/ConsoleWriter.cs b/HpToolsLauncher/ConsoleWriter.cs
index d9a20354f6..aecceed63c 100644
--- a/HpToolsLauncher/ConsoleWriter.cs
+++ b/HpToolsLauncher/ConsoleWriter.cs
@@ -1,7 +1,34 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System;
using System.Collections.Generic;
@@ -37,6 +64,12 @@ public static void WriteException(string message, Exception ex)
activeTestRun.ConsoleErr += message + "\n" + ex.Message + "\n" + ex.StackTrace + "\n";
}
+ public static void WriteException(Exception ex)
+ {
+ Console.Out.WriteLine(ex.StackTrace);
+ if (activeTestRun != null)
+ activeTestRun.ConsoleErr += ex.StackTrace + "\n";
+ }
public static void WriteErrLine(string message)
{
@@ -76,12 +109,22 @@ public static void WriteLine(string[] messages)
public static void WriteLine(string message)
{
- message = message.Replace("\\n", "\n");
- message = FilterXmlProblematicChars(message);
- //File.AppendAllText("c:\\stam11.stam", message);
- Console.Out.WriteLine(message);
+ message = FilterXmlProblematicChars(message);
+
+ Console.WriteLine(message);
+
if (activeTestRun != null)
activeTestRun.ConsoleOut += message + "\n";
}
+
+ public static void WriteLineWithTime(string message)
+ {
+ WriteLine(string.Format("{0} {1}", DateTime.Now.ToString(Launcher.DateFormat), message));
+ }
+
+ public static void WriteErrLineWithTime(string message)
+ {
+ WriteLine(string.Format("Error: {0} {1}", DateTime.Now.ToString(Launcher.DateFormat), message));
+ }
}
}
diff --git a/HpToolsLauncher/ElevatedProcess.cs b/HpToolsLauncher/ElevatedProcess.cs
new file mode 100644
index 0000000000..0e9002f74e
--- /dev/null
+++ b/HpToolsLauncher/ElevatedProcess.cs
@@ -0,0 +1,245 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace HpToolsLauncher
+{
+ [Serializable]
+ public class ElevatedProcessException : Exception
+ {
+ public ElevatedProcessException(string message) : base(message) { }
+ public ElevatedProcessException(string message, Exception innerException) : base(message, innerException) { }
+ }
+
+ public class ElevatedProcess : IDisposable
+ {
+ private readonly string _path;
+ private readonly string _arguments;
+ private readonly string _workDirectory;
+ private NativeProcess.PROCESS_INFORMATION _processInformation;
+ private const uint STILL_ACTIVE = 259;
+ private const uint INFINITE = 0xFFFFFFFF;
+
+ public ElevatedProcess(string path, string arguments, string workDirectory)
+ {
+ _path = path;
+ _arguments = arguments;
+ _workDirectory = workDirectory;
+ }
+
+ private int GetExitCode()
+ {
+ uint exitCode;
+ if (!NativeProcess.GetExitCodeProcess(_processInformation.hProcess, out exitCode))
+ {
+ return 0;
+ }
+
+ return (int)exitCode;
+ }
+
+ public int ExitCode
+ {
+ get
+ {
+ return GetExitCode();
+ }
+ }
+
+ public bool HasExited
+ {
+ get
+ {
+ return GetExitCode() != STILL_ACTIVE;
+ }
+ }
+
+ public void StartElevated()
+ {
+ Process process;
+ try
+ {
+ process = Process.GetProcessesByName("explorer").FirstOrDefault();
+ }
+ catch (InvalidOperationException e)
+ {
+ throw new ElevatedProcessException("An error has occurred while trying to find the 'explorer' process: ", e);
+ }
+
+ if (process == null)
+ {
+ throw new ElevatedProcessException("No process with the name 'explorer' found!");
+ }
+
+ // we can retrieve the token information from explorer
+ int explorerPid = process.Id;
+
+ // open the explorer process with the necessary flags
+ IntPtr hProcess = NativeProcess.OpenProcess(NativeProcess.ProcessAccessFlags.DuplicateHandle | NativeProcess.ProcessAccessFlags.QueryInformation, false, explorerPid);
+
+ if (hProcess == IntPtr.Zero)
+ {
+ throw new ElevatedProcessException("OpenProcess() failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ IntPtr hUser;
+
+ // get the secondary token from the explorer process
+ if (!NativeProcess.OpenProcessToken(hProcess, NativeProcess.TOKEN_QUERY | NativeProcess.TOKEN_DUPLICATE | NativeProcess.TOKEN_ASSIGN_PRIMARY, out hUser))
+ {
+ NativeProcess.CloseHandle(hProcess);
+
+ throw new ElevatedProcessException("OpenProcessToken() failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ IntPtr userToken;
+
+ // convert the secondary token to a primary token
+ if (!NativeProcess.DuplicateTokenEx(hUser, NativeProcess.MAXIMUM_ALLOWED, IntPtr.Zero, NativeProcess.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
+ NativeProcess.TOKEN_TYPE.TokenPrimary, out userToken))
+ {
+ NativeProcess.CloseHandle(hUser);
+ NativeProcess.CloseHandle(hProcess);
+
+ throw new ElevatedProcessException("DuplicateTokenEx() failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ // the explorer session id will be used in order to launch the given executable
+ uint sessionId;
+
+ if (!NativeProcess.ProcessIdToSessionId((uint)explorerPid, out sessionId))
+ {
+ throw new ElevatedProcessException("ProcessIdToSessionId() failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ uint tokenInformationLen = (uint)Marshal.SizeOf(sessionId);
+
+ // set the session id
+ if (!NativeProcess.SetTokenInformation(userToken, NativeProcess.TOKEN_INFORMATION_CLASS.TokenSessionId, ref sessionId, tokenInformationLen))
+ {
+ NativeProcess.CloseHandle(hUser);
+ NativeProcess.CloseHandle(hProcess);
+ NativeProcess.CloseHandle(userToken);
+
+ throw new ElevatedProcessException("SetTokenInformation failed with: " + Marshal.GetLastWin32Error());
+ }
+
+ if (!NativeProcess.ImpersonateLoggedOnUser(userToken))
+ {
+ NativeProcess.CloseHandle(hUser);
+ NativeProcess.CloseHandle(hProcess);
+ NativeProcess.CloseHandle(userToken);
+
+ throw new ElevatedProcessException("ImpersonateLoggedOnUser failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ // these handles are no longer needed
+ NativeProcess.CloseHandle(hUser);
+ NativeProcess.CloseHandle(hProcess);
+
+ NativeProcess.STARTUPINFO startupInfo = new NativeProcess.STARTUPINFO();
+ NativeProcess.PROCESS_INFORMATION pInfo = new NativeProcess.PROCESS_INFORMATION();
+ startupInfo.cb = Marshal.SizeOf(pInfo);
+
+ string commandLine = string.Format("{0} {1}", _path, _arguments);
+
+ IntPtr pEnv;
+
+ // create a new environment block for the process
+ if (!NativeProcess.CreateEnvironmentBlock(out pEnv, userToken, false))
+ {
+ throw new ElevatedProcessException("CreateEnvironmentBlock() failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ // create the process with the retrieved token
+ if (!NativeProcess.CreateProcessAsUser(userToken, null, commandLine, IntPtr.Zero, IntPtr.Zero, false,
+ NativeProcess.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT | NativeProcess.CreateProcessFlags.CREATE_SUSPENDED |
+ NativeProcess.CreateProcessFlags.CREATE_NO_WINDOW, pEnv, _workDirectory, ref startupInfo, out pInfo))
+ {
+ NativeProcess.CloseHandle(userToken);
+
+ if (pEnv != IntPtr.Zero)
+ {
+ NativeProcess.DestroyEnvironmentBlock(pEnv);
+ }
+
+ throw new ElevatedProcessException("CreateProcessAsUser() failed with error code: " + Marshal.GetLastWin32Error());
+ }
+
+ NativeProcess.ResumeThread(pInfo.hThread);
+
+ // the environment block can be destroyed now
+ if (pEnv != IntPtr.Zero)
+ {
+ NativeProcess.DestroyEnvironmentBlock(pEnv);
+ }
+
+ // save the process information
+ _processInformation = pInfo;
+
+ NativeProcess.RevertToSelf();
+ }
+
+ public void WaitForExit()
+ {
+ NativeProcess.WaitForSingleObject(_processInformation.hProcess, INFINITE);
+ }
+
+ public bool WaitForExit(int milliseconds)
+ {
+ NativeProcess.WaitForSingleObject(_processInformation.hProcess, (uint)milliseconds);
+
+ return HasExited;
+ }
+
+ public void Kill()
+ {
+ NativeProcess.TerminateProcess(_processInformation.hProcess, 0);
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ public void Close()
+ {
+ // close the handles before the object is destroyed
+ NativeProcess.CloseHandle(_processInformation.hProcess);
+ NativeProcess.CloseHandle(_processInformation.hThread);
+ }
+ }
+}
\ No newline at end of file
diff --git a/HpToolsLauncher/ExportOptions.cs b/HpToolsLauncher/ExportOptions.cs
index ace8c7f1b2..8528786c41 100644
--- a/HpToolsLauncher/ExportOptions.cs
+++ b/HpToolsLauncher/ExportOptions.cs
@@ -1,7 +1,34 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
namespace HpToolsLauncher
{
diff --git a/HpToolsLauncher/Helper.cs b/HpToolsLauncher/Helper.cs
deleted file mode 100644
index ed83c997ca..0000000000
--- a/HpToolsLauncher/Helper.cs
+++ /dev/null
@@ -1,996 +0,0 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Timers;
-using System.Web.UI;
-using System.Xml;
-using System.Xml.Linq;
-using System.Xml.XPath;
-using System.Xml.Xsl;
-using HpToolsLauncher.Properties;
-using Microsoft.Win32;
-
-namespace HpToolsLauncher
-{
- public enum TestType
- {
- QTP,
- ST,
- LoadRunner,
- }
-
- public enum TestState
- {
- Waiting,
- Running,
- NoRun,
- Passed,
- Failed,
- Error,
- Warning,
- Unknown,
- }
-
- public enum TestResult
- {
- Passed,
- Failed,
- Warning,
- Done,
- }
-
- public static class Helper
- {
- #region Constants
-
- public const string FT_REG_ROOT = @"SOFTWARE\Mercury Interactive\QuickTest Professional\CurrentVersion";
-
- internal const string FT_REG_ROOT_64_BIT =
- @"SOFTWARE\Wow6432Node\Mercury Interactive\QuickTest Professional\CurrentVersion";
-
- public const string FT_ROOT_PATH_KEY = "QuickTest Professional";
- private const string QTP_ROOT_ENV_VAR_NAME = "QTP_TESTS_ROOT";
-
-
- public const string ServiceTestRegistryKey = @"SOFTWARE\Hewlett-Packard\HP Service Test";
- public const string ServiceTesCurrentVersionRegistryKey = ServiceTestRegistryKey + @"\CurrentVersion";
-
- public const string ServiceTesWOW64RegistryKey = @"SOFTWARE\Wow6432Node\Hewlett-Packard\HP Service Test";
- public const string ServiceTesCurrentVersionWOW64RegistryKey = ServiceTesWOW64RegistryKey + @"\CurrentVersion";
-
- public const string LoadRunnerRegistryKey = @"SOFTWARE\Mercury Interactive\LoadRunner";
- public const string LoadRunner64RegisryKey = @"SOFTWARE\Wow6432Node\Mercury Interactive\LoadRunner";
- public const string LoadRunnerControllerRegistryKey = @"CustComponent\Controller\CurrentVersion";
- public const string LoadRunnerControllerDirRegistryKey = @"\CurrentVersion";
-
- public const string LoadRunnerControllerDirRegistryValue = @"\Controller";
-
- public static readonly System.Collections.ObjectModel.ReadOnlyCollection LoadRunnerENVVariables =
- new System.Collections.ObjectModel.ReadOnlyCollection(new[] {"LG_PATH", "LR_PATH"});
-
-
- public const string InstalltionFolderValue = "LOCAL_MLROOT";
-
- public const string UftViewerInstalltionFolderRegistryKey =
- @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{E86D56AE-6660-4357-890F-8B79AB7A8F7B}";
-
- public const string UftViewerInstalltionFolderRegistryKey64Bit =
- @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{E86D56AE-6660-4357-890F-8B79AB7A8F7B}";
-
-
- public const string ResultsFileName = "Results.xml";
- public const string QTPReportProcessPath = @"bin\reportviewer.exe";
-
- public const string STFileExtention = ".st";
- public const string QTPFileExtention = ".tsp";
- public const string LoadRunnerFileExtention = ".lrs";
-
- #endregion
-
- public static Assembly HPToolsAssemblyResolver(object sender, ResolveEventArgs args)
- {
- AssemblyName asmName = new AssemblyName(args.Name);
- if (asmName == null) return null;
-
- string assemblyName = asmName.Name;
- if (assemblyName.EndsWith(".resources")) return null;
-
- if (assemblyName == "HpToolsLauncher.XmlSerializers") return null;
-
- string installtionPath = null;
- installtionPath = Helper.getLRInstallPath();
- if (installtionPath == null)
- {
- ConsoleWriter.WriteErrLine(string.Format(Resources.LoadRunnerNotInstalled,
- System.Environment.MachineName));
- Environment.Exit((int) Launcher.ExitCodeEnum.Aborted);
- }
-
- installtionPath = Path.Combine(installtionPath, "bin");
-
- Assembly ans;
- if (!File.Exists(Path.Combine(installtionPath, assemblyName + ".dll")))
- {
- //resource!
- ConsoleWriter.WriteErrLine("cannot locate " + assemblyName + ".dll in installation directory");
- Environment.Exit((int) Launcher.ExitCodeEnum.Aborted);
- }
- else
- {
- //Console.WriteLine("loading " + assemblyName + " from " + Path.Combine(installtionPath, assemblyName + ".dll"));
- ans = Assembly.LoadFrom(Path.Combine(installtionPath, assemblyName + ".dll"));
-
- AssemblyName loadedName = ans.GetName();
- if (loadedName.Name == "Interop.Wlrun")
- {
- if (loadedName.Version.Major > 11 ||
- (loadedName.Version.Major == 11 && loadedName.Version.Minor >= 52))
- {
- return ans;
- }
- else
- {
- ConsoleWriter.WriteErrLine(string.Format(Resources.HPToolsAssemblyResolverWrongVersion,
- Environment.MachineName));
- Environment.Exit((int) Launcher.ExitCodeEnum.Aborted);
- }
- }
- else
- {
- return ans;
- }
-
- }
-
-
- return null;
-
- }
-
-
- public static string GetRootDirectoryPath()
- {
- String directoryPath;
- RegistryKey regkey = Registry.LocalMachine.OpenSubKey(FT_REG_ROOT);
-
- if (regkey != null)
- directoryPath = (string) regkey.GetValue(FT_ROOT_PATH_KEY);
- else
- {
-//TRY 64 bit REG path
- regkey = Registry.LocalMachine.OpenSubKey(FT_REG_ROOT_64_BIT);
- if (regkey != null)
- directoryPath = (string) regkey.GetValue(FT_ROOT_PATH_KEY);
- else
- directoryPath = GetRootFromEnvironment();
- }
-
- return directoryPath;
- }
-
-
- //verify that files/fodlers exist (does not recurse into folders)
- public static List ValidateFiles(IEnumerable tests)
- {
- List validTests = new List();
- foreach (string test in tests)
- {
- if (!File.Exists(test) && !Directory.Exists(test))
- {
- ConsoleWriter.WriteLine(string.Format(">>>> File/Folder not found: '{0}'", test));
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- }
- else
- {
- validTests.Add(test);
- }
- }
- return validTests;
- }
-
- public static bool IsTestingToolsInstalled(TestStorageType type)
- {
- //we want to check if we have Service Test, QTP installed on a machine
-
- return IsQtpInstalled() || IsServiceTestInstalled() || isLoadRunnerInstalled();
-
- }
-
- public static bool isLoadRunnerInstalled()
- {
- //try 32 bit
- RegistryKey regkey = Registry.LocalMachine.OpenSubKey(LoadRunnerRegistryKey);
-
- if (regkey == null)
- {
- //try 64-bit
- regkey = Registry.LocalMachine.OpenSubKey(LoadRunner64RegisryKey);
-
- }
-
- if (regkey != null)
- {
-
- //LoadRunner Exist.
- //check if Controller is installed (not SA version)
-
- if (regkey.OpenSubKey(LoadRunnerControllerRegistryKey) != null)
- {
- return true;
- }
-
- }
- return false;
-
- }
-
- public static bool IsQtpInstalled()
- {
- RegistryKey regkey;
- string value;
- regkey = Registry.LocalMachine.OpenSubKey(FT_REG_ROOT);
- if (regkey == null)
- {
- //try 64 bit
- regkey = Registry.LocalMachine.OpenSubKey(FT_REG_ROOT_64_BIT);
- }
-
- if (regkey != null)
- {
- value = (string) regkey.GetValue(FT_ROOT_PATH_KEY);
- if (!string.IsNullOrEmpty(value))
- {
- return true;
- }
- }
- return false;
- }
-
- public static bool IsServiceTestInstalled()
- {
- RegistryKey regkey;
- string value;
- regkey = Registry.LocalMachine.OpenSubKey(ServiceTesCurrentVersionRegistryKey);
- if (regkey == null)
- {
- //try 64 bit
- regkey = Registry.LocalMachine.OpenSubKey(ServiceTesCurrentVersionWOW64RegistryKey);
- }
-
- if (regkey != null)
- {
- value = (string) regkey.GetValue(InstalltionFolderValue);
- if (!string.IsNullOrEmpty(value))
- {
- return true;
- }
- }
- return false;
- }
-
- private static string GetRootFromEnvironment()
- {
- string qtpRoot = Environment.GetEnvironmentVariable(QTP_ROOT_ENV_VAR_NAME, EnvironmentVariableTarget.Process);
-
- if (string.IsNullOrEmpty(qtpRoot))
- {
- qtpRoot = Environment.GetEnvironmentVariable(QTP_ROOT_ENV_VAR_NAME, EnvironmentVariableTarget.User);
-
- if (string.IsNullOrEmpty(qtpRoot))
- {
- qtpRoot = Environment.GetEnvironmentVariable(QTP_ROOT_ENV_VAR_NAME,
- EnvironmentVariableTarget.Machine);
-
- if (string.IsNullOrEmpty(qtpRoot))
- {
- qtpRoot = Environment.CurrentDirectory;
- }
- }
- }
-
- return qtpRoot;
- }
-
- public static string GetSTInstallPath()
- {
- string ret = String.Empty;
- var regKey = Registry.LocalMachine.OpenSubKey(ServiceTesCurrentVersionRegistryKey);
- if (regKey != null)
- {
- var val = regKey.GetValue(InstalltionFolderValue);
- if (null != val)
- {
- ret = val.ToString();
- }
- }
- else
- {
- regKey = Registry.LocalMachine.OpenSubKey(ServiceTesCurrentVersionWOW64RegistryKey);
- if (regKey != null)
- {
- var val = regKey.GetValue(InstalltionFolderValue);
- if (null != val)
- {
- ret = val.ToString();
- }
- }
- else
- {
- ret = GetRootDirectoryPath() ?? string.Empty;
- }
- }
-
- if (!String.IsNullOrEmpty(ret))
- {
- ret = ret.EndsWith("\\") ? ret : (ret + "\\");
- if (ret.EndsWith("\\bin\\"))
- {
- int endIndex = ret.LastIndexOf("\\bin\\");
- if (endIndex != -1)
- {
- ret = ret.Substring(0, endIndex) + "\\";
- }
- }
- }
-
- return ret;
- }
-
- public static string getLRInstallPath()
- {
- string installPath = null;
- System.Collections.IDictionary envVariables = Environment.GetEnvironmentVariables();
-
- //try to find LoadRunner install path in environment vars
- foreach (string variable in LoadRunnerENVVariables)
- {
- if (envVariables.Contains(variable))
- return envVariables[variable] as string;
- }
-
- //Fallback to registry
- //try 32 bit
- RegistryKey regkey = Registry.LocalMachine.OpenSubKey(LoadRunnerRegistryKey);
-
- if (regkey == null)
- {
- //try 64-bit
- regkey = Registry.LocalMachine.OpenSubKey(LoadRunner64RegisryKey);
-
- }
-
- if (regkey != null)
- {
-
- //LoadRunner Exists. check if Controller is installed (not SA version)
- regkey = regkey.OpenSubKey(LoadRunnerControllerDirRegistryKey);
- if (regkey != null)
- return regkey.GetValue("Controller").ToString();
-
- }
-
- return installPath;
- }
-
- public static List GetTestsLocations(string baseDir)
- {
- var testsLocations = new List();
- if (string.IsNullOrEmpty(baseDir) || !Directory.Exists(baseDir))
- {
- return testsLocations;
- }
-
- WalkDirectoryTree(new DirectoryInfo(baseDir), ref testsLocations);
- return testsLocations;
- }
-
- public static TestType GetTestType(string path)
- {
-
-
- if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
- {
-//ST and QTP uses folder as test locations
- var stFiles = Directory.GetFiles(path,
- @"*.st?",
- SearchOption.TopDirectoryOnly);
-
- return (stFiles.Count() > 0) ? TestType.ST : TestType.QTP;
- }
- else //not directory
- {
-//loadrunner is a path to file...
- return TestType.LoadRunner;
- }
- }
-
- public static bool IsDirectory(string path)
- {
- var fa = File.GetAttributes(path);
- var isDirectory = false;
- if ((fa & FileAttributes.Directory) != 0)
- {
- isDirectory = true;
- }
- return isDirectory;
- }
-
- static void WalkDirectoryTree(System.IO.DirectoryInfo root, ref List results)
- {
- System.IO.FileInfo[] files = null;
- System.IO.DirectoryInfo[] subDirs = null;
-
- // First, process all the files directly under this folder
- try
- {
-
- files = root.GetFiles("*" + STFileExtention);
- files = files.Union(root.GetFiles("*" + QTPFileExtention)).ToArray();
- files = files.Union(root.GetFiles("*" + LoadRunnerFileExtention)).ToArray();
- }
- catch (Exception e)
- {
- // This code just writes out the message and continues to recurse.
- // You may decide to do something different here. For example, you
- // can try to elevate your privileges and access the file again.
- //log.Add(e.Message);
- }
-
- if (files != null)
- {
- foreach (System.IO.FileInfo fi in files)
- {
- if (fi.Extension == LoadRunnerFileExtention)
- results.Add(fi.FullName);
- else
- results.Add(fi.Directory.FullName);
-
- // In this example, we only access the existing FileInfo object. If we
- // want to open, delete or modify the file, then
- // a try-catch block is required here to handle the case
- // where the file has been deleted since the call to TraverseTree().
- }
-
- // Now find all the subdirectories under this directory.
- subDirs = root.GetDirectories();
-
- foreach (System.IO.DirectoryInfo dirInfo in subDirs)
- {
- // Recursive call for each subdirectory.
- WalkDirectoryTree(dirInfo, ref results);
- }
- }
- }
-
- public static string GetTempDir()
- {
- string baseTemp = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
-
- string dirName = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 6);
- string tempDirPath = Path.Combine(baseTemp, dirName);
-
- return tempDirPath;
- }
-
- public static string CreateTempDir()
- {
- string tempDirPath = GetTempDir();
-
- Directory.CreateDirectory(tempDirPath);
-
- return tempDirPath;
- }
-
- public static bool IsNetworkPath(String path)
- {
- if (path.StartsWith(@"\\"))
- return true;
- var dir = new DirectoryInfo(path);
- var drive = new DriveInfo(dir.Root.ToString());
- return drive.DriveType == DriveType.Network;
- }
-
- public static bool IsLeanFTRunning()
- {
- bool bRet = false;
- Process[] procArray = Process.GetProcessesByName("LFTRuntime");
- // Hardcoded temporarily since LeanFT does not store the process name anywhere
- if (procArray.Length != 0)
- {
- bRet = true;
- }
- return bRet;
- }
-
- public static bool IsSprinterRunning()
- {
- RegistryKey key =
- Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Hewlett-Packard\\Manual Runner\\Process");
- if (key == null)
- return false;
-
- var arrayName = key.GetSubKeyNames();
- if (arrayName.Length == 0)
- return false;
- foreach (string s in arrayName)
- {
- Process[] sprinterProcArray = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(s));
- if (sprinterProcArray.Length != 0)
- return true;
-
- }
- return false;
- }
-
- public static bool CanUftProcessStart(out string reason)
- {
- //Close UFT when some of the Sprinter processes is running
- if (IsSprinterRunning())
- {
- reason = Resources.UFT_Sprinter_Running;
- return false;
- }
-
- //Close UFT when LeanFT engine is running
- if (IsLeanFTRunning())
- {
- reason = Resources.UFT_LeanFT_Running;
- return false;
- }
- reason = string.Empty;
- return true;
- }
-
- #region Report Related
-
- public static string GetUftViewerInstallPath()
- {
- string ret = String.Empty;
- var regKey = Registry.LocalMachine.OpenSubKey(UftViewerInstalltionFolderRegistryKey) ??
- Registry.LocalMachine.OpenSubKey(UftViewerInstalltionFolderRegistryKey64Bit);
-
- if (regKey != null)
- {
- var val = regKey.GetValue("InstallLocation");
- if (null != val)
- {
- ret = val.ToString();
- }
- }
-
- if (!String.IsNullOrEmpty(ret))
- {
- ret = ret.EndsWith("\\") ? ret : (ret + "\\");
- }
-
- return ret;
- }
-
- public static string GetLastRunFromReport(string reportPath)
- {
- if (!Directory.Exists(reportPath))
- return null;
- string resultsFileFullPath = reportPath + @"\" + ResultsFileName;
- if (!File.Exists(resultsFileFullPath))
- return null;
- try
- {
- var root = XElement.Load(resultsFileFullPath);
-
- var element = root.XPathSelectElement("//Doc/Summary");
- var lastStartRun = element.Attribute("sTime");
- return lastStartRun.Value.Split(new char[] {' '})[0];
-
- }
- catch (Exception)
- {
- return null;
- }
- }
-
- public static TestState GetTestStateFromUFTReport(TestRunResults runDesc, string[] resultFiles)
- {
- try
- {
- TestState finalState = TestState.Unknown;
-
- foreach (string resultsFileFullPath in resultFiles)
- {
- finalState = TestState.Unknown;
- string desc = "";
- TestState state = GetStateFromUFTResultsFile(resultsFileFullPath, out desc);
- if (finalState == TestState.Unknown || finalState == TestState.Passed)
- {
- finalState = state;
- if (!string.IsNullOrWhiteSpace(desc))
- {
- if (finalState == TestState.Error)
- {
- runDesc.ErrorDesc = desc;
- }
- if (finalState == TestState.Failed)
- {
- runDesc.FailureDesc = desc;
- }
- }
- }
- }
-
- if (finalState == TestState.Unknown)
- finalState = TestState.Passed;
-
- if (finalState == TestState.Failed && string.IsNullOrWhiteSpace(runDesc.FailureDesc))
- runDesc.FailureDesc = "Test failed";
-
- runDesc.TestState = finalState;
- return runDesc.TestState;
- }
- catch (Exception e)
- {
- return TestState.Unknown;
- }
-
- }
-
-
- public static TestState GetTestStateFromLRReport(TestRunResults runDesc, string[] resultFiles)
- {
-
- foreach (string resultFileFullPath in resultFiles)
- {
- string desc = "";
- runDesc.TestState = GetTestStateFromLRReport(resultFileFullPath, out desc);
- if (runDesc.TestState == TestState.Failed)
- {
- runDesc.ErrorDesc = desc;
- break;
- }
- }
-
- return runDesc.TestState;
- }
-
-
- public static TestState GetTestStateFromReport(TestRunResults runDesc)
- {
- try
- {
- if (!Directory.Exists(runDesc.ReportLocation))
- {
- runDesc.ErrorDesc = string.Format(Resources.DirectoryNotExistError, runDesc.ReportLocation);
-
- runDesc.TestState = TestState.Error;
- return runDesc.TestState;
- }
- //if there is Result.xml -> UFT
- //if there is sla.xml file -> LR
-
- string[] resultFiles = Directory.GetFiles(runDesc.ReportLocation, "Results.xml",
- SearchOption.TopDirectoryOnly);
- if (resultFiles.Length == 0)
- resultFiles = Directory.GetFiles(runDesc.ReportLocation, "run_results.xml",
- SearchOption.TopDirectoryOnly);
- //resultFiles = Directory.GetFiles(Path.Combine(runDesc.ReportLocation, "Report"), "Results.xml", SearchOption.TopDirectoryOnly);
-
- if (resultFiles != null && resultFiles.Length > 0)
- return GetTestStateFromUFTReport(runDesc, resultFiles);
-
- resultFiles = Directory.GetFiles(runDesc.ReportLocation, "SLA.xml", SearchOption.AllDirectories);
-
- if (resultFiles != null && resultFiles.Length > 0)
- {
- return GetTestStateFromLRReport(runDesc, resultFiles);
- }
-
- //no LR or UFT => error
- runDesc.ErrorDesc = string.Format("no results file found for " + runDesc.TestName);
- runDesc.TestState = TestState.Error;
- return runDesc.TestState;
- }
- catch (Exception e)
- {
- return TestState.Unknown;
- }
-
- }
-
-
- private static TestState GetTestStateFromLRReport(string resultFileFullPath, out string desc)
- {
- desc = "";
-
- XmlDocument xdoc = new XmlDocument();
- xdoc.Load(resultFileFullPath);
- return checkNodeStatus(xdoc.DocumentElement, out desc);
- }
-
- private static TestState checkNodeStatus(XmlNode node, out string desc)
- {
- desc = "";
- if (node == null)
- return TestState.Failed;
-
- if (node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text)
- {
- if (node.InnerText.ToLowerInvariant() == "failed")
- {
- if (node.Attributes != null && node.Attributes["FullName"] != null)
- {
- desc = string.Format(Resources.LrSLARuleFailed, node.Attributes["FullName"].Value,
- node.Attributes["GoalValue"].Value, node.Attributes["ActualValue"].Value);
- ConsoleWriter.WriteLine(desc);
- }
- return TestState.Failed;
- }
- else
- {
- return TestState.Passed;
- }
- }
- //node has children
- foreach (XmlNode childNode in node.ChildNodes)
- {
- TestState res = checkNodeStatus(childNode, out desc);
- if (res == TestState.Failed)
- {
- if (string.IsNullOrEmpty(desc) && node.Attributes != null && node.Attributes["FullName"] != null)
- {
- desc = string.Format(Resources.LrSLARuleFailed, node.Attributes["FullName"].Value,
- node.Attributes["GoalValue"].Value, node.Attributes["ActualValue"].Value);
- ConsoleWriter.WriteLine(desc);
- }
- return TestState.Failed;
- }
- }
- return TestState.Passed;
- }
-
-
- private static TestState GetStateFromUFTResultsFile(string resultsFileFullPath, out string desc)
- {
- TestState finalState = TestState.Unknown;
- desc = "";
- var status = "";
- var doc = new XmlDocument {PreserveWhitespace = true};
- doc.Load(resultsFileFullPath);
- string strFileName = Path.GetFileName(resultsFileFullPath);
- if (strFileName.Equals("run_results.xml"))
- {
- XmlNodeList rNodeList = doc.SelectNodes("/Results/ReportNode/Data");
- if (rNodeList == null)
- {
- desc = string.Format(Resources.XmlNodeNotExistError, "/Results/ReportNode/Data");
- finalState = TestState.Error;
- }
-
- var node = rNodeList.Item(0);
- XmlNode resultNode = ((XmlElement) node).GetElementsByTagName("Result").Item(0);
-
- status = resultNode.InnerText;
-
- }
- else
- {
- var testStatusPathNode = doc.SelectSingleNode("//Report/Doc/NodeArgs");
- if (testStatusPathNode == null)
- {
- desc = string.Format(Resources.XmlNodeNotExistError, "//Report/Doc/NodeArgs");
- finalState = TestState.Error;
- }
-
- if (!testStatusPathNode.Attributes["status"].Specified)
- finalState = TestState.Unknown;
-
- status = testStatusPathNode.Attributes["status"].Value;
- }
-
- var result = (TestResult) Enum.Parse(typeof(TestResult), status);
- if (result == TestResult.Passed || result == TestResult.Done)
- {
- finalState = TestState.Passed;
- }
- else if (result == TestResult.Warning)
- {
- finalState = TestState.Warning;
- }
- else
- {
- finalState = TestState.Failed;
- }
-
- return finalState;
- }
-
- public static string GetUnknownStateReason(string reportPath)
- {
- if (!Directory.Exists(reportPath))
- {
- return string.Format("Directory '{0}' doesn't exist", reportPath);
- }
- string resultsFileFullPath = reportPath + @"\" + ResultsFileName;
- if (!File.Exists(resultsFileFullPath))
- {
- return string.Format("Could not find results file '{0}'", resultsFileFullPath);
- }
-
- var doc = new XmlDocument {PreserveWhitespace = true};
- doc.Load(resultsFileFullPath);
- var testStatusPathNode = doc.SelectSingleNode("//Report/Doc/NodeArgs");
- if (testStatusPathNode == null)
- {
- return string.Format("XML node '{0}' could not be found", "//Report/Doc/NodeArgs");
- }
- return string.Empty;
- }
-
- public static void OpenReport(string reportDirectory, ref string optionalReportViewerPath)
- {
- Process p = null;
- try
- {
- string viewerPath = optionalReportViewerPath;
- string reportPath = reportDirectory;
- string resultsFilePath = reportPath + "\\" + ResultsFileName;
-
- if (!File.Exists(resultsFilePath))
- {
- return;
- }
-
- var si = new ProcessStartInfo();
- if (string.IsNullOrEmpty(viewerPath))
- {
- viewerPath = GetUftViewerInstallPath();
- optionalReportViewerPath = viewerPath;
- }
- si.Arguments = " -r \"" + reportPath + "\"";
-
- si.FileName = Path.Combine(viewerPath, QTPReportProcessPath);
- si.WorkingDirectory = Path.Combine(viewerPath, @"bin" + @"\");
-
- p = Process.Start(si);
- if (p != null)
- {
- }
- return;
- }
- catch (Exception ex)
- {
- }
- finally
- {
- if (p != null)
- {
- p.Close();
- }
- }
- return;
- }
-
- #endregion
-
- #region Export Related
-
- ///
- /// Copy directories from source to target
- ///
- /// full path source directory
- /// full path target directory
- /// if true, all subdirectories and contents will be copied
- /// if true, the source directory will be created too
- public static void CopyDirectories(string sourceDir, string targetDir,
- bool includeSubDirectories = false, bool includeRoot = false)
- {
- var source = new DirectoryInfo(sourceDir);
- var target = new DirectoryInfo(targetDir);
- DirectoryInfo workingTarget = target;
-
- if (includeRoot)
- workingTarget = Directory.CreateDirectory(target.FullName);
-
- CopyContents(source, workingTarget, includeSubDirectories);
- }
-
- private static void CopyContents(DirectoryInfo source, DirectoryInfo target, bool includeSubDirectories)
- {
- if (!Directory.Exists(target.FullName))
- {
- Directory.CreateDirectory(target.FullName);
- }
-
-
- foreach (FileInfo fi in source.GetFiles())
- {
- string targetFile = Path.Combine(target.ToString(), fi.Name);
-
- fi.CopyTo(targetFile, true);
- }
-
- if (includeSubDirectories)
- {
- DirectoryInfo[] subDirectories = source.GetDirectories();
- foreach (DirectoryInfo diSourceSubDir in subDirectories)
- {
- DirectoryInfo nextTargetSubDir =
- target.CreateSubdirectory(diSourceSubDir.Name);
- CopyContents(diSourceSubDir, nextTargetSubDir, true);
- }
- }
- }
-
- public static void CopyFilesFromFolder(string sourceFolder, IEnumerable fileNames, string targetFolder)
- {
- foreach (var fileName in fileNames)
- {
- var sourceFullPath = Path.Combine(sourceFolder, fileName);
- var targetFullPath = Path.Combine(targetFolder, fileName);
- File.Copy(sourceFullPath, targetFullPath, true);
- }
- }
-
- ///
- /// Create html file according to a matching xml
- ///
- /// the values xml
- /// the xml transformation file
- /// the full file name - where to save the product
- public static void CreateHtmlFromXslt(string xmlPath, string xslPath, string targetFile)
- {
- var xslTransform = new XslCompiledTransform();
- //xslTransform.Load(xslPath);
- xslTransform.Load(xslPath, new XsltSettings(false, true), null);
-
- var sb = new StringBuilder();
- var sw = new StringWriter(sb);
- var xmlWriter = new XhtmlTextWriter(sw);
- xslTransform.Transform(xmlPath, null, xmlWriter);
-
-
- File.WriteAllText(targetFile, sb.ToString());
- }
-
- #endregion
-
-
- }
-
- public class Stopper {
- private readonly int _milliSeconds;
-
-
- public Stopper(int milliSeconds)
- {
- this._milliSeconds = milliSeconds;
- }
-
-
- ///
- /// Creates timer in seconds to replace thread.sleep due to ui freezes in jenkins.
- /// Should be replaced in the future with ASync tasks
- ///
- public void Start()
- {
- if (_milliSeconds < 1)
- {
- return;
- }
- DateTime desired = DateTime.Now.AddMilliseconds(_milliSeconds);
- var a = 0;
- while (DateTime.Now < desired)
- {
- a += 1;
- }
- }
- }
-
-}
diff --git a/HpToolsLauncher/HpToolsLauncher.csproj b/HpToolsLauncher/HpToolsLauncher.csproj
index bbb7728e8d..8114e537f6 100644
--- a/HpToolsLauncher/HpToolsLauncher.csproj
+++ b/HpToolsLauncher/HpToolsLauncher.csproj
@@ -1,183 +1,206 @@
-
-
-
- Debug
- x86
- 8.0.30703
- 2.0
- {11BC441C-87A6-41B9-82AE-1F2F606AF45E}
- Exe
- Properties
- HpToolsLauncher
- HpToolsLauncher
- v4.0
-
-
- 512
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
-
- x86
- true
- full
- false
- ..\src\main\resources\
- DEBUG;TRACE
- prompt
- 4
-
-
- x86
- pdbonly
- false
- ..\src\main\resources\
- TRACE
- prompt
- 4
- false
-
-
- true
-
-
- HpToolsLauncher.Program
-
-
-
- externals\interop.OTAClient.dll
- True
-
-
- externals\Interop.Wlrun.dll
- False
-
-
- externals\QTObjectModelLib.dll
- True
-
-
-
-
- False
-
-
-
-
- False
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- junit.xsd
- code
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
- Designer
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
- Designer
-
-
-
-
-
-
-
- False
- Microsoft .NET Framework 4 %28x86 and x64%29
- true
-
-
- False
- .NET Framework 3.5 SP1
- false
-
-
- False
- Windows Installer 4.5
- true
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {11BC441C-87A6-41B9-82AE-1F2F606AF45E}
+ Exe
+ Properties
+ HpToolsLauncher
+ HpToolsLauncher
+ v4.0
+
+
+ 512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ x86
+ true
+ full
+ false
+ ..\src\main\resources\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ ..\src\main\resources\
+ TRACE
+ prompt
+ 4
+ false
+ 5
+
+
+ true
+
+
+ HpToolsLauncher.Program
+
+
+
+ externals\interop.OTAClient.dll
+ True
+
+
+ externals\Interop.Wlrun.dll
+ False
+
+
+
+ externals\QTObjectModelLib.dll
+ True
+
+
+
+
+ False
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ junit.xsd
+ code
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Designer
+
+
+ Designer
+
+
+
+
+ ResXFileCodeGenerator
+ Designer
+ Resources.Designer.cs
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Windows Installer 4.5
+ true
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HpToolsLauncher/HpToolsLauncher.csproj.DotSettings b/HpToolsLauncher/HpToolsLauncher.csproj.DotSettings
new file mode 100644
index 0000000000..662f95686e
--- /dev/null
+++ b/HpToolsLauncher/HpToolsLauncher.csproj.DotSettings
@@ -0,0 +1,2 @@
+
+ CSharp50
\ No newline at end of file
diff --git a/HpToolsLauncher/HpToolsLauncher.sln b/HpToolsLauncher/HpToolsLauncher.sln
index 908e40a21c..7be42d16c7 100644
--- a/HpToolsLauncher/HpToolsLauncher.sln
+++ b/HpToolsLauncher/HpToolsLauncher.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2018
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HpToolsLauncher", "HpToolsLauncher.csproj", "{11BC441C-87A6-41B9-82AE-1F2F606AF45E}"
EndProject
@@ -26,56 +26,71 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Debug|Any CPU.ActiveCfg = Debug|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Debug|x64.ActiveCfg = Debug|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Debug|x86.ActiveCfg = Debug|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Debug|x86.Build.0 = Debug|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Release|Any CPU.ActiveCfg = Release|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Release|Mixed Platforms.ActiveCfg = Release|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Release|Mixed Platforms.Build.0 = Release|x86
+ {11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Release|x64.ActiveCfg = Release|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Release|x86.ActiveCfg = Release|x86
{11BC441C-87A6-41B9-82AE-1F2F606AF45E}.Release|x86.Build.0 = Release|x86
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|x64.Build.0 = Debug|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Debug|x86.ActiveCfg = Debug|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|Any CPU.Build.0 = Release|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|x64.ActiveCfg = Release|Any CPU
+ {A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|x64.Build.0 = Release|Any CPU
{A1DAB8E0-DAB0-40F8-AA44-B5B4C2913301}.Release|x86.ActiveCfg = Release|Any CPU
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Debug|Any CPU.ActiveCfg = Debug|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Debug|x64.ActiveCfg = Debug|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Debug|x86.ActiveCfg = Debug|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Debug|x86.Build.0 = Debug|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Release|Any CPU.ActiveCfg = Release|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Release|Mixed Platforms.ActiveCfg = Release|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Release|Mixed Platforms.Build.0 = Release|x86
+ {49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Release|x64.ActiveCfg = Release|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Release|x86.ActiveCfg = Release|x86
{49496A5D-3FD7-437E-9649-1E2CE2BA6838}.Release|x86.Build.0 = Release|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Debug|Any CPU.ActiveCfg = Debug|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {2DFF94C6-A748-4749-B716-6D8DFB936D43}.Debug|x64.ActiveCfg = Debug|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Debug|x86.ActiveCfg = Debug|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Debug|x86.Build.0 = Debug|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Release|Any CPU.ActiveCfg = Release|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Release|Mixed Platforms.ActiveCfg = Release|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Release|Mixed Platforms.Build.0 = Release|x86
+ {2DFF94C6-A748-4749-B716-6D8DFB936D43}.Release|x64.ActiveCfg = Release|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Release|x86.ActiveCfg = Release|x86
{2DFF94C6-A748-4749-B716-6D8DFB936D43}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7A0855DE-8F59-478E-BADC-0559F9C32FEF}
+ EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = HpToolsLauncher1.vsmdi
EndGlobalSection
diff --git a/HpToolsLauncher/HpToolsLauncherTests/HpToolsLauncherTests.csproj b/HpToolsLauncher/HpToolsLauncherTests/HpToolsLauncherTests.csproj
index 62da9171d6..c59248b238 100644
--- a/HpToolsLauncher/HpToolsLauncherTests/HpToolsLauncherTests.csproj
+++ b/HpToolsLauncher/HpToolsLauncherTests/HpToolsLauncherTests.csproj
@@ -37,7 +37,10 @@
-
+
+ False
+ ..\externals\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
+
3.5
@@ -50,6 +53,7 @@
+
diff --git a/HpToolsLauncher/HpToolsLauncherTests/ParallelRunnerEnvironmentUtilTests.cs b/HpToolsLauncher/HpToolsLauncherTests/ParallelRunnerEnvironmentUtilTests.cs
new file mode 100644
index 0000000000..062ec91e17
--- /dev/null
+++ b/HpToolsLauncher/HpToolsLauncherTests/ParallelRunnerEnvironmentUtilTests.cs
@@ -0,0 +1,445 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher;
+using HpToolsLauncher.ParallelRunner;
+using HpToolsLauncher.ParallelTestRunConfiguraion;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Collections.Generic;
+
+namespace HpToolsLauncherTests
+{
+ [TestClass]
+ public class ParallelRunnerEnvironmentUtilTests
+ {
+ private static readonly string MobileEnvironment = "osType : Android,osVersion : 4.4.2,manufacturerAndModel : \"samsung GT-I9515\"";
+ private static readonly string WebEnvironment = "browser : chrome";
+
+ [TestMethod]
+ public void GetEnvironmentPropertiesTest_ValidEnvironment_ReturnsExpectedProperties()
+ {
+ Dictionary properties = ParallelRunnerEnvironmentUtil.
+ GetEnvironmentProperties(MobileEnvironment);
+
+ // there should be 3 properties
+ Assert.AreEqual(properties.Count, 3);
+
+ // check if all the properties are present
+ Assert.IsTrue(properties.ContainsKey("ostype"));
+ Assert.IsTrue(properties.ContainsKey("osversion"));
+ Assert.IsTrue(properties.ContainsKey("manufacturerandmodel"));
+
+ Assert.AreEqual("android", properties["ostype"]);
+ Assert.AreEqual("4.4.2", properties["osversion"]);
+ Assert.AreEqual("\"samsung gt-i9515\"", properties["manufacturerandmodel"]);
+ }
+
+ [TestMethod]
+ public void GetEnvironmentPropertiesTest_NoValueEnvironment_ReturnsEmptyDictionary()
+ {
+ string environment = "deviceId: ";
+
+ Dictionary properties = ParallelRunnerEnvironmentUtil.
+ GetEnvironmentProperties(environment);
+
+ // there should be 0 properties
+ Assert.AreEqual(0, properties.Count);
+ }
+
+ [TestMethod]
+ public void GetEnvironmentPropertiesTest_NoKeyEnvironment_ReturnsEmptyDictionary()
+ {
+ string environment = ": Android ";
+
+ Dictionary properties = ParallelRunnerEnvironmentUtil.
+ GetEnvironmentProperties(environment);
+
+ // there should be 0 properties
+ Assert.AreEqual(0, properties.Count);
+ }
+
+ [TestMethod]
+ public void GetEnvironmentPropertiesTest_NullEnvironment_ReturnsEmptyDictionary()
+ {
+ string environment = null;
+
+ Dictionary properties = ParallelRunnerEnvironmentUtil.
+ GetEnvironmentProperties(environment);
+
+ // there should be 0 properties
+ Assert.AreEqual(0, properties.Count);
+ }
+
+ [TestMethod]
+ public void GetEnvironmentPropertiesTest_EmptyEnvironment_ReturnsEmptyDictionary()
+ {
+ string environment = "";
+
+ Dictionary properties = ParallelRunnerEnvironmentUtil.
+ GetEnvironmentProperties(environment);
+
+ // there should be 0 properties
+ Assert.AreEqual(0, properties.Count);
+ }
+
+ [TestMethod]
+ public void ParseMobileEnvironmentTest_ValidMobileEnvironment_ReturnsExpectedMobileEnvironment()
+ {
+ MobileEnvironment mobileEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseMobileEnvironment(MobileEnvironment);
+
+ // function suceeded
+ Assert.IsNotNull(mobileEnvironment);
+
+ // propertes should be non-null
+ Assert.IsNotNull(mobileEnvironment.device);
+ Assert.IsNotNull(mobileEnvironment.lab);
+
+ Device device = mobileEnvironment.device;
+
+ // not present in the string
+ Assert.IsNull(device.deviceID);
+
+ // only the manufacturer should be filled
+ Assert.IsNull(device.model);
+
+ // must be present
+ Assert.IsNotNull(device.manufacturer);
+ Assert.IsNotNull(device.osType);
+ Assert.IsNotNull(device.osVersion);
+
+ Assert.AreEqual("android", device.osType);
+ Assert.AreEqual("4.4.2", device.osVersion);
+ Assert.AreEqual("\"samsung gt-i9515\"", device.manufacturer);
+ }
+
+ [TestMethod]
+ public void ParseMobileEnvironmentTest_InvalidKeyMobileEnvironment_ReturnsNull()
+ {
+ string invalidEnvironment = "invalid: android";
+
+ MobileEnvironment mobileEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseMobileEnvironment(invalidEnvironment);
+
+ // function suceeded
+ Assert.IsNull(mobileEnvironment);
+ }
+
+ [TestMethod]
+ public void ParseMobileEnvironmentTest_NullMobileEnvironment_ReturnsNull()
+ {
+ MobileEnvironment mobileEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseMobileEnvironment(null);
+
+ // function suceeded
+ Assert.IsNull(mobileEnvironment);
+ }
+
+ [TestMethod]
+ public void ParseMobileEnvironmentTest_EmptyMobileEnvironment_ReturnsNull()
+ {
+ MobileEnvironment mobileEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseMobileEnvironment("");
+
+ // function suceeded
+ Assert.IsNull(mobileEnvironment);
+ }
+
+ [TestMethod]
+ public void ParseWebEnvironmentTest_ValidWebEnvironment_ReturnsExpectedWebEnvironment()
+ {
+ WebEnvironment webEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseWebEnvironment(WebEnvironment);
+
+ // function suceeded
+ Assert.IsNotNull(webEnvironment);
+
+ // browser should be present
+ Assert.IsNotNull(webEnvironment.browser);
+
+ // local browser lab should be present
+ Assert.IsNotNull(webEnvironment.lab);
+
+ // browser should be 'chrome'
+ Assert.AreEqual("chrome", webEnvironment.browser);
+
+ Assert.AreEqual("LocalBrowser", webEnvironment.lab);
+ }
+
+ [TestMethod]
+ public void ParseWebEnvironmentTest_InvalidKeyWebEnvironment_ReturnsExpectedWebEnvironment()
+ {
+ string invalidKey = "brows: Chrome";
+
+ WebEnvironment webEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseWebEnvironment(invalidKey);
+
+ // function suceeded
+ Assert.IsNull(webEnvironment);
+ }
+
+ [TestMethod]
+ public void ParseWebEnvironmentTest_NullWebEnvironment_ReturnsExpectedWebEnvironment()
+ {
+ WebEnvironment webEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseWebEnvironment(null);
+
+ // function suceeded
+ Assert.IsNull(webEnvironment);
+ }
+
+ [TestMethod]
+ public void ParseWebEnvironmentTest_EmptyWebEnvironment_ReturnsExpectedWebEnvironment()
+ {
+ WebEnvironment webEnvironment = ParallelRunnerEnvironmentUtil.
+ ParseWebEnvironment("");
+
+ // function suceeded
+ Assert.IsNull(webEnvironment);
+ }
+
+ [TestMethod]
+ public void GetEvironmentTypeTest_ValidMobileEnvironment_ReturnMobileEnvironment()
+ {
+ EnvironmentType type =
+ ParallelRunnerEnvironmentUtil.GetEnvironmentType(MobileEnvironment);
+
+ Assert.AreEqual(EnvironmentType.MOBILE, type);
+ }
+
+ [TestMethod]
+ public void GetEvironmentTypeTest_ValidWebEnvironment_ReturnWebEnvironment()
+ {
+ EnvironmentType type =
+ ParallelRunnerEnvironmentUtil.GetEnvironmentType(WebEnvironment);
+
+ Assert.AreEqual(EnvironmentType.WEB, type);
+ }
+
+ [TestMethod]
+ public void GetEvironmentTypeTest_NullEnvironment_ReturnUnknownEnvironment()
+ {
+ EnvironmentType type =
+ ParallelRunnerEnvironmentUtil.GetEnvironmentType(null);
+
+ Assert.AreEqual(EnvironmentType.UNKNOWN, type);
+ }
+
+ [TestMethod]
+ public void GetEvironmentTypeTest_EnvironmentEmpty_ReturnUnknownEnvironment()
+ {
+ EnvironmentType type =
+ ParallelRunnerEnvironmentUtil.GetEnvironmentType("");
+
+ Assert.AreEqual(EnvironmentType.UNKNOWN, type);
+ }
+
+ [TestMethod]
+ public void ParseEnvironmentStringsTest_ValidEnvironments_ReturnValidRunConfiguration()
+ {
+ IList environments = new List{
+ MobileEnvironment,
+ WebEnvironment
+ };
+
+ TestInfo mockTesInfo = new TestInfo("c:\tests\test1",
+ "c:\tests\test1", "1", "Test1");
+
+ mockTesInfo.ReportPath = mockTesInfo.TestPath;
+
+ ParallelTestRunConfiguration configuration = null;
+
+ try
+ {
+ configuration = ParallelRunnerEnvironmentUtil.
+ ParseEnvironmentStrings(environments, mockTesInfo);
+ }
+ catch (ParallelRunnerConfigurationException)
+ {
+ // since the environments are valid there should be no exception
+ Assert.Fail();
+ }
+
+ // report paths should be equal
+ Assert.AreEqual(mockTesInfo.ReportPath, configuration.reportPath);
+
+ // we have two parallel runs
+ // one for web and one for mobile
+ Assert.AreEqual(2, configuration.parallelRuns.Length);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(ParallelRunnerConfigurationException),
+ "Invalid environments were allowed!")]
+ public void ParseEnvironmentStringsTest_InvalidEnvironments_ThrowException()
+ {
+ // the list of supported browsers
+ IList environments = new List{
+ "browser: unknown",
+ };
+
+ TestInfo mockTesInfo = new TestInfo("c:\tests\test1",
+ "c:\tests\test1", "1", "Test1");
+
+ mockTesInfo.ReportPath = mockTesInfo.TestPath;
+
+ ParallelTestRunConfiguration configuration = ParallelRunnerEnvironmentUtil.
+ ParseEnvironmentStrings(environments, mockTesInfo);
+ }
+
+ [TestMethod]
+ public void ParseEnvironmentStringsTest_UnknownEnvironments_ReturnEmptyConfiguration()
+ {
+ // the list of supported browsers
+ IList environments = new List{
+ "test: ",
+ };
+
+ TestInfo mockTesInfo = new TestInfo("c:\tests\test1",
+ "c:\tests\test1", "1", "Test1");
+
+ mockTesInfo.ReportPath = mockTesInfo.TestPath;
+ ParallelTestRunConfiguration configuration = null;
+
+ try
+ {
+ configuration = ParallelRunnerEnvironmentUtil.
+ ParseEnvironmentStrings(environments, mockTesInfo);
+ }
+ catch (ParallelRunnerConfigurationException)
+ {
+ Assert.Fail();
+ }
+
+ Assert.AreEqual(0, configuration.parallelRuns.Length);
+ }
+
+ [TestMethod]
+ public void GetMCProxySettingsTest_ValidMCSettings_ReturnsExpectedProxySettings()
+ {
+ McConnectionInfo mcConnectionInfo = new McConnectionInfo();
+ mcConnectionInfo.ProxyAddress = "192.168.1.1";
+ mcConnectionInfo.ProxyPort = 8080;
+ mcConnectionInfo.UseProxyAuth = true;
+ mcConnectionInfo.ProxyUserName = "test";
+ mcConnectionInfo.ProxyPassword = "test";
+
+ ProxySettings settings = ParallelRunnerEnvironmentUtil.GetMCProxySettings(mcConnectionInfo);
+
+ Assert.IsNotNull(settings);
+ Assert.IsNotNull(settings.authentication);
+
+ Assert.AreEqual(mcConnectionInfo.ProxyUserName, settings.authentication.username);
+ Assert.AreEqual(mcConnectionInfo.ProxyAddress, settings.hostname);
+ Assert.AreEqual(mcConnectionInfo.ProxyPort, settings.port);
+ }
+
+ [TestMethod]
+ public void GetMCProxySettingsTest_InvalidMCSettings_ReturnsNullProxySettings()
+ {
+ McConnectionInfo mcConnectionInfo = new McConnectionInfo();
+
+ ProxySettings settings = ParallelRunnerEnvironmentUtil.GetMCProxySettings(mcConnectionInfo);
+
+ Assert.IsNull(settings);
+ }
+
+ [TestMethod]
+ public void ParseMCSettingsTest_ValidMCSettingsSSL_ReturnsExpectedSettings()
+ {
+ McConnectionInfo mcConnectionInfo = new McConnectionInfo();
+ mcConnectionInfo.HostAddress = "192.168.1.1";
+ mcConnectionInfo.HostPort = "8080";
+ mcConnectionInfo.UserName = "test";
+ mcConnectionInfo.Password = "test";
+ mcConnectionInfo.UseSSL = true;
+
+ UFTSettings settings = ParallelRunnerEnvironmentUtil.ParseMCSettings(mcConnectionInfo);
+
+ Assert.IsNotNull(settings);
+ Assert.IsNotNull(settings.mc);
+
+ Assert.AreEqual(mcConnectionInfo.HostAddress, settings.mc.hostname);
+ Assert.AreEqual(mcConnectionInfo.HostPort, settings.mc.port.ToString());
+ Assert.AreEqual(mcConnectionInfo.UserName, settings.mc.username);
+ Assert.AreEqual("https", settings.mc.protocol);
+ }
+
+ [TestMethod]
+ public void ParseMCSettingsTest_ValidMCSettingsNonSSL_ReturnsExpectedSettings()
+ {
+ McConnectionInfo mcConnectionInfo = new McConnectionInfo();
+ mcConnectionInfo.HostAddress = "192.168.1.1";
+ mcConnectionInfo.HostPort = "8080";
+ mcConnectionInfo.UserName = "test";
+ mcConnectionInfo.Password = "test";
+
+ UFTSettings settings = ParallelRunnerEnvironmentUtil.ParseMCSettings(mcConnectionInfo);
+
+ Assert.IsNotNull(settings);
+ Assert.IsNotNull(settings.mc);
+
+ Assert.AreEqual(mcConnectionInfo.HostAddress, settings.mc.hostname);
+ Assert.AreEqual(mcConnectionInfo.HostPort, settings.mc.port.ToString());
+ Assert.AreEqual(mcConnectionInfo.UserName, settings.mc.username);
+ Assert.AreEqual("http", settings.mc.protocol);
+ }
+
+ [TestMethod]
+ public void ParseMCSettingsTest_InvalidMCSettings_ReturnsNullSettings()
+ {
+ McConnectionInfo mcConnectionInfo = new McConnectionInfo();
+
+ UFTSettings settings = ParallelRunnerEnvironmentUtil.ParseMCSettings(mcConnectionInfo);
+
+ Assert.IsNull(settings);
+ }
+
+ [TestMethod]
+ public void IsKnownMobilePropertyTest_KnownProperty_ReturnsTrue()
+ {
+ bool isKnown = ParallelRunnerEnvironmentUtil.IsKnownMobileProperty("deviceId")
+ && ParallelRunnerEnvironmentUtil.IsKnownMobileProperty("osVersion")
+ && ParallelRunnerEnvironmentUtil.IsKnownMobileProperty("osType")
+ && ParallelRunnerEnvironmentUtil.IsKnownMobileProperty("manufacturerAndModel");
+
+ Assert.IsTrue(isKnown);
+ }
+
+ [TestMethod]
+ public void IsKnownMobilePropertyTest_UnknownProperty_ReturnsTrue()
+ {
+ bool isKnown = ParallelRunnerEnvironmentUtil.IsKnownMobileProperty("unknown");
+ Assert.IsFalse(isKnown);
+ }
+ }
+}
diff --git a/HpToolsLauncher/HpToolsLauncherTests/Properties/AssemblyInfo.cs b/HpToolsLauncher/HpToolsLauncherTests/Properties/AssemblyInfo.cs
index 524ab8605e..54bc59bd81 100644
--- a/HpToolsLauncher/HpToolsLauncherTests/Properties/AssemblyInfo.cs
+++ b/HpToolsLauncher/HpToolsLauncherTests/Properties/AssemblyInfo.cs
@@ -1,10 +1,36 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/HpToolsLauncher/HpToolsLauncherTests/UnitTest1.cs b/HpToolsLauncher/HpToolsLauncherTests/UnitTest1.cs
index b503bd1c5a..4e7efc30e8 100644
--- a/HpToolsLauncher/HpToolsLauncherTests/UnitTest1.cs
+++ b/HpToolsLauncher/HpToolsLauncherTests/UnitTest1.cs
@@ -1,180 +1,203 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Linq;
-
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using HpToolsLauncher;
-using System.IO;
-using System.Xml.Linq;
-
-namespace HpToolsLauncherTests
-{
- [TestClass]
- public class UnitTest1
- {
- string testIniFile = @"c:\stam.ini";
- string testPropertiesFile = @"c:\tempPropFile.txt";
-
- [TestInitialize]
- public void TestsInit()
- {
- File.WriteAllText(testIniFile, "[Files]\nTest1=b\nTest2=c\n\n[Test1]\nparam1=\"\"=\\=ss=sא\nparam2=bbb\n\n[Test2]\nparaאm1=tעtt");
- File.WriteAllText(testPropertiesFile, "#\n#Thu Sep 06 11:36:38 IDT 2012\na\\==\\=\"''b\nasd\\u05D2asd=\\u05D2\\u05D3\\u05DB\\u05D3\\u05D2\\u05DB");
- }
-
- [TestCleanup]
- public void TestsCleanUp()
- {
- File.Delete(testIniFile);
- File.Delete(testPropertiesFile);
- }
-
-
- [TestMethod]
- public void TestQcTestSetFolderFromAPIRunner()
- {
- string file1 = "c:\\stam1.ini";
- JavaProperties props = new JavaProperties();
- props["TestSet1"] = "Aaron\\";
- props["TestSet2"] = "Tomer";
- props["almServer"] = "http://vmsoa22:8080/qcbin";
- props["almUser"] = "sa";
- props["almPassword"] = "";
- props["almDomain"] = "Default";
- props["almProject"] = "Aaron";
- props["almRunMode"] = "RUN_LOCAL";
- props["almTimeout"] = "-1";
- props["almRunHost"] = "";
- props.Save(file1, "");
- Launcher runner = new Launcher("false", file1, TestStorageType.Alm);
-
- runner.Run();
- }
-
- [TestMethod]
- public void TestMtbxReadFile()
- {
- string content = " ";
- List tests = MtbxManager.LoadMtbx(content, "TestGroup1");
- Assert.IsTrue(tests.Count == 2);
- }
-
- [TestMethod]
- public void TestGenerateApiXmlFile()
- {
- string content = " ";
- List tests = MtbxManager.LoadMtbx(content, "dunno");
- string xmlContent = tests[0].GenerateAPITestXmlForTest();
- //XDocument doc = XDocument.Parse(xmlContent);
- Assert.IsTrue(xmlContent.Contains("abc"));
- Assert.IsTrue(xmlContent.Contains("name=\"mee\" type=\"xs:int\""));
- }
-
- [TestMethod]
- public void TestQcTestRunFromAPIRunner()
- {
- string file1 = "c:\\stam1.ini";
- JavaProperties props = new JavaProperties();
- props["TestSet1"] = "Aaron\\Amit";
- props["almServer"] = "http://vmsoa22:8080/qcbin";
- props["almUser"] = "sa";
- props["almPassword"] = "";
- props["almDomain"] = "Default";
- props["almProject"] = "Aaron";
- props["almRunMode"] = "RUN_LOCAL";
- props["almTimeout"] = "-1";
- props["almRunHost"] = "";
- props.Save(file1, "");
- Launcher runner = new Launcher("false", file1, TestStorageType.Alm);
-
- runner.Run();
- }
-
- [TestMethod]
- public void TestGetTestStateFromReport()
- {
- TestRunResults res = new TestRunResults { ReportLocation = @"c:\Temp\report\" };
- TestState state = Helper.GetTestStateFromReport(res);
- }
-
- [TestMethod]
- public void TestQcTestRun()
- {
- AlmTestSetsRunner runner = new AlmTestSetsRunner("http://vmsoa22:8080/qcbin/",
- "sa",
- "",
- "DEFAULT",
- "Aaron",
- 100000,
- QcRunMode.RUN_LOCAL,
- null,
- new List { "Aaron\\Amit" });
-
- if (runner.Connected)
- runner.Run();
-
- //runner.RunTestSet(
- // "Aaron",
- // "Amit",
- // 100000,
- // QcRunMode.RUN_LOCAL,
- // null);
- }
-
- //[TestMethod]
- //public void RunAPITestWithParams()
- //{
- // var jenkinsEnv = new Dictionary();
- // jenkinsEnv.Add("workspace","c:\\tests");
- // FileSystemTestsRunner runner = new FileSystemTestsRunner(new List() { @"c:\workspace\mtbx\stam.mtbx" }, TimeSpan.FromMinutes(10), 500, TimeSpan.FromMinutes(10), new List() { "" }, jenkinsEnv);
- // runner.Run();
- //}
-
- //[TestMethod]
- //public void RunGUITestWithParams()
- //{
- //}
-
- [TestMethod]
- public void TestJavaPropertiesSaveAndLoad()
- {
- JavaProperties props = new JavaProperties();
- JavaProperties props1 = new JavaProperties();
- props.Add("a=", "b=\"''");
- props.Store("c:\\tempPropFileCsharp.txt", "comment1");
- props1.Load("c:\\tempPropFileCsharp.txt");
- File.Delete("c:\\tempPropFileCsharp.txt");
- Assert.AreEqual(props1["a="], props["a="]);
- }
-
- [TestMethod]
- public void TestIniFile()
- {
- try
- {
- IniManager m = new IniManager(testIniFile);
- HashSet sects = m.GetSectionNames();
- HashSet fileEnts = m.GetEntryNames("Files");
- Dictionary FilesDict = m.GetSectionAsDictionary("Files");
- Dictionary Test1Dict = m.GetSectionAsDictionary("Test1");
- Dictionary Test2Dict = m.GetSectionAsDictionary("Test2");
- var dict = IniManager.LoadIniFileAsDictionary(testIniFile);
-
- Assert.IsTrue(FilesDict.Count > 0);
- Assert.IsTrue(Test1Dict.Count > 0);
- Assert.IsTrue(dict.Count > 0);
- }
- catch
- {
- Assert.Fail();
- }
- }
-
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher;
+using HpToolsLauncher.Utils;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Collections.Generic;
+using System.IO;
+
+namespace HpToolsLauncherTests
+{
+ [TestClass]
+ public class UnitTest1
+ {
+ string testIniFile = @"c:\stam.ini";
+ string testPropertiesFile = @"c:\tempPropFile.txt";
+
+ [TestInitialize]
+ public void TestsInit()
+ {
+ File.WriteAllText(testIniFile, "[Files]\nTest1=b\nTest2=c\n\n[Test1]\nparam1=\"\"=\\=ss=sא\nparam2=bbb\n\n[Test2]\nparaאm1=tעtt");
+ File.WriteAllText(testPropertiesFile, "#\n#Thu Sep 06 11:36:38 IDT 2012\na\\==\\=\"''b\nasd\\u05D2asd=\\u05D2\\u05D3\\u05DB\\u05D3\\u05D2\\u05DB");
+ }
+
+ [TestCleanup]
+ public void TestsCleanUp()
+ {
+ File.Delete(testIniFile);
+ File.Delete(testPropertiesFile);
+ }
+
+
+ [TestMethod]
+ public void TestQcTestSetFolderFromAPIRunner()
+ {
+ string file1 = "c:\\stam1.ini";
+ JavaProperties props = new JavaProperties();
+ props["TestSet1"] = "Aaron\\";
+ props["TestSet2"] = "Tomer";
+ props["almServer"] = "http://vmsoa22:8080/qcbin";
+ props["almUser"] = "sa";
+ props["almPassword"] = "";
+ props["almDomain"] = "Default";
+ props["almProject"] = "Aaron";
+ props["almRunMode"] = "RUN_LOCAL";
+ props["almTimeout"] = "-1";
+ props["almRunHost"] = "";
+ props.Save(file1, "");
+ Launcher runner = new Launcher(file1, TestStorageType.Alm);
+
+ runner.Run();
+ }
+
+ [TestMethod]
+ public void TestMtbxReadFile()
+ {
+ string content = " ";
+ List tests = MtbxManager.LoadMtbx(content, "TestGroup1");
+ Assert.IsTrue(tests.Count == 2);
+ }
+
+ [TestMethod]
+ public void TestGenerateApiXmlFile()
+ {
+ string content = " ";
+ List tests = MtbxManager.LoadMtbx(content, "dunno");
+ string xmlContent = tests[0].GenerateAPITestXmlForTest(new Dictionary(), false);
+ //XDocument doc = XDocument.Parse(xmlContent);
+ Assert.IsTrue(xmlContent.Contains("abc"));
+ Assert.IsTrue(xmlContent.Contains("name=\"mee\" type=\"xs:int\""));
+ }
+
+ [TestMethod]
+ public void TestQcTestRunFromAPIRunner()
+ {
+ string file1 = "c:\\stam1.ini";
+ JavaProperties props = new JavaProperties();
+ props["TestSet1"] = "Aaron\\Amit";
+ props["almServer"] = "http://vmsoa22:8080/qcbin";
+ props["almUser"] = "sa";
+ props["almPassword"] = "";
+ props["almDomain"] = "Default";
+ props["almProject"] = "Aaron";
+ props["almRunMode"] = "RUN_LOCAL";
+ props["almTimeout"] = "-1";
+ props["almRunHost"] = "";
+ props.Save(file1, "");
+ Launcher runner = new Launcher(file1, TestStorageType.Alm);
+
+ runner.Run();
+ }
+
+ [TestMethod]
+ public void TestGetTestStateFromReport()
+ {
+ TestRunResults res = new TestRunResults { ReportLocation = @"c:\Temp\report\" };
+ TestState state = Helper.GetTestStateFromReport(res);
+ }
+
+ [TestMethod]
+ public void TestQcTestRun()
+ {
+ AlmTestSetsRunner runner = new AlmTestSetsRunner("http://vmsoa22:8080/qcbin/",
+ "sa",
+ "",
+ "DEFAULT",
+ "Aaron",
+ 100000,
+ QcRunMode.RUN_LOCAL,
+ null,
+ new List { "Aaron\\Amit" }, new List(), false, "", new List { "Failed", "Blocked" }, false, TestStorageType.Alm, false, "", "");
+
+ if (runner.Connected)
+ runner.Run();
+
+ //runner.RunTestSet(
+ // "Aaron",
+ // "Amit",
+ // 100000,
+ // QcRunMode.RUN_LOCAL,
+ // null);
+ }
+
+ //[TestMethod]
+ //public void RunAPITestWithParams()
+ //{
+ // var jenkinsEnv = new Dictionary();
+ // jenkinsEnv.Add("workspace","c:\\tests");
+ // FileSystemTestsRunner runner = new FileSystemTestsRunner(new List() { @"c:\workspace\mtbx\stam.mtbx" }, TimeSpan.FromMinutes(10), 500, TimeSpan.FromMinutes(10), new List() { "" }, jenkinsEnv);
+ // runner.Run();
+ //}
+
+ //[TestMethod]
+ //public void RunGUITestWithParams()
+ //{
+ //}
+
+ [TestMethod]
+ public void TestJavaPropertiesSaveAndLoad()
+ {
+ JavaProperties props = new JavaProperties();
+ JavaProperties props1 = new JavaProperties();
+ props.Add("a=", "b=\"''");
+ props.Store("c:\\tempPropFileCsharp.txt", "comment1");
+ props1.Load("c:\\tempPropFileCsharp.txt");
+ File.Delete("c:\\tempPropFileCsharp.txt");
+ Assert.AreEqual(props1["a="], props["a="]);
+ }
+
+ [TestMethod]
+ public void TestIniFile()
+ {
+ try
+ {
+ IniManager m = new IniManager(testIniFile);
+ HashSet sects = m.GetSectionNames();
+ HashSet fileEnts = m.GetEntryNames("Files");
+ Dictionary FilesDict = m.GetSectionAsDictionary("Files");
+ Dictionary Test1Dict = m.GetSectionAsDictionary("Test1");
+ Dictionary Test2Dict = m.GetSectionAsDictionary("Test2");
+ var dict = IniManager.LoadIniFileAsDictionary(testIniFile);
+
+ Assert.IsTrue(FilesDict.Count > 0);
+ Assert.IsTrue(Test1Dict.Count > 0);
+ Assert.IsTrue(dict.Count > 0);
+ }
+ catch
+ {
+ Assert.Fail();
+ }
+ }
+
+ }
+}
diff --git a/HpToolsLauncher/IProcessAdapter.cs b/HpToolsLauncher/IProcessAdapter.cs
new file mode 100644
index 0000000000..db93ba05f2
--- /dev/null
+++ b/HpToolsLauncher/IProcessAdapter.cs
@@ -0,0 +1,176 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace HpToolsLauncher
+{
+ public interface IProcessAdapter
+ {
+ int ExitCode { get; }
+
+ bool HasExited { get; }
+
+ void Start();
+
+ void WaitForExit();
+
+ bool WaitForExit(int milliseconds);
+
+ void Kill();
+
+ void Close();
+ }
+
+ public class ProcessAdapter : IProcessAdapter
+ {
+ private Process Process { get; set; }
+
+ public int ExitCode
+ {
+ get
+ {
+ return Process.ExitCode;
+ }
+ }
+
+ public bool HasExited
+ {
+ get
+ {
+ return Process.HasExited;
+ }
+ }
+
+ public ProcessAdapter(Process process) { Process = process; }
+
+ public void Start()
+ {
+ Process.Start();
+
+ if (Process.StartInfo.RedirectStandardError)
+ {
+ Process.BeginErrorReadLine();
+ }
+
+ if (Process.StartInfo.RedirectStandardOutput)
+ {
+ Process.BeginOutputReadLine();
+ }
+ }
+
+ public void WaitForExit()
+ {
+ Process.WaitForExit();
+ }
+
+ public bool WaitForExit(int milliseconds)
+ {
+ return Process.WaitForExit(milliseconds);
+ }
+
+ public void Kill()
+ {
+ Process.Kill();
+ }
+
+ public void Close()
+ {
+ Process.Close();
+ }
+ }
+
+ public class ElevatedProcessAdapter : IProcessAdapter
+ {
+ private ElevatedProcess ElevatedProcess { get; set; }
+
+ public int ExitCode
+ {
+ get
+ {
+ return ElevatedProcess.ExitCode;
+ }
+ }
+
+ public bool HasExited
+ {
+ get
+ {
+ return ElevatedProcess.HasExited;
+ }
+ }
+
+ public ElevatedProcessAdapter(ElevatedProcess elevatedProcess) { this.ElevatedProcess = elevatedProcess; }
+
+ public void Start()
+ {
+ ElevatedProcess.StartElevated();
+ }
+
+ public void WaitForExit()
+ {
+ ElevatedProcess.WaitForExit();
+ }
+
+ public bool WaitForExit(int milliseconds)
+ {
+ return ElevatedProcess.WaitForExit(milliseconds);
+ }
+
+ public void Kill()
+ {
+ ElevatedProcess.Kill();
+ }
+
+ public void Close()
+ {
+ ElevatedProcess.Close();
+ }
+ }
+
+ public static class ProcessAdapterFactory
+ {
+ ///
+ /// Create a process adapter based on the type of process.
+ ///
+ /// the process object
+ /// an adapter for the given process, null if no adapter available
+ public static IProcessAdapter CreateAdapter(object process)
+ {
+ if (process is Process) return new ProcessAdapter((Process)process);
+ if (process is ElevatedProcess) return new ElevatedProcessAdapter((ElevatedProcess)process);
+
+ return null;
+ }
+ }
+}
diff --git a/HpToolsLauncher/IniManager.cs b/HpToolsLauncher/IniManager.cs
index acb537355e..e6f71f57d2 100644
--- a/HpToolsLauncher/IniManager.cs
+++ b/HpToolsLauncher/IniManager.cs
@@ -1,7 +1,34 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System.Collections.Generic;
using System.Runtime.InteropServices;
@@ -134,7 +161,7 @@ public Dictionary GetSectionAsDictionary(string section)
return retval;
}
- public static Dictionary> LoadIniFileAsDictionary(string strFileName)
+ public static Dictionary> LoadIniFileAsDictionary(string strFileName)
{
Dictionary> retVal = new Dictionary>();
IniManager man = new IniManager(strFileName);
diff --git a/HpToolsLauncher/Interfaces/IAssetRunner.cs b/HpToolsLauncher/Interfaces/IAssetRunner.cs
index d817698883..644eefc7ad 100644
--- a/HpToolsLauncher/Interfaces/IAssetRunner.cs
+++ b/HpToolsLauncher/Interfaces/IAssetRunner.cs
@@ -1,7 +1,34 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System;
namespace HpToolsLauncher
@@ -9,6 +36,7 @@ namespace HpToolsLauncher
public interface IAssetRunner : IDisposable
{
TestSuiteRunResults Run();
- bool RunWasCancelled {get;set;}
+ void SafelyCancel();
+ bool RunWasCancelled { get; set; }
}
}
\ No newline at end of file
diff --git a/HpToolsLauncher/Interfaces/IFileSysTestRunner.cs b/HpToolsLauncher/Interfaces/IFileSysTestRunner.cs
index 8e9cef7d59..cbcc0e5c1a 100644
--- a/HpToolsLauncher/Interfaces/IFileSysTestRunner.cs
+++ b/HpToolsLauncher/Interfaces/IFileSysTestRunner.cs
@@ -1,15 +1,45 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-namespace HpToolsLauncher
-{
- public delegate bool RunCancelledDelegate();
- public interface IFileSysTestRunner
- {
- TestRunResults RunTest(TestInfo fileName, ref string errorReason, RunCancelledDelegate runCancelled);
- void CleanUp();
- }
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System.Collections.Generic;
+
+namespace HpToolsLauncher
+{
+ public delegate bool RunCancelledDelegate();
+ public interface IFileSysTestRunner
+ {
+ TestRunResults RunTest(TestInfo fileName, ref string errorReason, RunCancelledDelegate runCancelled, out Dictionary outParams);
+
+ void CleanUp();
+ void SafelyCancel();
+ }
}
\ No newline at end of file
diff --git a/HpToolsLauncher/Interfaces/IMtbManager.cs b/HpToolsLauncher/Interfaces/IMtbManager.cs
index 50b1ba5236..fac3b29aba 100644
--- a/HpToolsLauncher/Interfaces/IMtbManager.cs
+++ b/HpToolsLauncher/Interfaces/IMtbManager.cs
@@ -1,7 +1,34 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System.Collections.Generic;
diff --git a/HpToolsLauncher/Interfaces/IXmlBuilder.cs b/HpToolsLauncher/Interfaces/IXmlBuilder.cs
index 37c0335d5b..1e904055a1 100644
--- a/HpToolsLauncher/Interfaces/IXmlBuilder.cs
+++ b/HpToolsLauncher/Interfaces/IXmlBuilder.cs
@@ -1,12 +1,34 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
namespace HpToolsLauncher
{
diff --git a/HpToolsLauncher/Interfaces/JavaProperties/JavaIniFile.cs b/HpToolsLauncher/Interfaces/JavaProperties/JavaIniFile.cs
new file mode 100644
index 0000000000..3a74c0cdf3
--- /dev/null
+++ b/HpToolsLauncher/Interfaces/JavaProperties/JavaIniFile.cs
@@ -0,0 +1,116 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Text.RegularExpressions;
+
+namespace HpToolsLauncher
+{
+ public class JavaIniFile : Dictionary
+ {
+ Regex reg = new Regex(@"\[(?.*?)\]", RegexOptions.Compiled);
+ public void Load(string filename)
+ {
+ this.Clear();
+ //Dictionary
+ StringBuilder sb = new StringBuilder();
+ //Dictionary retVal = new Dictionary();
+
+ string[] fileLines = File.ReadAllLines(filename, Encoding.Default);
+ int i = 0;
+ string currentSectionName = null;
+ foreach (string line in fileLines)
+ {
+ Match match = reg.Match(line);
+ if (match.Success)
+ {
+ //get the new section name
+ string sectName = match.Groups["section"].Value;
+ if (currentSectionName != null)
+ {
+ //load the previous section to a properties object
+ JavaProperties props = new JavaProperties();
+ using (MemoryStream s = new MemoryStream(Encoding.Default.GetBytes(sb.ToString())))
+ {
+ props.Load(s);
+ }
+
+ //add to the dictionary
+ this.Add(currentSectionName, props);
+ }
+ //the current section becomes the new section
+ currentSectionName = sectName;
+ //clear the old section from the builder
+ sb.Clear();
+ }
+ else
+ {
+ sb.AppendLine(line);
+ }
+ ++i;
+ }
+
+ if (currentSectionName != null)
+ {
+ //load the last section to a properties object
+ JavaProperties props1 = new JavaProperties();
+ using (MemoryStream s1 = new MemoryStream(Encoding.Default.GetBytes(sb.ToString())))
+ {
+ props1.Load(s1);
+ }
+
+ //add to the dictionary
+ this.Add(currentSectionName, props1);
+ }
+ }
+
+ public void Save(string fileName)
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (string sect in this.Keys)
+ {
+ sb.AppendLine("[" + sect + "]");
+ JavaProperties props = this[sect];
+ using (MemoryStream s = new MemoryStream())
+ {
+ props.Save(s, null);
+ sb.AppendLine(s.ToString());
+ }
+ }
+ File.WriteAllText(fileName,sb.ToString());
+ }
+ }
+}
diff --git a/HpToolsLauncher/Interfaces/JavaProperties/JavaProperties.cs b/HpToolsLauncher/Interfaces/JavaProperties/JavaProperties.cs
new file mode 100644
index 0000000000..92dac2f75b
--- /dev/null
+++ b/HpToolsLauncher/Interfaces/JavaProperties/JavaProperties.cs
@@ -0,0 +1,630 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Collections;
+
+namespace HpToolsLauncher
+{
+
+ ///
+ /// This class is a direct port to C# of the java properties class
+ ///
+ public class JavaProperties : Dictionary
+ {
+
+ protected JavaProperties defaults;
+
+ ///
+ /// Creates an empty property list with no default values.
+ ///
+ public JavaProperties()
+ : this(null)
+ {
+
+ }
+
+ ///
+ /// Creates an empty property list with the specified defaults.
+ ///
+ ///
+ public JavaProperties(JavaProperties defaults)
+ {
+ this.defaults = defaults;
+ }
+
+
+
+ ///
+ /// loads properties
+ ///
+ ///
+ public void Load(TextReader reader)
+ {
+ LoadInternal(new LineReader(reader));
+ }
+
+
+ ///
+ /// loads properties from a file
+ ///
+ ///
+ public void Load(string fullpath)
+ {
+ using (FileStream s = File.OpenRead(fullpath))
+ {
+ LoadInternal(new LineReader(s));
+ }
+ }
+
+ ///
+ /// loads properties from stream
+ ///
+ ///
+ public void Load(Stream inStream)
+ {
+ LoadInternal(new LineReader(inStream));
+ }
+
+ private void LoadInternal(LineReader lr)
+ {
+ char[] convtBuf = new char[1024];
+ int limit;
+ int keyLen;
+ int valueStart;
+ char c;
+ bool hasSep;
+ bool precedingBackslash;
+
+ while ((limit = lr.readLine()) >= 0)
+ {
+ c = '\0';
+ keyLen = 0;
+ valueStart = limit;
+ hasSep = false;
+
+ //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
+ precedingBackslash = false;
+ while (keyLen < limit)
+ {
+ c = lr.lineBuf[keyLen];
+ //need check if escaped.
+ if ((c == '=' || c == ':') && !precedingBackslash)
+ {
+ valueStart = keyLen + 1;
+ hasSep = true;
+ break;
+ }
+ else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash)
+ {
+ valueStart = keyLen + 1;
+ break;
+ }
+ if (c == '\\')
+ {
+ precedingBackslash = !precedingBackslash;
+ }
+ else
+ {
+ precedingBackslash = false;
+ }
+ keyLen++;
+ }
+ while (valueStart < limit)
+ {
+ c = lr.lineBuf[valueStart];
+ if (c != ' ' && c != '\t' && c != '\f')
+ {
+ if (!hasSep && (c == '=' || c == ':'))
+ {
+ hasSep = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+ valueStart++;
+ }
+ String key = LoadConvert(lr.lineBuf, 0, keyLen, convtBuf);
+ String value = LoadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
+ this[key] = value;
+ }
+ }
+
+ class LineReader
+ {
+ public LineReader(Stream inStream)
+ {
+ this.inStream = inStream;
+ inByteBuf = new byte[8192];
+ }
+
+ public LineReader(TextReader reader)
+ {
+ this.reader = reader;
+ inCharBuf = new char[8192];
+ }
+
+ byte[] inByteBuf;
+ char[] inCharBuf;
+ internal char[] lineBuf = new char[1024];
+ int inLimit = 0;
+ int inOff = 0;
+ Stream inStream;
+ TextReader reader;
+
+ public int readLine()
+ {
+ int len = 0;
+ char c = '\0';
+
+ bool skipWhiteSpace = true;
+ bool isCommentLine = false;
+ bool isNewLine = true;
+ bool appendedLineBegin = false;
+ bool precedingBackslash = false;
+ bool skipLF = false;
+
+ while (true)
+ {
+ if (inOff >= inLimit)
+ {
+ inLimit = (inStream == null) ? reader.Read(inCharBuf, 0, inCharBuf.Length)
+ : inStream.Read(inByteBuf, 0, inByteBuf.Length);
+ inOff = 0;
+ if (inLimit <= 0)
+ {
+ if (len == 0 || isCommentLine)
+ {
+ return -1;
+ }
+ return len;
+ }
+ }
+ if (inStream != null)
+ {
+ //The line below is equivalent to calling a
+ //ISO8859-1 decoder.
+ c = (char)(0xff & inByteBuf[inOff++]);
+ }
+ else
+ {
+ c = inCharBuf[inOff++];
+ }
+ if (skipLF)
+ {
+ skipLF = false;
+ if (c == '\n')
+ {
+ continue;
+ }
+ }
+ if (skipWhiteSpace)
+ {
+ if (c == ' ' || c == '\t' || c == '\f')
+ {
+ continue;
+ }
+ if (!appendedLineBegin && (c == '\r' || c == '\n'))
+ {
+ continue;
+ }
+ skipWhiteSpace = false;
+ appendedLineBegin = false;
+ }
+ if (isNewLine)
+ {
+ isNewLine = false;
+ if (c == '#' || c == '!')
+ {
+ isCommentLine = true;
+ continue;
+ }
+ }
+
+ if (c != '\n' && c != '\r')
+ {
+ lineBuf[len++] = c;
+ if (len == lineBuf.Length)
+ {
+ int newLength = lineBuf.Length * 2;
+ if (newLength < 0)
+ {
+ newLength = Int32.MaxValue;
+ }
+ char[] buf = new char[newLength];
+ Array.Copy(lineBuf, 0, buf, 0, lineBuf.Length);
+ lineBuf = buf;
+ }
+ //flip the preceding backslash flag
+ if (c == '\\')
+ {
+ precedingBackslash = !precedingBackslash;
+ }
+ else
+ {
+ precedingBackslash = false;
+ }
+ }
+ else
+ {
+ // reached EOL
+ if (isCommentLine || len == 0)
+ {
+ isCommentLine = false;
+ isNewLine = true;
+ skipWhiteSpace = true;
+ len = 0;
+ continue;
+ }
+ if (inOff >= inLimit)
+ {
+ inLimit = (inStream == null)
+ ? reader.Read(inCharBuf, 0, inCharBuf.Length)
+ : inStream.Read(inByteBuf, 0, inByteBuf.Length);
+ inOff = 0;
+ if (inLimit <= 0)
+ {
+ return len;
+ }
+ }
+ if (precedingBackslash)
+ {
+ len -= 1;
+ //skip the leading whitespace characters in following line
+ skipWhiteSpace = true;
+ appendedLineBegin = true;
+ precedingBackslash = false;
+ if (c == '\r')
+ {
+ skipLF = true;
+ }
+ }
+ else
+ {
+ return len;
+ }
+ }
+ }
+ }
+ }
+
+
+ ///
+ /// Converts encoded \uxxxx to unicode chars and changes special saved chars to their original forms
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private String LoadConvert(char[] in1, int off, int len, char[] convtBuf)
+ {
+ if (convtBuf.Length < len)
+ {
+ int newLen = len * 2;
+ if (newLen < 0)
+ {
+ newLen = Int32.MaxValue;
+ }
+ convtBuf = new char[newLen];
+ }
+ char aChar;
+ char[] out1 = convtBuf;
+ int outLen = 0;
+ int end = off + len;
+
+ while (off < end)
+ {
+ aChar = in1[off++];
+ if (aChar == '\\')
+ {
+ aChar = in1[off++];
+ if (aChar == 'u')
+ {
+ // Read the xxxx
+ int value = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ aChar = in1[off++];
+ switch (aChar)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ value = (value << 4) + aChar - '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ value = (value << 4) + 10 + aChar - 'a';
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ value = (value << 4) + 10 + aChar - 'A';
+ break;
+ default:
+ throw new ArgumentException(
+ "Malformed \\uxxxx encoding.");
+ }
+ }
+ out1[outLen++] = (char)value;
+ }
+ else
+ {
+ if (aChar == 't') aChar = '\t';
+ else if (aChar == 'r') aChar = '\r';
+ else if (aChar == 'n') aChar = '\n';
+ else if (aChar == 'f') aChar = '\f';
+ out1[outLen++] = aChar;
+ }
+ }
+ else
+ {
+ out1[outLen++] = aChar;
+ }
+ }
+ return new String(out1, 0, outLen);
+ }
+
+
+ ///
+ /// Converts unicodes to encoded \uxxxx and escapes special characters with a preceding slash
+ ///
+ ///
+ ///
+ ///
+ ///
+ private String SaveConvert(String theString,
+ bool escapeSpace,
+ bool escapeUnicode)
+ {
+ int len = theString.Length;
+ int bufLen = len * 2;
+ if (bufLen < 0)
+ {
+ bufLen = Int32.MaxValue;
+ }
+ StringBuilder outBuffer = new StringBuilder(bufLen);
+
+ for (int x = 0; x < len; x++)
+ {
+ char aChar = theString[x];
+ // Handle common case first, selecting largest block that
+ // avoids the specials below
+ if ((aChar > 61) && (aChar < 127))
+ {
+ if (aChar == '\\')
+ {
+ outBuffer.Append('\\'); outBuffer.Append('\\');
+ continue;
+ }
+ outBuffer.Append(aChar);
+ continue;
+ }
+ switch (aChar)
+ {
+ case ' ':
+ if (x == 0 || escapeSpace)
+ outBuffer.Append('\\');
+ outBuffer.Append(' ');
+ break;
+ case '\t': outBuffer.Append('\\'); outBuffer.Append('t');
+ break;
+ case '\n': outBuffer.Append('\\'); outBuffer.Append('n');
+ break;
+ case '\r': outBuffer.Append('\\'); outBuffer.Append('r');
+ break;
+ case '\f': outBuffer.Append('\\'); outBuffer.Append('f');
+ break;
+ case '=': // Fall through
+ case ':': // Fall through
+ case '#': // Fall through
+ case '!':
+ outBuffer.Append('\\'); outBuffer.Append(aChar);
+ break;
+ default:
+ if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode)
+ {
+ outBuffer.Append('\\');
+ outBuffer.Append('u');
+ outBuffer.Append(ToHex((aChar >> 12) & 0xF));
+ outBuffer.Append(ToHex((aChar >> 8) & 0xF));
+ outBuffer.Append(ToHex((aChar >> 4) & 0xF));
+ outBuffer.Append(ToHex(aChar & 0xF));
+ }
+ else
+ {
+ outBuffer.Append(aChar);
+ }
+ break;
+ }
+ }
+ return outBuffer.ToString();
+ }
+
+ private static void WriteComments(System.IO.TextWriter bw, String comments)
+ {
+ bw.Write("#");
+ int len = comments.Length;
+ int current = 0;
+ int last = 0;
+ char[] uu = new char[6];
+ uu[0] = '\\';
+ uu[1] = 'u';
+ while (current < len)
+ {
+ char c = comments[current];
+ if (c > '\u00ff' || c == '\n' || c == '\r')
+ {
+ if (last != current)
+ bw.Write(comments.Substring(last, current));
+ if (c > '\u00ff')
+ {
+ uu[2] = ToHex((c >> 12) & 0xf);
+ uu[3] = ToHex((c >> 8) & 0xf);
+ uu[4] = ToHex((c >> 4) & 0xf);
+ uu[5] = ToHex(c & 0xf);
+ bw.Write(new String(uu));
+ }
+ else
+ {
+ bw.Write(bw.NewLine);
+ if (c == '\r' &&
+ current != len - 1 &&
+ comments[current + 1] == '\n')
+ {
+ current++;
+ }
+ if (current == len - 1 ||
+ (comments[current + 1] != '#' &&
+ comments[current + 1] != '!'))
+ bw.Write("#");
+ }
+ last = current + 1;
+ }
+ current++;
+ }
+ if (last != current)
+ bw.Write(comments.Substring(last, current) + bw.NewLine);
+
+ }
+
+ //@Deprecated
+ public void Save(Stream out1, String comments)
+ {
+ try
+ {
+ Store(out1, comments);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ public void Save(String fileName, String comments)
+ {
+ Store(fileName, comments);
+ }
+
+ ///
+ /// saves the properties
+ ///
+ ///
+ ///
+ public void Store(TextWriter writer, String comments)
+ {
+ StoreInternal(writer, comments, false);
+ }
+
+ ///
+ /// saves the properties to stream
+ ///
+ ///
+ ///
+ public void Store(Stream out1, String comments)
+ {
+ TextWriter t = new StreamWriter(out1, Encoding.GetEncoding("ISO-8859-1"));
+ StoreInternal(t, comments, true);
+ }
+
+ ///
+ /// saves the properties to file
+ ///
+ ///
+ ///
+ public void Store(string fullpath, String comments)
+ {
+ using (StreamWriter wr = new StreamWriter(fullpath, false, Encoding.GetEncoding("ISO-8859-1")))
+ {
+ StoreInternal(wr, comments, true);
+ }
+ }
+ private void StoreInternal(TextWriter bw, String comments, bool escUnicode)
+ {
+ if (comments != null)
+ {
+ WriteComments(bw, comments);
+ }
+ bw.Write("#" + DateTime.Now.ToString() + bw.NewLine);
+ {
+ foreach (string key in Keys)
+ {
+ String val = (string)this[key];
+ string key1 = SaveConvert(key, true, escUnicode);
+ /* No need to escape embedded and trailing spaces for value, hence
+ * pass false to flag.
+ */
+ val = SaveConvert(val, false, escUnicode);
+ bw.Write(key1 + "=" + val + bw.NewLine);
+ }
+ }
+ bw.Flush();
+ }
+
+ ///
+ /// Convert a nibble to a hex character
+ ///
+ /// nibble to convert
+ ///
+ private static char ToHex(int nibble)
+ {
+ return hexDigit[(nibble & 0xF)];
+ }
+
+ private static char[] hexDigit = {
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+ };
+ }
+
+}
+
+
diff --git a/HpToolsLauncher/JavaProperties/JavaIniFile.cs b/HpToolsLauncher/JavaProperties/JavaIniFile.cs
index 2ab52af500..ce0cce62f9 100644
--- a/HpToolsLauncher/JavaProperties/JavaIniFile.cs
+++ b/HpToolsLauncher/JavaProperties/JavaIniFile.cs
@@ -1,13 +1,38 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.IO;
+using System.Text;
using System.Text.RegularExpressions;
namespace HpToolsLauncher
@@ -83,7 +108,7 @@ public void Save(string fileName)
sb.AppendLine(s.ToString());
}
}
- File.WriteAllText(fileName,sb.ToString());
+ File.WriteAllText(fileName, sb.ToString());
}
}
}
diff --git a/HpToolsLauncher/JavaProperties/JavaProperties.cs b/HpToolsLauncher/JavaProperties/JavaProperties.cs
index c7de5e21c3..1916afa57c 100644
--- a/HpToolsLauncher/JavaProperties/JavaProperties.cs
+++ b/HpToolsLauncher/JavaProperties/JavaProperties.cs
@@ -1,14 +1,39 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.IO;
-using System.Collections;
+using System.Text;
namespace HpToolsLauncher
{
@@ -30,6 +55,18 @@ public JavaProperties()
}
+ public string GetOrDefault(string key, string defaultValue = "")
+ {
+ if (this.ContainsKey(key))
+ {
+ return this[key];
+ }
+ else
+ {
+ return defaultValue;
+ }
+ }
+
///
/// Creates an empty property list with the specified defaults.
///
@@ -430,13 +467,17 @@ private String SaveConvert(String theString,
outBuffer.Append('\\');
outBuffer.Append(' ');
break;
- case '\t': outBuffer.Append('\\'); outBuffer.Append('t');
+ case '\t':
+ outBuffer.Append('\\'); outBuffer.Append('t');
break;
- case '\n': outBuffer.Append('\\'); outBuffer.Append('n');
+ case '\n':
+ outBuffer.Append('\\'); outBuffer.Append('n');
break;
- case '\r': outBuffer.Append('\\'); outBuffer.Append('r');
+ case '\r':
+ outBuffer.Append('\\'); outBuffer.Append('r');
break;
- case '\f': outBuffer.Append('\\'); outBuffer.Append('f');
+ case '\f':
+ outBuffer.Append('\\'); outBuffer.Append('f');
break;
case '=': // Fall through
case ':': // Fall through
@@ -518,7 +559,7 @@ public void Save(Stream out1, String comments)
{
Store(out1, comments);
}
- catch (IOException e)
+ catch (IOException)
{
}
}
diff --git a/HpToolsLauncher/JunitXml/JunitXmlBuilder.cs b/HpToolsLauncher/JunitXml/JunitXmlBuilder.cs
index 3bb6671098..07bab58bee 100644
--- a/HpToolsLauncher/JunitXml/JunitXmlBuilder.cs
+++ b/HpToolsLauncher/JunitXml/JunitXmlBuilder.cs
@@ -1,169 +1,229 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System.IO;
-using System.Xml.Serialization;
-using System.Xml;
-
-namespace HpToolsLauncher
-{
- public class JunitXmlBuilder : IXmlBuilder
- {
- private string _xmlName = "APIResults.xml";
-
- public string XmlName
- {
- get { return _xmlName; }
- set { _xmlName = value; }
- }
- //public const string ClassName = "uftRunner";
- public const string ClassName = "HPToolsFileSystemRunner";
- public const string RootName = "uftRunnerRoot";
-
- XmlSerializer _serializer = new XmlSerializer(typeof(testsuites));
-
- testsuites _testSuites = new testsuites();
-
-
- public JunitXmlBuilder()
- {
- _testSuites.name = RootName;
- }
-
- ///
- /// converts all data from the test resutls in to the Junit xml format and writes the xml file to disk.
- ///
- ///
- public void CreateXmlFromRunResults(TestSuiteRunResults results)
- {
- _testSuites = new testsuites();
-
- testsuite uftts = new testsuite
- {
- errors = results.NumErrors.ToString(),
- tests = results.NumTests.ToString(),
- failures = results.NumFailures.ToString(),
- name = results.SuiteName,
- package = ClassName
- };
- foreach (TestRunResults testRes in results.TestRuns)
- {
- if (testRes.TestType == TestType.LoadRunner.ToString())
- {
- testsuite lrts = CreateXmlFromLRRunResults(testRes);
- _testSuites.AddTestsuite(lrts);
- }
- else
- {
- testcase ufttc = CreateXmlFromUFTRunResults(testRes);
- uftts.AddTestCase(ufttc);
- }
- }
- if(uftts.testcase.Length > 0)
- _testSuites.AddTestsuite(uftts);
-
- if (File.Exists(XmlName))
- File.Delete(XmlName);
-
- using (Stream s = File.OpenWrite(XmlName))
- {
- _serializer.Serialize(s, _testSuites);
- }
- }
-
- private testsuite CreateXmlFromLRRunResults(TestRunResults testRes)
- {
- testsuite lrts = new testsuite();
- int totalTests = 0, totalFailures = 0, totalErrors = 0;
-
- string resultFileFullPath = testRes.ReportLocation + "\\SLA.xml";
- if (File.Exists(resultFileFullPath))
- {
- try
- {
- XmlDocument xdoc = new XmlDocument();
- xdoc.Load(resultFileFullPath);
-
- foreach (XmlNode childNode in xdoc.DocumentElement.ChildNodes)
- {
- if (childNode.Attributes != null && childNode.Attributes["FullName"] != null)
- {
- testRes.TestGroup = testRes.TestPath;
- testcase lrtc = CreateXmlFromUFTRunResults(testRes);
- lrtc.name = childNode.Attributes["FullName"].Value;
- if (childNode.InnerText.ToLowerInvariant().Contains("failed"))
- {
- lrtc.status = "fail";
- totalFailures++;
- }
- else if (childNode.InnerText.ToLowerInvariant().Contains("passed"))
- {
- lrtc.status = "pass";
- lrtc.error = new error[] { };
- }
- totalErrors += lrtc.error.Length;
- lrts.AddTestCase(lrtc);
- totalTests++;
- }
- }
- }
- catch (System.Xml.XmlException)
- {
-
- }
- }
-
- lrts.name = testRes.TestPath;
- lrts.tests = totalTests.ToString();
- lrts.errors = totalErrors.ToString();
- lrts.failures = totalFailures.ToString();
- lrts.time = testRes.Runtime.TotalSeconds.ToString();
- return lrts;
- }
-
- private testcase CreateXmlFromUFTRunResults(TestRunResults testRes)
- {
- testcase tc = new testcase
- {
- systemout = testRes.ConsoleOut,
- systemerr = testRes.ConsoleErr,
- report = testRes.ReportLocation,
- classname = "All-Tests." + ((testRes.TestGroup == null) ? "" : testRes.TestGroup.Replace(".", "_")),
- name = testRes.TestPath,
- type = testRes.TestType,
- time = testRes.Runtime.TotalSeconds.ToString()
- };
-
- if (!string.IsNullOrWhiteSpace(testRes.FailureDesc))
- tc.AddFailure(new failure { message = testRes.FailureDesc });
-
- switch (testRes.TestState)
- {
- case TestState.Passed:
- tc.status = "pass";
- break;
- case TestState.Failed:
- tc.status = "fail";
- break;
- case TestState.Error:
- tc.status = "error";
- break;
- case TestState.Warning:
- tc.status = "warning";
- break;
- default:
- tc.status = "pass";
- break;
- }
- if (!string.IsNullOrWhiteSpace(testRes.ErrorDesc))
- tc.AddError(new error { message = testRes.ErrorDesc });
- return tc;
- }
-
-
-
-
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.Utils;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace HpToolsLauncher
+{
+ public class JunitXmlBuilder : IXmlBuilder
+ {
+ private string _xmlName = "APIResults.xml";
+
+ public string XmlName
+ {
+ get { return _xmlName; }
+ set { _xmlName = value; }
+ }
+
+ public const string ClassName = "HPToolsFileSystemRunner";
+ public const string RootName = "uftRunnerRoot";
+ private const string ALL_TESTS_FORMAT = "All-Tests.{0}";
+ private const string DOT = ".";
+ private const string UNDERSCORE = "_";
+ private const string PASS = "pass";
+ private const string FAIL = "fail";
+ private const string ERROR = "error";
+ private const string WARNING = "warning";
+
+ private readonly XmlSerializer _serializer = new XmlSerializer(typeof(testsuites));
+ private readonly testsuites _testSuites = new testsuites();
+
+ public JunitXmlBuilder()
+ {
+ _testSuites.name = RootName;
+ }
+
+ public testsuites TestSuites
+ {
+ get { return _testSuites; }
+ }
+
+ ///
+ /// converts all data from the test results in to the Junit xml format and writes the xml file to disk.
+ ///
+ ///
+ public void CreateXmlFromRunResults(TestSuiteRunResults results)
+ {
+ testsuite uftts = new testsuite
+ {
+ errors = results.NumErrors,
+ tests = results.NumTests,
+ failures = results.NumFailures,
+ name = results.SuiteName,
+ package = ClassName
+ };
+ foreach (TestRunResults testRes in results.TestRuns)
+ {
+ if (testRes.TestType == TestType.LoadRunner)
+ {
+ testsuite lrts = CreateXmlFromLRRunResults(testRes);
+ _testSuites.AddTestsuite(lrts);
+ }
+ else
+ {
+ testcase ufttc = CovertUFTRunResultsToTestcase(testRes);
+ uftts.AddTestCase(ufttc);
+ }
+ }
+ if (uftts.testcase.Length > 0)
+ {
+ _testSuites.AddTestsuite(uftts);
+ }
+
+ if (File.Exists(XmlName))
+ {
+ File.Delete(XmlName);
+ }
+
+ using (Stream s = File.OpenWrite(XmlName))
+ {
+ _serializer.Serialize(s, _testSuites);
+ }
+ }
+
+ ///
+ /// Create or update the xml report. This function is called in a loop after each test execution in order to get the report built progressively
+ /// If the job is aborted by user we still can provide the (partial) report with completed tests results.
+ ///
+ /// reference to testsuite object, existing or going to be added to _testSuites collection
+ /// test run results to be converted
+ /// flag to indicate if the first param testsuite must be added to the collection
+ public void CreateOrUpdatePartialXmlReport(testsuite ts, TestRunResults testRes, bool addToTestSuites)
+ {
+ testcase tc = CovertUFTRunResultsToTestcase(testRes);
+ ts.AddTestCase(tc);
+ if (addToTestSuites)
+ {
+ _testSuites.AddTestsuite(ts);
+ }
+
+ // NOTE: if the file already exists it will be overwritten / replaced, the entire _testSuites will be serialized every time
+ using (Stream s = File.Open(_xmlName, FileMode.Create, FileAccess.Write, FileShare.Read))
+ {
+ _serializer.Serialize(s, _testSuites);
+ }
+ }
+
+ private testsuite CreateXmlFromLRRunResults(TestRunResults testRes)
+ {
+ testsuite lrts = new testsuite();
+ int totalTests = 0, totalFailures = 0, totalErrors = 0;
+
+ string resultFileFullPath = testRes.ReportLocation + "\\SLA.xml";
+ if (File.Exists(resultFileFullPath))
+ {
+ try
+ {
+ XmlDocument xdoc = new XmlDocument();
+ xdoc.Load(resultFileFullPath);
+
+ foreach (XmlNode childNode in xdoc.DocumentElement.ChildNodes)
+ {
+ if (childNode.Attributes != null && childNode.Attributes["FullName"] != null)
+ {
+ testRes.TestGroup = testRes.TestPath;
+ testcase lrtc = CovertUFTRunResultsToTestcase(testRes);
+ lrtc.name = childNode.Attributes["FullName"].Value;
+ if (childNode.InnerText.ToLowerInvariant().Contains("failed"))
+ {
+ lrtc.status = "fail";
+ totalFailures++;
+ }
+ else if (childNode.InnerText.ToLowerInvariant().Contains("passed"))
+ {
+ lrtc.status = "pass";
+ lrtc.error = new error[] { };
+ }
+ totalErrors += lrtc.error.Length;
+ lrts.AddTestCase(lrtc);
+ totalTests++;
+ }
+ }
+ }
+ catch (XmlException)
+ {
+
+ }
+ }
+
+ lrts.name = testRes.TestPath;
+ lrts.tests = totalTests;
+ lrts.errors = totalErrors;
+ lrts.failures = totalFailures;
+ lrts.time = testRes.Runtime.TotalSeconds.ToString(CultureInfo.InvariantCulture);
+ return lrts;
+ }
+
+ private testcase CovertUFTRunResultsToTestcase(TestRunResults testRes)
+ {
+ testcase tc = new testcase
+ {
+ systemout = testRes.ConsoleOut,
+ systemerr = testRes.ConsoleErr,
+ report = testRes.ReportLocation,
+ classname = string.Format(ALL_TESTS_FORMAT, testRes.TestGroup == null ? string.Empty : testRes.TestGroup.Replace(DOT, UNDERSCORE)),
+ name = testRes.TestPath,
+ type = testRes.TestType.ToString(),
+ time = testRes.Runtime.TotalSeconds.ToString(CultureInfo.InvariantCulture)
+ };
+
+ if (!string.IsNullOrWhiteSpace(testRes.FailureDesc))
+ tc.AddFailure(new failure { message = testRes.FailureDesc });
+
+ switch (testRes.TestState)
+ {
+ case TestState.Passed:
+ tc.status = PASS;
+ break;
+ case TestState.Failed:
+ tc.status = FAIL;
+ break;
+ case TestState.Error:
+ tc.status = ERROR;
+ break;
+ case TestState.Warning:
+ tc.status = WARNING;
+ break;
+ default:
+ tc.status = PASS;
+ break;
+ }
+ if (!string.IsNullOrWhiteSpace(testRes.ErrorDesc))
+ tc.AddError(new error { message = testRes.ErrorDesc });
+ return tc;
+ }
+ }
+}
diff --git a/HpToolsLauncher/JunitXml/junit.cs b/HpToolsLauncher/JunitXml/junit.cs
index 2df6283412..437dd880c9 100644
--- a/HpToolsLauncher/JunitXml/junit.cs
+++ b/HpToolsLauncher/JunitXml/junit.cs
@@ -420,11 +420,11 @@ public partial class testsuite
private string nameField;
- private string testsField;
+ private int testsField;
- private string failuresField;
+ private int failuresField;
- private string errorsField;
+ private int errorsField;
private string timeField;
@@ -513,7 +513,7 @@ public string name
///
[System.Xml.Serialization.XmlAttributeAttribute()]
- public string tests
+ public int tests
{
get
{
@@ -527,7 +527,7 @@ public string tests
///
[System.Xml.Serialization.XmlAttributeAttribute()]
- public string failures
+ public int failures
{
get
{
@@ -541,7 +541,7 @@ public string failures
///
[System.Xml.Serialization.XmlAttributeAttribute()]
- public string errors
+ public int errors
{
get
{
@@ -798,4 +798,22 @@ internal void RemoveTestSuite(string name)
if (foundSuite != null)
testsuiteField.Remove(foundSuite);
}
+
+ internal testsuite GetTestSuiteOrDefault(string name, string package, out bool isNewTestSuite)
+ {
+ isNewTestSuite = false;
+ foreach (testsuite ts in testsuiteField)
+ if (ts.name == name && ts.package == package)
+ return ts;
+
+ isNewTestSuite = true;
+ return new testsuite
+ {
+ name = name,
+ package = package,
+ tests = 0,
+ errors = 0,
+ failures = 0
+ };
+ }
}
diff --git a/HpToolsLauncher/JunitXml/junit.xsd b/HpToolsLauncher/JunitXml/junit.xsd
index 1346313f4b..86987bf68f 100644
--- a/HpToolsLauncher/JunitXml/junit.xsd
+++ b/HpToolsLauncher/JunitXml/junit.xsd
@@ -1,4 +1,36 @@
+
+
diff --git a/HpToolsLauncher/Launcher.cs b/HpToolsLauncher/Launcher.cs
index 9670b05594..6836fbf7f0 100644
--- a/HpToolsLauncher/Launcher.cs
+++ b/HpToolsLauncher/Launcher.cs
@@ -1,639 +1,1014 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using HpToolsLauncher.Properties;
-
-namespace HpToolsLauncher
-{
- public enum CIName
- {
- Hudson,
- Jenkins,
- TFS,
- CCNET,
- }
-
- public class McConnectionInfo
- {
- public string MobileUserName { get; set; }
- public string MobilePassword{ get; set; }
- public string MobileHostAddress { get; set; }
- public string MobileHostPort { get; set; }
-
- public int MobileUseSSL { get; set; }
-
- public int MobileUseProxy { get; set; }
- public int MobileProxyType { get; set; }
- public string MobileProxySetting_Address { get; set; }
- public int MobileProxySetting_Port { get; set; }
- public int MobileProxySetting_Authentication { get; set; }
- public string MobileProxySetting_UserName { get; set; }
- public string MobileProxySetting_Password { get; set; }
-
-
- public McConnectionInfo() {
- MobileHostPort = "8080";
- MobileUserName = "";
- MobilePassword = "";
- MobileHostAddress = "";
-
- MobileUseSSL = 0;
-
- MobileUseProxy = 0;
- MobileProxyType = 0;
- MobileProxySetting_Address = "";
- MobileProxySetting_Port = 0;
- MobileProxySetting_Authentication = 0;
- MobileProxySetting_UserName = "";
- MobileProxySetting_Password = "";
-
- }
-
- public override string ToString()
- {
- string McConnectionStr =
- string.Format("Mc HostAddress: {0}, McPort: {1}, Username: {2}, UseSSL: {3}, UseProxy: {4}, ProxyType: {5}, ProxyAddress: {6}, ProxyPort: {7}, ProxyAuth: {8}, ProxyUser: {9}",
- MobileHostAddress, MobileHostPort, MobileUserName, MobileUseSSL, MobileUseProxy, MobileProxyType, MobileProxySetting_Address, MobileProxySetting_Port, MobileProxySetting_Authentication,
- MobileProxySetting_UserName);
- return McConnectionStr;
- }
- }
-
- public class Launcher
- {
- private IXmlBuilder _xmlBuilder;
- private bool _ciRun = false;
- private readonly string _paramFileName = null;
- private JavaProperties _ciParams = new JavaProperties();
- private TestStorageType _runtype = TestStorageType.Unknown;
- private readonly string _failOnUftTestFailed;
- private static ExitCodeEnum _exitCode = ExitCodeEnum.Passed;
- private static string _dateFormat = "dd/MM/yyyy HH:mm:ss";
-
- public static string DateFormat
- {
- get { return Launcher._dateFormat; }
- set { Launcher._dateFormat = value; }
- }
-
- ///
- /// if running an alm job theses strings are mandatory:
- ///
- private string[] requiredParamsForQcRun = { "almServerUrl",
- "almUserName",
- "almPassword",
- "almDomain",
- "almProject",
- "almRunMode",
- "almTimeout",
- "almRunHost"};
-
- ///
- /// a place to save the unique timestamp which shows up in properties/results/abort file names
- /// this timestamp per job run.
- ///
- public static string UniqueTimeStamp { get; set; }
-
- public enum ExitCodeEnum
- {
- Passed = 0,
- Failed = -1,
- Unstable = -2,
- Aborted = -3
- }
- ///
- /// saves the exit code in case we want to run all tests but fail at the end since a file wasn't found
- ///
- public static ExitCodeEnum ExitCode
- {
- get { return Launcher._exitCode; }
- set { Launcher._exitCode = value; }
- }
-
-
- ///
- /// constructor
- ///
- ///
- ///
- ///
- public Launcher(string failOnTestFailed, string paramFileName, TestStorageType runtype)
- {
- _runtype = runtype;
- if (paramFileName != null)
- _ciParams.Load(paramFileName);
- _paramFileName = paramFileName;
-
- _failOnUftTestFailed = string.IsNullOrEmpty(failOnTestFailed) ? "N" : failOnTestFailed;
- }
-
- static String secretkey = "EncriptionPass4Java";
-
- ///
- /// decrypts strings which were encrypted by Encrypt (in the c# or java code, mainly for qc passwords)
- ///
- ///
- ///
- ///
- string Decrypt(string textToDecrypt, string key)
- {
- RijndaelManaged rijndaelCipher = new RijndaelManaged();
- rijndaelCipher.Mode = CipherMode.CBC;
- rijndaelCipher.Padding = PaddingMode.PKCS7;
-
- rijndaelCipher.KeySize = 0x80;
- rijndaelCipher.BlockSize = 0x80;
- byte[] encryptedData = Convert.FromBase64String(textToDecrypt);
- byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
- byte[] keyBytes = new byte[0x10];
- int len = pwdBytes.Length;
- if (len > keyBytes.Length)
- {
- len = keyBytes.Length;
- }
- Array.Copy(pwdBytes, keyBytes, len);
- rijndaelCipher.Key = keyBytes;
- rijndaelCipher.IV = keyBytes;
- byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length);
- return Encoding.UTF8.GetString(plainText);
- }
-
- ///
- /// encrypts strings to be decrypted by decrypt function(in the c# or java code, mainly for qc passwords)
- ///
- ///
- ///
- ///
- string Encrypt(string textToEncrypt, string key)
- {
- RijndaelManaged rijndaelCipher = new RijndaelManaged();
- rijndaelCipher.Mode = CipherMode.CBC;
- rijndaelCipher.Padding = PaddingMode.PKCS7;
-
- rijndaelCipher.KeySize = 0x80;
- rijndaelCipher.BlockSize = 0x80;
- byte[] pwdBytes = Encoding.UTF8.GetBytes(key);
- byte[] keyBytes = new byte[0x10];
- int len = pwdBytes.Length;
- if (len > keyBytes.Length)
- {
- len = keyBytes.Length;
- }
- Array.Copy(pwdBytes, keyBytes, len);
- rijndaelCipher.Key = keyBytes;
- rijndaelCipher.IV = keyBytes;
- ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
- byte[] plainText = Encoding.UTF8.GetBytes(textToEncrypt);
- return Convert.ToBase64String(transform.TransformFinalBlock(plainText, 0, plainText.Length));
- }
-
- ///
- /// writes to console using the ConsolWriter class
- ///
- ///
- private static void WriteToConsole(string message)
- {
- ConsoleWriter.WriteLine(message);
- }
-
- ///
- /// analyzes and runs the tests given in the param file.
- ///
- public void Run()
- {
- _ciRun = true;
- if (_runtype == TestStorageType.Unknown)
- Enum.TryParse(_ciParams["runType"], true, out _runtype);
- if (_runtype == TestStorageType.Unknown)
- {
- WriteToConsole(Resources.LauncherNoRuntype);
- return;
- }
-
- if (!_ciParams.ContainsKey("resultsFilename"))
- {
- WriteToConsole(Resources.LauncherNoResFilenameFound);
- return;
- }
- string resultsFilename = _ciParams["resultsFilename"];
-
- if (_ciParams.ContainsKey("uniqueTimeStamp"))
- {
- UniqueTimeStamp = _ciParams["uniqueTimeStamp"];
- }
- else
- {
- UniqueTimeStamp = resultsFilename.ToLower().Replace("results", "").Replace(".xml", "");
- }
-
- //create the runner according to type
- IAssetRunner runner = CreateRunner(_runtype, _ciParams);
-
- //runner instantiation failed (no tests to run or other problem)
- if (runner == null)
- {
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
-
- //run the tests!
- RunTests(runner, resultsFilename);
-
- //Console.WriteLine("Press any key to exit...");
- //Console.ReadKey();
- ConsoleQuickEdit.Enable();
- if (Launcher.ExitCode != ExitCodeEnum.Passed)
- Environment.Exit((int)Launcher.ExitCode);
- }
-
- ///
- /// creates the correct runner according to the given type
- ///
- ///
- ///
- IAssetRunner CreateRunner(TestStorageType runType, JavaProperties ciParams)
- {
- IAssetRunner runner = null;
- switch (runType)
- {
- case TestStorageType.Alm:
- //check that all required parameters exist
- foreach (string param1 in requiredParamsForQcRun)
- {
- if (!_ciParams.ContainsKey(param1))
- {
- ConsoleWriter.WriteLine(string.Format(Resources.LauncherParamRequired, param1));
- return null;
- }
- }
-
- //parse params that need parsing
- double dblQcTimeout = int.MaxValue;
- if (!double.TryParse(_ciParams["almTimeout"], out dblQcTimeout))
- {
- ConsoleWriter.WriteLine(Resources.LauncherTimeoutNotNumeric);
- dblQcTimeout = int.MaxValue;
- }
-
- ConsoleWriter.WriteLine(string.Format(Resources.LuancherDisplayTimout, dblQcTimeout));
-
- QcRunMode enmQcRunMode = QcRunMode.RUN_LOCAL;
- if (!Enum.TryParse(_ciParams["almRunMode"], true, out enmQcRunMode))
- {
- ConsoleWriter.WriteLine(Resources.LauncherIncorrectRunmode);
- enmQcRunMode = QcRunMode.RUN_LOCAL;
- }
- ConsoleWriter.WriteLine(string.Format(Resources.LauncherDisplayRunmode, enmQcRunMode.ToString()));
-
- //go over testsets in the parameters, and collect them
- List sets = GetParamsWithPrefix("TestSet");
-
- if (sets.Count == 0)
- {
- ConsoleWriter.WriteLine(Resources.LauncherNoTests);
- return null;
- }
-
- //create an Alm runner
- runner = new AlmTestSetsRunner(_ciParams["almServerUrl"],
- _ciParams["almUserName"],
- Decrypt(_ciParams["almPassword"], secretkey),
- _ciParams["almDomain"],
- _ciParams["almProject"],
- dblQcTimeout,
- enmQcRunMode,
- _ciParams["almRunHost"],
- sets);
- break;
- case TestStorageType.FileSystem:
-
- //get the tests
- IEnumerable tests = GetParamsWithPrefix("Test");
-
- IEnumerable jenkinsEnvVariablesWithCommas = GetParamsWithPrefix("JenkinsEnv");
- Dictionary jenkinsEnvVariables = new Dictionary();
- foreach (string var in jenkinsEnvVariablesWithCommas)
- {
- string[] nameVal = var.Split(",;".ToCharArray());
- jenkinsEnvVariables.Add(nameVal[0], nameVal[1]);
- }
- //parse the timeout into a TimeSpan
- TimeSpan timeout = TimeSpan.MaxValue;
- if (_ciParams.ContainsKey("fsTimeout"))
- {
- string strTimoutInSeconds = _ciParams["fsTimeout"];
- if (strTimoutInSeconds.Trim() != "-1")
- {
- int intTimoutInSeconds = 0;
- int.TryParse(strTimoutInSeconds, out intTimoutInSeconds);
- timeout = TimeSpan.FromSeconds(intTimoutInSeconds);
- }
- }
- ConsoleWriter.WriteLine("Launcher timeout is " + timeout.ToString(@"dd\:\:hh\:mm\:ss"));
-
- //LR specific values:
- //default values are set by JAVA code, in com.hp.application.automation.tools.model.RunFromFileSystemModel.java
-
- int pollingInterval = 30;
- if (_ciParams.ContainsKey("controllerPollingInterval"))
- pollingInterval = int.Parse(_ciParams["controllerPollingInterval"]);
- ConsoleWriter.WriteLine("Controller Polling Interval: " + pollingInterval + " seconds");
-
- TimeSpan perScenarioTimeOutMinutes = TimeSpan.MaxValue;
- if (_ciParams.ContainsKey("PerScenarioTimeOut"))
- {
- string strTimoutInMinutes = _ciParams["PerScenarioTimeOut"];
- //ConsoleWriter.WriteLine("reading PerScenarioTimeout: "+ strTimoutInMinutes);
- if (strTimoutInMinutes.Trim() != "-1")
- {
- int intTimoutInMinutes = 0;
- if (int.TryParse(strTimoutInMinutes, out intTimoutInMinutes))
- perScenarioTimeOutMinutes = TimeSpan.FromMinutes(intTimoutInMinutes);
- //ConsoleWriter.WriteLine("PerScenarioTimeout: "+perScenarioTimeOutMinutes+" minutes");
- }
- }
- ConsoleWriter.WriteLine("PerScenarioTimeout: " + perScenarioTimeOutMinutes.ToString(@"dd\:\:hh\:mm\:ss") + " minutes");
-
- char[] delim = { '\n' };
- List ignoreErrorStrings = new List();
- if (_ciParams.ContainsKey("ignoreErrorStrings"))
- {
- if (_ciParams.ContainsKey("ignoreErrorStrings"))
- {
- ignoreErrorStrings.AddRange(Array.ConvertAll(_ciParams["ignoreErrorStrings"].Split(delim, StringSplitOptions.RemoveEmptyEntries), ignoreError => ignoreError.Trim()));
- }
- }
-
- if (tests == null || tests.Count() == 0)
- {
- WriteToConsole(Resources.LauncherNoTestsFound);
- }
-
- List validTests = Helper.ValidateFiles(tests);
-
- if (tests != null && tests.Count() > 0 && validTests.Count == 0)
- {
- ConsoleWriter.WriteLine(Resources.LauncherNoValidTests);
- return null;
- }
-
- //--MC connection info
- McConnectionInfo mcConnectionInfo = new McConnectionInfo();
- if (_ciParams.ContainsKey("MobileHostAddress"))
- {
- string mcServerUrl = _ciParams["MobileHostAddress"];
-
- if (!string.IsNullOrEmpty(mcServerUrl) )
- {
- //url is something like http://xxx.xxx.xxx.xxx:8080
- string[] strArray = mcServerUrl.Split(new Char[] { ':' });
- if (strArray.Length == 3)
- {
- mcConnectionInfo.MobileHostAddress = strArray[1].Replace("/", "");
- mcConnectionInfo.MobileHostPort = strArray[2];
- }
-
- //mc username
- if (_ciParams.ContainsKey("MobileUserName"))
- {
- string mcUsername = _ciParams["MobileUserName"];
- if (!string.IsNullOrEmpty(mcUsername))
- {
- mcConnectionInfo.MobileUserName = mcUsername;
- }
- }
-
- //mc password
- if (_ciParams.ContainsKey("MobilePassword"))
- {
- string mcPassword = _ciParams["MobilePassword"];
- if (!string.IsNullOrEmpty(mcPassword))
- {
- mcConnectionInfo.MobilePassword = Decrypt(mcPassword, secretkey);
- }
- }
-
- //ssl
- if (_ciParams.ContainsKey("MobileUseSSL"))
- {
- string mcUseSSL = _ciParams["MobileUseSSL"];
- if (!string.IsNullOrEmpty(mcUseSSL))
- {
- mcConnectionInfo.MobileUseSSL = int.Parse(mcUseSSL);
- }
- }
-
- //Proxy enabled flag
- if (_ciParams.ContainsKey("MobileUseProxy"))
- {
- string useProxy = _ciParams["MobileUseProxy"];
- if (!string.IsNullOrEmpty(useProxy))
- {
- mcConnectionInfo.MobileUseProxy = int.Parse(useProxy);
- }
- }
-
-
- //Proxy type
- if (_ciParams.ContainsKey("MobileProxyType"))
- {
- string proxyType = _ciParams["MobileProxyType"];
- if (!string.IsNullOrEmpty(proxyType))
- {
- mcConnectionInfo.MobileProxyType = int.Parse(proxyType);
- }
- }
-
-
- //proxy address
- if (_ciParams.ContainsKey("MobileProxySetting_Address"))
- {
- string proxyAddress = _ciParams["MobileProxySetting_Address"];
- if (!string.IsNullOrEmpty(proxyAddress))
- {
- // data is something like "16.105.9.23:8080"
- string[] strArray4ProxyAddr = proxyAddress.Split(new Char[] { ':' });
- if (strArray.Length == 2)
- {
- mcConnectionInfo.MobileProxySetting_Address = strArray4ProxyAddr[0];
- mcConnectionInfo.MobileProxySetting_Port = int.Parse(strArray4ProxyAddr[1]);
- }
- }
- }
-
- //Proxy authentication
- if (_ciParams.ContainsKey("MobileProxySetting_Authentication"))
- {
- string proxyAuthentication = _ciParams["MobileProxySetting_Authentication"];
- if (!string.IsNullOrEmpty(proxyAuthentication))
- {
- mcConnectionInfo.MobileProxySetting_Authentication = int.Parse(proxyAuthentication);
- }
- }
-
- //Proxy username
- if (_ciParams.ContainsKey("MobileProxySetting_UserName"))
- {
- string proxyUsername = _ciParams["MobileProxySetting_UserName"];
- if (!string.IsNullOrEmpty(proxyUsername))
- {
- mcConnectionInfo.MobileProxySetting_UserName = proxyUsername;
- }
- }
-
- //Proxy password
- if (_ciParams.ContainsKey("MobileProxySetting_Password"))
- {
- string proxyPassword = _ciParams["MobileProxySetting_Password"];
- if (!string.IsNullOrEmpty(proxyPassword))
- {
- mcConnectionInfo.MobileProxySetting_Password = Decrypt(proxyPassword, secretkey);
- }
- }
-
- }
- }
-
- // other mobile info
- string mobileinfo = "";
- if (_ciParams.ContainsKey("mobileinfo"))
- {
- mobileinfo = _ciParams["mobileinfo"];
- }
-
- runner = new FileSystemTestsRunner(validTests, timeout, pollingInterval, perScenarioTimeOutMinutes, ignoreErrorStrings, jenkinsEnvVariables, mcConnectionInfo, mobileinfo);
-
- break;
-
- default:
- runner = null;
- break;
- }
- return runner;
- }
-
- private List GetParamsWithPrefix(string prefix)
- {
- int idx = 1;
- List parameters = new List();
- while (_ciParams.ContainsKey(prefix + idx))
- {
- string set = _ciParams[prefix + idx];
- if (set.StartsWith("Root\\"))
- set = set.Substring(5);
- set = set.TrimEnd("\\".ToCharArray());
- parameters.Add(set.TrimEnd());
- ++idx;
- }
- return parameters;
- }
-
- ///
- /// used by the run fuction to run the tests
- ///
- ///
- ///
- private void RunTests(IAssetRunner runner, string resultsFile)
- {
- try
- {
- if (_ciRun)
- {
- _xmlBuilder = new JunitXmlBuilder();
- _xmlBuilder.XmlName = resultsFile;
- }
-
- TestSuiteRunResults results = runner.Run();
-
- if (results == null)
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
-
- _xmlBuilder.CreateXmlFromRunResults(results);
-
- //if there is an error
- if (results.TestRuns.Any(tr => tr.TestState == TestState.Failed || tr.TestState == TestState.Error))
- {
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- }
-
- int numFailures = results.TestRuns.Count(t => t.TestState == TestState.Failed);
- int numSuccess = results.TestRuns.Count(t => t.TestState == TestState.Passed);
- int numErrors = results.TestRuns.Count(t => t.TestState == TestState.Error);
-
- //TODO: Temporery fix to remove since jenkins doesnt retrive resutls from jobs that marked as failed and unstable marks jobs with only failed tests
- if ((numErrors <= 0) && (numFailures > 0))
- {
- Launcher.ExitCode = Launcher.ExitCodeEnum.Unstable;
- }
-
- foreach (var testRun in results.TestRuns)
- {
- if (testRun.FatalErrors > 0 && !testRun.TestPath.Equals(""))
- {
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- break;
- }
- }
-
- //this is the total run summary
- ConsoleWriter.ActiveTestRun = null;
- string runStatus = "";
- switch (Launcher.ExitCode)
- {
- case ExitCodeEnum.Passed:
- runStatus = "Job succeeded";
- break;
- case ExitCodeEnum.Unstable:
- runStatus = "Job unstable (Passed with failed tests)";
- break;
- case ExitCodeEnum.Aborted:
- runStatus = "Job failed due to being Aborted";
- break;
- case ExitCodeEnum.Failed:
- runStatus = "Job failed";
- break;
- default:
- runStatus = "Error: Job status is Undefined";
- break;
- }
-
- ConsoleWriter.WriteLine(Resources.LauncherDoubleSeperator);
- ConsoleWriter.WriteLine(string.Format(Resources.LauncherDisplayStatistics, runStatus, results.TestRuns.Count, numSuccess, numFailures, numErrors));
-
- if (!runner.RunWasCancelled)
- {
- results.TestRuns.ForEach(tr => ConsoleWriter.WriteLine(((tr.HasWarnings) ? "Warning".PadLeft(7) : tr.TestState.ToString().PadRight(7)) + ": " + tr.TestPath));
-
- ConsoleWriter.WriteLine(Resources.LauncherDoubleSeperator);
- if (ConsoleWriter.ErrorSummaryLines != null && ConsoleWriter.ErrorSummaryLines.Count > 0)
- {
- ConsoleWriter.WriteLine("Job Errors summary:");
- ConsoleWriter.ErrorSummaryLines.ForEach(line => ConsoleWriter.WriteLine(line));
- }
-
- }
-
- //ConsoleWriter.WriteLine("Returning " + runStatus + ".");
- }
- finally
- {
- try
- {
- runner.Dispose();
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.LauncherRunnerDisposeError, ex.Message));
- };
- }
-
- }
-
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.Properties;
+using HpToolsLauncher.RTS;
+using HpToolsLauncher.TestRunners;
+using HpToolsLauncher.Utils;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace HpToolsLauncher
+{
+ public enum CiName
+ {
+ Hudson,
+ Jenkins,
+ TFS,
+ CCNET
+ }
+
+ public class Launcher
+ {
+ private IAssetRunner _runner;
+ private IXmlBuilder _xmlBuilder;
+ private bool _ciRun = false;
+ private readonly JavaProperties _ciParams = new JavaProperties();
+ private TestStorageType _runType;
+ private static ExitCodeEnum _exitCode = ExitCodeEnum.Passed;
+ private const string _dateFormat = "dd'/'MM'/'yyyy HH':'mm':'ss";
+ private string _encoding;
+ private const string PASSWORD = "Password";
+ private const string RERUN_ALL_TESTS = "Rerun the entire set of tests";
+ private const string RERUN_SPECIFIC_TESTS = "Rerun specific tests in the build";
+ private const string RERUN_FAILED_TESTS = "Rerun only failed tests";
+ private const string ONE = "1";
+ private const string CLEANUP_TEST = "CleanupTest";
+
+ public const string ClassName = "HPToolsFileSystemRunner";
+
+ public static string DateFormat
+ {
+ get { return _dateFormat; }
+ }
+
+ ///
+ /// if running an alm job theses strings are mandatory:
+ ///
+ private readonly string[] requiredParamsForQcRun = { "almServerUrl",
+ "almUsername",
+ "almPassword",
+ "almDomain",
+ "almProject",
+ "almRunMode",
+ "almTimeout",
+ "almRunHost"};
+ private readonly char[] _colon_semicolon = ",;".ToCharArray();
+
+ ///
+ /// a place to save the unique timestamp which shows up in properties/results/abort file names
+ /// this timestamp per job run.
+ ///
+ public static string UniqueTimeStamp { get; set; }
+
+ ///
+ /// saves the exit code in case we want to run all tests but fail at the end since a file wasn't found
+ ///
+ public static ExitCodeEnum ExitCode
+ {
+ get { return _exitCode; }
+ set { _exitCode = value; }
+ }
+
+ public enum ExitCodeEnum
+ {
+ Passed = 0,
+ Failed = -1,
+ Unstable = -2,
+ Aborted = -3
+ }
+
+
+ ///
+ /// constructor
+ ///
+ ///
+ ///
+ public Launcher(string paramFileName, TestStorageType runType, string encoding = "UTF-8")
+ {
+ _runType = runType;
+ if (paramFileName != null)
+ _ciParams.Load(paramFileName);
+
+ _encoding = encoding;
+ }
+
+ ///
+ /// writes to console using the ConsolWriter class
+ ///
+ ///
+ private static void WriteToConsole(string message)
+ {
+ ConsoleWriter.WriteLine(message);
+ }
+
+ public void SafelyCancel()
+ {
+ if (_runner != null)
+ {
+ _runner.SafelyCancel();
+ }
+ }
+
+ ///
+ /// analyzes and runs the tests given in the param file.
+ ///
+ public void Run()
+ {
+ _ciRun = true;
+ if (_runType == TestStorageType.Unknown)
+ Enum.TryParse(_ciParams["runType"], true, out _runType);
+ if (_runType == TestStorageType.Unknown)
+ {
+ WriteToConsole(Resources.LauncherNoRuntype);
+ return;
+ }
+
+ if (!_ciParams.ContainsKey("resultsFilename"))
+ {
+ WriteToConsole(Resources.LauncherNoResFilenameFound);
+ return;
+ }
+ string resultsFilename = _ciParams["resultsFilename"];
+
+ UniqueTimeStamp = _ciParams.GetOrDefault("uniqueTimeStamp", resultsFilename.ToLower().Replace("results", string.Empty).Replace(".xml", string.Empty));
+
+ //run the entire set of test once
+ //create the runner according to type
+ _runner = CreateRunner(true);
+
+ //runner instantiation failed (no tests to run or other problem)
+ if (_runner == null)
+ {
+ ConsoleWriter.WriteLine("empty runner;");
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ return;
+ }
+
+ TestSuiteRunResults results = _runner.Run();
+
+ string onCheckFailedTests = _ciParams.GetOrDefault("onCheckFailedTest");
+ bool rerunTestsOnFailure = !string.IsNullOrEmpty(onCheckFailedTests) && Convert.ToBoolean(onCheckFailedTests.ToLower());
+ if (_runType != TestStorageType.MBT)
+ {
+ RunSummary(resultsFilename, results);
+ }
+
+ if (_runType == TestStorageType.FileSystem)
+ {
+ //the "On failure" option is selected and the run build contains failed tests
+ // we need to check if there were any failed tests
+ bool thereAreFailedTests = _exitCode == ExitCodeEnum.Failed || results.NumFailures > 0;
+ if (rerunTestsOnFailure && thereAreFailedTests)
+ {
+ ConsoleWriter.WriteLine("There are failed tests.");
+
+ string fsTestType = _ciParams.GetOrDefault("testType");
+
+ //rerun the selected tests (either the entire set, just the selected tests or only the failed tests)
+ List runResults = results.TestRuns;
+ List reruntests = new List();
+ int index = 0;
+ foreach (var item in runResults)
+ {
+ if ((fsTestType == RERUN_ALL_TESTS) ||
+ (fsTestType == RERUN_FAILED_TESTS && (item.TestState == TestState.Failed || item.TestState == TestState.Error)))
+ {
+ index++;
+ reruntests.Add(new TestInfo(string.Format("FailedTest{0}", index), item.TestInfo));
+ }
+ }
+ if (fsTestType == RERUN_SPECIFIC_TESTS)
+ {
+ var specificTests = GetValidTests("FailedTest", Resources.LauncherNoFailedTestsFound, Resources.LauncherNoValidFailedTests, fsTestType);
+ reruntests = FileSystemTestsRunner.GetListOfTestInfo(specificTests);
+ }
+
+ // save the initial XmlBuilder because it contains testcases already created, in order to speed up the report building
+ JunitXmlBuilder initialXmlBuilder = ((RunnerBase)_runner).XmlBuilder;
+ //create the runner according to type
+ _runner = CreateRunner(false, reruntests);
+
+ //runner instantiation failed (no tests to run or other problem)
+ if (_runner == null)
+ {
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ return;
+ }
+
+ ((RunnerBase)_runner).XmlBuilder = initialXmlBuilder; // reuse the populated initialXmlBuilder because it contains testcases already created, in order to speed up the report building
+ TestSuiteRunResults rerunResults = _runner.Run();
+
+ RunSummary(resultsFilename, results, rerunResults);
+ }
+ }
+ Environment.Exit((int)_exitCode);
+ }
+
+ ///
+ /// creates the correct runner according to the given type
+ ///
+ ///
+ private IAssetRunner CreateRunner(bool isFirstRun, List reruntests = null)
+ {
+ IAssetRunner runner = null;
+
+ switch (_runType)
+ {
+ case TestStorageType.AlmLabManagement:
+
+ case TestStorageType.Alm:
+ {
+ //check that all required parameters exist
+ foreach (string param1 in requiredParamsForQcRun)
+ {
+ if (!_ciParams.ContainsKey(param1))
+ {
+ ConsoleWriter.WriteLine(string.Format(Resources.LauncherParamRequired, param1));
+ return null;
+ }
+ }
+
+ //parse params that need parsing
+ double dblQcTimeout;
+ if (!double.TryParse(_ciParams["almTimeout"], out dblQcTimeout))
+ {
+ ConsoleWriter.WriteLine(Resources.LauncherTimeoutNotNumeric);
+ dblQcTimeout = int.MaxValue;
+ }
+
+ ConsoleWriter.WriteLine(string.Format(Resources.LuancherDisplayTimout, dblQcTimeout));
+
+ QcRunMode enmQcRunMode;
+ if (!Enum.TryParse(_ciParams["almRunMode"], true, out enmQcRunMode))
+ {
+ ConsoleWriter.WriteLine(Resources.LauncherIncorrectRunmode);
+ enmQcRunMode = QcRunMode.RUN_LOCAL;
+ }
+ ConsoleWriter.WriteLine(string.Format(Resources.LauncherDisplayRunmode, enmQcRunMode.ToString()));
+
+ //go over test sets in the parameters, and collect them
+ List sets = GetParamsWithPrefix("TestSet", true);
+
+ if (sets.Count == 0)
+ {
+ ConsoleWriter.WriteLine(Resources.LauncherNoTests);
+ return null;
+ }
+
+ List @params = GetValidParams();
+
+ //check if filterTests flag is selected; if yes apply filters on the list
+ bool isFilterSelected;
+ string filter = _ciParams.GetOrDefault("FilterTests");
+
+ isFilterSelected = !string.IsNullOrEmpty(filter) && Convert.ToBoolean(filter.ToLower());
+
+ string filterByName = _ciParams.GetOrDefault("FilterByName");
+
+ string statuses = _ciParams.GetOrDefault("FilterByStatus");
+
+ List filterByStatuses = new List();
+
+ if (statuses != string.Empty)
+ {
+ if (statuses.Contains(","))
+ {
+ filterByStatuses = statuses.Split(',').ToList();
+ }
+ else
+ {
+ filterByStatuses.Add(statuses);
+ }
+ }
+
+ bool isSSOEnabled = _ciParams.ContainsKey("SSOEnabled") ? Convert.ToBoolean(_ciParams["SSOEnabled"]) : false;
+ string clientID = _ciParams.GetOrDefault("almClientID");
+ string apiKey = _ciParams.ContainsKey("almApiKeySecret") ? Encrypter.Decrypt(_ciParams["almApiKeySecret"]) : string.Empty;
+ string almRunHost = _ciParams.GetOrDefault("almRunHost");
+
+ //create an Alm runner
+ runner = new AlmTestSetsRunner(_ciParams["almServerUrl"],
+ _ciParams["almUsername"],
+ Encrypter.Decrypt(_ciParams["almPassword"]),
+ _ciParams["almDomain"],
+ _ciParams["almProject"],
+ dblQcTimeout,
+ enmQcRunMode,
+ almRunHost,
+ sets,
+ @params,
+ isFilterSelected,
+ filterByName,
+ filterByStatuses,
+ isFirstRun,
+ _runType,
+ isSSOEnabled,
+ clientID, apiKey);
+ break;
+ }
+ case TestStorageType.FileSystem:
+ {
+ bool displayController = _ciParams.GetOrDefault("displayController") == ONE;
+ string analysisTemplate = _ciParams.GetOrDefault("analysisTemplate");
+
+ bool printInputParams = _ciParams.GetOrDefault("printTestParams", ONE) == ONE;
+ IEnumerable jenkinsEnvVarsWithCommas = GetParamsWithPrefix("JenkinsEnv");
+ Dictionary jenkinsEnvVars = new Dictionary();
+ foreach (string var in jenkinsEnvVarsWithCommas)
+ {
+ string[] nameVal = var.Split(_colon_semicolon);
+ jenkinsEnvVars.Add(nameVal[0], nameVal[1]);
+ }
+
+ //add build tests and cleanup tests in correct order
+ List validTests = new List();
+ List cleanupAndRerunTests = new List();
+
+ if (isFirstRun)
+ {
+ ConsoleWriter.WriteLine("Run build tests");
+ List validBuildTests = GetValidTests("Test", Resources.LauncherNoTestsFound, Resources.LauncherNoValidTests, string.Empty);
+ if (validBuildTests.Count == 0)
+ {
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ }
+
+ //run only the build tests
+ foreach (var item in validBuildTests)
+ {
+ validTests.Add(item);
+ }
+ }
+ else
+ { //add also cleanup tests
+ string fsTestType = _ciParams.GetOrDefault("testType");
+ List validCleanupTests = GetValidTests(CLEANUP_TEST, Resources.LauncherNoCleanupTestsFound, Resources.LauncherNoValidCleanupTests, fsTestType);
+ List reruns = GetParamsWithPrefix("Reruns");
+ List numberOfReruns = new List();
+ foreach (var item in reruns)
+ {
+ numberOfReruns.Add(int.Parse(item));
+ }
+
+ bool noRerunsSet = CheckListOfRerunValues(numberOfReruns);
+
+ if (noRerunsSet)
+ {
+ ConsoleWriter.WriteLine("In order to rerun the tests the number of reruns should be greater than zero.");
+ }
+ else
+ {
+ switch (fsTestType)
+ {
+ case RERUN_ALL_TESTS: ConsoleWriter.WriteLine("The entire test set will run again."); break;
+ case RERUN_SPECIFIC_TESTS: ConsoleWriter.WriteLine("Only the selected tests will run again."); break;
+ case RERUN_FAILED_TESTS: ConsoleWriter.WriteLine("Only the failed tests will run again."); break;
+ }
+
+ for (int i = 0; i < numberOfReruns.Count; i++)
+ {
+ var currentRerun = numberOfReruns[i];
+
+ if (fsTestType == RERUN_ALL_TESTS || fsTestType == RERUN_FAILED_TESTS)
+ {
+ while (currentRerun > 0)
+ {
+ if (validCleanupTests.Count > 0)
+ {
+ var cleanupTest = FileSystemTestsRunner.GetFirstTestInfo(validCleanupTests[i], jenkinsEnvVars);
+ if (cleanupTest != null)
+ cleanupAndRerunTests.Add(cleanupTest);
+ }
+
+ if (reruntests.Count > 0)
+ {
+ cleanupAndRerunTests.AddRange(reruntests);
+ }
+ else
+ {
+ Console.WriteLine(fsTestType == RERUN_ALL_TESTS ? "There are no tests to rerun." : "There are no failed tests to rerun.");
+ break;
+ }
+
+ currentRerun--;
+ }
+ }
+ else if (fsTestType == RERUN_SPECIFIC_TESTS)
+ {
+ while (currentRerun > 0)
+ {
+ if (validCleanupTests.Count > 0)
+ {
+ var cleanupTest = FileSystemTestsRunner.GetFirstTestInfo(validCleanupTests[i], jenkinsEnvVars);
+ if (cleanupTest != null)
+ cleanupAndRerunTests.Add(cleanupTest);
+ }
+ if (reruntests != null && reruntests.Count > i)
+ cleanupAndRerunTests.Add(reruntests[i]);
+ else
+ {
+ Console.WriteLine(string.Format("There is no specific test with index = {0}", i + 1));
+ break;
+ }
+
+ currentRerun--;
+ }
+ }
+ }
+ }
+ }
+
+ //parse the timeout into a TimeSpan
+ TimeSpan timeout = TimeSpan.MaxValue;
+ if (_ciParams.ContainsKey("fsTimeout"))
+ {
+ string strTimeoutInSeconds = _ciParams["fsTimeout"];
+ if (strTimeoutInSeconds.Trim() != "-1")
+ {
+ int intTimeoutInSeconds;
+ int.TryParse(strTimeoutInSeconds, out intTimeoutInSeconds);
+ timeout = TimeSpan.FromSeconds(intTimeoutInSeconds);
+ }
+ }
+ ConsoleWriter.WriteLine("Launcher timeout is " + timeout.ToString(@"dd\:\:hh\:mm\:ss"));
+
+ //LR specific values:
+ //default values are set by JAVA code, in com.hpe.application.automation.tools.model.RunFromFileSystemModel.java
+
+ int pollingInterval = 30;
+ if (_ciParams.ContainsKey("controllerPollingInterval"))
+ pollingInterval = int.Parse(_ciParams["controllerPollingInterval"]);
+ ConsoleWriter.WriteLine("Controller Polling Interval: " + pollingInterval + " seconds");
+
+ TimeSpan perScenarioTimeOutMinutes = TimeSpan.MaxValue;
+ if (_ciParams.ContainsKey("PerScenarioTimeOut"))
+ {
+ string strTimeoutInMinutes = _ciParams["PerScenarioTimeOut"];
+ int intTimoutInMinutes;
+ if (strTimeoutInMinutes.Trim() != "-1" && int.TryParse(strTimeoutInMinutes, out intTimoutInMinutes))
+ perScenarioTimeOutMinutes = TimeSpan.FromMinutes(intTimoutInMinutes);
+ }
+ ConsoleWriter.WriteLine("PerScenarioTimeout: " + perScenarioTimeOutMinutes.ToString(@"dd\:\:hh\:mm\:ss") + " minutes");
+
+ char[] delimiter = { '\n' };
+ List ignoreErrorStrings = new List();
+ if (_ciParams.ContainsKey("ignoreErrorStrings"))
+ {
+ ignoreErrorStrings.AddRange(Array.ConvertAll(_ciParams["ignoreErrorStrings"].Split(delimiter, StringSplitOptions.RemoveEmptyEntries), ignoreError => ignoreError.Trim()));
+ }
+
+ //If a file path was provided and it doesn't exist stop the analysis launcher
+ if (!string.IsNullOrWhiteSpace(analysisTemplate) && !Helper.FileExists(analysisTemplate))
+ {
+ return null;
+ }
+
+ //--MC connection info
+ McConnectionInfo mcConnectionInfo = null;
+ try
+ {
+ mcConnectionInfo = new McConnectionInfo(_ciParams);
+ }
+ catch(NoMcConnectionException)
+ {
+ // no action, the Test will use the default UFT One settings
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteErrLine(ex.Message);
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ }
+
+ // other mobile info
+ string mobileinfo = string.Empty;
+ if (_ciParams.ContainsKey("mobileinfo"))
+ {
+ mobileinfo = _ciParams["mobileinfo"];
+ }
+ CloudBrowser cloudBrowser = null;
+ string strCloudBrowser = _ciParams.GetOrDefault("cloudBrowser").Trim();
+ if (!strCloudBrowser.IsNullOrEmpty())
+ {
+ CloudBrowser.TryParse(strCloudBrowser, out cloudBrowser);
+ }
+
+ var parallelRunnerEnvironments = new Dictionary>();
+
+ // retrieve the parallel runner environment for each test
+ if (_ciParams.ContainsKey("parallelRunnerMode"))
+ {
+ foreach (var test in validTests)
+ {
+ string envKey = "Parallel" + test.Id + "Env";
+ List testEnvironments = GetParamsWithPrefix(envKey);
+
+ // add the environments for all the valid tests
+ parallelRunnerEnvironments.Add(test.Id, testEnvironments);
+ }
+ }
+
+ // users can provide a custom report path
+ string reportPath = null;
+ if (_ciParams.ContainsKey("fsReportPath"))
+ {
+ if (Directory.Exists(_ciParams["fsReportPath"]))
+ { //path is not parameterized
+ reportPath = _ciParams["fsReportPath"];
+ }
+ else
+ { //path is parameterized
+ string fsReportPath = _ciParams["fsReportPath"];
+
+ //get parameter name
+ fsReportPath = fsReportPath.Trim(new char[] { ' ', '$', '{', '}' });
+
+ //get parameter value
+ fsReportPath = fsReportPath.Trim(new char[] { ' ', '\t' });
+ try
+ {
+ reportPath = jenkinsEnvVars[fsReportPath];
+ }
+ catch (KeyNotFoundException)
+ {
+ Console.WriteLine("============================================================================");
+ Console.WriteLine("The provided results folder path {0} does not exist.", fsReportPath);
+ Console.WriteLine("============================================================================");
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ }
+ }
+ }
+
+ RunAsUser uftRunAsUser = null;
+ string username = _ciParams.GetOrDefault("uftRunAsUserName");
+ if (!string.IsNullOrEmpty(username))
+ {
+ string encryptedAndEncodedPwd = _ciParams.GetOrDefault("uftRunAsUserEncodedPassword");
+ string encryptedPwd = _ciParams.GetOrDefault("uftRunAsUserPassword");
+ if (!string.IsNullOrEmpty(encryptedAndEncodedPwd))
+ {
+ string encodedPwd = Encrypter.Decrypt(encryptedAndEncodedPwd);
+ uftRunAsUser = new RunAsUser(username, encodedPwd);
+ }
+ else if (!string.IsNullOrEmpty(encryptedPwd))
+ {
+ string plainTextPwd = Encrypter.Decrypt(encryptedPwd);
+ uftRunAsUser = new RunAsUser(username, plainTextPwd.ToSecureString());
+ }
+ }
+
+ SummaryDataLogger summaryDataLogger = GetSummaryDataLogger();
+ List scriptRTSSet = GetScriptRtsSet();
+ string resultsFilename = _ciParams["resultsFilename"];
+ string uftRunMode = _ciParams.GetOrDefault("fsUftRunMode", "Fast");
+ if (validTests.Count > 0)
+ {
+ runner = new FileSystemTestsRunner(validTests, GetValidParams(), printInputParams, timeout, uftRunMode, pollingInterval, perScenarioTimeOutMinutes, ignoreErrorStrings, jenkinsEnvVars, new DigitalLab(mcConnectionInfo, mobileinfo, cloudBrowser), parallelRunnerEnvironments, displayController, analysisTemplate, summaryDataLogger, scriptRTSSet, reportPath, resultsFilename, _encoding, uftRunAsUser);
+ }
+ else if (cleanupAndRerunTests.Count > 0)
+ {
+ runner = new FileSystemTestsRunner(cleanupAndRerunTests, printInputParams, timeout, uftRunMode, pollingInterval, perScenarioTimeOutMinutes, ignoreErrorStrings, jenkinsEnvVars, new DigitalLab(mcConnectionInfo, mobileinfo, cloudBrowser), parallelRunnerEnvironments, displayController, analysisTemplate, summaryDataLogger, scriptRTSSet, reportPath, resultsFilename, _encoding, uftRunAsUser);
+ }
+ else
+ {
+ ConsoleWriter.WriteLine(Resources.FsRunnerNoValidTests);
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ }
+
+ break;
+ }
+ case TestStorageType.MBT:
+ string parentFolder = _ciParams["parentFolder"];
+ string repoFolder = _ciParams["repoFolder"];
+
+ int counter = 1;
+ string testProp = "test" + counter;
+ List tests = new List();
+ while (_ciParams.ContainsKey(testProp))
+ {
+ MBTTest test = new MBTTest();
+ tests.Add(test);
+
+ test.Name = _ciParams[testProp];
+ test.Script = _ciParams.GetOrDefault("script" + counter);
+ test.UnitIds = _ciParams.GetOrDefault("unitIds" + counter);
+ test.UnderlyingTests = new List(_ciParams.GetOrDefault("underlyingTests" + counter).Split(';'));
+ test.PackageName = _ciParams.GetOrDefault("package" + counter);
+ test.DatableParams = _ciParams.GetOrDefault("datableParams" + counter);
+
+ test.PackageName = _ciParams.GetOrDefault("package" + counter, "");
+ test.DatableParams = _ciParams.GetOrDefault("datableParams" + counter, "");
+ testProp = "test" + (++counter);
+ }
+
+ runner = new MBTRunner(parentFolder, repoFolder, tests);
+ break;
+ default:
+ runner = null;
+ break;
+ }
+ return runner;
+ }
+
+ private List GetParamsWithPrefix(string prefix, bool skipEmptyEntries = false)
+ {
+ int idx = 1;
+ List parameters = new List();
+ while (_ciParams.ContainsKey(prefix + idx))
+ {
+ string set = _ciParams[prefix + idx];
+ if (set.StartsWith("Root\\"))
+ set = set.Substring(5);
+ set = set.TrimEnd(" \\".ToCharArray());
+ if (!(skipEmptyEntries && string.IsNullOrWhiteSpace(set)))
+ {
+ parameters.Add(set);
+ }
+ ++idx;
+ }
+ return parameters;
+ }
+
+ private Dictionary GetKeyValuesWithPrefix(string prefix)
+ {
+ int idx = 1;
+
+ Dictionary dict = new Dictionary();
+
+ while (_ciParams.ContainsKey(prefix + idx))
+ {
+ string set = _ciParams[prefix + idx];
+ if (set.StartsWith("Root\\"))
+ set = set.Substring(5);
+ set = set.TrimEnd(" \\".ToCharArray());
+ string key = prefix + idx;
+ dict[key] = set;
+ ++idx;
+ }
+
+ return dict;
+ }
+
+ ///
+ /// used by the run fuction to run the tests
+ ///
+ ///
+ ///
+ private void RunSummary(string resultsFile, TestSuiteRunResults results, TestSuiteRunResults rerunResults = null)
+ {
+ try
+ {
+ if (results == null)
+ {
+ Environment.Exit((int)ExitCodeEnum.Failed);
+ return;
+ }
+
+ if (_runType != TestStorageType.FileSystem) // for FileSystem the report is already generated inside FileSystemTestsRunner.Run()
+ {
+ if (_ciRun)
+ {
+ _xmlBuilder = new JunitXmlBuilder();
+ _xmlBuilder.XmlName = resultsFile;
+ }
+
+ _xmlBuilder.CreateXmlFromRunResults(results);
+ }
+ var allTestRuns = new List(results.TestRuns);
+
+ if (allTestRuns.Count == 0)
+ {
+ ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator);
+ ConsoleWriter.WriteLine("No tests were run");
+ _exitCode = ExitCodeEnum.Failed;
+ Environment.Exit((int)_exitCode);
+ }
+
+ bool is4Rerun = rerunResults != null && rerunResults.TestRuns.Count > 0;
+
+ int failures, successes, errors, warnings;
+ if (is4Rerun)
+ {
+ UpdateExitCode(rerunResults, out successes, out failures, out errors, out warnings);
+ failures += results.NumFailures;
+ successes += allTestRuns.Count(t => t.TestState == TestState.Passed);
+ errors += results.NumErrors;
+ warnings += results.NumWarnings;
+ allTestRuns.AddRange(rerunResults.TestRuns);
+ }
+ else
+ {
+ UpdateExitCode(results, out successes, out failures, out errors, out warnings);
+ }
+
+ //this is the total run summary
+ ConsoleWriter.ActiveTestRun = null;
+ string runStatus = string.Empty;
+
+ switch (_exitCode)
+ {
+ case ExitCodeEnum.Passed:
+ runStatus = "Job succeeded";
+ break;
+ case ExitCodeEnum.Unstable:
+ {
+ if (failures > 0 && warnings > 0)
+ {
+ runStatus = "Job unstable (Passed with failed tests and generated warnings)";
+ }
+ else if (failures > 0)
+ {
+ runStatus = "Job unstable (Passed with failed tests)";
+ }
+ else if (warnings > 0)
+ {
+ runStatus = "Job unstable (Generated warnings)";
+ }
+
+ break;
+ }
+ case ExitCodeEnum.Aborted:
+ runStatus = "Job failed due to being Aborted";
+ break;
+ case ExitCodeEnum.Failed:
+ runStatus = "Job failed";
+ break;
+ default:
+ runStatus = "Error: Job status is Undefined";
+ break;
+ }
+
+ ConsoleWriter.WriteLine(Resources.LauncherDoubleSeparator);
+ ConsoleWriter.WriteLine(string.Format(Resources.LauncherDisplayStatistics, runStatus, allTestRuns.Count, successes, failures, errors, warnings));
+
+ int testIndex = 1;
+ if (!_runner.RunWasCancelled)
+ {
+ allTestRuns.ForEach(tr => { ConsoleWriter.WriteLine(((tr.HasWarnings) ? "Warning".PadLeft(7) : tr.TestState.ToString().PadRight(7)) + ": " + tr.TestPath + "[" + testIndex + "]"); testIndex++; });
+
+ ConsoleWriter.WriteLine(Resources.LauncherDoubleSeparator);
+
+ if (ConsoleWriter.ErrorSummaryLines != null && ConsoleWriter.ErrorSummaryLines.Count > 0)
+ {
+ ConsoleWriter.WriteLine("Job Errors summary:");
+ ConsoleWriter.ErrorSummaryLines.ForEach(line => ConsoleWriter.WriteLine(line));
+ }
+ }
+ }
+ finally
+ {
+ try
+ {
+ _runner.Dispose();
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteLine(string.Format(Resources.LauncherRunnerDisposeError, ex.Message));
+ }
+ }
+ }
+
+ private void UpdateExitCode(TestSuiteRunResults results, out int successes, out int failures, out int errors, out int warnings)
+ {
+ failures = results.NumFailures;
+ successes = results.TestRuns.Count(t => t.TestState == TestState.Passed);
+ errors = results.NumErrors;
+ warnings = results.NumWarnings;
+
+ if (_exitCode != ExitCodeEnum.Aborted)
+ {
+ if (errors > 0)
+ {
+ _exitCode = ExitCodeEnum.Failed;
+ }
+ else if (failures > 0 && successes > 0)
+ {
+ _exitCode = ExitCodeEnum.Unstable;
+ }
+ else if (failures > 0)
+ {
+ _exitCode = ExitCodeEnum.Failed;
+ }
+ else if (warnings > 0)
+ {
+ _exitCode = ExitCodeEnum.Unstable;
+ }
+ else if (successes > 0)
+ {
+ _exitCode = ExitCodeEnum.Passed;
+ }
+
+ foreach (var testRun in results.TestRuns)
+ {
+ if (testRun.FatalErrors > 0 && !string.IsNullOrWhiteSpace(testRun.TestPath))
+ {
+ _exitCode = ExitCodeEnum.Failed;
+ break;
+ }
+ }
+ }
+ }
+
+ private SummaryDataLogger GetSummaryDataLogger()
+ {
+ SummaryDataLogger summaryDataLogger;
+
+ if (_ciParams.ContainsKey("SummaryDataLog"))
+ {
+ string[] summaryDataLogFlags = _ciParams["SummaryDataLog"].Split(";".ToCharArray());
+
+ if (summaryDataLogFlags.Length == 4)
+ {
+ //If the polling interval is not a valid number, set it to default (10 seconds)
+ int summaryDataLoggerPollingInterval;
+ if (!int.TryParse(summaryDataLogFlags[3], out summaryDataLoggerPollingInterval))
+ {
+ summaryDataLoggerPollingInterval = 10;
+ }
+
+ summaryDataLogger = new SummaryDataLogger(
+ summaryDataLogFlags[0] == ONE,
+ summaryDataLogFlags[1] == ONE,
+ summaryDataLogFlags[2] == ONE,
+ summaryDataLoggerPollingInterval
+ );
+ }
+ else
+ {
+ summaryDataLogger = new SummaryDataLogger();
+ }
+ }
+ else
+ {
+ summaryDataLogger = new SummaryDataLogger();
+ }
+
+ return summaryDataLogger;
+ }
+
+ private List GetScriptRtsSet()
+ {
+ List scriptRtsSet = new List();
+
+ IEnumerable scriptNames = GetParamsWithPrefix("ScriptRTS");
+ foreach (string scriptName in scriptNames)
+ {
+ ScriptRTSModel scriptRts = new ScriptRTSModel(scriptName);
+
+ IEnumerable additionalAttributes = GetParamsWithPrefix("AdditionalAttribute");
+ foreach (string additionalAttribute in additionalAttributes)
+ {
+ //Each additional attribute contains: script name, aditional attribute name, value and description
+ string[] additionalAttributeArguments = additionalAttribute.Split(";".ToCharArray());
+ if (additionalAttributeArguments.Length == 4 && additionalAttributeArguments[0].Equals(scriptName))
+ {
+ scriptRts.AddAdditionalAttribute(new AdditionalAttributeModel(
+ additionalAttributeArguments[1],
+ additionalAttributeArguments[2],
+ additionalAttributeArguments[3])
+ );
+ }
+ }
+
+ scriptRtsSet.Add(scriptRts);
+ }
+
+ return scriptRtsSet;
+ }
+
+ ///
+ /// Retrieve the list of valid test to run
+ ///
+ ///
+ ///
+ ///
+ /// a list of tests
+ private List GetValidTests(string propPrefix, string errorNoTestsFound, string errorNoValidTests, string fsTestType)
+ {
+ if (fsTestType != RERUN_FAILED_TESTS || propPrefix == CLEANUP_TEST)
+ {
+ List tests = new List();
+ Dictionary testsKeyValue = GetKeyValuesWithPrefix(propPrefix);
+ if (propPrefix == CLEANUP_TEST && testsKeyValue.Count == 0)
+ {
+ return tests;
+ }
+
+ foreach (var item in testsKeyValue)
+ {
+ tests.Add(new TestData(item.Value, item.Key));
+ }
+
+ if (tests.Count == 0)
+ {
+ WriteToConsole(errorNoTestsFound);
+ }
+ else
+ {
+ List validTests = Helper.ValidateFiles(tests);
+
+ if (validTests.Count > 0) return validTests;
+
+ //no valid tests found
+ ConsoleWriter.WriteLine(errorNoValidTests);
+ }
+ }
+
+ return new List();
+ }
+
+
+ ///
+ /// Returns all the valid parameters from the props file (CI args).
+ ///
+ ///
+ private List GetValidParams()
+ {
+ List parameters = new List();
+
+ int initialNumOfTests = _ciParams.ContainsKey("numOfTests") ? int.Parse(_ciParams["numOfTests"]) : 0;
+
+ for (int i = 1; i <= initialNumOfTests; ++i)
+ {
+ int j = 1;
+ while (_ciParams.ContainsKey(string.Format("Param{0}_Name_{1}", i, j)))
+ {
+ string name = _ciParams[string.Format("Param{0}_Name_{1}", i, j)].Trim();
+
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ ConsoleWriter.WriteLine(string.Format("Found no name associated with parameter with index {0} for test {1}.", j, i));
+ continue;
+ }
+
+ string val = _ciParams[string.Format("Param{0}_Value_{1}", i, j)].Trim();
+
+ string type = _ciParams[string.Format("Param{0}_Type_{1}", i, j)];
+ if (string.IsNullOrWhiteSpace(type))
+ {
+ ConsoleWriter.WriteLine(string.Format("Found no type associated with parameter {0}.", name));
+ continue;
+ }
+ else if (type == PASSWORD && !string.IsNullOrWhiteSpace(val))
+ {
+ val = Encrypter.Decrypt(val);
+ }
+
+ parameters.Add(new TestParameter(i, name, val, type.ToLower()));
+ ++j;
+ }
+ }
+
+ return parameters;
+ }
+
+ ///
+ /// Check if at least one test needs to run again
+ ///
+ ///
+ /// true if there is at least a test that needs to run again, false otherwise
+ private bool CheckListOfRerunValues(List numberOfReruns)
+ {
+ bool noRerunsSet = true;
+ for (var j = 0; j < numberOfReruns.Count; j++)
+ {
+ if (numberOfReruns.ElementAt(j) <= 0) continue;
+ noRerunsSet = false;
+ break;
+ }
+
+ return noRerunsSet;
+ }
+ }
+}
diff --git a/HpToolsLauncher/MtbManager.cs b/HpToolsLauncher/MtbManager.cs
index 7ba9250739..acc5ab9c82 100644
--- a/HpToolsLauncher/MtbManager.cs
+++ b/HpToolsLauncher/MtbManager.cs
@@ -1,18 +1,45 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+using HpToolsLauncher.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using HpToolsLauncher.Properties;
//using UFT.Runner.Properties;
namespace HpToolsLauncher
{
- public class MtbManager
+ public class MtbManager
{
public delegate IEnumerable GetContentDelegate();
diff --git a/HpToolsLauncher/MtbxManager.cs b/HpToolsLauncher/MtbxManager.cs
index 11aba14770..c71b78070b 100644
--- a/HpToolsLauncher/MtbxManager.cs
+++ b/HpToolsLauncher/MtbxManager.cs
@@ -1,189 +1,268 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Xml.Linq;
-using System.Xml.Schema;
-using HpToolsLauncher.Properties;
-
-namespace HpToolsLauncher
-{
- public class MtbxManager
- {
-
- private static string _defaultFileExt = ".mtbx";
-
-
-
- //the xml format of an mtbx file below:
- /*
-
-
-
-
-
-
-
-
-
-
-
-
- */
- public static List LoadMtbx(string mtbxContent, string testGroup)
- {
- return LoadMtbx(mtbxContent, null, testGroup);
- }
-
- public static List Parse(string mtbxFileName)
- {
- string xmlContent = File.ReadAllText(mtbxFileName);
- return Parse(xmlContent, null, mtbxFileName);
- }
-
- private static XAttribute GetAttribute(XElement x, XName attributeName)
- {
- return x.Attributes().FirstOrDefault(a => a.Name.Namespace == attributeName.Namespace
- && string.Equals(a.Name.LocalName, attributeName.LocalName, StringComparison.OrdinalIgnoreCase));
- }
-
- private static XElement GetElement(XElement x, XName eName)
- {
- return x.Elements().FirstOrDefault(a => a.Name.Namespace == eName.Namespace
- && string.Equals(a.Name.LocalName, eName.LocalName, StringComparison.OrdinalIgnoreCase));
- }
-
- private static IEnumerable GetElements(XElement x, XName eName)
- {
- return x.Elements().Where(a => a.Name.Namespace == eName.Namespace
- && string.Equals(a.Name.LocalName, eName.LocalName, StringComparison.OrdinalIgnoreCase));
- }
-
- public static List Parse(string mtbxFileName, Dictionary jankinsEnvironmentVars, string testGroupName)
- {
- return LoadMtbx(File.ReadAllText(mtbxFileName), jankinsEnvironmentVars, testGroupName);
- }
- private static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
- {
- StringBuilder sb = new StringBuilder();
-
- int previousIndex = 0;
- int index = str.IndexOf(oldValue, comparison);
- while (index != -1)
- {
- sb.Append(str.Substring(previousIndex, index - previousIndex));
- sb.Append(newValue);
- index += oldValue.Length;
-
- previousIndex = index;
- index = str.IndexOf(oldValue, index, comparison);
- }
- sb.Append(str.Substring(previousIndex));
-
- return sb.ToString();
- }
-
- public static List LoadMtbx(string xmlContent, Dictionary jankinsEnvironmentVars, string testGroupName)
- {
- var localEnv = Environment.GetEnvironmentVariables();
-
- foreach (string varName in localEnv.Keys)
- {
- string value = (string)localEnv[varName];
- xmlContent = ReplaceString(xmlContent, "%" + varName + "%", value, StringComparison.OrdinalIgnoreCase);
- xmlContent = ReplaceString(xmlContent, "${" + varName + "}", value, StringComparison.OrdinalIgnoreCase);
- }
-
- if (jankinsEnvironmentVars != null)
- {
- foreach (string varName in jankinsEnvironmentVars.Keys)
- {
- string value = jankinsEnvironmentVars[varName];
- xmlContent = ReplaceString(xmlContent, "%" + varName + "%", value, StringComparison.OrdinalIgnoreCase);
- xmlContent = ReplaceString(xmlContent, "${" + varName + "}", value, StringComparison.OrdinalIgnoreCase);
- }
- }
-
- List retval = new List();
- XDocument doc = XDocument.Parse(xmlContent);
-
- XmlSchemaSet schemas = new XmlSchemaSet();
-
- var assembly = Assembly.GetExecutingAssembly();
-
- var schemaStream = assembly.GetManifestResourceStream("HpToolsLauncher.MtbxSchema.xsd");
-
- XmlSchema schema = XmlSchema.Read(schemaStream, null);
-
- schemas.Add(schema);
-
- string validationMessages = "";
- doc.Validate(schemas, (o, e) =>
- {
- validationMessages += e.Message + Environment.NewLine;
- });
-
- if (!string.IsNullOrWhiteSpace(validationMessages))
- ConsoleWriter.WriteLine("mtbx schema validation errors: " + validationMessages);
- try
- {
- var root = doc.Root;
- foreach (var test in GetElements(root, "Test"))
- {
- string path = GetAttribute(test, "path").Value;
-
- if (!Directory.Exists(path))
- {
- string line = string.Format(Resources.GeneralFileNotFound, path);
- ConsoleWriter.WriteLine(line);
- ConsoleWriter.ErrorSummaryLines.Add(line);
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- continue;
- }
-
- XAttribute xname = GetAttribute(test, "name");
-
- string name = "";
- if (xname != null)
- name = xname.Value;
-
- TestInfo col = new TestInfo(path, name, testGroupName);
- HashSet paramNames = new HashSet();
-
- foreach (var param in GetElements(test, "Parameter"))
- {
-
- string pname = GetAttribute(param, "name").Value;
- string pval = GetAttribute(param, "value").Value;
- XAttribute xptype = GetAttribute(param, "type");
- string ptype = "string";
-
- if (xptype != null)
- ptype = xptype.Value;
-
- var testParam = new TestParameterInfo() { Name = pname, Type = ptype, Value = pval };
- if (!paramNames.Contains(testParam.Name))
- {
- paramNames.Add(testParam.Name);
- col.ParameterList.Add(testParam);
- }
- else
- {
- string line = string.Format(Resources.GeneralDuplicateParameterWarning, pname, path);
- ConsoleWriter.WriteLine(line);
- }
- }
-
- retval.Add(col);
- }
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteException("Problem while parsing Mtbx file", ex);
- }
- return retval;
- }
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.Properties;
+using HpToolsLauncher.TestRunners;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Xml.Linq;
+using System.Xml.Schema;
+
+namespace HpToolsLauncher
+{
+ public class MtbxManager
+ {
+
+ //the xml format of an mtbx file below:
+ /*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ */
+ public static List LoadMtbx(string mtbxContent, string testGroup)
+ {
+ return LoadMtbx(mtbxContent, null, testGroup);
+ }
+
+ public static List Parse(string mtbxFileName)
+ {
+ string xmlContent = File.ReadAllText(mtbxFileName);
+ return Parse(xmlContent, null, mtbxFileName);
+ }
+
+ private static XAttribute GetAttribute(XElement x, XName attributeName)
+ {
+ return x.Attributes().FirstOrDefault(a => a.Name.Namespace == attributeName.Namespace
+ && string.Equals(a.Name.LocalName, attributeName.LocalName, StringComparison.OrdinalIgnoreCase));
+ }
+
+ private static XElement GetElement(XElement x, XName eName)
+ {
+ return x.Elements().FirstOrDefault(a => a.Name.Namespace == eName.Namespace
+ && string.Equals(a.Name.LocalName, eName.LocalName, StringComparison.OrdinalIgnoreCase));
+ }
+
+ private static IEnumerable GetElements(XElement x, XName eName)
+ {
+ return x.Elements().Where(a => a.Name.Namespace == eName.Namespace
+ && string.Equals(a.Name.LocalName, eName.LocalName, StringComparison.OrdinalIgnoreCase));
+ }
+
+ public static List Parse(string mtbxFileName, Dictionary jenkinsEnvVars, string testGroupName)
+ {
+ return LoadMtbx(File.ReadAllText(mtbxFileName), jenkinsEnvVars, testGroupName);
+ }
+ private static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int previousIndex = 0;
+ int index = str.IndexOf(oldValue, comparison);
+ while (index != -1)
+ {
+ sb.Append(str.Substring(previousIndex, index - previousIndex));
+ sb.Append(newValue);
+ index += oldValue.Length;
+
+ previousIndex = index;
+ index = str.IndexOf(oldValue, index, comparison);
+ }
+ sb.Append(str.Substring(previousIndex));
+
+ return sb.ToString();
+ }
+
+ public static List LoadMtbx(string xmlContent, Dictionary jankinsEnvVars, string testGroupName)
+ {
+ var localEnv = Environment.GetEnvironmentVariables();
+
+ foreach (string varName in localEnv.Keys)
+ {
+ string value = (string)localEnv[varName];
+ xmlContent = ReplaceString(xmlContent, "%" + varName + "%", value, StringComparison.OrdinalIgnoreCase);
+ xmlContent = ReplaceString(xmlContent, "${" + varName + "}", value, StringComparison.OrdinalIgnoreCase);
+ }
+
+ if (jankinsEnvVars != null)
+ {
+ foreach (string varName in jankinsEnvVars.Keys)
+ {
+ string value = jankinsEnvVars[varName];
+ xmlContent = ReplaceString(xmlContent, "%" + varName + "%", value, StringComparison.OrdinalIgnoreCase);
+ xmlContent = ReplaceString(xmlContent, "${" + varName + "}", value, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+
+ List retval = new List();
+ XDocument doc = XDocument.Parse(xmlContent);
+
+ XmlSchemaSet schemas = new XmlSchemaSet();
+
+ var assembly = Assembly.GetExecutingAssembly();
+
+ var schemaStream = assembly.GetManifestResourceStream("HpToolsLauncher.MtbxSchema.xsd");
+
+ XmlSchema schema = XmlSchema.Read(schemaStream, null);
+
+ schemas.Add(schema);
+
+ string validationMessages = "";
+ doc.Validate(schemas, (o, e) =>
+ {
+ validationMessages += e.Message + Environment.NewLine;
+ });
+
+ if (!string.IsNullOrWhiteSpace(validationMessages))
+ ConsoleWriter.WriteLine("mtbx schema validation errors: " + validationMessages);
+ try
+ {
+ var root = doc.Root;
+ foreach (var test in GetElements(root, "Test"))
+ {
+ string path = GetAttribute(test, "path").Value;
+
+ if (!Directory.Exists(path))
+ {
+ string line = string.Format(Resources.GeneralFileNotFound, path);
+ ConsoleWriter.WriteLine(line);
+ ConsoleWriter.ErrorSummaryLines.Add(line);
+ Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
+ continue;
+ }
+
+ XAttribute xname = GetAttribute(test, "name");
+ string name = "Unnamed Test";
+ if (xname != null && xname.Value != "")
+ {
+ name = xname.Value;
+ }
+
+ // optional report path attribute
+ XAttribute xReportPath = GetAttribute(test, "reportPath");
+ string reportPath = null;
+
+ if (xReportPath != null)
+ {
+ reportPath = xReportPath.Value;
+ }
+
+ TestInfo testInfo = new TestInfo(path, name, testGroupName)
+ {
+ ReportPath = reportPath
+ };
+
+ HashSet paramNames = new HashSet();
+
+ foreach (var param in GetElements(test, "Parameter"))
+ {
+ string pname = GetAttribute(param, "name").Value;
+ string pval = GetAttribute(param, "value").Value;
+ XAttribute attrType = GetAttribute(param, "type");
+ XAttribute attrSource = GetAttribute(param, "source");
+ string ptype = "string";
+ string source = null;
+
+ if (attrType != null)
+ ptype = attrType.Value;
+ if (attrSource != null)
+ source = attrSource.Value;
+
+ var testParam = new TestParameterInfo() { Name = pname, Type = ptype, Value = pval, Source = source };
+ if (!paramNames.Contains(testParam.Name))
+ {
+ paramNames.Add(testParam.Name);
+ testInfo.Params.Add(testParam);
+ }
+ else
+ {
+ string line = string.Format(Resources.GeneralDuplicateParameterWarning, pname, path);
+ ConsoleWriter.WriteLine(line);
+ }
+ }
+
+ XElement dataTable = GetElement(test, "DataTable");
+ if (dataTable != null)
+ {
+ testInfo.DataTablePath = GetAttribute(dataTable, "path").Value;
+ }
+
+ XElement iterations = GetElement(test, "Iterations");
+ if (iterations != null)
+ {
+ IterationInfo ii = new IterationInfo();
+ XAttribute modeAttr = GetAttribute(iterations, "mode");
+ if (modeAttr != null)
+ {
+ ii.IterationMode = modeAttr.Value;
+ }
+ XAttribute startAttr = GetAttribute(iterations, "start");
+ if (startAttr != null)
+ {
+ ii.StartIteration = startAttr.Value;
+ }
+ XAttribute endAttr = GetAttribute(iterations, "end");
+ if (endAttr != null)
+ {
+ ii.EndIteration = endAttr.Value;
+ }
+
+ testInfo.IterationInfo = ii;
+ }
+
+ retval.Add(testInfo);
+ }
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteException("Problem while parsing Mtbx file", ex);
+ }
+ return retval;
+ }
+ }
+}
diff --git a/HpToolsLauncher/MtbxSchema.xsd b/HpToolsLauncher/MtbxSchema.xsd
index 5395b57782..75026d5eda 100644
--- a/HpToolsLauncher/MtbxSchema.xsd
+++ b/HpToolsLauncher/MtbxSchema.xsd
@@ -1,4 +1,36 @@
-
+
+
+
@@ -32,7 +64,6 @@
-
@@ -46,13 +77,27 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HpToolsLauncher/NativeProcess.cs b/HpToolsLauncher/NativeProcess.cs
new file mode 100644
index 0000000000..d7eb8aa640
--- /dev/null
+++ b/HpToolsLauncher/NativeProcess.cs
@@ -0,0 +1,535 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace HpToolsLauncher
+{
+ public static class NativeProcess
+ {
+ //Use these for DesiredAccess
+ public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
+ public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
+ public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
+ public const UInt32 TOKEN_DUPLICATE = 0x0002;
+ public const UInt32 TOKEN_IMPERSONATE = 0x0004;
+ public const UInt32 TOKEN_QUERY = 0x0008;
+ public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
+ public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
+ public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
+ public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
+ public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
+ public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
+ public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
+ TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
+ TOKEN_ADJUST_SESSIONID);
+
+ public const uint MAXIMUM_ALLOWED = 0x02000000;
+
+ public const Int32 INFINITE = -1;
+ public const Int32 WAIT_ABANDONED = 0x80;
+ public const Int32 WAIT_OBJECT_0 = 0x00;
+ public const Int32 WAIT_TIMEOUT = 0x102;
+ public const Int32 WAIT_FAILED = -1;
+
+ public enum ShowWindowCommands : uint
+ {
+ ///
+ /// Hides the window and activates another window.
+ ///
+ SW_HIDE = 0,
+
+ ///
+ /// Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
+ ///
+ SW_SHOWNORMAL = 1,
+
+ ///
+ /// Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
+ ///
+ SW_NORMAL = 1,
+
+ ///
+ /// Activates the window and displays it as a minimized window.
+ ///
+ SW_SHOWMINIMIZED = 2,
+
+ ///
+ /// Activates the window and displays it as a maximized window.
+ ///
+ SW_SHOWMAXIMIZED = 3,
+
+ ///
+ /// Maximizes the specified window.
+ ///
+ SW_MAXIMIZE = 3,
+
+ ///
+ /// Displays a window in its most recent size and position. This value is similar to , except the window is not activated.
+ ///
+ SW_SHOWNOACTIVATE = 4,
+
+ ///
+ /// Activates the window and displays it in its current size and position.
+ ///
+ SW_SHOW = 5,
+
+ ///
+ /// Minimizes the specified window and activates the next top-level window in the z-order.
+ ///
+ SW_MINIMIZE = 6,
+
+ ///
+ /// Displays the window as a minimized window. This value is similar to , except the window is not activated.
+ ///
+ SW_SHOWMINNOACTIVE = 7,
+
+ ///
+ /// Displays the window in its current size and position. This value is similar to , except the window is not activated.
+ ///
+ SW_SHOWNA = 8,
+
+ ///
+ /// Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
+ ///
+ SW_RESTORE = 9
+ }
+
+ public enum ProcessAccessFlags : uint
+ {
+ All = 0x001F0FFF,
+ Terminate = 0x00000001,
+ CreateThread = 0x00000002,
+ VirtualMemoryOperation = 0x00000008,
+ VirtualMemoryRead = 0x00000010,
+ VirtualMemoryWrite = 0x00000020,
+ DuplicateHandle = 0x00000040,
+ CreateProcess = 0x000000080,
+ SetQuota = 0x00000100,
+ SetInformation = 0x00000200,
+ QueryInformation = 0x00000400,
+ QueryLimitedInformation = 0x00001000,
+ Synchronize = 0x00100000
+ };
+
+ public enum CreateProcessFlags
+ {
+ CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
+ CREATE_DEFAULT_ERROR_MODE = 0x04000000,
+ CREATE_NEW_CONSOLE = 0x00000010,
+ CREATE_NEW_PROCESS_GROUP = 0x00000200,
+ CREATE_NO_WINDOW = 0x08000000,
+ CREATE_PROTECTED_PROCESS = 0x00040000,
+ CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
+ CREATE_SEPARATE_WOW_VDM = 0x00000800,
+ CREATE_SHARED_WOW_VDM = 0x00001000,
+ CREATE_SUSPENDED = 0x00000004,
+ CREATE_UNICODE_ENVIRONMENT = 0x00000400,
+ DEBUG_ONLY_THIS_PROCESS = 0x00000002,
+ DEBUG_PROCESS = 0x00000001,
+ DETACHED_PROCESS = 0x00000008,
+ EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
+ INHERIT_PARENT_AFFINITY = 0x00010000
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct STARTUPINFO
+ {
+ public Int32 cb;
+ public string lpReserved;
+ public string lpDesktop;
+ public string lpTitle;
+ public Int32 dwX;
+ public Int32 dwY;
+ public Int32 dwXSize;
+ public Int32 dwYSize;
+ public Int32 dwXCountChars;
+ public Int32 dwYCountChars;
+ public Int32 dwFillAttribute;
+ public Int32 dwFlags;
+ public Int16 wShowWindow;
+ public Int16 cbReserved2;
+ public IntPtr lpReserved2;
+ public IntPtr hStdInput;
+ public IntPtr hStdOutput;
+ public IntPtr hStdError;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct STARTUPINFOEX
+ {
+ public STARTUPINFO StartupInfo;
+ public IntPtr lpAttributeList;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PROCESS_INFORMATION
+ {
+ public IntPtr hProcess;
+ public IntPtr hThread;
+ public int dwProcessId;
+ public int dwThreadId;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct SECURITY_ATTRIBUTES
+ {
+ public int nLength;
+ public IntPtr lpSecurityDescriptor;
+ public int bInheritHandle;
+ }
+
+ public enum SECURITY_IMPERSONATION_LEVEL
+ {
+ SecurityAnonymous,
+ SecurityIdentification,
+ SecurityImpersonation,
+ SecurityDelegation
+ }
+
+ public enum TOKEN_TYPE
+ {
+ TokenPrimary = 1,
+ TokenImpersonation
+ }
+
+ public enum TOKEN_INFORMATION_CLASS
+ {
+ ///
+ /// The buffer receives a TOKEN_USER structure that contains the user account of the token.
+ ///
+ TokenUser = 1,
+
+ ///
+ /// The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.
+ ///
+ TokenGroups,
+
+ ///
+ /// The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.
+ ///
+ TokenPrivileges,
+
+ ///
+ /// The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.
+ ///
+ TokenOwner,
+
+ ///
+ /// The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.
+ ///
+ TokenPrimaryGroup,
+
+ ///
+ /// The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.
+ ///
+ TokenDefaultDacl,
+
+ ///
+ /// The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
+ ///
+ TokenSource,
+
+ ///
+ /// The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.
+ ///
+ TokenType,
+
+ ///
+ /// The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails.
+ ///
+ TokenImpersonationLevel,
+
+ ///
+ /// The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.
+ ///
+ TokenStatistics,
+
+ ///
+ /// The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.
+ ///
+ TokenRestrictedSids,
+
+ ///
+ /// The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token.
+ ///
+ TokenSessionId,
+
+ ///
+ /// The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token.
+ ///
+ TokenGroupsAndPrivileges,
+
+ ///
+ /// Reserved.
+ ///
+ TokenSessionReference,
+
+ ///
+ /// The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag.
+ ///
+ TokenSandBoxInert,
+
+ ///
+ /// Reserved.
+ ///
+ TokenAuditPolicy,
+
+ ///
+ /// The buffer receives a TOKEN_ORIGIN value.
+ ///
+ TokenOrigin,
+
+ ///
+ /// The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.
+ ///
+ TokenElevationType,
+
+ ///
+ /// The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token.
+ ///
+ TokenLinkedToken,
+
+ ///
+ /// The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated.
+ ///
+ TokenElevation,
+
+ ///
+ /// The buffer receives a DWORD value that is nonzero if the token has ever been filtered.
+ ///
+ TokenHasRestrictions,
+
+ ///
+ /// The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token.
+ ///
+ TokenAccessInformation,
+
+ ///
+ /// The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token.
+ ///
+ TokenVirtualizationAllowed,
+
+ ///
+ /// The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token.
+ ///
+ TokenVirtualizationEnabled,
+
+ ///
+ /// The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level.
+ ///
+ TokenIntegrityLevel,
+
+ ///
+ /// The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set.
+ ///
+ TokenUIAccess,
+
+ ///
+ /// The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.
+ ///
+ TokenMandatoryPolicy,
+
+ ///
+ /// The buffer receives the token's logon security identifier (SID).
+ ///
+ TokenLogonSid,
+
+ ///
+ /// The maximum value for this enumeration
+ ///
+ MaxTokenInfoClass
+ }
+
+ public enum PROCESSINFOCLASS : int
+ {
+ ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
+ ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
+ ProcessIoCounters, // q: IO_COUNTERS
+ ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX
+ ProcessTimes, // q: KERNEL_USER_TIMES
+ ProcessBasePriority, // s: KPRIORITY
+ ProcessRaisePriority, // s: ULONG
+ ProcessDebugPort, // q: HANDLE
+ ProcessExceptionPort, // s: HANDLE
+ ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
+ ProcessLdtInformation, // 10
+ ProcessLdtSize,
+ ProcessDefaultHardErrorMode, // qs: ULONG
+ ProcessIoPortHandlers, // (kernel-mode only)
+ ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
+ ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
+ ProcessUserModeIOPL,
+ ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
+ ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
+ ProcessWx86Information,
+ ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION
+ ProcessAffinityMask, // s: KAFFINITY
+ ProcessPriorityBoost, // qs: ULONG
+ ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
+ ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
+ ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
+ ProcessWow64Information, // q: ULONG_PTR
+ ProcessImageFileName, // q: UNICODE_STRING
+ ProcessLUIDDeviceMapsEnabled, // q: ULONG
+ ProcessBreakOnTermination, // qs: ULONG
+ ProcessDebugObjectHandle, // 30, q: HANDLE
+ ProcessDebugFlags, // qs: ULONG
+ ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
+ ProcessIoPriority, // qs: ULONG
+ ProcessExecuteFlags, // qs: ULONG
+ ProcessResourceManagement,
+ ProcessCookie, // q: ULONG
+ ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
+ ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION
+ ProcessPagePriority, // q: ULONG
+ ProcessInstrumentationCallback, // 40
+ ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
+ ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
+ ProcessImageFileNameWin32, // q: UNICODE_STRING
+ ProcessImageFileMapping, // q: HANDLE (input)
+ ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
+ ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
+ ProcessGroupInformation, // q: USHORT[]
+ ProcessTokenVirtualizationEnabled, // s: ULONG
+ ProcessConsoleHostProcess, // q: ULONG_PTR
+ ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION
+ ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
+ ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
+ ProcessDynamicFunctionTableInformation,
+ ProcessHandleCheckingMode,
+ ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
+ ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
+ MaxProcessInfoClass
+ };
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct PROCESS_BASIC_INFORMATION
+ {
+ public IntPtr ExitStatus;
+ public IntPtr PebBaseAddress;
+ public IntPtr AffinityMask;
+ public IntPtr BasePriority;
+ public UIntPtr UniqueProcessId;
+ public IntPtr InheritedFromUniqueProcessId;
+
+ public int Size
+ {
+ get { return (int)Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)); }
+ }
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct LUID
+ {
+ public uint LowPart;
+ public int HighPart;
+ }
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
+
+ public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
+ {
+ return OpenProcess(flags, false, proc.Id);
+ }
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
+ ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment,
+ string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
+
+ [DllImport("advapi32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
+
+ [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ public extern static bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes,
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, out IntPtr phNewToken);
+
+ [DllImport("advapi32.dll", SetLastError = true)]
+ public static extern Boolean SetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass,
+ ref UInt32 TokenInformation, UInt32 TokenInformationLength);
+
+ [DllImport("Kernel32.dll", SetLastError = true)]
+ public static extern int CloseHandle(IntPtr hObject);
+
+ [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ public static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes,
+ IntPtr lpThreadAttributes, bool bInheritHandles, CreateProcessFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
+ ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
+
+ [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern uint ResumeThread(IntPtr hThread);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);
+ [DllImport("kernel32.dll")]
+ public static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId);
+ [DllImport("advapi32.dll", SetLastError = true)]
+ public static extern bool ConvertStringSidToSid(string StringSid, out IntPtr ptrSid);
+
+ [DllImport("userenv.dll", SetLastError = true)]
+ public static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);
+
+ [DllImport("userenv.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool DestroyEnvironmentBlock(IntPtr lpEnvironment);
+
+ [DllImport("advapi32.dll", SetLastError = true)]
+ public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
+
+ [DllImport("advapi32.dll", SetLastError = true)]
+ public static extern bool RevertToSelf();
+
+ [DllImport("Kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId")] public static extern int WTSGetActiveConsoleSessionId();
+
+ [DllImport("NTDLL.DLL", SetLastError = true)]
+ public static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, out int pSize);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);
+ }
+}
diff --git a/HpToolsLauncher/ParallelRunner/ParallelRunnerEnvironmentUtil.cs b/HpToolsLauncher/ParallelRunner/ParallelRunnerEnvironmentUtil.cs
new file mode 100644
index 0000000000..5f9092d58b
--- /dev/null
+++ b/HpToolsLauncher/ParallelRunner/ParallelRunnerEnvironmentUtil.cs
@@ -0,0 +1,495 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.ParallelTestRunConfiguraion;
+using HpToolsLauncher.Utils;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Web.Script.Serialization;
+using AuthType = HpToolsLauncher.McConnectionInfo.AuthType;
+
+namespace HpToolsLauncher.ParallelRunner
+{
+ [Serializable]
+ public class ParallelRunnerConfigurationException : Exception
+ {
+ public ParallelRunnerConfigurationException(string message) : base(message)
+ {
+ }
+
+ public ParallelRunnerConfigurationException(string message, Exception innerException) : base(message, innerException)
+ { }
+ };
+
+ public enum EnvironmentType
+ {
+ WEB,
+ MOBILE,
+ UNKNOWN
+ }
+
+ public class ParallelRunnerEnvironmentUtil
+ {
+ // the list of supported browsers
+ private static readonly IList BrowserNames = new List
+ {
+ "IE",
+ "IE64",
+ "CHROME",
+ "FIREFOX",
+ "FIREFOX64",
+ }.AsReadOnly();
+
+ // environment specific constants
+ private const char EnvironmentTokenSeparator = ',';
+ private const char EnvironmentKeyValueSeparator = ':';
+
+ // environment keys
+ private const string DeviceIdKey = "deviceId";
+ private const string ManufacturerAndModelKey = "manufacturerAndModel";
+ private const string OsVersionKey = "osVersion";
+ private const string OsTypeKey = "osType";
+ private const string BrowserKey = "browser";
+
+ // parallel runner config specific constants
+ private const string WebLab = "LocalBrowser";
+ private const string MobileCenterLab = "MobileCenter";
+
+ // the list of mobile properties
+ private static readonly IList MobileProperties = new List
+ {
+ DeviceIdKey,
+ ManufacturerAndModelKey,
+ OsVersionKey,
+ OsTypeKey,
+ }.AsReadOnly();
+
+ ///
+ /// Parse the environment string and return a dictionary containing the values.
+ ///
+ /// The jenkins environment string.
+ /// the dictionary containing the key/value pairs
+ public static Dictionary GetEnvironmentProperties(string environment)
+ {
+ var dictionary = new Dictionary();
+
+ if (string.IsNullOrEmpty(environment))
+ return dictionary;
+
+ // the environment could be : "deviceId : 12412"
+ // or "manufacturerAndModel: Samsung S6, osVersion: > 6"
+ // or for web: "browser: Chrome"
+
+ // the environment string is case-sensitive
+ environment = environment.Trim();
+
+ // we get the key value pairs by splitting them
+ string[] tokens = environment.Split(EnvironmentTokenSeparator);
+
+ foreach (var token in tokens)
+ {
+ string[] keyValuePair = token.Split(EnvironmentKeyValueSeparator);
+
+ // invalid setting, there should be at least two values
+ if (keyValuePair.Length <= 1) continue;
+
+ string key = keyValuePair[0].Trim().ToLower();
+
+ if (string.IsNullOrEmpty(key)) continue;
+
+ // we will also consider the case when we have something like
+ // "manufacturerAndModel : some:string:separated"
+ // so the first one will be the key and the rest will be the value
+ string value = string.Join("", keyValuePair.Skip(1).ToArray())
+ .Trim();
+
+ // must have a value
+ if (string.IsNullOrEmpty(value)) continue;
+
+ dictionary[key] = value;
+ }
+
+ return dictionary;
+ }
+
+ ///
+ /// Parse the mobile environment provided in jenkins.
+ ///
+ /// the environment string
+ /// the MobileEnvironment for ParallelRunner
+ public static MobileEnvironment ParseMobileEnvironment(string environment)
+ {
+ var dictionary = GetEnvironmentProperties(environment);
+
+ // invalid environment string
+ if (dictionary.Count == 0) return null;
+
+ var device = new Device();
+
+ var mobileEnvironment = new MobileEnvironment
+ {
+ device = device,
+ lab = MobileCenterLab
+ };
+
+ if (dictionary.ContainsKey(DeviceIdKey.ToLower()))
+ {
+ if (!string.IsNullOrEmpty(dictionary[DeviceIdKey.ToLower()]))
+ {
+ device.deviceID = dictionary[DeviceIdKey.ToLower()];
+ }
+ }
+
+ if (dictionary.ContainsKey(ManufacturerAndModelKey.ToLower()))
+ {
+ if (!string.IsNullOrEmpty(dictionary[ManufacturerAndModelKey.ToLower()]))
+ {
+ device.manufacturer = dictionary[ManufacturerAndModelKey.ToLower()];
+ }
+ }
+
+ if (dictionary.ContainsKey(OsVersionKey.ToLower()))
+ {
+ if (!string.IsNullOrEmpty(dictionary[OsVersionKey.ToLower()]))
+ {
+ device.osVersion = dictionary[OsVersionKey.ToLower()];
+ }
+ }
+
+ if (dictionary.ContainsKey(OsTypeKey.ToLower()))
+ {
+ if (!string.IsNullOrEmpty(dictionary[OsTypeKey.ToLower()]))
+ {
+ device.osType = dictionary[OsTypeKey.ToLower()];
+ }
+ }
+
+ // the environment string should contain at least a valid property
+ // in order for PrallelRunner to be able to query MC for the specific device
+ if (device.deviceID == null && (device.osType == null && device.osVersion == null && device.manufacturer == null))
+ {
+ return null;
+ }
+
+ return mobileEnvironment;
+ }
+
+ ///
+ /// Parse the web environment provided.
+ ///
+ /// the environment string
+ /// the WebEnvironmnet for ParallelRunner
+ public static WebEnvironment ParseWebEnvironment(string environment)
+ {
+ // example of environment string for web
+ // "browser: Chrome"
+
+ var dictionary = GetEnvironmentProperties(environment);
+
+ if (!dictionary.ContainsKey(BrowserKey.ToLower())) return null;
+
+ WebEnvironment webEnvironment = new WebEnvironment { lab = WebLab };
+
+ var browser = dictionary[BrowserKey.ToLower()];
+
+ // try to find a browser that matches the one provided
+ foreach (var browserName in BrowserNames)
+ {
+ if (string.Equals(browserName, browser, StringComparison.CurrentCultureIgnoreCase))
+ {
+ webEnvironment.browser = dictionary[BrowserKey.ToLower()];
+ return webEnvironment;
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Check if a given propery is part of the mobile properties.
+ ///
+ /// the property to check
+ /// true if the given property is a mobile prop, false otherwise
+ public static bool IsKnownMobileProperty(string property)
+ {
+ foreach (var knownProp in MobileProperties)
+ {
+ if (knownProp.ToLower() == property.ToLower())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Return the environment type based on the environment string provided.
+ ///
+ /// the environment string
+ /// the environment type
+ public static EnvironmentType GetEnvironmentType(string environment)
+ {
+ if (string.IsNullOrEmpty(environment)) return EnvironmentType.UNKNOWN;
+
+ environment = environment.Trim().ToLower();
+
+ Dictionary props = GetEnvironmentProperties(environment);
+
+ // no valid property found
+ if (props.Count == 0)
+ {
+ return EnvironmentType.UNKNOWN;
+ }
+
+ // web environment only contains the browser key
+ if (props.ContainsKey(BrowserKey.ToLower()) && props.Count == 1)
+ {
+ return EnvironmentType.WEB;
+ }
+
+ // check if it's a mobile environment
+ foreach (var prop in props)
+ {
+ if (!IsKnownMobileProperty(prop.Key))
+ {
+ return EnvironmentType.UNKNOWN;
+ }
+ }
+
+ return EnvironmentType.MOBILE;
+ }
+
+ ///
+ /// Parse all of the provided environment strings for this test.
+ ///
+ /// the environments list
+ /// the test information
+ /// the parallel test run configuration
+ public static ParallelTestRunConfiguration ParseEnvironmentStrings(IEnumerable environments, TestInfo testInfo)
+ {
+ var parallelTestRunConfiguration = new ParallelTestRunConfiguration
+ {
+ reportPath = testInfo.ReportPath
+ };
+
+ var items = new List();
+
+ foreach (var env in environments)
+ {
+ var environment = new ParallelTestRunConfiguraion.Environment();
+
+ // try to determine the environment type
+ var type = GetEnvironmentType(env);
+
+ if (type == EnvironmentType.MOBILE)
+ {
+ environment.mobile = ParseMobileEnvironment(env);
+
+ if (environment.mobile == null)
+ {
+ throw new ParallelRunnerConfigurationException("Invalid mobile configuration provided: " + env);
+ }
+ }
+ else if (type == EnvironmentType.WEB)
+ {
+ environment.web = ParseWebEnvironment(env);
+
+ if (environment.web == null)
+ {
+ throw new ParallelRunnerConfigurationException("Invalid web configuration provided: " + env);
+ }
+ }
+ else
+ {
+ // environment might be an empty string, just ignore it
+ continue;
+ }
+
+ var item = new ParallelTestRunConfigurationItem
+ {
+ test = testInfo.TestPath,
+ env = environment,
+ reportPath = testInfo.TestPath
+ };
+
+ items.Add(item);
+ }
+
+ parallelTestRunConfiguration.parallelRuns = items.ToArray();
+
+ return parallelTestRunConfiguration;
+ }
+
+ ///
+ /// Return the proxy settings.
+ ///
+ /// the mc connection info
+ ///
+ public static ProxySettings GetMCProxySettings(McConnectionInfo mcConnectionInfo)
+ {
+ if (string.IsNullOrEmpty(mcConnectionInfo.ProxyAddress))
+ return null;
+
+ AuthenticationSettings authenticationSettings = null;
+
+ if (!string.IsNullOrEmpty(mcConnectionInfo.ProxyUserName)
+ && !string.IsNullOrEmpty(mcConnectionInfo.ProxyPassword))
+ {
+ authenticationSettings = new AuthenticationSettings
+ {
+ username = mcConnectionInfo.ProxyUserName,
+ password = WinUserNativeMethods.
+ ProtectBSTRToBase64(mcConnectionInfo.ProxyPassword)
+ };
+ }
+
+ ProxySettings proxySettings = new ProxySettings
+ {
+ authentication = authenticationSettings,
+ hostname = mcConnectionInfo.ProxyAddress,
+ port = mcConnectionInfo.ProxyPort,
+ type = mcConnectionInfo.ProxyType == 1 ? "system" : "http",
+ };
+
+ return proxySettings;
+ }
+
+ ///
+ /// Parses the MC settings and returns the corresponding UFT settings.
+ ///
+ /// the mc settings
+ /// the parallel runner uft settings
+ public static UFTSettings ParseMCSettings(McConnectionInfo mc)
+ {
+ if (mc == null) return null;
+
+ if (mc.HostAddress.IsNullOrEmpty() ||
+ (mc.MobileAuthType == AuthType.UsernamePassword && mc.UserName.IsNullOrEmpty() && mc.Password.IsNullOrEmpty()) ||
+ (mc.MobileAuthType == AuthType.AuthToken && mc.ExecToken.IsNullOrEmpty()) ||
+ string.IsNullOrEmpty(mc.HostPort))
+ return null;
+
+ MCSettings mcSettings = new MCSettings
+ {
+ username = mc.UserName,
+ password = WinUserNativeMethods.ProtectBSTRToBase64(mc.Password),
+ hostname = mc.HostAddress,
+ port = Convert.ToInt32(mc.HostPort),
+ protocol = mc.UseSSL ? "https" : "http",
+ tenantId = mc.TenantId,
+ authType = (int)mc.MobileAuthType,
+ accessKey = Convert.ToBase64String(Encoding.UTF8.GetBytes(mc.ExecToken))
+ };
+
+ var proxy = GetMCProxySettings(mc);
+
+ // set the proxy information if we have it
+ if (proxy != null)
+ {
+ mcSettings.proxy = proxy;
+ }
+
+ UFTSettings uftSettings = new UFTSettings
+ {
+ mc = mcSettings
+ };
+
+ return uftSettings;
+ }
+
+ ///
+ /// Creates the json config file needed by the parallel runner and returns the path.
+ ///
+ /// The test information.
+ ///
+ /// the path of the newly generated config file
+ ///
+ public static string GetConfigFilePath(TestInfo testInfo, McConnectionInfo mcConnectionInfo, Dictionary> environments)
+ {
+ // no environment defined for this test
+ if (!environments.ContainsKey(testInfo.TestId))
+ {
+ throw new ParallelRunnerConfigurationException("No parallel runner environments found for this test!");
+ }
+
+ // get the parallel run configuration
+ var config = ParseEnvironmentStrings(environments[testInfo.TestId], testInfo);
+
+ // there were no valid environments provided
+ if (config.parallelRuns.Length == 0)
+ {
+ throw new ParallelRunnerConfigurationException("No valid environments found for this test!");
+ }
+
+ var mcSettings = ParseMCSettings(mcConnectionInfo);
+
+ // set the mobile center settings if provided
+ if (mcSettings != null)
+ {
+ config.settings = mcSettings;
+ }
+
+ var configFilePath = Path.Combine(testInfo.TestPath, testInfo.TestId + ".json");
+
+ JavaScriptSerializer serializer = new JavaScriptSerializer();
+
+ string configJson;
+ try
+ {
+ configJson = serializer.Serialize(config);
+ }
+ catch (InvalidOperationException e)
+ {
+ throw new ParallelRunnerConfigurationException("Invalid json confguration provided: ", e);
+ }
+ catch (ArgumentException e)
+ {
+ throw new ParallelRunnerConfigurationException("Configuration serialization recursion limit exceeded: ", e);
+ }
+
+ try
+ {
+ File.WriteAllText(configFilePath, configJson);
+ }
+ catch (Exception e)
+ {
+ throw new ParallelRunnerConfigurationException("Could not write configuration file: ", e);
+ }
+
+ return configFilePath;
+ }
+ }
+}
diff --git a/HpToolsLauncher/ParallelRunner/ParallelTestRunConfiguration.cs b/HpToolsLauncher/ParallelRunner/ParallelTestRunConfiguration.cs
new file mode 100644
index 0000000000..511340d0d0
--- /dev/null
+++ b/HpToolsLauncher/ParallelRunner/ParallelTestRunConfiguration.cs
@@ -0,0 +1,193 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+namespace HpToolsLauncher.ParallelTestRunConfiguraion
+{
+ public class UFTSettings
+ {
+ public MCSettings mc { get; set; }
+ }
+ public class MCSettings
+ {
+ public string protocol { get; set; }
+ public string hostname { get; set; }
+ public int port { get; set; }
+ public string pathname { get; set; }
+ public string account { get; set; }
+ public string username { get; set; }
+ public string password { get; set; }
+ public string tenantId { get; set; }
+ public string workspaceId { get; set; }
+ public ProxySettings proxy { get; set; }
+ public int authType { get; set; }
+ public string accessKey { get; set; }
+ }
+ public class ProxySettings
+ {
+ public string type { get; set; }
+ public string hostname { get; set; }
+ public int port { get; set; }
+ public string pathname { get; set; }
+ public AuthenticationSettings authentication { get; set; }
+ }
+ public class AuthenticationSettings
+ {
+ public string username { get; set; }
+ public string password { get; set; }
+ }
+
+ public class TestRunConfigurationBase
+ {
+ ///
+ /// The Report Path
+ ///
+ public string reportPath { get; set; }
+ ///
+ /// The Log Folder
+ ///
+ public string logFolder { get; set; }
+ ///
+ /// The Log Level
+ ///
+ public string logLevel { get; set; }
+ ///
+ /// Run Mode: Normal|Fast , default is Fast
+ ///
+ public string runMode { get; set; }
+
+ public UFTSettings settings { get; set; }
+ }
+
+ public class ParallelTestRunConfiguration : TestRunConfigurationBase
+ {
+ ///
+ /// The Test Runs
+ ///
+ public ParallelTestRunConfigurationItem[] parallelRuns { get; set; }
+ }
+
+ ///
+ /// TestRun Configuration for qtdrv
+ ///
+ public class TestRunConfiguration : TestRunConfigurationBase
+ {
+ ///
+ /// GUI Test Path
+ /// e.g. test = C:\GUITest1
+ ///
+ public string test { get; set; }
+ ///
+ /// The Web|Mobile Environment (Optional)
+ ///
+ public Environment env { get; set; }
+ }
+
+ ///
+ /// Test run result for ParallelRunner
+ ///
+ public class RunResult : TestRunConfiguration
+ {
+ public string errorMessage { get; set; }
+ }
+
+ ///
+ /// TestRun Configuration for ParallelRunner
+ ///
+ public class ParallelTestRunConfigurationItem : TestRunConfiguration
+ {
+ ///
+ /// Report Suffix (Optional)
+ /// e.g. reportSuffix= ID_C3ZDU,reportPath = C:\parallelexecution\Res1, test= C:\GUITest1
+ /// Full ReportPath = C:\parallelexecution\Res1\GUITest1_ID_C3ZDU
+ ///
+ public string reportSuffix { get; set; }
+ }
+
+ public class Environment
+ {
+ ///
+ /// Web Environment
+ ///
+ public WebEnvironment web { get; set; }
+ ///
+ /// Mobile Environment
+ ///
+ public MobileEnvironment mobile { get; set; }
+ }
+
+ #region Web Environment
+ ///
+ /// SRF Web Desktop Environment
+ ///
+ public class WebEnvironment
+ {
+ ///
+ /// Lab "LocalBrowser"|"MobileCenter"|"SRF"
+ ///
+ public string lab { get; set; }
+ public string platform { get; set; }
+ public string browser { get; set; }
+ public string resolution { get; set; }
+ public string tunnelName { get; set; }
+ }
+
+ #endregion
+
+ #region Mobile Environment
+ public class MobileEnvironment
+ {
+ ///
+ /// Lab "Disable"|"MobileCenter"|"SRF"
+ ///
+ public string lab { get; set; }
+ public Device device { get; set; }
+ }
+
+ ///
+ /// Device Info
+ /// e.g.
+ /// "deviceID": "EYKNTO6999999999",
+ /// "model": "8681-A01",
+ /// "osVersion": "5.1",
+ /// "osType": "ANDROID",
+ /// "manufacturer": "QiKU"
+ ///
+ public class Device
+ {
+ public string deviceID { get; set; }
+ public string manufacturer { get; set; }
+ public string model { get; set; }
+ public string osVersion { get; set; }
+ public string osType { get; set; }
+ }
+ #endregion
+}
diff --git a/HpToolsLauncher/ProcessExtensions.cs b/HpToolsLauncher/ProcessExtensions.cs
new file mode 100644
index 0000000000..d646115194
--- /dev/null
+++ b/HpToolsLauncher/ProcessExtensions.cs
@@ -0,0 +1,80 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace HpToolsLauncher
+{
+ public static class ProcessExtensions
+ {
+ ///
+ /// Get the parent process for a given process handle.
+ ///
+ /// the process handle
+ /// The parent process
+ private static Process GetParentProcess(IntPtr hProcess)
+ {
+ NativeProcess.PROCESS_BASIC_INFORMATION pbi = new NativeProcess.PROCESS_BASIC_INFORMATION();
+ int pbiLength = Marshal.SizeOf(pbi);
+ int returnLength = 0;
+
+ int status = NativeProcess.NtQueryInformationProcess(hProcess, NativeProcess.PROCESSINFOCLASS.ProcessBasicInformation,
+ ref pbi, pbiLength, out returnLength);
+
+ if (status != 0)
+ {
+ throw new Win32Exception(status);
+ }
+
+ try
+ {
+ return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
+ }
+ catch (ArgumentException)
+ { // Not found
+ return null;
+ }
+ }
+ ///
+ /// Returns the parent process of a given process
+ ///
+ /// the process for which to find the parent
+ /// the parent process
+ public static Process Parent(this Process process)
+ {
+ return GetParentProcess(process.Handle);
+ }
+ }
+}
diff --git a/HpToolsLauncher/Program.cs b/HpToolsLauncher/Program.cs
index 7cdb277c94..f3e2fd6f09 100644
--- a/HpToolsLauncher/Program.cs
+++ b/HpToolsLauncher/Program.cs
@@ -1,87 +1,156 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HpToolsLauncher.Properties;
-
-namespace HpToolsLauncher
-{
- public enum TestStorageType
- {
- Alm,
- FileSystem,
- LoadRunner,
- Unknown
- }
-
- class Program
- {
- private static readonly Dictionary argsDictionary = new Dictionary();
-
- static void Main(string[] args)
- {
- ConsoleWriter.WriteLine(Resources.GeneralStarted);
- ConsoleQuickEdit.Disable();
- if (args.Count() == 0 || args.Contains("/?"))
- {
- ShowHelp();
- return;
- }
- for (int i = 0; i < args.Count(); i = i + 2)
- {
- string key = args[i].StartsWith("-") ? args[i].Substring(1) : args[i];
- string val = i + 1 < args.Count() ? args[i + 1].Trim() : String.Empty;
- argsDictionary[key] = val;
- }
- string paramFileName, runtype;
- string failOnTestFailed = "N";
- argsDictionary.TryGetValue("runtype", out runtype);
- argsDictionary.TryGetValue("paramfile", out paramFileName);
- TestStorageType enmRuntype = TestStorageType.Unknown;
-
- if (!Enum.TryParse(runtype, true, out enmRuntype))
- enmRuntype = TestStorageType.Unknown;
-
- if (string.IsNullOrEmpty(paramFileName))
- {
- ShowHelp();
- return;
- }
- var apiRunner = new Launcher(failOnTestFailed, paramFileName, enmRuntype);
-
- apiRunner.Run();
- }
-
- private static void ShowHelp()
- {
- Console.WriteLine("HP Automation Tools Command Line Executer");
- Console.WriteLine();
- Console.Write("Usage: HpToolsLauncher.exe");
- Console.Write(" -paramfile ");
- Console.ForegroundColor = ConsoleColor.Cyan;
- Console.Write(" ");
- Console.ResetColor();
- Console.WriteLine();
- Console.WriteLine();
- Console.WriteLine("-paramfile is required in for the program to run");
- Console.WriteLine("the parameter file may contain the following fields:");
- Console.WriteLine("\trunType=");
- Console.WriteLine("\talmServerUrl=http://:/qcbin");
- Console.WriteLine("\talmUserName=");
- Console.WriteLine("\talmPassword=");
- Console.WriteLine("\talmDomain=");
- Console.WriteLine("\talmProject=");
- Console.WriteLine("\talmRunMode=");
- Console.WriteLine("\talmTimeout=<-1>/");
- Console.WriteLine("\talmRunHost=");
- Console.WriteLine("\tTestSet=/");
- Console.WriteLine("\tTest=//");
- Console.WriteLine("* the last two fields may recur more than once with different index numbers");
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.Properties;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace HpToolsLauncher
+{
+ public enum TestStorageType
+ {
+ Alm,
+ AlmLabManagement,
+ FileSystem,
+ LoadRunner,
+ MBT,
+ Unknown
+ }
+
+ static class Program
+ {
+ private static readonly Dictionary argsDictionary = new Dictionary();
+ private static Launcher _apiRunner;
+
+ //[MTAThread]
+ static void Main(string[] args)
+ {
+ ConsoleWriter.WriteLine(Resources.GeneralStarted);
+ ConsoleQuickEdit.Disable();
+ Console.OutputEncoding = Encoding.UTF8;
+ if (!args.Any() || args.Contains("/?"))
+ {
+ ShowHelp();
+ return;
+ }
+ for (int i = 0; i < args.Count(); i += 2)
+ {
+ string key = args[i].StartsWith("-") ? args[i].Substring(1) : args[i];
+ string val = i + 1 < args.Count() ? args[i + 1].Trim() : string.Empty;
+ argsDictionary[key] = val;
+ }
+ string runtype, paramFileName, outEncoding;
+ TestStorageType enmRuntype;
+ argsDictionary.TryGetValue("runtype", out runtype);
+ argsDictionary.TryGetValue("paramfile", out paramFileName);
+ argsDictionary.TryGetValue("encoding", out outEncoding);
+ if (!Enum.TryParse(runtype, true, out enmRuntype))
+ enmRuntype = TestStorageType.Unknown;
+
+ if (string.IsNullOrEmpty(paramFileName))
+ {
+ ShowHelp();
+ return;
+ }
+ else
+ {
+ paramFileName = paramFileName.Trim();
+ if (!File.Exists(paramFileName))
+ {
+ Console.WriteLine("Error: The file [{0}] cannot be found in folder [{1}].", paramFileName, Directory.GetCurrentDirectory());
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(outEncoding))
+ {
+ try
+ {
+ Console.OutputEncoding = Encoding.GetEncoding(outEncoding);
+ }
+ catch
+ {
+ Console.WriteLine("Unsupported encoding {0}. In this case UTF-8 will be used.", outEncoding);
+ }
+ }
+
+ Console.CancelKeyPress += Console_CancelKeyPress;
+
+ _apiRunner = new Launcher(paramFileName, enmRuntype, outEncoding);
+ _apiRunner.Run();
+ }
+
+ private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
+ {
+ e.Cancel = true;
+ _apiRunner.SafelyCancel();
+ }
+
+ private static void ShowHelp()
+ {
+ Console.WriteLine("Micro Focus Automation Tools Command Line Executer");
+ Console.WriteLine();
+ Console.Write("Usage: HpToolsLauncher.exe");
+ Console.Write(" -paramfile ");
+ Console.ForegroundColor = ConsoleColor.Cyan;
+ Console.Write(" ");
+ Console.ResetColor();
+ Console.Write(" -encoding ");
+ Console.ForegroundColor = ConsoleColor.Cyan;
+ Console.Write("ASCII | UTF-7 | UTF-8 | UTF-16");
+ Console.ResetColor();
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("-paramfile is required in for the program to run");
+ Console.WriteLine("the parameter file may contain the following fields:");
+ Console.WriteLine("\trunType=");
+ Console.WriteLine("\talmServerUrl=http://:/qcbin");
+ Console.WriteLine("\talmUserName=");
+ Console.WriteLine("\talmPassword=");
+ Console.WriteLine("\talmDomain=");
+ Console.WriteLine("\talmProject=");
+ Console.WriteLine("\talmRunMode=");
+ Console.WriteLine("\talmTimeout=<-1>/");
+ Console.WriteLine("\talmRunHost=");
+ Console.WriteLine("\tTestSet=/");
+ Console.WriteLine("\tTest=//");
+ Console.WriteLine("* the last two fields may recur more than once with different index numbers");
+ Console.WriteLine();
+ Console.WriteLine("-encoding is optional and can take one of the values: ASCII, UTF-7, UTF-8 or UTF-16");
+
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+ }
+}
diff --git a/HpToolsLauncher/Properties/AssemblyInfo.cs b/HpToolsLauncher/Properties/AssemblyInfo.cs
index e5e26aed36..5a0df6ac3e 100644
--- a/HpToolsLauncher/Properties/AssemblyInfo.cs
+++ b/HpToolsLauncher/Properties/AssemblyInfo.cs
@@ -1,10 +1,36 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/HpToolsLauncher/Properties/Resources.Designer.cs b/HpToolsLauncher/Properties/Resources.Designer.cs
index 89e61d710c..6ad6e3957a 100644
--- a/HpToolsLauncher/Properties/Resources.Designer.cs
+++ b/HpToolsLauncher/Properties/Resources.Designer.cs
@@ -1,1027 +1,1354 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.34003
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace HpToolsLauncher.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HpToolsLauncher.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to Could not find TestSet {0}.
- ///
- internal static string AlmRunnerCantFindTest {
- get {
- return ResourceManager.GetString("AlmRunnerCantFindTest", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to One or more of the required connection parameters is empty..
- ///
- internal static string AlmRunnerConnParamEmpty {
- get {
- return ResourceManager.GetString("AlmRunnerConnParamEmpty", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Link: {0}.
- ///
- internal static string AlmRunnerDisplayLink {
- get {
- return ResourceManager.GetString("AlmRunnerDisplayLink", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test set name: {0}, Test set id: {1}.
- ///
- internal static string AlmRunnerDisplayTest {
- get {
- return ResourceManager.GetString("AlmRunnerDisplayTest", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test {0}: {1} will run on host: {2}.
- ///
- internal static string AlmRunnerDisplayTestRunOnHost {
- get {
- return ResourceManager.GetString("AlmRunnerDisplayTestRunOnHost", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot Login to QC: Authorization failed..
- ///
- internal static string AlmRunnerErrorAuthorization {
- get {
- return ResourceManager.GetString("AlmRunnerErrorAuthorization", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Check that your QC client is installed properly\n {0} \n{1}..
- ///
- internal static string AlmRunnerErrorBadQcInstallation {
- get {
- return ResourceManager.GetString("AlmRunnerErrorBadQcInstallation", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot connect to QC: Project / Domain does not exist..
- ///
- internal static string AlmRunnerErrorConnectToProj {
- get {
- return ResourceManager.GetString("AlmRunnerErrorConnectToProj", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Problem in updating tests status for test: {0}\n {1}.
- ///
- internal static string AlmRunnerErrorGettingStat {
- get {
- return ResourceManager.GetString("AlmRunnerErrorGettingStat", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to folder {0} cannot be found in ALM.
- ///
- internal static string AlmRunnerNoSuchFolder {
- get {
- return ResourceManager.GetString("AlmRunnerNoSuchFolder", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to "Number of tests in set: ".
- ///
- internal static string AlmRunnerNumTests {
- get {
- return ResourceManager.GetString("AlmRunnerNumTests", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to problem while setting remote host: {0}.
- ///
- internal static string AlmRunnerProblemWithHost {
- get {
- return ResourceManager.GetString("AlmRunnerProblemWithHost", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Problem while running TestSet: .
- ///
- internal static string AlmRunnerRunError {
- get {
- return ResourceManager.GetString("AlmRunnerRunError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Run ID:.
- ///
- internal static string AlmRunnerRunIdCaption {
- get {
- return ResourceManager.GetString("AlmRunnerRunIdCaption", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to "Scheduler started at:.
- ///
- internal static string AlmRunnerSchedStarted {
- get {
- return ResourceManager.GetString("AlmRunnerSchedStarted", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to "ALM server {0} unreachable, check that server Url is correct".
- ///
- internal static string AlmRunnerServerUnreachable {
- get {
- return ResourceManager.GetString("AlmRunnerServerUnreachable", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Starting test set execution.
- ///
- internal static string AlmRunnerStartingExecution {
- get {
- return ResourceManager.GetString("AlmRunnerStartingExecution", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test: {0}, Id: {1}, Execution status: {2}.
- ///
- internal static string AlmRunnerStat {
- get {
- return ResourceManager.GetString("AlmRunnerStat", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test: {0}, Id: {1}, Execution status: {2}, Message: {3}.
- ///
- internal static string AlmRunnerStatWithMessage {
- get {
- return ResourceManager.GetString("AlmRunnerStatWithMessage", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test complete:.
- ///
- internal static string AlmRunnerTestCompleteCaption {
- get {
- return ResourceManager.GetString("AlmRunnerTestCompleteCaption", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test set: {0}, finished at {1}.
- ///
- internal static string AlmRunnerTestsetDone {
- get {
- return ResourceManager.GetString("AlmRunnerTestsetDone", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test: {0}, Status: {1}, Message: {2} \nLink: {3}\n.
- ///
- internal static string AlmRunnerTestStat {
- get {
- return ResourceManager.GetString("AlmRunnerTestStat", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Unable to delete report folder {0}..
- ///
- internal static string CannotDeleteReportFolder {
- get {
- return ResourceManager.GetString("CannotDeleteReportFolder", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Untitled.
- ///
- internal static string DefaultName {
- get {
- return ResourceManager.GetString("DefaultName", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Directory '{0}' doesn't exist..
- ///
- internal static string DirectoryNotExistError {
- get {
- return ResourceManager.GetString("DirectoryNotExistError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Exception was thrown from external process..
- ///
- internal static string ExceptionExternalProcess {
- get {
- return ResourceManager.GetString("ExceptionExternalProcess", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Run cancelled by user..
- ///
- internal static string ExceptionUserCancelled {
- get {
- return ResourceManager.GetString("ExceptionUserCancelled", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Failed to create Temp Dir {0}..
- ///
- internal static string FailedToCreateTempDirError {
- get {
- return ResourceManager.GetString("FailedToCreateTempDirError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No HP testing tool is installed on {0}.
- ///
- internal static string FileSystemTestsRunner_No_HP_testing_tool_is_installed_on {
- get {
- return ResourceManager.GetString("FileSystemTestsRunner_No_HP_testing_tool_is_installed_on", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ===============================\nThere are no valid tests to run!\n===============================.
- ///
- internal static string FsRunnerNoValidTests {
- get {
- return ResourceManager.GetString("FsRunnerNoValidTests", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Running test: {0}.
- ///
- internal static string FsRunnerRunningTest {
- get {
- return ResourceManager.GetString("FsRunnerRunningTest", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test result: {0}.
- ///
- internal static string FsRunnerTestDone {
- get {
- return ResourceManager.GetString("FsRunnerTestDone", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test result: Succeeded with Warnings.
- ///
- internal static string FsRunnerTestDoneWarnings {
- get {
- return ResourceManager.GetString("FsRunnerTestDoneWarnings", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} tests found:.
- ///
- internal static string FsRunnerTestsFound {
- get {
- return ResourceManager.GetString("FsRunnerTestsFound", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ========================\nJob was aborted by user!\n========================.
- ///
- internal static string GeneralAbortedByUser {
- get {
- return ResourceManager.GetString("GeneralAbortedByUser", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ============================================================================.
- ///
- internal static string GeneralDoubleSeperator {
- get {
- return ResourceManager.GetString("GeneralDoubleSeperator", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to The Parameter {0} of test: {1} is defined more than once.
- ///
- internal static string GeneralDuplicateParameterWarning {
- get {
- return ResourceManager.GetString("GeneralDuplicateParameterWarning", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Error: {0}\n{1}.
- ///
- internal static string GeneralErrorWithStack {
- get {
- return ResourceManager.GetString("GeneralErrorWithStack", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to >>> File/Folder not found: {0}.
- ///
- internal static string GeneralFileNotFound {
- get {
- return ResourceManager.GetString("GeneralFileNotFound", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to QTP is not installed on {0}..
- ///
- internal static string GeneralQtpNotInstalled {
- get {
- return ResourceManager.GetString("GeneralQtpNotInstalled", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to "Started...".
- ///
- internal static string GeneralStarted {
- get {
- return ResourceManager.GetString("GeneralStarted", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test run was aborted by user. Stopping all tests..
- ///
- internal static string GeneralStopAborted {
- get {
- return ResourceManager.GetString("GeneralStopAborted", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test run was cancelled.
- ///
- internal static string GeneralTestCanceled {
- get {
- return ResourceManager.GetString("GeneralTestCanceled", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ==============\nJob timed out!\n==============.
- ///
- internal static string GeneralTimedOut {
- get {
- return ResourceManager.GetString("GeneralTimedOut", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Timeout has expired.
- ///
- internal static string GeneralTimeoutExpired {
- get {
- return ResourceManager.GetString("GeneralTimeoutExpired", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to The LoadRunner version must be 11.52 or higher. Check that '{0}' has a compatible version of LoadRunner..
- ///
- internal static string HPToolsAssemblyResolverWrongVersion {
- get {
- return ResourceManager.GetString("HPToolsAssemblyResolverWrongVersion", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Run mode is set to: {0}.
- ///
- internal static string LauncherDisplayRunmode {
- get {
- return ResourceManager.GetString("LauncherDisplayRunmode", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Run status: {0}, total tests: {1}, succeeded: {2}, failures: {3}, errors: {4}.
- ///
- internal static string LauncherDisplayStatistics {
- get {
- return ResourceManager.GetString("LauncherDisplayStatistics", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to ================================================.
- ///
- internal static string LauncherDoubleSeperator {
- get {
- return ResourceManager.GetString("LauncherDoubleSeperator", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to The parameter 'runMode' should be: RUN_LOCAL | RUN_REMOTE | RUN_PLANNED_HOST.
- ///
- internal static string LauncherIncorrectRunmode {
- get {
- return ResourceManager.GetString("LauncherIncorrectRunmode", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No results filename provided, please add one.
- ///
- internal static string LauncherNoResFilenameFound {
- get {
- return ResourceManager.GetString("LauncherNoResFilenameFound", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No runType parameter was provided. Enter a runType (Alm/FileSystem/LoadRunner)..
- ///
- internal static string LauncherNoRuntype {
- get {
- return ResourceManager.GetString("LauncherNoRuntype", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No test sets were found. Add some test sets or folders..
- ///
- internal static string LauncherNoTests {
- get {
- return ResourceManager.GetString("LauncherNoTests", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No tests were found. Add tests or folders containing tests..
- ///
- internal static string LauncherNoTestsFound {
- get {
- return ResourceManager.GetString("LauncherNoTestsFound", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No valid tests were found. Fix the test paths..
- ///
- internal static string LauncherNoValidTests {
- get {
- return ResourceManager.GetString("LauncherNoValidTests", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to The parameter '{0}' is required to run a test from QC..
- ///
- internal static string LauncherParamRequired {
- get {
- return ResourceManager.GetString("LauncherParamRequired", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to An error occured while disposing runner: {0}..
- ///
- internal static string LauncherRunnerDisposeError {
- get {
- return ResourceManager.GetString("LauncherRunnerDisposeError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Service Test is not installed on {0}.
- ///
- internal static string LauncherStNotInstalled {
- get {
- return ResourceManager.GetString("LauncherStNotInstalled", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to almTimeout should be an integer!.
- ///
- internal static string LauncherTimeoutNotNumeric {
- get {
- return ResourceManager.GetString("LauncherTimeoutNotNumeric", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to LoadRunner is not installed on {0}..
- ///
- internal static string LoadRunnerNotInstalled {
- get {
- return ResourceManager.GetString("LoadRunnerNotInstalled", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Analyzing results....
- ///
- internal static string LrAnalysingResults {
- get {
- return ResourceManager.GetString("LrAnalysingResults", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Error during Analysis run. See output console for details.
- ///
- internal static string LrAnalysisRunTimeError {
- get {
- return ResourceManager.GetString("LrAnalysisRunTimeError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Timeout for Analysis passed..
- ///
- internal static string LrAnalysisTimeOut {
- get {
- return ResourceManager.GetString("LrAnalysisTimeOut", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Failed to initilize Analysis launcher..
- ///
- internal static string LrAnlysisInitFail {
- get {
- return ResourceManager.GetString("LrAnlysisInitFail", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Analysis Results:.
- ///
- internal static string LrAnlysisResults {
- get {
- return ResourceManager.GetString("LrAnlysisResults", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cleaning up the environment....
- ///
- internal static string LrCleanENV {
- get {
- return ResourceManager.GetString("LrCleanENV", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Controller failed to stop..
- ///
- internal static string LrControllerFailedToStop {
- get {
- return ResourceManager.GetString("LrControllerFailedToStop", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Ignored error message : "{0}" contains ignored string "{1}"..
- ///
- internal static string LrErrorIgnored {
- get {
- return ResourceManager.GetString("LrErrorIgnored", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Errors during scenario run: \n.
- ///
- internal static string LRErrorReasonSummaryTitle {
- get {
- return ResourceManager.GetString("LRErrorReasonSummaryTitle", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Error(s) summary: .
- ///
- internal static string LRErrorsSummary {
- get {
- return ResourceManager.GetString("LRErrorsSummary", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to {0} ignored , {1} errors.
- ///
- internal static string LrErrorSummeryNum {
- get {
- return ResourceManager.GetString("LrErrorSummeryNum", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Exception while trying to analyze results:.
- ///
- internal static string LRExceptionInAnalysisRunner {
- get {
- return ResourceManager.GetString("LRExceptionInAnalysisRunner", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot open scenario {0} ret code = {1}..
- ///
- internal static string LrFailedToOpenScenario {
- get {
- return ResourceManager.GetString("LrFailedToOpenScenario", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Failed to start the LoadRunner Controller..
- ///
- internal static string LrFailToOpenController {
- get {
- return ResourceManager.GetString("LrFailToOpenController", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot register the end scenario event. End scenario detection is based on Vuser status..
- ///
- internal static string LrFailToRegisterEndScenarioEvent {
- get {
- return ResourceManager.GetString("LrFailToRegisterEndScenarioEvent", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Preparing scenario {0} for execution..
- ///
- internal static string LrInitScenario {
- get {
- return ResourceManager.GetString("LrInitScenario", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot collate results ret code = {0}..
- ///
- internal static string LrScenarioCollateFail {
- get {
- return ResourceManager.GetString("LrScenarioCollateFail", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Scenario {0} ended after {1}:{2}:{3}..
- ///
- internal static string LrScenarioEnded {
- get {
- return ResourceManager.GetString("LrScenarioEnded", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Timeout passed. Stopping sceario by force..
- ///
- internal static string LrScenarioEndedTimeOut {
- get {
- return ResourceManager.GetString("LrScenarioEndedTimeOut", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Errors occured during scenario execution. Stopping the scenario run..
- ///
- internal static string LrScenarioEndedWithErrors {
- get {
- return ResourceManager.GetString("LrScenarioEndedWithErrors", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Scenario open process timed out..
- ///
- internal static string LrScenarioOpenTimeOut {
- get {
- return ResourceManager.GetString("LrScenarioOpenTimeOut", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Scenario Execution timeout ({0} seconds) passed..
- ///
- internal static string LrScenarioTimeOut {
- get {
- return ResourceManager.GetString("LrScenarioTimeOut", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot connect to Load Generator {0}..
- ///
- internal static string LrScenarioValidationCannotConnectLG {
- get {
- return ResourceManager.GetString("LrScenarioValidationCannotConnectLG", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot synchronize with Load Generator {0}..
- ///
- internal static string LrScenarioValidationCannotSyncLG {
- get {
- return ResourceManager.GetString("LrScenarioValidationCannotSyncLG", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No Load Generators were configured for the scenario {0.}.
- ///
- internal static string LrScenarioValidationFailNoLGs {
- get {
- return ResourceManager.GetString("LrScenarioValidationFailNoLGs", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Scenario {0} does not have an SLA configuration..
- ///
- internal static string LrScenarioValidationFailNoSLA {
- get {
- return ResourceManager.GetString("LrScenarioValidationFailNoSLA", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Load Generator {0} connected.
- ///
- internal static string LrScenarioValidationLGConnected {
- get {
- return ResourceManager.GetString("LrScenarioValidationLGConnected", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Could not connect to Load Generator {0}..
- ///
- internal static string LrScenarioValidationLGNotReady {
- get {
- return ResourceManager.GetString("LrScenarioValidationLGNotReady", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to SLA rule {0} failed: GoalValue = {1} ActualValue = {2}.
- ///
- internal static string LrSLARuleFailed {
- get {
- return ResourceManager.GetString("LrSLARuleFailed", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Starting scenario....
- ///
- internal static string LrStartScenario {
- get {
- return ResourceManager.GetString("LrStartScenario", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Cannot start scenario {0}. Return Code = {1}..
- ///
- internal static string LrStartScenarioFail {
- get {
- return ResourceManager.GetString("LrStartScenarioFail", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Stop scenario failed. Return code = {0}.
- ///
- internal static string LrStopScenarioEnded {
- get {
- return ResourceManager.GetString("LrStopScenarioEnded", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test FAILED. {0} errors occured during scenario execution..
- ///
- internal static string LRTestFailDueToFatalErrors {
- get {
- return ResourceManager.GetString("LRTestFailDueToFatalErrors", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Test PASSED.
- ///
- internal static string LRTestPassed {
- get {
- return ResourceManager.GetString("LRTestPassed", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Setting test state to WARNING. {0} Ignored errors occured during scenario execution..
- ///
- internal static string LRTestWarningDueToIgnoredErrors {
- get {
- return ResourceManager.GetString("LRTestWarningDueToIgnoredErrors", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Timeout is set to: {0}.
- ///
- internal static string LuancherDisplayTimout {
- get {
- return ResourceManager.GetString("LuancherDisplayTimout", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to QTPActivity.TestCleanup - exception {0}.
- ///
- internal static string QtpCleanupError {
- get {
- return ResourceManager.GetString("QtpCleanupError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to QTP is not launched..
- ///
- internal static string QtpNotLaunchedError {
- get {
- return ResourceManager.GetString("QtpNotLaunchedError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to QTP could not handle output arguments..
- ///
- internal static string QtpOutputError {
- get {
- return ResourceManager.GetString("QtpOutputError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to QTP could not run..
- ///
- internal static string QtpRunError {
- get {
- return ResourceManager.GetString("QtpRunError", resourceCulture);
- }
- }
-
- ///
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace HpToolsLauncher.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HpToolsLauncher.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Duplicate parameter name entry found, please check the parameters' specification, falling back to default parameters for {0}. test or testset..
+ ///
+ internal static string AlmDuplicateParameter {
+ get {
+ return ResourceManager.GetString("AlmDuplicateParameter", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not find Test {0}.
+ ///
+ internal static string AlmRunnerCantFindTest {
+ get {
+ return ResourceManager.GetString("AlmRunnerCantFindTest", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not find TestSet {0}.
+ ///
+ internal static string AlmRunnerCantFindTestSet {
+ get {
+ return ResourceManager.GetString("AlmRunnerCantFindTestSet", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to One or more of the required connection parameters is empty..
+ ///
+ internal static string AlmRunnerConnParamEmpty {
+ get {
+ return ResourceManager.GetString("AlmRunnerConnParamEmpty", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Copy the following report link inside an IE browser to view the test run results: {0}.
+ ///
+ internal static string AlmRunnerDisplayLink {
+ get {
+ return ResourceManager.GetString("AlmRunnerDisplayLink", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test set name: {0}, Test set id: {1}.
+ ///
+ internal static string AlmRunnerDisplayTest {
+ get {
+ return ResourceManager.GetString("AlmRunnerDisplayTest", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test {0}: {1} will run on host: {2}.
+ ///
+ internal static string AlmRunnerDisplayTestRunOnHost {
+ get {
+ return ResourceManager.GetString("AlmRunnerDisplayTestRunOnHost", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot Login to QC: Authorization failed..
+ ///
+ internal static string AlmRunnerErrorAuthorization {
+ get {
+ return ResourceManager.GetString("AlmRunnerErrorAuthorization", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Check that your QC client is installed properly
+ ///{0}
+ ///{1}..
+ ///
+ internal static string AlmRunnerErrorBadQcInstallation {
+ get {
+ return ResourceManager.GetString("AlmRunnerErrorBadQcInstallation", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot connect to QC: Project / Domain does not exist..
+ ///
+ internal static string AlmRunnerErrorConnectToProj {
+ get {
+ return ResourceManager.GetString("AlmRunnerErrorConnectToProj", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Problem in updating tests status for test: {0}
+ ///{1}.
+ ///
+ internal static string AlmRunnerErrorGettingStat {
+ get {
+ return ResourceManager.GetString("AlmRunnerErrorGettingStat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Invalid parameter format, check job configuration to re-configure parameter definitions for test: {0}. Falling back to default parameter definitions..
+ ///
+ internal static string AlmRunnerErrorParameterFormat {
+ get {
+ return ResourceManager.GetString("AlmRunnerErrorParameterFormat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unable to login. Please check username and password..
+ ///
+ internal static string AlmRunnerIncorectCredentials {
+ get {
+ return ResourceManager.GetString("AlmRunnerIncorectCredentials", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to folder {0} cannot be found in ALM.
+ ///
+ internal static string AlmRunnerNoSuchFolder {
+ get {
+ return ResourceManager.GetString("AlmRunnerNoSuchFolder", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Number of tests in set:.
+ ///
+ internal static string AlmRunnerNumTests {
+ get {
+ return ResourceManager.GetString("AlmRunnerNumTests", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Problem while setting remote host: {0}.
+ ///
+ internal static string AlmRunnerProblemWithHost {
+ get {
+ return ResourceManager.GetString("AlmRunnerProblemWithHost", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Problem while running TestSet: .
+ ///
+ internal static string AlmRunnerRunError {
+ get {
+ return ResourceManager.GetString("AlmRunnerRunError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Run ID:.
+ ///
+ internal static string AlmRunnerRunIdCaption {
+ get {
+ return ResourceManager.GetString("AlmRunnerRunIdCaption", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scheduler started at:.
+ ///
+ internal static string AlmRunnerSchedStarted {
+ get {
+ return ResourceManager.GetString("AlmRunnerSchedStarted", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ALM server {0} unreachable, check that server Url is correct.
+ ///
+ internal static string AlmRunnerServerUnreachable {
+ get {
+ return ResourceManager.GetString("AlmRunnerServerUnreachable", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Starting test set execution.
+ ///
+ internal static string AlmRunnerStartingExecution {
+ get {
+ return ResourceManager.GetString("AlmRunnerStartingExecution", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test: {0}, Id: {1}, Execution status: {2}.
+ ///
+ internal static string AlmRunnerStat {
+ get {
+ return ResourceManager.GetString("AlmRunnerStat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test: {0}, Id: {1}, Execution status: {2}, Message: {3}.
+ ///
+ internal static string AlmRunnerStatWithMessage {
+ get {
+ return ResourceManager.GetString("AlmRunnerStatWithMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test complete:.
+ ///
+ internal static string AlmRunnerTestCompleteCaption {
+ get {
+ return ResourceManager.GetString("AlmRunnerTestCompleteCaption", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test set: {0}, aborted at {1}.
+ ///
+ internal static string AlmRunnerTestsetAborted {
+ get {
+ return ResourceManager.GetString("AlmRunnerTestsetAborted", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test set: {0}, finished at {1}.
+ ///
+ internal static string AlmRunnerTestsetDone {
+ get {
+ return ResourceManager.GetString("AlmRunnerTestsetDone", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test: {0}, Status: {1}, Message: {2}, Link: {3}.
+ ///
+ internal static string AlmRunnerTestStat {
+ get {
+ return ResourceManager.GetString("AlmRunnerTestStat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test: {0} >> Previous state -> {1}; After update state -> {2}.
+ ///
+ internal static string AlmRunnerUpdateStateAfterAbort {
+ get {
+ return ResourceManager.GetString("AlmRunnerUpdateStateAfterAbort", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot find the test folder..
+ ///
+ internal static string AlmTestSetsRunnerGetFolderError {
+ get {
+ return ResourceManager.GetString("AlmTestSetsRunnerGetFolderError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No test meets the filtering criteria.
+ ///
+ internal static string AlmTestSetsRunnerNoTestAfterApplyingFilters {
+ get {
+ return ResourceManager.GetString("AlmTestSetsRunnerNoTestAfterApplyingFilters", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unable to delete report folder {0}..
+ ///
+ internal static string CannotDeleteReportFolder {
+ get {
+ return ResourceManager.GetString("CannotDeleteReportFolder", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cloud Browser is not supported in UFT One {0}. Please upgrade to UFT One 23.4 or later..
+ ///
+ internal static string CloudBrowserNotSupported {
+ get {
+ return ResourceManager.GetString("CloudBrowserNotSupported", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CreateTDConnection.
+ ///
+ internal static string CreateTDConnection {
+ get {
+ return ResourceManager.GetString("CreateTDConnection", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Untitled.
+ ///
+ internal static string DefaultName {
+ get {
+ return ResourceManager.GetString("DefaultName", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Directory '{0}' doesn't exist..
+ ///
+ internal static string DirectoryNotExistError {
+ get {
+ return ResourceManager.GetString("DirectoryNotExistError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Exception was thrown from external process..
+ ///
+ internal static string ExceptionExternalProcess {
+ get {
+ return ResourceManager.GetString("ExceptionExternalProcess", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Run cancelled by user..
+ ///
+ internal static string ExceptionUserCancelled {
+ get {
+ return ResourceManager.GetString("ExceptionUserCancelled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Failed to create Temp Dir {0}..
+ ///
+ internal static string FailedToCreateTempDirError {
+ get {
+ return ResourceManager.GetString("FailedToCreateTempDirError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No Micro Focus testing tool is installed on {0}.
+ ///
+ internal static string FileSystemTestsRunner_No_HP_testing_tool_is_installed_on {
+ get {
+ return ResourceManager.GetString("FileSystemTestsRunner_No_HP_testing_tool_is_installed_on", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Duplicate parameter name entry found, please check the parameters' specification..
+ ///
+ internal static string FsDuplicateParamNames {
+ get {
+ return ResourceManager.GetString("FsDuplicateParamNames", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Invalid parameter format, check job configuration to re-configure parameter definitions for test: {0}. Falling back to default values, without skipping this test..
+ ///
+ internal static string FsRunnerErrorParameterFormat {
+ get {
+ return ResourceManager.GetString("FsRunnerErrorParameterFormat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to =============================== There are no valid tests to run! ===============================.
+ ///
+ internal static string FsRunnerNoValidTests {
+ get {
+ return ResourceManager.GetString("FsRunnerNoValidTests", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Running test: {0}.
+ ///
+ internal static string FsRunnerRunningTest {
+ get {
+ return ResourceManager.GetString("FsRunnerRunningTest", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test result: {0}.
+ ///
+ internal static string FsRunnerTestDone {
+ get {
+ return ResourceManager.GetString("FsRunnerTestDone", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test result: Succeeded with Warnings.
+ ///
+ internal static string FsRunnerTestDoneWarnings {
+ get {
+ return ResourceManager.GetString("FsRunnerTestDoneWarnings", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to {0} tests found:.
+ ///
+ internal static string FsRunnerTestsFound {
+ get {
+ return ResourceManager.GetString("FsRunnerTestsFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ========================\nJob was aborted by user!\n========================.
+ ///
+ internal static string GeneralAbortedByUser {
+ get {
+ return ResourceManager.GetString("GeneralAbortedByUser", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ============================================================================.
+ ///
+ internal static string GeneralDoubleSeperator {
+ get {
+ return ResourceManager.GetString("GeneralDoubleSeperator", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The Parameter {0} of test: {1} is defined more than once.
+ ///
+ internal static string GeneralDuplicateParameterWarning {
+ get {
+ return ResourceManager.GetString("GeneralDuplicateParameterWarning", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Error: {0}\n{1}.
+ ///
+ internal static string GeneralErrorWithStack {
+ get {
+ return ResourceManager.GetString("GeneralErrorWithStack", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to >>> File/Folder not found: {0}.
+ ///
+ internal static string GeneralFileNotFound {
+ get {
+ return ResourceManager.GetString("GeneralFileNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Input parameter type mismatch (skipped), check your test configuration in UFT. param: '{0}'.
+ ///
+ internal static string GeneralParameterTypeMismatchWith1Type {
+ get {
+ return ResourceManager.GetString("GeneralParameterTypeMismatchWith1Type", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Illegal input parameter type (skipped). param: '{0}'. expected type: '{1}'. actual type: '{2}'.
+ ///
+ internal static string GeneralParameterTypeMismatchWith2Types {
+ get {
+ return ResourceManager.GetString("GeneralParameterTypeMismatchWith2Types", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Using parameter {0} = {1}.
+ ///
+ internal static string GeneralParameterUsage {
+ get {
+ return ResourceManager.GetString("GeneralParameterUsage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Using parameter {0} = **********.
+ ///
+ internal static string GeneralParameterUsageMask {
+ get {
+ return ResourceManager.GetString("GeneralParameterUsageMask", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to QTP is not installed on {0}..
+ ///
+ internal static string GeneralQtpNotInstalled {
+ get {
+ return ResourceManager.GetString("GeneralQtpNotInstalled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to "Started...".
+ ///
+ internal static string GeneralStarted {
+ get {
+ return ResourceManager.GetString("GeneralStarted", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test run was aborted by user. Stopping all tests..
+ ///
+ internal static string GeneralStopAborted {
+ get {
+ return ResourceManager.GetString("GeneralStopAborted", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test run was cancelled.
+ ///
+ internal static string GeneralTestCanceled {
+ get {
+ return ResourceManager.GetString("GeneralTestCanceled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ============== Job timed out! ==============.
+ ///
+ internal static string GeneralTimedOut {
+ get {
+ return ResourceManager.GetString("GeneralTimedOut", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Timeout has expired.
+ ///
+ internal static string GeneralTimeoutExpired {
+ get {
+ return ResourceManager.GetString("GeneralTimeoutExpired", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The LoadRunner version must be 11.52 or higher. Check that '{0}' has a compatible version of LoadRunner..
+ ///
+ internal static string HPToolsAssemblyResolverWrongVersion {
+ get {
+ return ResourceManager.GetString("HPToolsAssemblyResolverWrongVersion", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Invalid report path provided: '{0}'.
+ ///
+ internal static string InvalidReportPath {
+ get {
+ return ResourceManager.GetString("InvalidReportPath", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Run mode is set to: {0}.
+ ///
+ internal static string LauncherDisplayRunmode {
+ get {
+ return ResourceManager.GetString("LauncherDisplayRunmode", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Run status: {0}, total tests: {1}, succeeded: {2}, failures: {3}, errors: {4}, warnings: {5}.
+ ///
+ internal static string LauncherDisplayStatistics {
+ get {
+ return ResourceManager.GetString("LauncherDisplayStatistics", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ================================================.
+ ///
+ internal static string LauncherDoubleSeparator {
+ get {
+ return ResourceManager.GetString("LauncherDoubleSeparator", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The parameter 'runMode' should be: RUN_LOCAL | RUN_REMOTE | RUN_PLANNED_HOST.
+ ///
+ internal static string LauncherIncorrectRunmode {
+ get {
+ return ResourceManager.GetString("LauncherIncorrectRunmode", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No cleanup tests were found. Add some cleanup tests..
+ ///
+ internal static string LauncherNoCleanupTestsFound {
+ get {
+ return ResourceManager.GetString("LauncherNoCleanupTestsFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No tests were selected to rerun..
+ ///
+ internal static string LauncherNoFailedTestsFound {
+ get {
+ return ResourceManager.GetString("LauncherNoFailedTestsFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No results filename provided, please add one.
+ ///
+ internal static string LauncherNoResFilenameFound {
+ get {
+ return ResourceManager.GetString("LauncherNoResFilenameFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No runType parameter was provided. Enter a runType (Alm/FileSystem/LoadRunner)..
+ ///
+ internal static string LauncherNoRuntype {
+ get {
+ return ResourceManager.GetString("LauncherNoRuntype", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No test sets were found. Add some test sets or folders..
+ ///
+ internal static string LauncherNoTests {
+ get {
+ return ResourceManager.GetString("LauncherNoTests", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No tests were found. Add tests or folders containing tests..
+ ///
+ internal static string LauncherNoTestsFound {
+ get {
+ return ResourceManager.GetString("LauncherNoTestsFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No valid cleanup tests were found. Fix the test paths..
+ ///
+ internal static string LauncherNoValidCleanupTests {
+ get {
+ return ResourceManager.GetString("LauncherNoValidCleanupTests", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No valid failed tests to rerun were found. Fix the test paths..
+ ///
+ internal static string LauncherNoValidFailedTests {
+ get {
+ return ResourceManager.GetString("LauncherNoValidFailedTests", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No valid tests were found. Fix the test paths..
+ ///
+ internal static string LauncherNoValidTests {
+ get {
+ return ResourceManager.GetString("LauncherNoValidTests", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The parameter '{0}' is required to run a test from QC..
+ ///
+ internal static string LauncherParamRequired {
+ get {
+ return ResourceManager.GetString("LauncherParamRequired", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to An error occurred while disposing runner: {0}..
+ ///
+ internal static string LauncherRunnerDisposeError {
+ get {
+ return ResourceManager.GetString("LauncherRunnerDisposeError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Service Test is not installed on {0}.
+ ///
+ internal static string LauncherStNotInstalled {
+ get {
+ return ResourceManager.GetString("LauncherStNotInstalled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to almTimeout should be an integer!.
+ ///
+ internal static string LauncherTimeoutNotNumeric {
+ get {
+ return ResourceManager.GetString("LauncherTimeoutNotNumeric", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to LoadRunner is not installed on {0}..
+ ///
+ internal static string LoadRunnerNotInstalled {
+ get {
+ return ResourceManager.GetString("LoadRunnerNotInstalled", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Analyzing results....
+ ///
+ internal static string LrAnalysingResults {
+ get {
+ return ResourceManager.GetString("LrAnalysingResults", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Error during Analysis run. See output console for details.
+ ///
+ internal static string LrAnalysisRunTimeError {
+ get {
+ return ResourceManager.GetString("LrAnalysisRunTimeError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Timeout for Analysis passed..
+ ///
+ internal static string LrAnalysisTimeOut {
+ get {
+ return ResourceManager.GetString("LrAnalysisTimeOut", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Failed to initialize Analysis launcher..
+ ///
+ internal static string LrAnlysisInitFail {
+ get {
+ return ResourceManager.GetString("LrAnlysisInitFail", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Analysis Results:.
+ ///
+ internal static string LrAnlysisResults {
+ get {
+ return ResourceManager.GetString("LrAnlysisResults", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cleaning up the environment....
+ ///
+ internal static string LrCleanENV {
+ get {
+ return ResourceManager.GetString("LrCleanENV", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Controller failed to stop..
+ ///
+ internal static string LrControllerFailedToStop {
+ get {
+ return ResourceManager.GetString("LrControllerFailedToStop", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Ignored error message : "{0}" contains ignored string "{1}"..
+ ///
+ internal static string LrErrorIgnored {
+ get {
+ return ResourceManager.GetString("LrErrorIgnored", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Errors during scenario run: \n.
+ ///
+ internal static string LRErrorReasonSummaryTitle {
+ get {
+ return ResourceManager.GetString("LRErrorReasonSummaryTitle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Error(s) summary: .
+ ///
+ internal static string LRErrorsSummary {
+ get {
+ return ResourceManager.GetString("LRErrorsSummary", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to {0} ignored , {1} errors.
+ ///
+ internal static string LrErrorSummeryNum {
+ get {
+ return ResourceManager.GetString("LrErrorSummeryNum", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Exception while trying to analyze results:.
+ ///
+ internal static string LRExceptionInAnalysisRunner {
+ get {
+ return ResourceManager.GetString("LRExceptionInAnalysisRunner", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot open scenario {0} ret code = {1}..
+ ///
+ internal static string LrFailedToOpenScenario {
+ get {
+ return ResourceManager.GetString("LrFailedToOpenScenario", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Failed to start the LoadRunner Controller..
+ ///
+ internal static string LrFailToOpenController {
+ get {
+ return ResourceManager.GetString("LrFailToOpenController", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot register the end scenario event. End scenario detection is based on Vuser status..
+ ///
+ internal static string LrFailToRegisterEndScenarioEvent {
+ get {
+ return ResourceManager.GetString("LrFailToRegisterEndScenarioEvent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Preparing scenario {0} for execution..
+ ///
+ internal static string LrInitScenario {
+ get {
+ return ResourceManager.GetString("LrInitScenario", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to An error occured during RTS in script {0}: {1}.
+ ///
+ internal static string LrRTSError {
+ get {
+ return ResourceManager.GetString("LrRTSError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot collate results ret code = {0}..
+ ///
+ internal static string LrScenarioCollateFail {
+ get {
+ return ResourceManager.GetString("LrScenarioCollateFail", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scenario {0} ended after {1}:{2}:{3}..
+ ///
+ internal static string LrScenarioEnded {
+ get {
+ return ResourceManager.GetString("LrScenarioEnded", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Timeout passed. Stopping scenario by force..
+ ///
+ internal static string LrScenarioEndedTimeOut {
+ get {
+ return ResourceManager.GetString("LrScenarioEndedTimeOut", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Errors occurred during scenario execution. Stopping the scenario run..
+ ///
+ internal static string LrScenarioEndedWithErrors {
+ get {
+ return ResourceManager.GetString("LrScenarioEndedWithErrors", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scenario open process timed out..
+ ///
+ internal static string LrScenarioOpenTimeOut {
+ get {
+ return ResourceManager.GetString("LrScenarioOpenTimeOut", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scenario Execution timeout {0} (d:h:m:s) passed..
+ ///
+ internal static string LrScenarioTimeOut {
+ get {
+ return ResourceManager.GetString("LrScenarioTimeOut", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot connect to Load Generator {0}..
+ ///
+ internal static string LrScenarioValidationCannotConnectLG {
+ get {
+ return ResourceManager.GetString("LrScenarioValidationCannotConnectLG", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot synchronize with Load Generator {0}..
+ ///
+ internal static string LrScenarioValidationCannotSyncLG {
+ get {
+ return ResourceManager.GetString("LrScenarioValidationCannotSyncLG", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No Load Generators were configured for the scenario {0.}.
+ ///
+ internal static string LrScenarioValidationFailNoLGs {
+ get {
+ return ResourceManager.GetString("LrScenarioValidationFailNoLGs", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scenario {0} does not have an SLA configuration..
+ ///
+ internal static string LrScenarioValidationFailNoSLA {
+ get {
+ return ResourceManager.GetString("LrScenarioValidationFailNoSLA", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Load Generator {0} connected.
+ ///
+ internal static string LrScenarioValidationLGConnected {
+ get {
+ return ResourceManager.GetString("LrScenarioValidationLGConnected", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not connect to Load Generator {0}..
+ ///
+ internal static string LrScenarioValidationLGNotReady {
+ get {
+ return ResourceManager.GetString("LrScenarioValidationLGNotReady", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SLA rule {0} failed: GoalValue = {1} ActualValue = {2}.
+ ///
+ internal static string LrSLARuleFailed {
+ get {
+ return ResourceManager.GetString("LrSLARuleFailed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Starting scenario....
+ ///
+ internal static string LrStartScenario {
+ get {
+ return ResourceManager.GetString("LrStartScenario", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot start scenario {0}. Return Code = {1}..
+ ///
+ internal static string LrStartScenarioFail {
+ get {
+ return ResourceManager.GetString("LrStartScenarioFail", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Stop scenario failed. Return code = {0}.
+ ///
+ internal static string LrStopScenarioEnded {
+ get {
+ return ResourceManager.GetString("LrStopScenarioEnded", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to An error occured during summary data logging: {0}.
+ ///
+ internal static string LrSummaryDataLoggingError {
+ get {
+ return ResourceManager.GetString("LrSummaryDataLoggingError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test FAILED. {0} errors occurred during scenario execution..
+ ///
+ internal static string LRTestFailDueToFatalErrors {
+ get {
+ return ResourceManager.GetString("LRTestFailDueToFatalErrors", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Test PASSED.
+ ///
+ internal static string LRTestPassed {
+ get {
+ return ResourceManager.GetString("LRTestPassed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Setting test state to WARNING. {0} Ignored errors occurred during scenario execution..
+ ///
+ internal static string LRTestWarningDueToIgnoredErrors {
+ get {
+ return ResourceManager.GetString("LRTestWarningDueToIgnoredErrors", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Timeout is set to: {0}.
+ ///
+ internal static string LuancherDisplayTimout {
+ get {
+ return ResourceManager.GetString("LuancherDisplayTimout", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Empty Digital Lab Server..
+ ///
+ internal static string McEmptyHostAddress {
+ get {
+ return ResourceManager.GetString("McEmptyHostAddress", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Invalid execution token for Digital Lab, should contain ClientID, SecretKey and TenantID..
+ ///
+ internal static string McInvalidToken {
+ get {
+ return ResourceManager.GetString("McInvalidToken", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Invalid Digital Lab Server URL: '{0}'..
+ ///
+ internal static string McInvalidUrl {
+ get {
+ return ResourceManager.GetString("McInvalidUrl", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Malformed execution token for Digital Lab, invalid key value: {0}..
+ ///
+ internal static string McMalformedTokenInvalidKey {
+ get {
+ return ResourceManager.GetString("McMalformedTokenInvalidKey", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Malformed execution token for Digital Lab, key-value pairs are not separated by {0}..
+ ///
+ internal static string McMalformedTokenInvalidKeyValueSeparator {
+ get {
+ return ResourceManager.GetString("McMalformedTokenInvalidKeyValueSeparator", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Malformed execution token for Digital Lab, token without key-value..
+ ///
+ internal static string McMalformedTokenMissingKeyValuePair {
+ get {
+ return ResourceManager.GetString("McMalformedTokenMissingKeyValuePair", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parameter name missing. Please specify the parameter name..
+ ///
+ internal static string MissingParameterName {
+ get {
+ return ResourceManager.GetString("MissingParameterName", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parameter value is unspecified. Please provide a value or an empty string..
+ ///
+ internal static string MissingParameterValue {
+ get {
+ return ResourceManager.GetString("MissingParameterValue", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Missing quotes for {0} in parameter definition..
+ ///
+ internal static string MissingQuotesInParamFormat {
+ get {
+ return ResourceManager.GetString("MissingQuotesInParamFormat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to You are using an old version of QC. Please update ALM QC..
+ ///
+ internal static string OldVersionOfQC {
+ get {
+ return ResourceManager.GetString("OldVersionOfQC", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to .
+ ///
+ internal static string ParallelRunnerExecutableNotFound {
+ get {
+ return ResourceManager.GetString("ParallelRunnerExecutableNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to QTPActivity.TestCleanup - exception {0}.
+ ///
+ internal static string QtpCleanupError {
+ get {
+ return ResourceManager.GetString("QtpCleanupError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to QTP is not launched..
+ ///
+ internal static string QtpNotLaunchedError {
+ get {
+ return ResourceManager.GetString("QtpNotLaunchedError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to QTP could not handle output arguments..
+ ///
+ internal static string QtpOutputError {
+ get {
+ return ResourceManager.GetString("QtpOutputError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to QTP could not run..
+ ///
+ internal static string QtpRunError {
+ get {
+ return ResourceManager.GetString("QtpRunError", resourceCulture);
+ }
+ }
+
+ ///
/// Looks up a localized string similar to Test execution stopped due to unsaved changes in QuickTest.
- ///Save the test in QuickTest and then run it again..
- ///
- internal static string QtpUnsavedError {
- get {
- return ResourceManager.GetString("QtpUnsavedError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Could not find results file '{0}'..
- ///
- internal static string ResultFileNotExistError {
- get {
- return ResourceManager.GetString("ResultFileNotExistError", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to -------------------------------------------------------------------------------------------------------.
- ///
- internal static string SingleSeperator {
- get {
- return ResourceManager.GetString("SingleSeperator", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to HP Testing Tool is missing : HP Service Test/HP Unified Function Testing.
- ///
- internal static string STExecuterNotFound {
- get {
- return ResourceManager.GetString("STExecuterNotFound", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to UFT cannot start while the LeanFT engine is running..
- ///
- internal static string UFT_LeanFT_Running {
- get {
- return ResourceManager.GetString("UFT_LeanFT_Running", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to UFT cannot start while HP Sprinter is running..
- ///
- internal static string UFT_Sprinter_Running {
- get {
- return ResourceManager.GetString("UFT_Sprinter_Running", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to XML node '{0}' could not be found..
- ///
- internal static string XmlNodeNotExistError {
- get {
- return ResourceManager.GetString("XmlNodeNotExistError", resourceCulture);
- }
- }
- }
-}
+ ///Save the test in QuickTest and then run it again..
+ ///
+ internal static string QtpUnsavedError {
+ get {
+ return ResourceManager.GetString("QtpUnsavedError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not find results file '{0}'..
+ ///
+ internal static string ResultFileNotExistError {
+ get {
+ return ResourceManager.GetString("ResultFileNotExistError", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to -------------------------------------------------------------------------------------------------------.
+ ///
+ internal static string SingleSeperator {
+ get {
+ return ResourceManager.GetString("SingleSeperator", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to ===========================.
+ ///
+ internal static string SmallDoubleSeparator {
+ get {
+ return ResourceManager.GetString("SmallDoubleSeparator", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Micro Focus Testing Tool is missing : Micro Focus Service Test/Micro Focus Unified Function Testing.
+ ///
+ internal static string STExecuterNotFound {
+ get {
+ return ResourceManager.GetString("STExecuterNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UFT cannot start while the LeanFT engine is running..
+ ///
+ internal static string UFT_LeanFT_Running {
+ get {
+ return ResourceManager.GetString("UFT_LeanFT_Running", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UFT cannot start while Micro Focus Sprinter is running..
+ ///
+ internal static string UFT_Sprinter_Running {
+ get {
+ return ResourceManager.GetString("UFT_Sprinter_Running", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The installed version of UFT One does not support the LaunchAsUser method. Please use the version 2023 or later..
+ ///
+ internal static string UftLaunchAsUserNotSupported {
+ get {
+ return ResourceManager.GetString("UftLaunchAsUserNotSupported", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to XML node '{0}' could not be found..
+ ///
+ internal static string XmlNodeNotExistError {
+ get {
+ return ResourceManager.GetString("XmlNodeNotExistError", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/HpToolsLauncher/Properties/Resources.resx b/HpToolsLauncher/Properties/Resources.resx
index bff27934aa..572ab59235 100644
--- a/HpToolsLauncher/Properties/Resources.resx
+++ b/HpToolsLauncher/Properties/Resources.resx
@@ -1,442 +1,553 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Untitled
-
-
- Directory '{0}' doesn't exist.
-
-
- Exception was thrown from external process.
-
-
- Run cancelled by user.
-
-
- QTPActivity.TestCleanup - exception {0}
-
-
- QTP is not launched.
-
-
- QTP could not handle output arguments.
-
-
- QTP could not run.
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Untitled
+
+
+ Directory '{0}' doesn't exist.
+
+
+ Exception was thrown from external process.
+
+
+ Run cancelled by user.
+
+
+ QTPActivity.TestCleanup - exception {0}
+
+
+ QTP is not launched.
+
+
+ QTP could not handle output arguments.
+
+
+ QTP could not run.
+
+
Test execution stopped due to unsaved changes in QuickTest.
-Save the test in QuickTest and then run it again.
-
-
- Could not find results file '{0}'.
-
-
- HP Testing Tool is missing : HP Service Test/HP Unified Function Testing
-
-
- XML node '{0}' could not be found.
-
-
- No HP testing tool is installed on {0}
-
-
- Could not find TestSet {0}
-
-
- One or more of the required connection parameters is empty.
-
-
- Link: {0}
-
-
- Test set name: {0}, Test set id: {1}
-
-
- Test {0}: {1} will run on host: {2}
-
-
- Cannot Login to QC: Authorization failed.
-
-
- Check that your QC client is installed properly\n {0} \n{1}.
-
-
- Cannot connect to QC: Project / Domain does not exist.
-
-
- Problem in updating tests status for test: {0}\n {1}
-
-
- folder {0} cannot be found in ALM
-
-
- "Number of tests in set: "
-
-
- problem while setting remote host: {0}
-
-
- Problem while running TestSet:
-
-
- Run ID:
-
-
- "Scheduler started at:
-
-
- "ALM server {0} unreachable, check that server Url is correct"
-
-
- Starting test set execution
-
-
- Test: {0}, Id: {1}, Execution status: {2}
-
-
- Test: {0}, Id: {1}, Execution status: {2}, Message: {3}
-
-
- Test complete:
-
-
- Test set: {0}, finished at {1}
-
-
- Test: {0}, Status: {1}, Message: {2} \nLink: {3}\n
-
-
- ===============================\nThere are no valid tests to run!\n===============================
-
-
- Running test: {0}
-
-
- Test result: {0}
-
-
- Test result: Succeeded with Warnings
-
-
- {0} tests found:
-
-
- ========================\nJob was aborted by user!\n========================
-
-
- ============================================================================
-
-
- Error: {0}\n{1}
-
-
- >>> File/Folder not found: {0}
-
-
- QTP is not installed on {0}.
-
-
- "Started..."
-
-
- Test run was aborted by user. Stopping all tests.
-
-
- Test run was cancelled
-
-
- ==============\nJob timed out!\n==============
-
-
- Timeout has expired
-
-
- Run mode is set to: {0}
-
-
- Run status: {0}, total tests: {1}, succeeded: {2}, failures: {3}, errors: {4}
-
-
- ================================================
-
-
- The parameter 'runMode' should be: RUN_LOCAL | RUN_REMOTE | RUN_PLANNED_HOST
-
-
- No test sets were found. Add some test sets or folders.
-
-
- No valid tests were found. Fix the test paths.
-
-
- The parameter '{0}' is required to run a test from QC.
-
-
- An error occured while disposing runner: {0}.
-
-
- Service Test is not installed on {0}
-
-
- almTimeout should be an integer!
-
-
- Timeout is set to: {0}
-
-
- -------------------------------------------------------------------------------------------------------
-
-
- No results filename provided, please add one
-
-
- No runType parameter was provided. Enter a runType (Alm/FileSystem/LoadRunner).
-
-
- No tests were found. Add tests or folders containing tests.
-
-
- LoadRunner is not installed on {0}.
-
-
- The LoadRunner version must be 11.52 or higher. Check that '{0}' has a compatible version of LoadRunner.
-
-
- Unable to delete report folder {0}.
-
-
- Failed to create Temp Dir {0}.
-
-
- Analyzing results...
-
-
- Cleaning up the environment...
-
-
- Controller failed to stop.
-
-
- Ignored error message : "{0}" contains ignored string "{1}".
-
-
- {0} ignored , {1} errors
-
-
- Exception while trying to analyze results:
-
-
- Cannot open scenario {0} ret code = {1}.
-
-
- Failed to start the LoadRunner Controller.
-
-
- Cannot register the end scenario event. End scenario detection is based on Vuser status.
-
-
- Preparing scenario {0} for execution.
-
-
- Cannot collate results ret code = {0}.
-
-
- Scenario {0} ended after {1}:{2}:{3}.
-
-
- Timeout passed. Stopping sceario by force.
-
-
- Errors occured during scenario execution. Stopping the scenario run.
-
-
- Scenario Execution timeout ({0} seconds) passed.
-
-
- Cannot connect to Load Generator {0}.
-
-
- Cannot synchronize with Load Generator {0}.
-
-
- No Load Generators were configured for the scenario {0.}
-
-
- Scenario {0} does not have an SLA configuration.
-
-
- Load Generator {0} connected
-
-
- Could not connect to Load Generator {0}.
-
-
- Starting scenario...
-
-
- Cannot start scenario {0}. Return Code = {1}.
-
-
- Stop scenario failed. Return code = {0}
-
-
- Test FAILED. {0} errors occured during scenario execution.
-
-
- Test PASSED
-
-
- Setting test state to WARNING. {0} Ignored errors occured during scenario execution.
-
-
- SLA rule {0} failed: GoalValue = {1} ActualValue = {2}
-
-
- Error during Analysis run. See output console for details
-
-
- Timeout for Analysis passed.
-
-
- Failed to initilize Analysis launcher.
-
-
- Analysis Results:
-
-
- Errors during scenario run: \n
-
-
- Error(s) summary:
-
-
- Scenario open process timed out.
-
-
- The Parameter {0} of test: {1} is defined more than once
-
-
- UFT cannot start while the LeanFT engine is running.
-
-
- UFT cannot start while HP Sprinter is running.
-
+Save the test in QuickTest and then run it again.
+
+
+ Could not find results file '{0}'.
+
+
+ Micro Focus Testing Tool is missing : Micro Focus Service Test/Micro Focus Unified Function Testing
+
+
+ XML node '{0}' could not be found.
+
+
+ No Micro Focus testing tool is installed on {0}
+
+
+ Could not find TestSet {0}
+
+
+ One or more of the required connection parameters is empty.
+
+
+ Copy the following report link inside an IE browser to view the test run results: {0}
+
+
+ Test set name: {0}, Test set id: {1}
+
+
+ Test {0}: {1} will run on host: {2}
+
+
+ Cannot Login to QC: Authorization failed.
+
+
+ Check that your QC client is installed properly
+{0}
+{1}.
+
+
+ Cannot connect to QC: Project / Domain does not exist.
+
+
+ Problem in updating tests status for test: {0}
+{1}
+
+
+ folder {0} cannot be found in ALM
+
+
+ Number of tests in set:
+
+
+ Problem while setting remote host: {0}
+
+
+ Problem while running TestSet:
+
+
+ Run ID:
+
+
+ Scheduler started at:
+
+
+ ALM server {0} unreachable, check that server Url is correct
+
+
+ Unable to login. Please check username and password.
+
+
+ Starting test set execution
+
+
+ Test: {0}, Id: {1}, Execution status: {2}
+
+
+ Test: {0}, Id: {1}, Execution status: {2}, Message: {3}
+
+
+ Test complete:
+
+
+ Test set: {0}, finished at {1}
+
+
+ Test: {0}, Status: {1}, Message: {2}, Link: {3}
+
+
+ =============================== There are no valid tests to run! ===============================
+
+
+ Running test: {0}
+
+
+ Test result: {0}
+
+
+ Test result: Succeeded with Warnings
+
+
+ {0} tests found:
+
+
+ ========================\nJob was aborted by user!\n========================
+
+
+ ============================================================================
+
+
+ Error: {0}\n{1}
+
+
+ >>> File/Folder not found: {0}
+
+
+ QTP is not installed on {0}.
+
+
+ "Started..."
+
+
+ Test run was aborted by user. Stopping all tests.
+
+
+ Test run was cancelled
+
+
+ ============== Job timed out! ==============
+
+
+ Timeout has expired
+
+
+ Run mode is set to: {0}
+
+
+ Run status: {0}, total tests: {1}, succeeded: {2}, failures: {3}, errors: {4}, warnings: {5}
+
+
+ ================================================
+
+
+ The parameter 'runMode' should be: RUN_LOCAL | RUN_REMOTE | RUN_PLANNED_HOST
+
+
+ No test sets were found. Add some test sets or folders.
+
+
+ No valid tests were found. Fix the test paths.
+
+
+ No cleanup tests were found. Add some cleanup tests.
+
+
+ No valid cleanup tests were found. Fix the test paths.
+
+
+ No tests were selected to rerun.
+
+
+ No valid failed tests to rerun were found. Fix the test paths.
+
+
+ The parameter '{0}' is required to run a test from QC.
+
+
+ An error occurred while disposing runner: {0}.
+
+
+ Service Test is not installed on {0}
+
+
+ almTimeout should be an integer!
+
+
+ Timeout is set to: {0}
+
+
+ -------------------------------------------------------------------------------------------------------
+
+
+ No results filename provided, please add one
+
+
+ No runType parameter was provided. Enter a runType (Alm/FileSystem/LoadRunner).
+
+
+ No tests were found. Add tests or folders containing tests.
+
+
+ LoadRunner is not installed on {0}.
+
+
+ The LoadRunner version must be 11.52 or higher. Check that '{0}' has a compatible version of LoadRunner.
+
+
+ Unable to delete report folder {0}.
+
+
+ Failed to create Temp Dir {0}.
+
+
+ Analyzing results...
+
+
+ Cleaning up the environment...
+
+
+ Controller failed to stop.
+
+
+ Ignored error message : "{0}" contains ignored string "{1}".
+
+
+ {0} ignored , {1} errors
+
+
+ Exception while trying to analyze results:
+
+
+ Cannot open scenario {0} ret code = {1}.
+
+
+ Failed to start the LoadRunner Controller.
+
+
+ Cannot register the end scenario event. End scenario detection is based on Vuser status.
+
+
+ Preparing scenario {0} for execution.
+
+
+ Cannot collate results ret code = {0}.
+
+
+ Scenario {0} ended after {1}:{2}:{3}.
+
+
+ Timeout passed. Stopping scenario by force.
+
+
+ Errors occurred during scenario execution. Stopping the scenario run.
+
+
+ Scenario Execution timeout {0} (d:h:m:s) passed.
+
+
+ Cannot connect to Load Generator {0}.
+
+
+ Cannot synchronize with Load Generator {0}.
+
+
+ No Load Generators were configured for the scenario {0.}
+
+
+ Scenario {0} does not have an SLA configuration.
+
+
+ Load Generator {0} connected
+
+
+ Could not connect to Load Generator {0}.
+
+
+ Starting scenario...
+
+
+ Cannot start scenario {0}. Return Code = {1}.
+
+
+ Stop scenario failed. Return code = {0}
+
+
+ Test FAILED. {0} errors occurred during scenario execution.
+
+
+ Test PASSED
+
+
+ Setting test state to WARNING. {0} Ignored errors occurred during scenario execution.
+
+
+ SLA rule {0} failed: GoalValue = {1} ActualValue = {2}
+
+
+ Error during Analysis run. See output console for details
+
+
+ Timeout for Analysis passed.
+
+
+ Failed to initialize Analysis launcher.
+
+
+ Analysis Results:
+
+
+ Errors during scenario run: \n
+
+
+ Error(s) summary:
+
+
+ Scenario open process timed out.
+
+
+ The Parameter {0} of test: {1} is defined more than once
+
+
+ UFT cannot start while the LeanFT engine is running.
+
+
+ UFT cannot start while Micro Focus Sprinter is running.
+
+
+
+
+
+ Invalid report path provided: '{0}'
+
+
+ An error occured during summary data logging: {0}
+
+
+ An error occured during RTS in script {0}: {1}
+
+
+ ===========================
+
+
+ CreateTDConnection
+
+
+ You are using an old version of QC. Please update ALM QC.
+
+
+ Parameter name missing. Please specify the parameter name.
+
+
+ Parameter value is unspecified. Please provide a value or an empty string.
+
+
+ Cannot find the test folder.
+
+
+ No test meets the filtering criteria
+
+
+ Could not find Test {0}
+
+
+ Test set: {0}, aborted at {1}
+
+
+ Test: {0} >> Previous state -> {1}; After update state -> {2}
+
+
+ Invalid parameter format, check job configuration to re-configure parameter definitions for test: {0}. Falling back to default parameter definitions.
+
+
+ Missing quotes for {0} in parameter definition.
+
+
+ Invalid parameter format, check job configuration to re-configure parameter definitions for test: {0}. Falling back to default values, without skipping this test.
+
+
+ Invalid execution token for Digital Lab, should contain ClientID, SecretKey and TenantID.
+
+
+ Malformed execution token for Digital Lab, invalid key value: {0}.
+
+
+ Malformed execution token for Digital Lab, key-value pairs are not separated by {0}.
+
+
+ Malformed execution token for Digital Lab, token without key-value.
+
+
+ Duplicate parameter name entry found, please check the parameters' specification.
+
+
+ Duplicate parameter name entry found, please check the parameters' specification, falling back to default parameters for {0}. test or testset.
+
+
+ Input parameter type mismatch (skipped), check your test configuration in UFT. param: '{0}'
+
+
+ Illegal input parameter type (skipped). param: '{0}'. expected type: '{1}'. actual type: '{2}'
+
+
+ Using parameter {0} = {1}
+
+
+ Using parameter {0} = **********
+
+
+ The installed version of UFT One does not support the LaunchAsUser method. Please use the version 2023 or later.
+
+
+ Empty Digital Lab Server.
+
+
+ Invalid Digital Lab Server URL: '{0}'.
+
+
+ Cloud Browser is not supported in UFT One {0}. Please upgrade to UFT One 23.4 or later.
+
\ No newline at end of file
diff --git a/HpToolsLauncher/RTS/AdditionalAttributeModel.cs b/HpToolsLauncher/RTS/AdditionalAttributeModel.cs
new file mode 100644
index 0000000000..e61522acac
--- /dev/null
+++ b/HpToolsLauncher/RTS/AdditionalAttributeModel.cs
@@ -0,0 +1,66 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+namespace HpToolsLauncher.RTS
+{
+ ///
+ /// Model class which describes the structure of an additional attribute
+ ///
+ public class AdditionalAttributeModel
+ {
+ private string name;
+ private string value;
+ private string description;
+
+ public AdditionalAttributeModel(string name, string value, string description)
+ {
+ this.name = name;
+ this.value = value;
+ this.description = description;
+ }
+
+ public string GetName()
+ {
+ return name;
+ }
+
+ public string GetValue()
+ {
+ return value;
+ }
+
+ public string GetDescription()
+ {
+ return description;
+ }
+ }
+}
diff --git a/HpToolsLauncher/RTS/RTSHelper.cs b/HpToolsLauncher/RTS/RTSHelper.cs
new file mode 100644
index 0000000000..3bcf871199
--- /dev/null
+++ b/HpToolsLauncher/RTS/RTSHelper.cs
@@ -0,0 +1,223 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace HpToolsLauncher.RTS
+{
+ ///
+ /// Class responsible for building the runtime settings xml which is sent to controller to update runtime settings
+ /// It can modify an existing xml string by editing or adding properties (under the form key-value) to a given section
+ /// At the moment it is being used to modify additional attributes
+ ///
+ public class RTSHelper
+ {
+ public struct KeyValuePair
+ {
+ public string key;
+ public string value;
+
+ public KeyValuePair(string key, string value)
+ {
+ this.key = key;
+ this.value = value;
+ }
+ }
+
+ private const string END_OF_LINE = "\\r\\n";
+ public const string COMMAND_ARGUMENTS = "CommandArguments";
+
+ private string m_iniFileText;
+ private int m_startSectionIndex;
+ private int m_endSectionIndex;
+ private bool m_sectionExists;
+ private string m_sectionName;
+ private List m_inputKeyValuePairs;
+ private List m_keyValuePairs;
+
+ /**
+ * Set the begging and the end index of a section
+ */
+ private void SetSectionIndexes()
+ {
+ Regex regex = new Regex("\\[.*?\\]");
+ MatchCollection matches = regex.Matches(m_iniFileText);
+
+ bool sectionFound = false;
+ foreach (Match match in matches)
+ {
+ if (sectionFound == false)
+ {
+ if (match.Value.Equals(m_sectionName))
+ {
+ m_startSectionIndex = match.Index;
+ sectionFound = true;
+ }
+ }
+ else
+ {
+ m_endSectionIndex = match.Index;
+ break;
+ }
+ }
+
+ if (m_startSectionIndex != -1)
+ {
+ m_startSectionIndex += m_sectionName.Length;
+ }
+ else
+ {
+ CreateSection();
+ }
+ }
+
+ /**
+ * Create the section if it doesn't exist
+ */
+ private void CreateSection()
+ {
+ m_iniFileText = m_iniFileText.Insert(m_endSectionIndex, m_sectionName);
+
+ m_startSectionIndex = m_endSectionIndex + m_sectionName.Length;
+ m_endSectionIndex = m_iniFileText.Length;
+ m_sectionExists = false;
+ }
+
+ /**
+ * Set initial key-value pairs for the section
+ */
+ private void SetKeyValuePairs()
+ {
+ if (!m_sectionExists)
+ {
+ return;
+ }
+ string partial = m_iniFileText.Substring(m_startSectionIndex, m_endSectionIndex - m_startSectionIndex);
+ string[] keyValuePairs = partial.Split(new string[] { END_OF_LINE }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (string keyValuePair in keyValuePairs)
+ {
+ var results = keyValuePair.Split('=');
+ if (results.Length > 1)
+ {
+ m_keyValuePairs.Add(new KeyValuePair(results[0], results[1]));
+ }
+ }
+ }
+
+ /**
+ * Reconstruct the section with updates or new key-value pairs
+ */
+ private void ConstructUpdatedSection()
+ {
+ string sectionText = "";
+ foreach (KeyValuePair keyValuePair in m_keyValuePairs)
+ {
+ sectionText += END_OF_LINE + keyValuePair.key + "=" + keyValuePair.value;
+ }
+ sectionText += END_OF_LINE;
+
+ UpdateIniFileText(sectionText);
+ }
+
+ /**
+ * Updates the ini file text with the reconstructed section
+ */
+ private void UpdateIniFileText(string sectionText)
+ {
+ m_iniFileText = m_iniFileText.Remove(m_startSectionIndex, m_endSectionIndex - m_startSectionIndex).Insert(m_startSectionIndex, sectionText);
+ }
+
+ public RTSHelper(string iniFileText, string sectionName, List inputKeyValuePairs)
+ {
+ m_startSectionIndex = -1;
+ m_iniFileText = iniFileText;
+ m_endSectionIndex = m_iniFileText.Length;
+ m_keyValuePairs = new List();
+ m_sectionExists = true;
+
+ SetSectionName(sectionName);
+ SetInputKeyValuePairs(inputKeyValuePairs);
+
+ SetSectionIndexes();
+ SetKeyValuePairs();
+
+ foreach (KeyValuePair keyValuePair in m_inputKeyValuePairs)
+ {
+ UpdateKeyValuePair(keyValuePair);
+ }
+
+ ConstructUpdatedSection();
+ }
+
+ private void SetSectionName(string sectionName)
+ {
+ m_sectionName = "[" + sectionName + "]";
+ }
+
+ private void SetInputKeyValuePairs(List inputKeyValuePairs)
+ {
+ m_inputKeyValuePairs = inputKeyValuePairs;
+ }
+
+ /**
+ * Updates the value of the key if it exists
+ * Creates the key otherwise
+ */
+ private void UpdateKeyValuePair(KeyValuePair keyValuePair)
+ {
+ //Check if key exists
+ bool keyExists = false;
+ for (int i = 0; i < m_keyValuePairs.Count && m_sectionExists; i++)
+ {
+ if (m_keyValuePairs[i].key.Equals(keyValuePair.key))
+ {
+ m_keyValuePairs[i] = new KeyValuePair(m_keyValuePairs[i].key, keyValuePair.value);
+ keyExists = true;
+ break;
+ }
+ }
+ //Key doesn't exist, create new entry
+ if (!keyExists)
+ {
+ m_keyValuePairs.Add(new KeyValuePair(keyValuePair.key, keyValuePair.value));
+ }
+ }
+
+ public string GetUpdatedIniFileText()
+ {
+ return m_iniFileText;
+ }
+ }
+}
diff --git a/HpToolsLauncher/RTS/ScriptRTSModel.cs b/HpToolsLauncher/RTS/ScriptRTSModel.cs
new file mode 100644
index 0000000000..89e77a7f18
--- /dev/null
+++ b/HpToolsLauncher/RTS/ScriptRTSModel.cs
@@ -0,0 +1,86 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System.Collections.Generic;
+
+namespace HpToolsLauncher.RTS
+{
+ ///
+ /// Model class which contains the script name and runtime settings (currently additional attributes)
+ ///
+ public class ScriptRTSModel
+ {
+ private string scriptName;
+ private List additionalAttributes;
+
+ public ScriptRTSModel(string scriptName)
+ {
+ this.scriptName = scriptName;
+ additionalAttributes = new List();
+ }
+
+ public string GetScriptName()
+ {
+ return scriptName;
+ }
+ public void AddAdditionalAttribute(AdditionalAttributeModel additionalAttribute)
+ {
+ additionalAttributes.Add(additionalAttribute);
+ }
+
+ /**
+ * Convert additional attribute model to key value struct
+ */
+ public List GetKeyValuePairs()
+ {
+ List keyValuePairs = new List();
+
+ foreach (AdditionalAttributeModel additionalAttribute in additionalAttributes)
+ {
+ keyValuePairs.Add(
+ new RTSHelper.KeyValuePair(
+ additionalAttribute.GetName(),
+ additionalAttribute.GetValue()
+ )
+ );
+ keyValuePairs.Add(
+ new RTSHelper.KeyValuePair(
+ "~" + additionalAttribute.GetName(),
+ additionalAttribute.GetDescription()
+ )
+ );
+ }
+
+ return keyValuePairs;
+ }
+ }
+}
diff --git a/HpToolsLauncher/Runners/AlmTestSetsRunner.cs b/HpToolsLauncher/Runners/AlmTestSetsRunner.cs
index 472a1052c7..3b8e5d6b70 100644
--- a/HpToolsLauncher/Runners/AlmTestSetsRunner.cs
+++ b/HpToolsLauncher/Runners/AlmTestSetsRunner.cs
@@ -1,1129 +1,2089 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading;
-using HpToolsLauncher.Properties;
-using Mercury.TD.Client.Ota.QC9;
-
-//using Mercury.TD.Client.Ota.Api;
-
-namespace HpToolsLauncher
-{
- public class AlmTestSetsRunner : RunnerBase, IDisposable
- {
- QcRunMode m_runMode = QcRunMode.RUN_LOCAL;
- double m_timeout = -1;
- bool m_blnConnected = false;
- ITDConnection2 tdConnection = null;
- List colTestSets = new List();
- string m_runHost = null;
- string m_qcServer = null;
- string m_qcUser = null;
- string m_qcProject = null;
- string m_qcDomain = null;
-
- public bool Connected
- {
- get { return m_blnConnected; }
- set { m_blnConnected = value; }
- }
-
- public List TestSets
- {
- get { return colTestSets; }
- set { colTestSets = value; }
- }
-
- public QcRunMode RunMode
- {
- get { return m_runMode; }
- set { m_runMode = value; }
- }
-
- public double Timeout
- {
- get { return m_timeout; }
- set { m_timeout = value; }
- }
-
- public string RunHost
- {
- get { return m_runHost; }
- set { m_runHost = value; }
- }
-
- public ITDConnection2 TdConnection
- {
- get
- {
- if (tdConnection == null)
- CreateTdConnection();
-
- return tdConnection;
- }
- set { tdConnection = value; }
- }
-
-
- ///
- /// constructor
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public AlmTestSetsRunner(string qcServer,
- string qcUser,
- string qcPassword,
- string qcDomain,
- string qcProject,
- double intQcTimeout,
- QcRunMode enmQcRunMode,
- string runHost,
- List qcTestSets)
- {
- Timeout = intQcTimeout;
- RunMode = enmQcRunMode;
- RunHost = runHost;
-
- m_qcServer = qcServer;
- m_qcUser = qcUser;
- m_qcProject = qcProject;
- m_qcDomain = qcDomain;
-
- Connected = ConnectToProject(qcServer, qcUser, qcPassword, qcDomain, qcProject);
- TestSets = qcTestSets;
- if (!Connected)
- {
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
- }
-
- ///
- /// destructor - ensures dispose of connection
- ///
- ~AlmTestSetsRunner()
- {
- Dispose(false);
- }
-
-
- ///
- /// runs the tests given to the object.
- ///
- ///
- public override TestSuiteRunResults Run()
- {
- if (!Connected)
- return null;
- TestSuiteRunResults activeRunDesc = new TestSuiteRunResults();
- //find all the testSets under if given some folders in our list
- try
- {
- FindAllTestSetsUnderFolders();
- }
- catch (Exception ex)
- {
-
- ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerErrorBadQcInstallation, ex.Message, ex.StackTrace));
- return null;
- }
-
- //run all the TestSets
- foreach (string testset in TestSets)
- {
- string testset1 = testset.TrimEnd("\\".ToCharArray());
-
- int pos = testset1.LastIndexOf('\\');
- string tsDir = "";
- string tsName = testset1;
- if (pos != -1)
- {
- tsDir = testset1.Substring(0, pos).Trim("\\".ToCharArray());
- tsName = testset1.Substring(pos, testset1.Length - pos).Trim("\\".ToCharArray());
- }
-
- TestSuiteRunResults desc = RunTestSet(tsDir, tsName, Timeout, RunMode, RunHost);
- if (desc != null)
- activeRunDesc.AppendResults(desc);
- }
-
- return activeRunDesc;
- }
-
- ///
- /// creats a connection to Qc
- ///
- private void CreateTdConnection()
- {
-
- Type type = Type.GetTypeFromProgID("TDApiOle80.TDConnection");
-
- if (type == null)
- {
- ConsoleWriter.WriteLine(GetAlmNotInstalledError());
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
-
- try
- {
- object conn = Activator.CreateInstance(type);
- this.tdConnection = conn as ITDConnection2;
-
- }
- catch (FileNotFoundException ex)
- {
- ConsoleWriter.WriteLine(GetAlmNotInstalledError());
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
- }
-
- ///
- /// finds all folders in the TestSet list, scans their tree and adds all sets under the given folders
- /// updates the TestSets by expanding the folders, and removing them, so only Test sets remain in the collection
- ///
- private void FindAllTestSetsUnderFolders()
- {
- List extraSetsList = new List();
- List removeSetsList = new List();
- var tsTreeManager = (ITestSetTreeManager)tdConnection.TestSetTreeManager;
-
- //go over all the testsets / testSetFolders and check which is which
- foreach (string testsetOrFolder in TestSets)
- {
- //try getting the folder
- ITestSetFolder tsFolder = GetFolder("Root\\" + testsetOrFolder.TrimEnd("\\".ToCharArray()));
-
- //if it exists it's a folder and should be traversed to find all sets
- if (tsFolder != null)
- {
- removeSetsList.Add(testsetOrFolder);
-
- List setList = GetAllTestSetsFromDirTree(tsFolder);
- extraSetsList.AddRange(setList);
- }
-
- }
-
- TestSets.RemoveAll((a) => removeSetsList.Contains(a));
- TestSets.AddRange(extraSetsList);
- }
-
- ///
- /// recursively find all testsets in the qc directory tree, starting from a given folder
- ///
- ///
- ///
- ///
- private List GetAllTestSetsFromDirTree(ITestSetFolder tsFolder)
- {
- List retVal = new List();
- List children = tsFolder.FindChildren("");
- List testSets = tsFolder.FindTestSets("");
-
- if (testSets != null)
- {
- foreach (ITestSet childSet in testSets)
- {
- string tsPath = childSet.TestSetFolder.Path;
- tsPath = tsPath.Substring(5).Trim("\\".ToCharArray());
- string tsFullPath = tsPath + "\\" + childSet.Name;
- retVal.Add(tsFullPath.TrimEnd());
- }
- }
-
- if (children != null)
- {
- foreach (ITestSetFolder childFolder in children)
- {
- GetAllTestSetsFromDirTree(childFolder);
- }
- }
- return retVal;
- }
-
-
- ///
- /// get a QC folder
- ///
- ///
- /// the folder object
- private ITestSetFolder GetFolder(string testset)
- {
- var tsTreeManager = (ITestSetTreeManager)tdConnection.TestSetTreeManager;
- ITestSetFolder tsFolder = null;
- try
- {
- tsFolder = (ITestSetFolder)tsTreeManager.get_NodeByPath(testset);
- }
- catch (Exception ex)
- {
- return null;
- }
- return tsFolder;
- }
-
- ///
- /// gets test index given it's name
- ///
- ///
- ///
- ///
- public int GetIdxByTestName(string strName, TestSuiteRunResults results)
- {
- TestRunResults res = null;
- int retVal = -1;
-
- for (int i = 0; i < results.TestRuns.Count(); ++i)
- {
- res = results.TestRuns[i];
-
- if (res != null && res.TestName == strName)
- {
- retVal = i;
- break;
- }
- }
- return retVal;
- }
-
- ///
- /// returns a description of the failure
- ///
- ///
- ///
- private string GenerateFailedLog(IRun p_Test)
- {
- try
- {
- StepFactory sf = p_Test.StepFactory as StepFactory;
- if (sf == null)
- return "";
- IList stepList = sf.NewList("") as IList;
- if (stepList == null)
- return "";
-
- //var stList = p_Test.StepFactory.NewList("");
- //string l_szReturn = "";
- string l_szFailedMessage = "";
-
- //' loop on each step in the steps
- foreach (IStep s in stepList)
- {
- if (s.Status == "Failed")
- l_szFailedMessage += s["ST_DESCRIPTION"] + "'\n\r";
- }
- return l_szFailedMessage;
- }
- catch
- {
- return "";
- }
- }
-
-
- ///
- /// writes a summary of the test run after it's over
- ///
- ///
- private string GetTestInstancesString(ITestSet set)
- {
- string retVal = "";
- try
- {
- TSTestFactory factory = set.TSTestFactory;
- List list = factory.NewList("");
-
- if (list == null)
- return "";
-
- foreach (ITSTest testInstance in list)
- {
- retVal += testInstance.ID + ",";
- }
- retVal.TrimEnd(", \n".ToCharArray());
- }
- catch (Exception ex)
- { }
- return retVal;
- }
-
- ///
- /// runs a test set with given parameters (and a valid connection to the QC server)
- ///
- /// testSet folder name
- /// testSet name
- /// -1 for unlimited, or number of miliseconds
- /// run on LocalMachine or remote
- /// if run on remote machine - remote machine name
- ///
- public TestSuiteRunResults RunTestSet(string tsFolderName, string tsName, double timeout, QcRunMode runMode, string runHost)
- {
- string currentTestSetInstances = "";
- TestSuiteRunResults runDesc = new TestSuiteRunResults();
- TestRunResults activeTestDesc = null;
-
- var tsFactory = tdConnection.TestSetFactory;
- var tsTreeManager = (ITestSetTreeManager)tdConnection.TestSetTreeManager;
- List tsList = null;
- string tsPath = "Root\\" + tsFolderName;
- ITestSetFolder tsFolder = null;
-
- try
- {
- tsFolder = (ITestSetFolder)tsTreeManager.get_NodeByPath(tsPath);
- }
- catch (COMException ex)
- {
- //not found
- tsFolder = null;
- }
-
- if (tsFolder == null)
- {
- //node wasn't found, folder = null
- ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerNoSuchFolder, tsFolder));
-
- //this will make sure run will fail at the end. (since there was an error)
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- return null;
- }
- else
- {
- tsList = tsFolder.FindTestSets(tsName);
- }
- if (tsList == null)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerCantFindTest, tsName));
-
- //this will make sure run will fail at the end. (since there was an error)
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- return null;
- }
- ITestSet targetTestSet = null;
- foreach (ITestSet ts in tsList)
- {
- if (ts.Name.Equals(tsName, StringComparison.InvariantCultureIgnoreCase))
- {
- targetTestSet = ts;
- break;
- }
- }
-
- if (targetTestSet == null)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerCantFindTest, tsName));
-
- //this will make sure run will fail at the end. (since there was an error)
- Launcher.ExitCode = Launcher.ExitCodeEnum.Failed;
- return null;
- }
-
-
- ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator);
- ConsoleWriter.WriteLine(Resources.AlmRunnerStartingExecution);
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerDisplayTest, tsName, targetTestSet.ID));
-
- ITSScheduler Scheduler = null;
- try
- {
- //need to run this to install everyhting needed http://AlmServer:8080/qcbin/start_a.jsp?common=true
- //start the scheduler
- Scheduler = targetTestSet.StartExecution("");
-
-
- }
- catch (Exception ex)
- {
- Scheduler = null;
- }
- try
- {
-
- currentTestSetInstances = GetTestInstancesString(targetTestSet);
- }
- catch (Exception ex)
- {
- }
-
- if (Scheduler == null)
- {
- Console.WriteLine(GetAlmNotInstalledError());
-
- //proceeding with program execution is tasteless, since nothing will run without a properly installed QC.
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
-
- TSTestFactory tsTestFactory = targetTestSet.TSTestFactory;
- ITDFilter2 tdFilter = tsTestFactory.Filter;
- tdFilter["TC_CYCLE_ID"] = targetTestSet.ID.ToString();
-
- IList tList = tsTestFactory.NewList(tdFilter.Text);
- try
- {
- //set up for the run depending on where the test instances are to execute
- switch (runMode)
- {
- case QcRunMode.RUN_LOCAL:
- // run all tests on the local machine
- Scheduler.RunAllLocally = true;
- break;
- case QcRunMode.RUN_REMOTE:
- // run tests on a specified remote machine
- Scheduler.TdHostName = runHost;
- break;
- // RunAllLocally must not be set for remote invocation of tests. As such, do not do this: Scheduler.RunAllLocally = False
- case QcRunMode.RUN_PLANNED_HOST:
- // run on the hosts as planned in the test set
- Scheduler.RunAllLocally = false;
- break;
- }
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerProblemWithHost, ex.Message));
- }
-
- ConsoleWriter.WriteLine(Resources.AlmRunnerNumTests + tList.Count);
-
- int i = 1;
- foreach (ITSTest3 test in tList)
- {
- string runOnHost = runHost;
- if (runMode == QcRunMode.RUN_PLANNED_HOST)
- runOnHost = test.HostName;
-
- //if host isn't taken from QC (PLANNED) and not from the test definition (REMOTE), take it from LOCAL (machineName)
- string hostName = runOnHost;
- if (runMode == QcRunMode.RUN_LOCAL)
- {
- hostName = Environment.MachineName;
- }
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerDisplayTestRunOnHost, i, test.Name, hostName));
-
- Scheduler.RunOnHost[test.ID] = runOnHost;
-
- var testResults = new TestRunResults();
- testResults.TestName = test.Name;
- runDesc.TestRuns.Add(testResults);
-
- i = i + 1;
- }
-
- Stopwatch sw = Stopwatch.StartNew();
- Stopwatch testSw = null;
- try
- {
- //tests are actually run
- Scheduler.Run();
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteLine(Resources.AlmRunnerRunError + ex.Message);
- }
-
- ConsoleWriter.WriteLine(Resources.AlmRunnerSchedStarted + DateTime.Now.ToString(Launcher.DateFormat));
- ConsoleWriter.WriteLine(Resources.SingleSeperator);
- IExecutionStatus executionStatus = Scheduler.ExecutionStatus;
- bool tsExecutionFinished = false;
- ITSTest prevTest = null;
- ITSTest currentTest = null;
- string abortFilename = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\stop" + Launcher.UniqueTimeStamp + ".txt";
- //wait for the tests to end ("normally" or because of the timeout)
- while ((tsExecutionFinished == false) && (timeout == -1 || sw.Elapsed.TotalSeconds < timeout))
- {
- executionStatus.RefreshExecStatusInfo("all", true);
- tsExecutionFinished = executionStatus.Finished;
-
- if (System.IO.File.Exists(abortFilename))
- {
- break;
- }
-
- for (int j = 1; j <= executionStatus.Count; ++j)
- {
- TestExecStatus testExecStatusObj = executionStatus[j];
-
- currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
- if (currentTest == null)
- {
- ConsoleWriter.WriteLine(string.Format("currentTest is null for test.{0} during execution", j));
- continue;
- }
-
- activeTestDesc = UpdateTestStatus(runDesc, targetTestSet, testExecStatusObj, true);
-
- if (activeTestDesc.PrevTestState != activeTestDesc.TestState)
- {
- TestState tstate = activeTestDesc.TestState;
- if (tstate == TestState.Running)
- {
- //currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
- int testIndex = GetIdxByTestName(currentTest.Name, runDesc);
-
- int prevRunId = GetTestRunId(currentTest);
- runDesc.TestRuns[testIndex].PrevRunId = prevRunId;
-
- //closing previous test
- if (prevTest != null)
- {
- WriteTestRunSummary(prevTest);
- }
-
- //starting new test
- prevTest = currentTest;
-
- //assign the new test the consol writer so it will gather the output
-
- ConsoleWriter.ActiveTestRun = runDesc.TestRuns[testIndex];
-
- ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Running: " + currentTest.Name);
-
- //tell user that the test is running
- ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Running test: " + activeTestDesc.TestName + ", Test id: " + testExecStatusObj.TestId + ", Test instance id: " + testExecStatusObj.TSTestId);
-
- //start timing the new test run
- string foldername = "";
- ITestSetFolder folder = targetTestSet.TestSetFolder as ITestSetFolder;
-
- if (folder != null)
- foldername = folder.Name.Replace(".", "_");
-
- //the test group is it's test set. (dots are problematic since jenkins parses them as seperators between packadge and class)
- activeTestDesc.TestGroup = foldername + "\\" + targetTestSet.Name;
- activeTestDesc.TestGroup = activeTestDesc.TestGroup.Replace(".", "_");
- }
-
- TestState enmState = GetTsStateFromQcState(testExecStatusObj.Status as string);
- string statusString = enmState.ToString();
-
- if (enmState == TestState.Running)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerStat, activeTestDesc.TestName, testExecStatusObj.TSTestId, statusString));
- }
- else if (enmState != TestState.Waiting)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerStatWithMessage, activeTestDesc.TestName, testExecStatusObj.TSTestId, statusString, testExecStatusObj.Message));
- }
- if (System.IO.File.Exists(abortFilename))
- {
- break;
- }
- }
- }
-
- //wait 0.2 seconds
- Thread.Sleep(200);
-
- //check for abortion
- if (System.IO.File.Exists(abortFilename))
- {
- _blnRunCancelled = true;
-
- ConsoleWriter.WriteLine(Resources.GeneralStopAborted);
-
- //stop all test instances in this testSet.
- Scheduler.Stop(currentTestSetInstances);
-
- ConsoleWriter.WriteLine(Resources.GeneralAbortedByUser);
-
- //stop working
- Environment.Exit((int)Launcher.ExitCodeEnum.Aborted);
- }
- }
-
- //check status for each test
- if (timeout == -1 || sw.Elapsed.TotalSeconds < timeout)
- {
- //close last test
- if (prevTest != null)
- {
- WriteTestRunSummary(prevTest);
- }
-
- //done with all tests, stop collecting output in the testRun object.
- ConsoleWriter.ActiveTestRun = null;
- for (int k = 1; k <= executionStatus.Count; ++k)
- {
- if (System.IO.File.Exists(abortFilename))
- {
- break;
- }
-
- TestExecStatus testExecStatusObj = executionStatus[k];
- currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
- if (currentTest == null)
- {
- ConsoleWriter.WriteLine(string.Format("currentTest is null for test.{0} after whole execution", k));
- continue;
- }
-
- activeTestDesc = UpdateTestStatus(runDesc, targetTestSet, testExecStatusObj, false);
-
- UpdateCounters(activeTestDesc, runDesc);
-
- //currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
-
- string testPath = "Root\\" + tsFolderName + "\\" + tsName + "\\" + activeTestDesc.TestName;
-
- activeTestDesc.TestPath = testPath;
- }
-
- //update the total runtime
- runDesc.TotalRunTime = sw.Elapsed;
-
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerTestsetDone, tsName, DateTime.Now.ToString(Launcher.DateFormat)));
- }
- else
- {
- _blnRunCancelled = true;
- ConsoleWriter.WriteLine(Resources.GeneralTimedOut);
- Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted;
- }
-
- return runDesc;
- }
-
- ///
- /// writes a summary of the test run after it's over
- ///
- ///
- private void WriteTestRunSummary(ITSTest prevTest)
- {
- int prevRunId = ConsoleWriter.ActiveTestRun.PrevRunId;
-
- int runid = GetTestRunId(prevTest);
- if (runid > prevRunId)
- {
- string stepsString = GetTestStepsDescFromQc(prevTest);
-
- if (string.IsNullOrWhiteSpace(stepsString) && ConsoleWriter.ActiveTestRun.TestState != TestState.Error)
- stepsString = GetTestRunLog(prevTest);
-
- if (!string.IsNullOrWhiteSpace(stepsString))
- ConsoleWriter.WriteLine(stepsString);
-
- string linkStr = GetTestRunLink(prevTest, runid);
-
- ConsoleWriter.WriteLine("\n" + string.Format(Resources.AlmRunnerDisplayLink, linkStr));
- }
- ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " " + Resources.AlmRunnerTestCompleteCaption + " " + prevTest.Name +
- ((runid > prevRunId) ? ", " + Resources.AlmRunnerRunIdCaption + " " + runid : "")
- + "\n-------------------------------------------------------------------------------------------------------");
- }
-
- ///
- /// gets a link string for the test run in Qc
- ///
- ///
- ///
- ///
- private string GetTestRunLink(ITSTest prevTest, int runid)
- {
- bool oldQc = CheckIsOldQc();
- bool useSSL = (m_qcServer.Contains("https://"));
-
- ITestSet set = prevTest.TestSet;
- string testRunLink = useSSL ? ("tds://" + m_qcProject + "." + m_qcDomain + "." + m_qcServer.Replace("https://", "") + "/TestLabModule-000000003649890581?EntityType=IRun&EntityID=" + runid)
- : ("td://" + m_qcProject + "." + m_qcDomain + "." + m_qcServer.Replace("http://", "") + "/TestLabModule-000000003649890581?EntityType=IRun&EntityID=" + runid);
- string testRunLinkQc10 = useSSL ? ("tds://" + m_qcProject + "." + m_qcDomain + "." + m_qcServer.Replace("https://", "") + "/Test%20Lab?Action=FindRun&TestSetID=" + set.ID + "&TestInstanceID=" + prevTest.ID + "&RunID=" + runid)
- : ("td://" + m_qcProject + "." + m_qcDomain + "." + m_qcServer.Replace("http://", "") + "/Test%20Lab?Action=FindRun&TestSetID=" + set.ID + "&TestInstanceID=" + prevTest.ID + "&RunID=" + runid);
- string linkStr = (oldQc ? testRunLinkQc10 : testRunLink);
- return linkStr;
- }
-
- private string GetAlmNotInstalledError()
- {
- return "Could not create scheduler, please verify ALM client installation on run machine by downloading and in installing the add-in form: " + GetQcCommonInstallationURl(m_qcServer);
- }
-
- ///
- /// summerizes test steps after test has run
- ///
- ///
- /// a string containing descriptions of step states and messags
- string GetTestStepsDescFromQc(ITSTest test)
- {
- StringBuilder sb = new StringBuilder();
- try
- {
- //get runs for the test
- RunFactory rfactory = test.RunFactory;
- List runs = rfactory.NewList("");
- if (runs.Count == 0)
- return "";
-
- //get steps from run
- StepFactory stepFact = runs[runs.Count].StepFactory;
- List steps = stepFact.NewList("");
- if (steps.Count == 0)
- return "";
-
- //go over steps and format a string
- foreach (IStep step in steps)
- {
- sb.Append("Step: " + step.Name);
-
- if (!string.IsNullOrWhiteSpace(step.Status))
- sb.Append(", Status: " + step.Status);
-
- string desc = step["ST_DESCRIPTION"] as string;
- if (!string.IsNullOrEmpty(desc))
- {
- desc = "\n\t" + desc.Trim().Replace("\n", "\t").Replace("\r", "");
- if (!string.IsNullOrWhiteSpace(desc))
- sb.AppendLine(desc);
- }
- }
- }
- catch (Exception ex)
- {
- sb.AppendLine("Exception while reading step data: " + ex.Message);
- }
- return sb.ToString().TrimEnd();
- }
-
- private void UpdateCounters(TestRunResults test, TestSuiteRunResults testSuite)
- {
- if (test.TestState != TestState.Running &&
- test.TestState != TestState.Waiting &&
- test.TestState != TestState.Unknown)
- ++testSuite.NumTests;
-
- if (test.TestState == TestState.Failed)
- ++testSuite.NumFailures;
-
- if (test.TestState == TestState.Error)
- ++testSuite.NumErrors;
- }
-
- ///
- /// translate the qc states into a state enum
- ///
- ///
- ///
- private TestState GetTsStateFromQcState(string qcTestStatus)
- {
- if (qcTestStatus == null)
- return TestState.Unknown;
- switch (qcTestStatus)
- {
- case "Waiting":
- return TestState.Waiting;
- case "Error":
- return TestState.Error;
- case "No Run":
- return TestState.NoRun;
- case "Running":
- case "Connecting":
- return TestState.Running;
- case "Success":
- case "Finished":
- case "FinishedPassed":
- return TestState.Passed;
- case "FinishedFailed":
- return TestState.Failed;
- }
- return TestState.Unknown;
- }
-
- ///
- /// updates the test status in our list of tests
- ///
- ///
- ///
- private TestRunResults UpdateTestStatus(TestSuiteRunResults runResults, ITestSet targetTestSet, TestExecStatus testExecStatusObj, bool onlyUpdateState)
- {
- TestRunResults qTest = null;
- ITSTest currentTest = null;
- try
- {
- //find the test for the given status object
- currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
-
- if (currentTest == null)
- {
- return qTest;
- }
-
- //find the test in our list
- int testIndex = GetIdxByTestName(currentTest.Name, runResults);
- qTest = runResults.TestRuns[testIndex];
-
- if (qTest.TestType == null)
- {
- qTest.TestType = GetTestType(currentTest);
- }
-
- //update the state
- qTest.PrevTestState = qTest.TestState;
- qTest.TestState = GetTsStateFromQcState(testExecStatusObj.Status);
-
- if (!onlyUpdateState)
- {
- try
- {
- //duration and status are updated according to the run
- qTest.Runtime = TimeSpan.FromSeconds(currentTest.LastRun.Field("RN_DURATION"));
- }
- catch
- {
- //a problem getting duration, maybe the test isn't done yet - don't stop the flow..
- }
-
- switch (qTest.TestState)
- {
- case TestState.Failed:
- qTest.FailureDesc = GenerateFailedLog(currentTest.LastRun);
-
- if (string.IsNullOrWhiteSpace(qTest.FailureDesc))
- qTest.FailureDesc = testExecStatusObj.Status + " : " + testExecStatusObj.Message;
- break;
- case TestState.Error:
- qTest.ErrorDesc = testExecStatusObj.Status + " : " + testExecStatusObj.Message;
- break;
- default:
- break;
- }
-
- //check qc version for link type
- bool oldQc = CheckIsOldQc();
-
- //string testLink = " Alm link";
- string serverURl = m_qcServer.TrimEnd("/".ToCharArray());
- if (serverURl.ToLower().StartsWith("http://"))
- serverURl = serverURl.Substring(7);
-
- //string testLinkInLabQc10 = "td://" + m_qcProject + "." + m_qcDomain + "." + m_qcServer.Replace("http://", "") + "/Test%20Lab?Action=FindTestInstance&TestSetID=" + targetTestSet.ID + "&TestInstanceID=" + testExecStatusObj.TSTestId;
- //string testLinkInLab = "td://" + m_qcProject + "." + m_qcDomain + "." + m_qcServer.Replace("http://", "") + "/TestLabModule-000000003649890581?EntityType=ITestInstance&EntityID=" + testExecStatusObj.TSTestId;
-
- int runid = GetTestRunId(currentTest);
- string linkStr = GetTestRunLink(currentTest, runid);
-
- string statusString = GetTsStateFromQcState(testExecStatusObj.Status as string).ToString();
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerTestStat, currentTest.Name, statusString, testExecStatusObj.Message, linkStr));
- runResults.TestRuns[testIndex] = qTest;
- }
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerErrorGettingStat, currentTest.Name, ex.Message));
- }
-
- return qTest;
- }
-
- ///
- /// gets the runId for the given test
- ///
- /// a test instance
- /// the run id
- private static int GetTestRunId(ITSTest currentTest)
- {
- int runid = -1;
- IRun lastrun = currentTest.LastRun as IRun;
- if (lastrun != null)
- runid = lastrun.ID;
- return runid;
- }
-
- ///
- /// retrieves the run logs for the test when the steps are not reported to Qc (like in ST)
- ///
- ///
- /// the test run log
- private string GetTestRunLog(ITSTest currentTest)
- {
- string TestLog = "log\\vtd_user.log";
-
- IRun lastrun = currentTest.LastRun as IRun;
- string retVal = "";
- if (lastrun != null)
- {
- try
- {
- IExtendedStorage storage = lastrun.ExtendedStorage as IExtendedStorage;
-
- List list;
- bool wasFatalError;
- var path = storage.LoadEx(TestLog, true, out list, out wasFatalError);
- string logPath = Path.Combine(path, TestLog);
-
- if (File.Exists(logPath))
- {
- retVal = File.ReadAllText(logPath).TrimEnd();
- }
- }
- catch
- {
- retVal = "";
- }
- }
- retVal = ConsoleWriter.FilterXmlProblematicChars(retVal);
- return retVal;
- }
-
- ///
- /// checks Qc version (used for link format, 10 and smaller is old)
- ///
- /// true if this QC is an old one
- private bool CheckIsOldQc()
- {
- string ver = null;
- int intver = -1;
- string build = null;
- TdConnection.GetTDVersion(out ver, out build);
- bool oldQc = false;
- if (ver != null)
- {
- int.TryParse(ver, out intver);
- if (intver <= 10)
- oldQc = true;
- }
- else
- {
- oldQc = true;
- }
- return oldQc;
- }
-
- ///
- /// gets the type for a QC test
- ///
- ///
- ///
- private string GetTestType(dynamic currentTest)
- {
- string ttype = currentTest.Test.Type;
- if (ttype.ToUpper() == "SERVICE-TEST")
- {
- ttype = TestType.ST.ToString();
- }
- else
- {
- ttype = TestType.QTP.ToString();
- }
- return ttype;
- }
-
- ///
- /// connects to QC and logs in
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public bool ConnectToProject(string QCServerURL, string QCLogin, string QCPass, string QCDomain, string QCProject)
- {
- if (string.IsNullOrWhiteSpace(QCServerURL)
- || string.IsNullOrWhiteSpace(QCLogin)
- || string.IsNullOrWhiteSpace(QCDomain)
- || string.IsNullOrWhiteSpace(QCProject))
- {
- ConsoleWriter.WriteLine(Resources.AlmRunnerConnParamEmpty);
- return false;
- }
-
- try
- {
- TdConnection.InitConnectionEx(QCServerURL);
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteLine(ex.Message);
- }
-
- if (!TdConnection.Connected)
- {
- ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerServerUnreachable, QCServerURL));
- return false;
- }
- try
- {
- TdConnection.Login(QCLogin, QCPass);
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteLine(ex.Message);
- }
-
- if (!TdConnection.LoggedIn)
- {
- ConsoleWriter.WriteErrLine(Resources.AlmRunnerErrorAuthorization);
- return false;
- }
-
- try
- {
- TdConnection.Connect(QCDomain, QCProject);
- }
- catch (Exception ex)
- {
-
- }
-
- if (!TdConnection.ProjectConnected)
- {
- ConsoleWriter.WriteErrLine(Resources.AlmRunnerErrorConnectToProj);
- return false;
- }
- return true;
- }
-
- private string GetQcCommonInstallationURl(string QCServerURL)
- {
- return QCServerURL + "/TDConnectivity_index.html";
- }
-
- #region IDisposable Members
-
- public void Dispose(bool managed)
- {
- if (Connected)
- {
- tdConnection.Disconnect();
- Marshal.ReleaseComObject(tdConnection);
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- #endregion
-
-
- }
-
- public class QCFailure
- {
- public string Name { get; set; }
- public string Desc { get; set; }
- }
-
- public enum QcRunMode
- {
- RUN_LOCAL,
- RUN_REMOTE,
- RUN_PLANNED_HOST
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.Properties;
+using Mercury.TD.Client.Ota.QC9;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Security;
+using HpToolsLauncher.Utils;
+
+namespace HpToolsLauncher
+{
+ public class AlmTestSetsRunner : RunnerBase, IDisposable
+ {
+ private readonly char[] _backSlash = new char[] { '\\' };
+
+ private ITDConnection13 _tdConnection;
+ private ITDConnection2 _tdConnectionOld;
+ private const string TEST_DETAILS = "ID = {0}, TestSet = {1}, TestSetFolder = {2}";
+ private const string XML_PARAMS_START_TAG = "";
+ private const string XML_PARAM_NAME_VALUE = "";
+ private const string XML_PARAM_NAME_VALUE_TYPE = "";
+ private const string XML_PARAMS_END_TAG = "";
+ private readonly char[] COMMA = new char[] { ',' };
+ private const string API_TEST = "SERVICE-TEST";
+ private const string GUI_TEST = "QUICKTEST_TEST";
+ private List _params;
+ private const string PASSWORD = "password";
+
+ public ITDConnection13 TdConnection
+ {
+ get
+ {
+ if (_tdConnection == null)
+ CreateTdConnection();
+ return _tdConnection;
+ }
+ }
+
+ public ITDConnection2 TdConnectionOld
+ {
+ get
+ {
+ if (_tdConnectionOld == null)
+ CreateTdConnectionOld();
+ return _tdConnectionOld;
+ }
+ }
+
+ public bool Connected { get; set; }
+ public string MQcServer { get; set; }
+ public string MQcUser { get; set; }
+ public string MQcProject { get; set; }
+ public string MQcDomain { get; set; }
+ public string FilterByName { get; set; }
+ public bool IsFilterSelected { get; set; }
+ public bool InitialTestRun { get; set; }
+ public List FilterByStatuses { get; set; }
+ public List TestSets { get; set; }
+ public QcRunMode RunMode { get; set; }
+ public string RunHost { get; set; }
+ public TestStorageType Storage { get; set; }
+ public double Timeout { get; set; }
+ public bool SSOEnabled { get; set; }
+ public string ClientID { get; set; }
+ public string ApiKey { get; set; }
+
+ ///
+ /// constructor
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public AlmTestSetsRunner(string qcServer,
+ string qcUser,
+ string qcPassword,
+ string qcDomain,
+ string qcProject,
+ double intQcTimeout,
+ QcRunMode enmQcRunMode,
+ string runHost,
+ List qcTestSets,
+ List @params,
+ bool isFilterSelected,
+ string filterByName,
+ List filterByStatuses,
+ bool initialTestRun,
+ TestStorageType testStorageType,
+ bool isSSOEnabled,
+ string qcClientId,
+ string qcApiKey)
+ {
+
+ Timeout = intQcTimeout;
+ RunMode = enmQcRunMode;
+ RunHost = runHost;
+
+ MQcServer = qcServer;
+ MQcUser = qcUser;
+ MQcProject = qcProject;
+ MQcDomain = qcDomain;
+
+ IsFilterSelected = isFilterSelected;
+ FilterByName = filterByName;
+ FilterByStatuses = filterByStatuses;
+ InitialTestRun = initialTestRun;
+ SSOEnabled = isSSOEnabled;
+ ClientID = qcClientId;
+ ApiKey = qcApiKey;
+
+ Connected = ConnectToProject(MQcServer, MQcUser, qcPassword, MQcDomain, MQcProject, SSOEnabled, ClientID, ApiKey);
+ TestSets = qcTestSets;
+ _params = @params;
+ Storage = testStorageType;
+ if (!Connected)
+ {
+ Console.WriteLine("ALM Test set runner not connected");
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+ }
+
+ ///
+ /// destructor - ensures dispose of connection
+ ///
+ ~AlmTestSetsRunner()
+ {
+ Dispose(false);
+ }
+
+ //------------------------------- Connection to QC --------------------------
+
+ ///
+ /// Creates a connection to QC (for ALM 12.60 and 15)
+ ///
+ private void CreateTdConnection()
+ {
+ Type type = Type.GetTypeFromProgID("TDApiOle80.TDConnection");
+
+ if (type == null)
+ {
+ ConsoleWriter.WriteLine(GetAlmNotInstalledError());
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ try
+ {
+ object conn = Activator.CreateInstance(type);
+ _tdConnection = conn as ITDConnection13;
+
+ }
+ catch (FileNotFoundException ex)
+ {
+ ConsoleWriter.WriteLine(GetAlmNotInstalledError());
+ ConsoleWriter.WriteLine(ex.Message);
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+ }
+
+ ///
+ /// Creates a connection to QC (for ALM 12.55)
+ ///
+ private void CreateTdConnectionOld()
+ {
+ Type type = Type.GetTypeFromProgID("TDApiOle80.TDConnection");
+
+ if (type == null)
+ {
+ ConsoleWriter.WriteLine(GetAlmNotInstalledError());
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ try
+ {
+ object conn = Activator.CreateInstance(type);
+ _tdConnectionOld = conn as ITDConnection2;
+ }
+ catch (FileNotFoundException ex)
+ {
+ ConsoleWriter.WriteLine(GetAlmNotInstalledError());
+ ConsoleWriter.WriteLine(ex.Message);
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+ }
+
+ ///
+ /// Returns ALM QC installation URL
+ ///
+ ///
+ ///
+ private static string GetQcCommonInstallationUrl(string qcServerUrl)
+ {
+ return string.Format("{0}/TDConnectivity_index.html", qcServerUrl);
+ }
+
+ ///
+ /// checks Qc version (used for link format, 10 and smaller is old)
+ ///
+ /// true if this QC is an old one, false otherwise
+ private bool CheckIsOldQc()
+ {
+ bool oldQc = false;
+ if (TdConnection != null)
+ {
+ string ver, build;
+ TdConnection.GetTDVersion(out ver, out build);
+ if (ver != null)
+ {
+ int intver;
+ int.TryParse(ver, out intver);
+ if (intver <= 10)
+ oldQc = true;
+ }
+ else
+ {
+ oldQc = true;
+ }
+ }
+
+ return oldQc;
+ }
+
+ ///
+ /// connects to QC and logs in
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool ConnectToProject(string qcServerUrl, string qcLogin, string qcPass, string qcDomain, string qcProject, bool SSOEnabled, string qcClientID, string qcApiKey)
+ {
+ if (string.IsNullOrWhiteSpace(qcServerUrl)
+ || (string.IsNullOrWhiteSpace(qcLogin) && !SSOEnabled)
+ || string.IsNullOrWhiteSpace(qcDomain)
+ || string.IsNullOrWhiteSpace(qcProject)
+ || (SSOEnabled && (string.IsNullOrWhiteSpace(qcClientID)
+ || string.IsNullOrWhiteSpace(qcApiKey))))
+ {
+ ConsoleWriter.WriteLine(Resources.AlmRunnerConnParamEmpty);
+ return false;
+ }
+
+ if (TdConnection != null)
+ {
+ try
+ {
+ if (!SSOEnabled)
+ {
+ TdConnection.InitConnectionEx(qcServerUrl);
+ }
+ else
+ {
+ TdConnection.InitConnectionWithApiKey(qcServerUrl, qcClientID, qcApiKey);
+ }
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+ if (TdConnection.Connected)
+ {
+ try
+ {
+ if (!SSOEnabled)
+ {
+ TdConnection.Login(qcLogin, qcPass);
+ }
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+
+ if (TdConnection.LoggedIn)
+ {
+ try
+ {
+ TdConnection.Connect(qcDomain, qcProject);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ if (TdConnection.ProjectConnected)
+ {
+ return true;
+ }
+
+ ConsoleWriter.WriteErrLine(Resources.AlmRunnerErrorConnectToProj);
+ }
+ else
+ {
+ ConsoleWriter.WriteErrLine(Resources.AlmRunnerErrorAuthorization);
+ }
+
+ }
+ else
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerServerUnreachable, qcServerUrl));
+ }
+
+ return false;
+ }
+ else //older versions of ALM (< 12.60)
+ {
+ try
+ {
+ TdConnectionOld.InitConnectionEx(qcServerUrl);
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+
+ if (TdConnectionOld.Connected)
+ {
+ try
+ {
+ TdConnectionOld.Login(qcLogin, qcPass);
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+
+ if (TdConnectionOld.LoggedIn)
+ {
+ try
+ {
+ TdConnectionOld.Connect(qcDomain, qcProject);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ if (TdConnectionOld.ProjectConnected)
+ {
+ return true;
+ }
+
+ ConsoleWriter.WriteErrLine(Resources.AlmRunnerErrorConnectToProj);
+ }
+ else
+ {
+ ConsoleWriter.WriteErrLine(Resources.AlmRunnerErrorAuthorization);
+ }
+ }
+ else
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerServerUnreachable, qcServerUrl));
+ }
+
+ return false;
+ }
+ }
+
+ ///
+ /// Returns error message for incorrect installation of Alm QC.
+ ///
+ ///
+ private string GetAlmNotInstalledError()
+ {
+ return "Could not create scheduler, please verify ALM client installation on run machine by downloading and in installing the add-in form: " + GetQcCommonInstallationUrl(MQcServer);
+ }
+
+
+ ///
+ /// summarizes test steps after test has run
+ ///
+ ///
+ /// a string containing descriptions of step states and messages
+ private string GetTestStepsDescFromQc(ITSTest test)
+ {
+ StringBuilder sb = new StringBuilder();
+ try
+ {
+ //get runs for the test
+ RunFactory runFactory = test.RunFactory;
+ List runs = runFactory.NewList(string.Empty);
+ if (runs.Count == 0)
+ return string.Empty;
+
+ //get steps from run
+ StepFactory stepFact = runs[runs.Count].StepFactory;
+ List steps = stepFact.NewList(string.Empty);
+ if (steps.Count == 0)
+ return string.Empty;
+
+ //go over steps and format a string
+ foreach (IStep step in steps)
+ {
+ sb.Append("Step: " + step.Name);
+
+ if (!string.IsNullOrWhiteSpace(step.Status))
+ sb.Append(", Status: " + step.Status);
+
+ string desc = step["ST_DESCRIPTION"] as string;
+
+ if (string.IsNullOrEmpty(desc)) continue;
+
+ desc = "\n\t" + desc.Trim().Replace("\n", "\t").Replace("\r", string.Empty);
+ if (!string.IsNullOrWhiteSpace(desc))
+ sb.AppendLine(desc);
+ }
+ }
+ catch (Exception ex)
+ {
+ sb.AppendLine("Exception while reading step data: " + ex.Message);
+ }
+ return sb.ToString().TrimEnd();
+ }
+
+
+ //------------------------------- Retrieve test sets, test lists and filter tests --------------------------
+ ///
+ /// Get a QC folder
+ ///
+ ///
+ /// the folder object
+ private ITestSetFolder GetFolder(string testSet)
+ {
+ ITestSetTreeManager tsTreeManager;
+ if (TdConnection != null)
+ {
+ tsTreeManager = (ITestSetTreeManager)TdConnection.TestSetTreeManager;
+ }
+ else
+ {
+ tsTreeManager = (ITestSetTreeManager)TdConnectionOld.TestSetTreeManager;
+ }
+
+
+ ITestSetFolder tsFolder = null;
+ try
+ {
+ tsFolder = (ITestSetFolder)tsTreeManager.get_NodeByPath(testSet);
+ }
+ catch (Exception ex)
+ {
+ // if we are here, then most likely the current testSet is not a folder, so it's not necessary to print the error in release mode
+ Debug.WriteLine("Unable to retrieve test set folder: " + ex.Message);
+ }
+
+ return tsFolder;
+ }
+
+ ///
+ /// Finds all folders in the TestSet list, scans their tree and adds all sets under the given folders.
+ /// Updates the test sets by expanding the folders, and removing them, so only test sets remain in the collection.
+ ///
+ private void FindAllTestSetsUnderFolders()
+ {
+ List extraSetsList = new List();
+ List removeSetsList = new List();
+
+ //go over all the test sets / testSetFolders and check which is which
+ foreach (string testSetOrFolder in TestSets)
+ {
+ //try getting the folder
+ ITestSetFolder tsFolder = GetFolder("Root\\" + testSetOrFolder.TrimEnd(_backSlash));
+
+ //if it exists it's a folder and should be traversed to find all sets
+ if (tsFolder != null)
+ {
+ removeSetsList.Add(testSetOrFolder);
+
+ List setList = GetAllTestSetsFromDirTree(tsFolder);
+ extraSetsList.AddRange(setList);
+ }
+
+ }
+
+ TestSets.RemoveAll((a) => removeSetsList.Contains(a));
+ TestSets.AddRange(extraSetsList);
+ }
+
+ ///
+ /// Recursively find all test sets in the QC directory tree, starting from a given folder
+ ///
+ ///
+ /// the list of test sets
+ private List GetAllTestSetsFromDirTree(ITestSetFolder tsFolder)
+ {
+ List retVal = new List();
+ List children = tsFolder.FindChildren(string.Empty);
+ List testSets = tsFolder.FindTestSets(string.Empty);
+
+ if (testSets != null)
+ {
+ foreach (ITestSet childSet in testSets)
+ {
+ string tsPath = childSet.TestSetFolder.Path;
+ tsPath = tsPath.Substring(5).Trim(_backSlash);
+ string tsFullPath = string.Format(@"{0}\{1}", tsPath, childSet.Name);
+ retVal.Add(tsFullPath.TrimEnd());
+ }
+ }
+
+ if (children != null)
+ {
+ foreach (ITestSetFolder childFolder in children)
+ {
+ GetAllTestSetsFromDirTree(childFolder);
+ }
+ }
+ return retVal;
+ }
+
+ ///
+ /// Returns the test scheduled to run
+ ///
+ ///
+ ///
+ ///
+ /// the target test set
+ public ITestSet GetTargetTestSet(List testSetList, string testSuiteName, ITestSetFolder tsFolder)
+ {
+ ITestSet targetTestSet = null;
+
+ if (testSetList != null)
+ {
+ foreach (ITestSet testSet in testSetList)
+ {
+ string tempName = testSet.Name;
+ var testSetFolder = testSet.TestSetFolder as ITestSetFolder;
+ try
+ {
+ if (tempName.Equals(testSuiteName, StringComparison.OrdinalIgnoreCase) && testSetFolder.NodeID == tsFolder.NodeID)
+ {
+ targetTestSet = testSet;
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ if (targetTestSet != null) { return targetTestSet; }
+
+ return null;
+ }
+
+
+ ///
+ /// Returns the list of tests in the set
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// list of tests in set
+ public List GetTestListFromTestSet(TestStorageType testStorageType, ref ITestSetFolder tsFolder, string tsName, ref string testSuiteName, string tsPath, ref bool isTestPath, ref string testName)
+ {
+ if (testSuiteName == null) throw new ArgumentNullException("Missing test suite name");
+ ITestSetTreeManager tsTreeManager;
+ if (TdConnection != null)
+ {
+ _tdConnection.KeepConnection = true;
+ tsTreeManager = (ITestSetTreeManager)_tdConnection.TestSetTreeManager;
+ }
+ else
+ {
+ _tdConnectionOld.KeepConnection = true;
+ tsTreeManager = (ITestSetTreeManager)_tdConnectionOld.TestSetTreeManager;
+ }
+
+ try
+ {
+ //check test storage type
+ if (testStorageType.Equals(TestStorageType.AlmLabManagement))
+ {
+ tsFolder = (ITestSetFolder)tsTreeManager.NodeByPath["Root"];
+ GetTestSetById(tsFolder, Convert.ToInt32(tsName), ref testSuiteName);
+ }
+ else
+ {
+ tsFolder = (ITestSetFolder)tsTreeManager.get_NodeByPath(tsPath);
+ }
+
+ isTestPath = false;
+ }
+ catch (COMException ex)
+ {
+ //not found
+ tsFolder = null;
+ ConsoleWriter.WriteLine(ex.Message + " Trying to find specific test(s) with the given name(s) on the defined path, optionally applying the set filters");
+ }
+
+ // test set not found, try to find specific test by path
+
+ if (tsFolder == null)
+ {
+ // if test set path was not found, the path may points to specific test
+ // remove the test name and try find test set with parent path
+ try
+ {
+ int pos = tsPath.LastIndexOf("\\", StringComparison.Ordinal) + 1;
+ testName = testSuiteName;
+ testSuiteName = tsPath.Substring(pos, tsPath.Length - pos);
+ tsPath = tsPath.Substring(0, pos - 1);
+ tsFolder = (ITestSetFolder)tsTreeManager.get_NodeByPath(tsPath);
+ isTestPath = true;
+ }
+ catch (COMException ex)
+ {
+ tsFolder = null;
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+ }
+
+ if (tsFolder != null)
+ {
+ List testList = tsFolder.FindTestSets(testSuiteName);
+
+ if (testList == null)
+ {
+ // this means, there was no test sets with the specified name, we treat it as a single test, as if a user specified it
+ return null;
+ }
+
+ return testList;
+ }
+
+ //node wasn't found, folder = null
+
+ return null;
+ }
+
+ ///
+ /// Check if some test is contained or not in a tests list
+ ///
+ ///
+ ///
+ ///
+ public bool ListContainsTest(List testList, ITSTest test)
+ {
+ for (var index = testList.Count - 1; index >= 0; index--)
+ {
+ if (testList[index].TestName.Equals(test.TestName))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Filter a list of tests by different by name and/or status
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// the filtered list of tests
+ public IList FilterTests(ITestSet targetTestSet, bool isTestPath, string testName, bool isFilterSelected, List filterByStatuses, string filterByName, ref bool testExisted)
+ {
+ TSTestFactory tsTestFactory = targetTestSet.TSTestFactory;
+ ITDFilter2 tdFilter = tsTestFactory.Filter;
+
+ // DEF-673012 - causes problems when a non-existing and an existing specific test is given by the user, the list appears empty
+ // tdFilter["TC_CYCLE_ID"] = targetTestSet.ID.ToString();
+ // with commented out TC_CYCLE_ID, we get the initial testList by applying an empty filter
+ IList testList = tsTestFactory.NewList(tdFilter.Text);
+
+ List testsFilteredByStatus = new List();
+
+ if (isFilterSelected.Equals(true) && (!string.IsNullOrEmpty(filterByName) || filterByStatuses.Count > 0))
+ {
+ //filter by status
+ foreach (string status in filterByStatuses)
+ {
+ tdFilter["TC_STATUS"] = status;
+ IList statusList1 = tsTestFactory.NewList(tdFilter.Text);
+ for (int index = statusList1.Count; index > 0; index--)
+ {
+ testsFilteredByStatus.Add(statusList1[index]);
+ }
+ }
+
+ //filter by name
+ for (int index = testList.Count; index > 0; index--)
+ {
+ string tListIndexName = testList[index].Name;
+ string tListIndexTestName = testList[index].TestName;
+
+ if (!string.IsNullOrEmpty(filterByName))
+ {
+ if (filterByStatuses.Count == 0)
+ {
+ //only by name
+ if (!tListIndexName.ToLower().Contains(filterByName.ToLower()) &&
+ !tListIndexTestName.ToLower().Contains(filterByName.ToLower()))
+ {
+ testList.Remove(index);
+
+ if (isTestPath && testName.Equals(tListIndexTestName))
+ {
+ testExisted = true;
+ }
+ }
+ }
+ else //by name and statuses
+ {
+ if (!tListIndexName.ToLower().Contains(filterByName.ToLower()) &&
+ !tListIndexTestName.ToLower().Contains(filterByName.ToLower()) &&
+ !ListContainsTest(testsFilteredByStatus, testList[index]))
+ {
+ testList.Remove(index);
+
+ if (isTestPath && testName.Equals(tListIndexTestName))
+ {
+ testExisted = true;
+ }
+ }
+ }
+ }
+ else
+ { //only by statuses
+ if (!ListContainsTest(testsFilteredByStatus, testList[index]))
+ {
+ testList.Remove(index);
+
+ if (isTestPath && testName.Equals(tListIndexTestName))
+ {
+ testExisted = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (isTestPath)
+ {
+ // index starts from 1 !!!
+ int tListCount = 0;
+ tListCount = testList.Count;
+
+ // must loop from end to begin
+ for (var index = tListCount; index > 0; index--)
+ {
+ string tListIndexName = testList[index].Name;
+ string tListIndexTestName = testList[index].TestName;
+
+ if (!string.IsNullOrEmpty(tListIndexName) && !string.IsNullOrEmpty(testName) && !testName.Equals(tListIndexTestName))
+ {
+ testList.Remove(index);
+ }
+ else if (testName.Equals(tListIndexTestName))
+ {
+ testExisted = true;
+ }
+ }
+ }
+
+ return testList;
+ }
+
+ ///
+ /// Search test set in QC by the given ID
+ ///
+ ///
+ ///
+ ///
+ /// the test set identified by the given id or empty string in case the test set was not found
+ private string GetTestSetById(ITestSetFolder tsFolder, int testSetId, ref string testSuiteName)
+ {
+ List children = tsFolder.FindChildren(string.Empty);
+ List testSets = tsFolder.FindTestSets(string.Empty);
+
+ if (testSets != null)
+ {
+ foreach (ITestSet childSet in testSets)
+ {
+ if (childSet.ID != testSetId) continue;
+ string tsPath = childSet.TestSetFolder.Path;
+ tsPath = tsPath.Substring(5).Trim(_backSlash);
+ string tsFullPath = tsPath + "\\" + childSet.Name;
+ testSuiteName = childSet.Name;
+ return tsFullPath.TrimEnd();
+ }
+ }
+
+ if (children != null)
+ {
+ foreach (ITestSetFolder childFolder in children)
+ {
+ GetAllTestSetsFromDirTree(childFolder);
+ }
+ }
+ return string.Empty;
+ }
+
+ ///
+ /// Gets test index given it's name
+ ///
+ ///
+ ///
+ /// the test index
+ public int GetIndexOfTestIdentifiedByName(string strName, TestSuiteRunResults results)
+ {
+ return results.TestRuns.FindIndex(res => res.TestName == strName);
+ }
+
+ //------------------------------- Identify and set test parameters --------------------------
+ ///
+ /// Collect the inline parameters for the tests.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void CollectInlineTestParams(IList tList, string strParams, string initialFullTsPath, List @params)
+ {
+ int idx = 1;
+
+ foreach (ITSTest3 test in tList)
+ {
+ try
+ {
+ if (test.Type.Equals(API_TEST) && !string.IsNullOrEmpty(strParams)) //API test
+ {
+ CollectInlineApiTestParams(test, strParams, @params, idx);
+ }
+ else if (test.Type.Equals(GUI_TEST) && !string.IsNullOrEmpty(strParams)) //GUI test
+ {
+ CollectInlineGuiTestParams(test, strParams, @params, idx);
+ }
+ }
+ catch (ArgumentException)
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerErrorParameterFormat, initialFullTsPath));
+ }
+
+ ++idx;
+ }
+ }
+
+ ///
+ /// Collect the parameters for the tests from the props (CI args).
+ ///
+ ///
+ ///
+ private void CollectPropsTestParams(List @params, int testIdx)
+ {
+ List relevant = _params.FindAll(elem => elem.TestIdx == testIdx);
+ @params.AddRange(relevant);
+ }
+
+ ///
+ /// Schedule test instances to run.
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void ScheduleTest(TestSuiteRunResults runDesc, ITSScheduler scheduler, ITSTest3 test, int idx)
+ {
+ var runOnHost = RunHost;
+ if (RunMode == QcRunMode.RUN_PLANNED_HOST)
+ {
+ runOnHost = test.HostName; //test["TC_HOST_NAME"]; //runHost;
+ }
+
+ //if host isn't taken from QC (PLANNED) and not from the test definition (REMOTE), take it from LOCAL (machineName)
+ var hostName = runOnHost;
+ if (RunMode == QcRunMode.RUN_LOCAL)
+ {
+ hostName = Environment.MachineName;
+ }
+
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerDisplayTestRunOnHost, idx, test.Name, hostName));
+
+ scheduler.RunOnHost[test.ID] = runOnHost;
+
+ var testResults = new TestRunResults { TestName = test.Name };
+
+ runDesc.TestRuns.Add(testResults);
+ }
+
+ ///
+ /// Set test parameters for an API test
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void CollectInlineApiTestParams(ITSTest3 test, string strParams, IList testParams, int idx)
+ {
+ if (!string.IsNullOrEmpty(strParams))
+ {
+ string[] @params = strParams.Split(COMMA, StringSplitOptions.RemoveEmptyEntries);
+ IList paramNames, paramValues;
+
+ if (!Helper.ValidateInlineParams(@params, out paramNames, out paramValues))
+ {
+ throw new ArgumentException();
+ }
+
+ for (int i = 0; i < @params.Length; ++i)
+ {
+ testParams.Add(new TestParameter(idx, paramNames[i], paramValues[i], null));
+ }
+ }
+ }
+
+ ///
+ /// Set test parameters for a GUI test
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void CollectInlineGuiTestParams(ITSTest3 test, string strParams, IList testParams, int idx)
+ {
+ var xmlParams = new StringBuilder();
+
+ if (!string.IsNullOrWhiteSpace(strParams))
+ {
+ string[] @params = strParams.Split(COMMA, StringSplitOptions.RemoveEmptyEntries);
+ IList paramNames, paramValues;
+
+ if (!Helper.ValidateInlineParams(@params, out paramNames, out paramValues))
+ {
+ throw new ArgumentException();
+ }
+
+ for (int i = 0; i < @params.Length; ++i)
+ {
+ testParams.Add(new TestParameter(idx, paramNames[i], paramValues[i], null));
+ }
+ }
+ }
+
+ ///
+ /// gets the type for a QC test
+ ///
+ ///
+ ///
+ private TestType GetTestType(dynamic currentTest)
+ {
+ string testType = currentTest.Test.Type;
+ return testType.ToUpper() == API_TEST ? TestType.ST : TestType.QTP;
+ }
+
+ // ------------------------- Run tests and update test results --------------------------------
+
+ ///
+ /// runs the tests given to the object.
+ ///
+ ///
+ public override TestSuiteRunResults Run()
+ {
+ if (!Connected)
+ return null;
+
+ TestSuiteRunResults activeRunDescription = new TestSuiteRunResults();
+
+ //find all the testSets under given folders
+ try
+ {
+ FindAllTestSetsUnderFolders();
+ }
+ catch (Exception ex)
+ {
+
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerErrorBadQcInstallation, ex.Message, ex.StackTrace));
+ return null;
+ }
+
+ // we start the timer, it is important for the timeout
+ Stopwatch swForTimeout = Stopwatch.StartNew();
+
+ int idx = 1;
+ //run all the TestSets
+ foreach (string testSetItem in TestSets)
+ {
+ string testSet = testSetItem.TrimEnd(_backSlash);
+ string tsName = testSet;
+ int pos = testSetItem.LastIndexOf('\\');
+
+ string testSetDir = string.Empty;
+ string inlineTestParams = string.Empty;
+
+ if (pos != -1)
+ {
+ // check for inline params
+ testSetDir = testSet.Substring(0, pos).Trim(_backSlash);
+ if (testSetItem.IndexOf(" ", StringComparison.Ordinal) != -1 && testSet.Count(x => x == ' ') >= 1)
+ {
+ if (!testSet.Contains(':'))//test has no parameters attached
+ {
+ tsName = testSet.Substring(pos, testSet.Length - pos).Trim(_backSlash);
+ }
+ else
+ {
+ int quotationMarkIndex = testSet.IndexOf("\"", StringComparison.Ordinal);
+ if (quotationMarkIndex > pos)
+ {
+ tsName = testSet.Substring(pos, quotationMarkIndex - pos).Trim(_backSlash).TrimEnd(' ');
+ inlineTestParams = testSet.Substring(quotationMarkIndex, testSet.Length - quotationMarkIndex).Trim(_backSlash);
+ }
+ }
+ }
+ else
+ {
+ tsName = testSet.Substring(pos, testSet.Length - pos).Trim(_backSlash);
+ }
+ }
+
+ TestSuiteRunResults runResults = RunTestSet(testSetDir, tsName, inlineTestParams, swForTimeout, idx);
+ if (runResults != null)
+ activeRunDescription.AppendResults(runResults);
+
+ // if the run has cancelled, because of timeout, we should terminate the build
+ if (_isRunCancelled) break;
+
+ ++idx;
+ }
+
+ return activeRunDescription;
+ }
+
+ ///
+ /// Runs a test set with given parameters (and a valid connection to the QC server)
+ ///
+ /// testSet folder name
+ /// testSet name
+ ///
+ ///
+ ///
+ ///
+ public TestSuiteRunResults RunTestSet(string tsFolderName, string tsName, string inlineTestParams, Stopwatch swForTimeout, int testIdx)
+ {
+ string testSuiteName = tsName.TrimEnd();
+ ITestSetFolder tsFolder = null;
+ string tsPath = string.Format(@"Root\{0}", tsFolderName);
+ string initialFullTsPath = string.Format(@"{0}\{1}", tsPath, tsName);
+ bool isTestPath = false;
+ string currentTestSetInstances = string.Empty, testName = string.Empty;
+ TestSuiteRunResults runDesc = new TestSuiteRunResults();
+ TestRunResults activeTestDesc = new TestRunResults();
+ List testSetList = null;
+
+ ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator);
+
+ //get list of test sets
+ try
+ {
+ testSetList = GetTestListFromTestSet(Storage, ref tsFolder, tsName, ref testSuiteName, tsPath, ref isTestPath, ref testName);
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteErrLine("Unable to retrieve the list of tests");
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerCantFindTest, initialFullTsPath));
+ ConsoleWriter.WriteLine(ex.Message);
+ }
+
+ if (testSetList == null)
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerCantFindTest, initialFullTsPath));
+ UpdateTestResultsIfTestErrorAppearedBeforeRun(ref runDesc, ref activeTestDesc, initialFullTsPath, string.Format(Resources.AlmRunnerCantFindTest, activeTestDesc.TestPath));
+
+ return runDesc;
+ }
+
+ //get target test set
+ ITestSet targetTestSet = null;
+ try
+ {
+ targetTestSet = GetTargetTestSet(testSetList, testSuiteName, tsFolder);
+ }
+ catch (Exception)
+ {
+ ConsoleWriter.WriteErrLine("Empty target test set list");
+ }
+
+ if (targetTestSet == null)
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerCantFindTest, initialFullTsPath));
+ UpdateTestResultsIfTestErrorAppearedBeforeRun(ref runDesc, ref activeTestDesc, initialFullTsPath, string.Format(Resources.AlmRunnerCantFindTest, activeTestDesc.TestPath));
+
+ return runDesc;
+ }
+
+ ConsoleWriter.WriteLine(Resources.AlmRunnerStartingExecution);
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerDisplayTest, testSuiteName, targetTestSet.ID));
+
+ //start execution
+ ITSScheduler scheduler = null;
+ try
+ {
+ //need to run this to install everything needed http://AlmServer:8080/qcbin/start_a.jsp?common=true
+ //start the scheduler
+ scheduler = targetTestSet.StartExecution(string.Empty);
+ currentTestSetInstances = GetTestInstancesString(targetTestSet);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+
+ if (scheduler == null)
+ {
+ ConsoleWriter.WriteErrLine(GetAlmNotInstalledError());
+
+ //proceeding with program execution is tasteless, since nothing will run without a properly installed QC.
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ //filter tests
+ bool testExisted = false;
+ var filteredTestList = FilterTests(targetTestSet, isTestPath, testName, IsFilterSelected, FilterByStatuses, FilterByName, ref testExisted);
+
+ //set run host
+ try
+ {
+ //set up for the run depending on where the test instances are to execute
+ switch (RunMode)
+ {
+ case QcRunMode.RUN_LOCAL:
+ // run all tests on the local machine
+ scheduler.RunAllLocally = true;
+ break;
+ case QcRunMode.RUN_REMOTE:
+ // run tests on a specified remote machine
+ scheduler.TdHostName = RunHost;
+ break;
+ // RunAllLocally must not be set for remote invocation of tests. As such, do not do this: Scheduler.RunAllLocally = False
+ case QcRunMode.RUN_PLANNED_HOST:
+ // run on the hosts as planned in the test set
+ scheduler.RunAllLocally = false;
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerProblemWithHost, ex.Message));
+ }
+
+ //set test parameters
+ if (filteredTestList.Count > 0)
+ {
+ // placeholder list for test parameters
+ List @params = new List();
+
+ CollectInlineTestParams(filteredTestList, inlineTestParams, initialFullTsPath, @params);
+ CollectPropsTestParams(@params, testIdx);
+
+ try
+ {
+ CheckForDuplicateParams4Test(@params);
+ }
+ catch (ArgumentException)
+ {
+ ConsoleWriter.WriteErrLine(Resources.AlmDuplicateParameter);
+ throw;
+ }
+
+ // we prepare individual lists for the tests
+ // while we check for duplicates
+ // and then we set the test parameters
+
+ int index = 1;
+ foreach (ITSTest3 test in filteredTestList)
+ {
+ SetParams(test, @params);
+
+ ScheduleTest(runDesc, scheduler, test, index);
+ ++index;
+ }
+ }
+
+ // isTestPath is only true, if a specific test was given by the user
+ // if, the filteredTestList is empty, because of the filtering, we should not set the job status to failed
+ // only if, the specific given test was not found
+ if (filteredTestList.Count == 0 && isTestPath && !testExisted)
+ {
+ //this will make sure run will fail at the end. (since there was an error)
+ ConsoleWriter.WriteErrLine(string.Format(Resources.AlmRunnerCantFindTest, initialFullTsPath));
+
+ UpdateTestResultsIfTestErrorAppearedBeforeRun(ref runDesc, ref activeTestDesc, initialFullTsPath, string.Format(Resources.AlmRunnerCantFindTest, activeTestDesc.TestPath));
+ return runDesc;
+ }
+ else if (filteredTestList.Count == 0)
+ {
+ ConsoleWriter.WriteLine(Resources.AlmTestSetsRunnerNoTestAfterApplyingFilters);
+ return null;
+ }
+
+ //start test runner
+ Stopwatch sw = Stopwatch.StartNew();
+
+ try
+ {
+ //tests are actually run
+ scheduler.Run(filteredTestList);
+ }
+ catch (Exception ex)
+ {
+ ConsoleWriter.WriteErrLine(Resources.AlmRunnerRunError + ex.Message);
+ return null;
+ }
+
+ ConsoleWriter.WriteLine(Resources.AlmRunnerSchedStarted + DateTime.Now.ToString(Launcher.DateFormat));
+ ConsoleWriter.WriteLine(Resources.SingleSeperator);
+
+ IExecutionStatus executionStatus = scheduler.ExecutionStatus;
+
+ ITSTest prevTest = null;
+ ITSTest currentTest = null;
+ string abortFilename = string.Format(@"{0}\stop{1}.txt", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Launcher.UniqueTimeStamp);
+
+ if (Storage == TestStorageType.AlmLabManagement)
+ {
+ Timeout *= 60;
+ }
+ //update run result description
+ UpdateTestsResultsDescription(ref activeTestDesc, runDesc, scheduler, targetTestSet, currentTestSetInstances, Timeout, executionStatus, swForTimeout, ref prevTest, ref currentTest, abortFilename);
+
+ //done with all tests, stop collecting output in the testRun object.
+ ConsoleWriter.ActiveTestRun = null;
+
+ string testPath;
+ if (isTestPath)
+ {
+ testPath = string.Format(@"Root\{0}\", tsFolderName);
+ }
+ else
+ {
+ testPath = string.Format(@"Root\{0}\{1}\", tsFolderName, testSuiteName);
+ }
+
+ // if the run has been cancelled and a timeout is set, which has elapsed, skip this part, we are going to do it later with some corrections
+ if (!_isRunCancelled && (Timeout == -1 || swForTimeout.Elapsed.TotalSeconds < Timeout))
+ SetTestResults(ref currentTest, executionStatus, targetTestSet, activeTestDesc, runDesc, testPath, abortFilename);
+
+ // update the total runtime
+ runDesc.TotalRunTime = sw.Elapsed;
+
+ // test has executed in time
+ if (Timeout == -1 || swForTimeout.Elapsed.TotalSeconds < Timeout)
+ {
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerTestsetDone, testSuiteName, DateTime.Now.ToString(Launcher.DateFormat)));
+ }
+ else
+ {
+ ConsoleWriter.WriteLine(Resources.SmallDoubleSeparator);
+ ConsoleWriter.WriteLine(Resources.GeneralTimedOut);
+ ConsoleWriter.WriteLine(">>> Updating currently scheduled tests' state");
+ ConsoleWriter.WriteLine(">>> Setting all non-finished scheduled tests' state to 'Error'");
+ ConsoleWriter.WriteLine(Resources.SmallDoubleSeparator);
+
+ // we refresh the current test set instances' status
+ executionStatus.RefreshExecStatusInfo(currentTestSetInstances, true);
+
+ // stop all currently scheduled tests
+ scheduler.Stop(currentTestSetInstances);
+
+ // we should re-check every current test instances' status to perfectly match ALM statuses
+ UpdateTestResultsAfterAbort(executionStatus, targetTestSet, runDesc, testPath);
+
+ // scheduler process may not be terminated - this process is not terminated by the aborter
+ TerminateSchedulerIfNecessary();
+
+ Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted;
+
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerTestsetAborted, testSuiteName, DateTime.Now.ToString(Launcher.DateFormat)));
+ }
+
+ return runDesc;
+ }
+
+ ///
+ /// Sets the Test's parameters.
+ ///
+ ///
+ ///
+ private static void SetParams(ITSTest3 test, List @params)
+ {
+ switch (test.Type)
+ {
+ case API_TEST:
+ SetAPITestParams(test, @params);
+ break;
+ case GUI_TEST:
+ SetGUITestParams(test, @params);
+ break;
+ }
+ }
+
+ ///
+ /// Sets the GUI Test's parameters.
+ ///
+ ///
+ ///
+ private static void SetGUITestParams(ITSTest3 test, List @params)
+ {
+ var xmlParams = new StringBuilder();
+
+ if (@params.Count > 0)
+ {
+ xmlParams.Append(XML_PARAMS_START_TAG);
+ foreach (var param in @params)
+ {
+ xmlParams.AppendFormat(XML_PARAM_NAME_VALUE_TYPE, SecurityElement.Escape(param.ParamName), SecurityElement.Escape(param.ParamVal), param.ParamType);
+ }
+ xmlParams.Append(XML_PARAMS_END_TAG);
+ }
+
+ if (xmlParams.Length <= 0) return;
+
+ @params.ForEach(elem =>
+ {
+ if (elem.ParamType == PASSWORD)
+ ConsoleWriter.WriteLine(string.Format(Resources.GeneralParameterUsageMask, elem.ParamName));
+ else
+ ConsoleWriter.WriteLine(string.Format(Resources.GeneralParameterUsage, elem.ParamName, elem.ParamVal));
+ }
+ );
+
+ test["TC_EPARAMS"] = xmlParams.ToString();
+ test.Post();
+ }
+
+ ///
+ /// Sets the API Test's parameters.
+ ///
+ ///
+ ///
+ private static void SetAPITestParams(ITSTest3 test, List @params)
+ {
+ ISupportParameterValues paramTestValues = (ISupportParameterValues)test;
+ ParameterValueFactory paramValFactory = paramTestValues.ParameterValueFactory;
+ List listOfParams = paramValFactory.NewList(string.Empty);
+
+ foreach (ParameterValue param in listOfParams)
+ {
+ // we search for the paramter by name in the relevant list, if found we set it, otherwise skip this parameter from the factory
+ string name = param.Name;
+ TestParameter tmpParam = @params.Find(elem => elem.ParamName.Equals(name));
+
+ if (tmpParam == null) continue;
+
+ param.ActualValue = tmpParam.ParamVal;
+ param.Post();
+
+ ConsoleWriter.WriteLine(string.Format(Resources.GeneralParameterUsage, tmpParam.ParamName, tmpParam.ParamVal));
+ }
+ }
+
+ ///
+ /// Checks if the parameter list contains duplicates, throws ArgumentException because uses a Dictionary internally.
+ ///
+ ///
+ private static void CheckForDuplicateParams4Test(List @params)
+ {
+ // throws argumentexception if duplicate found
+ Dictionary tmpParams = new Dictionary();
+ @params.ForEach(param => tmpParams.Add(param.ParamName, param.ParamVal));
+ }
+
+ ///
+ /// Terminates wexectrl process which belongs to the current HpToolsLauncher process
+ ///
+ private void TerminateSchedulerIfNecessary()
+ {
+ Process exeCtrl = Process.GetProcessesByName("wexectrl").Where(p => p.SessionId == Process.GetCurrentProcess().SessionId).FirstOrDefault();
+
+ if (exeCtrl != null)
+ {
+ exeCtrl.Kill();
+ }
+ }
+
+ ///
+ /// Iterates over the currently scheduled tests and updates their status according to their run status, if the test is already in a finished state, it won't update it,
+ /// if it is in a non-finished state it sets to 'Error'
+ ///
+ ///
+ ///
+ ///
+ private void UpdateTestResultsAfterAbort(IExecutionStatus executionStatus, ITestSet targetTestSet, TestSuiteRunResults runDesc, string testPath)
+ {
+ ITSTest currentTest;
+ TestRunResults testDesc;
+ TestState prevState;
+
+ for (var k = 1; k <= executionStatus.Count; ++k)
+ {
+ TestExecStatus testExecStatusObj = executionStatus[k];
+ currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
+
+ if (currentTest == null)
+ {
+ continue;
+ }
+
+ testDesc = UpdateTestStatus(runDesc, targetTestSet, testExecStatusObj, true);
+
+ prevState = testDesc.TestState;
+
+ // if the test hasn't finished running and the timeout has expired, we should set their state to 'Error'
+ if (testDesc.TestState != TestState.Passed && testDesc.TestState != TestState.Error
+ && testDesc.TestState != TestState.Failed && testDesc.TestState != TestState.Warning)
+ {
+ testDesc.TestState = TestState.Error;
+ testDesc.ErrorDesc = Resources.GeneralTimeoutExpired;
+ }
+
+ // non-executed tests' group can be null, we should update it as well, otherwise in the report it won't be grouped accordingly
+ if (testDesc.TestGroup == null)
+ {
+ var currentFolder = targetTestSet.TestSetFolder as ITestSetFolder;
+ string folderName = "";
+
+ if (currentFolder != null)
+ {
+ folderName = currentFolder.Name.Replace(".", "_");
+ }
+
+ testDesc.TestGroup = string.Format(@"{0}\{1}", folderName, targetTestSet.Name).Replace(".", "_");
+ }
+
+ testDesc.TestPath = testPath + currentTest.TestName;
+
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerUpdateStateAfterAbort, testDesc.TestPath, prevState.ToString(), testDesc.TestState));
+
+ UpdateCounters(testDesc, runDesc);
+ }
+ }
+
+ ///
+ /// Updates the runDesc run results by describing the non-existing test error as a testDesc
+ ///
+ /// run results to be updated
+ /// the non-existing test's description
+ ///
+ ///
+ private void UpdateTestResultsIfTestErrorAppearedBeforeRun(ref TestSuiteRunResults runDesc, ref TestRunResults activeTestDesc, string tsPath, string errMessage)
+ {
+ runDesc.NumTests++;
+ runDesc.TotalRunTime = System.TimeSpan.Zero;
+ runDesc.NumErrors++;
+
+ activeTestDesc.TestState = TestState.Error;
+ activeTestDesc.TestPath = tsPath;
+ int pos = tsPath.LastIndexOf("\\", StringComparison.Ordinal) + 1;
+ activeTestDesc.TestName = tsPath.Substring(pos);
+ activeTestDesc.ErrorDesc = errMessage;
+ activeTestDesc.FatalErrors = 1;
+ activeTestDesc.Runtime = System.TimeSpan.Zero;
+
+ if (activeTestDesc.TestGroup == null)
+ {
+ activeTestDesc.TestGroup = tsPath;
+ }
+
+ runDesc.TestRuns.Add(activeTestDesc);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void SetTestResults(ref ITSTest currentTest, IExecutionStatus executionStatus, ITestSet targetTestSet, TestRunResults activeTestDesc, TestSuiteRunResults runDesc, string testPath, string abortFilename)
+ {
+ if (currentTest == null) throw new ArgumentNullException("Current test set is null.");
+
+ if (activeTestDesc == null) throw new ArgumentNullException("The test run results are empty.");
+
+ // write the status for each test
+ for (var k = 1; k <= executionStatus.Count; ++k)
+ {
+ if (File.Exists(abortFilename))
+ {
+ break;
+ }
+ TestExecStatus testExecStatusObj = executionStatus[k];
+ currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
+
+ if (currentTest == null)
+ {
+ ConsoleWriter.WriteLine(string.Format("currentTest is null for test.{0} after whole execution", k));
+ continue;
+ }
+
+ activeTestDesc = UpdateTestStatus(runDesc, targetTestSet, testExecStatusObj, false);
+ UpdateCounters(activeTestDesc, runDesc);
+
+ activeTestDesc.TestPath = testPath + currentTest.TestName;
+ }
+ }
+
+ ///
+ /// updates the test status in our list of tests
+ ///
+ ///
+ ///
+ ///
+ ///
+ private TestRunResults UpdateTestStatus(TestSuiteRunResults runResults, ITestSet targetTestSet, TestExecStatus testExecStatusObj, bool onlyUpdateState)
+ {
+ TestRunResults qTest = null;
+ ITSTest currentTest = null;
+ try
+ {
+ //find the test for the given status object
+ currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
+
+ //find the test in our list
+ var testIndex = GetIndexOfTestIdentifiedByName(currentTest.Name, runResults);
+
+ qTest = runResults.TestRuns[testIndex];
+ if (qTest.TestType == TestType.Unknown)
+ {
+ qTest.TestType = GetTestType(currentTest);
+ }
+
+ //update the state
+ qTest.PrevTestState = qTest.TestState;
+ qTest.TestState = GetTsStateFromQcState(testExecStatusObj);
+
+ if (!onlyUpdateState)
+ {
+ try
+ {
+ //duration and status are updated according to the run
+ qTest.Runtime = TimeSpan.FromSeconds(currentTest.LastRun.Field("RN_DURATION"));
+ }
+ catch
+ {
+ //a problem getting duration, maybe the test isn't done yet - don't stop the flow..
+ }
+
+ switch (qTest.TestState)
+ {
+ case TestState.Failed:
+ qTest.FailureDesc = GenerateFailedLog(currentTest.LastRun);
+
+ if (string.IsNullOrWhiteSpace(qTest.FailureDesc))
+ qTest.FailureDesc = string.Format("{0} : {1}", testExecStatusObj.Status, testExecStatusObj.Message);
+ break;
+ case TestState.Error:
+ qTest.ErrorDesc = string.Format("{0} : {1}", testExecStatusObj.Status, testExecStatusObj.Message);
+ break;
+ case TestState.Warning:
+ qTest.HasWarnings = true;
+ break;
+ case TestState.Waiting:
+ case TestState.Running:
+ case TestState.NoRun:
+ case TestState.Passed:
+ case TestState.Unknown:
+ default:
+ break;
+ }
+
+ var runId = GetTestRunId(currentTest);
+ string linkStr = GetTestRunLink(runId);
+
+ string statusString = GetTsStateFromQcState(testExecStatusObj).ToString();
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerTestStat, currentTest.Name, statusString, testExecStatusObj.Message, linkStr));
+ runResults.TestRuns[testIndex] = qTest;
+ }
+ }
+ catch (Exception ex)
+ {
+ if (currentTest != null)
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerErrorGettingStat, currentTest.Name, ex.Message));
+ }
+
+ return qTest;
+ }
+
+ ///
+ /// Update run results description
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void UpdateTestsResultsDescription(ref TestRunResults activeTestDesc, TestSuiteRunResults runDesc,
+ ITSScheduler scheduler, ITestSet targetTestSet,
+ string currentTestSetInstances, double timeout,
+ IExecutionStatus executionStatus, Stopwatch sw,
+ ref ITSTest prevTest, ref ITSTest currentTest, string abortFilename)
+ {
+ var tsExecutionFinished = false;
+
+ while (!tsExecutionFinished && (timeout == -1 || sw.Elapsed.TotalSeconds < timeout))
+ {
+ executionStatus.RefreshExecStatusInfo(currentTestSetInstances, true);
+ tsExecutionFinished = executionStatus.Finished;
+
+ if (File.Exists(abortFilename))
+ {
+ break;
+ }
+ for (var j = 1; j <= executionStatus.Count; ++j)
+ {
+ try
+ {
+ ITestExecStatus baseTestExecObj = executionStatus[j];
+ TestExecStatus testExecStatusObj = (TestExecStatus)baseTestExecObj;
+
+ if (testExecStatusObj == null)
+ {
+ Console.WriteLine("testExecStatusObj is null");
+ continue;
+ }
+ else
+ {
+ currentTest = targetTestSet.TSTestFactory[testExecStatusObj.TSTestId];
+ }
+ if (currentTest == null)
+ {
+ ConsoleWriter.WriteLine(string.Format("currentTest is null for test.{0} during execution", j));
+ continue;
+ }
+
+ activeTestDesc = UpdateTestStatus(runDesc, targetTestSet, testExecStatusObj, true);
+
+ if (activeTestDesc != null && activeTestDesc.PrevTestState != activeTestDesc.TestState)
+ {
+ TestState testState = activeTestDesc.TestState;
+ if (testState == TestState.Running)
+ {
+ int testIndex = GetIndexOfTestIdentifiedByName(currentTest.Name, runDesc);
+ if (testIndex == -1)
+ {
+ Console.WriteLine("No test index exist for this test");
+ }
+ int prevRunId = GetTestRunId(currentTest);
+ if (prevRunId == -1)
+ {
+ Console.WriteLine("No test runs exist for this test");
+ continue;
+ }
+ runDesc.TestRuns[testIndex].PrevRunId = prevRunId;
+
+ //starting new test
+ prevTest = currentTest;
+ //assign the new test the console writer so it will gather the output
+
+ ConsoleWriter.ActiveTestRun = runDesc.TestRuns[testIndex];
+
+ ConsoleWriter.WriteLineWithTime(string.Format("Running: {0}", currentTest.Name));
+ activeTestDesc.TestName = currentTest.Name;
+ //tell user that the test is running
+ ConsoleWriter.WriteLineWithTime(string.Format("Running test: {0}, Test id: {1}, Test instance id: {2}", activeTestDesc.TestName, testExecStatusObj.TestId, testExecStatusObj.TSTestId));
+
+ //start timing the new test run
+ string folderName = string.Empty;
+
+ ITestSetFolder folder = targetTestSet.TestSetFolder as ITestSetFolder;
+ if (folder != null)
+ folderName = folder.Name.Replace(".", "_");
+
+ //the test group is it's test set. (dots are problematic since jenkins parses them as separators between package and class)
+ activeTestDesc.TestGroup = string.Format(@"{0}\{1}", folderName, targetTestSet.Name).Replace(".", "_");
+ }
+
+ TestState execState = GetTsStateFromQcState(testExecStatusObj);
+
+ if (execState == TestState.Running)
+ {
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerStat, activeTestDesc.TestName, testExecStatusObj.TSTestId, execState));
+ }
+ else if (execState != TestState.Waiting)
+ {
+ ConsoleWriter.WriteLine(string.Format(Resources.AlmRunnerStatWithMessage, activeTestDesc.TestName, testExecStatusObj.TSTestId, execState, testExecStatusObj.Message));
+
+ if (execState != TestState.Unknown)
+ {
+ WriteTestRunSummary(currentTest);
+ }
+ }
+
+ if (File.Exists(abortFilename))
+ {
+ scheduler.Stop(currentTestSetInstances);
+ //stop working
+ Environment.Exit((int)Launcher.ExitCodeEnum.Aborted);
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ catch (InvalidCastException ex)
+ {
+ Console.WriteLine("Conversion failed: " + ex.Message);
+ }
+ }
+
+ //wait 0.2 seconds
+ Thread.Sleep(200);
+
+ //check for abortion
+ if (File.Exists(abortFilename))
+ {
+ _isRunCancelled = true;
+
+ ConsoleWriter.WriteLine(Resources.GeneralStopAborted);
+
+ //stop all test instances in this testSet.
+ scheduler.Stop(currentTestSetInstances);
+
+ ConsoleWriter.WriteLine(Resources.GeneralAbortedByUser);
+
+ //stop working
+ Environment.Exit((int)Launcher.ExitCodeEnum.Aborted);
+ }
+
+ if (sw.Elapsed.TotalSeconds >= timeout && timeout != -1)
+ {
+ // setting the flag ensures that we will recall later, that the currently scheduled tests are aborted because of the timeout
+ _isRunCancelled = true;
+ }
+ }
+ }
+
+ ///
+ /// gets a link string for the test run in Qc
+ ///
+ ///
+ ///
+ private string GetTestRunLink(int runId)
+ {
+ if (CheckIsOldQc())
+ {
+ return string.Empty;
+ }
+
+ var mQcServer = MQcServer.Trim();
+ var prefix = mQcServer.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ? "tds" : "td";
+ mQcServer = Regex.Replace(mQcServer, "^http[s]?://", string.Empty, RegexOptions.IgnoreCase);
+
+ if (!mQcServer.EndsWith("/"))
+ {
+ mQcServer += "/";
+ }
+
+ return string.Format("{0}://{1}.{2}.{3}TestRunsModule-00000000090859589?EntityType=IRun&EntityID={4}", prefix, MQcProject, MQcDomain, mQcServer, runId);
+ }
+
+ ///
+ /// gets the runId for the given test
+ ///
+ /// a test instance
+ /// the run id
+ private static int GetTestRunId(ITSTest currentTest)
+ {
+ int runId = -1;
+
+ if (currentTest == null) return runId;
+ if (currentTest.LastRun != null)
+ {
+ IRun lastRun = currentTest.LastRun as IRun;
+ runId = lastRun.ID;
+ return runId;
+ }
+
+ return runId;
+ }
+
+ ///
+ /// writes a summary of the test run after it's over
+ ///
+ ///
+ private void WriteTestRunSummary(ITSTest prevTest)
+ {
+ if (TdConnection != null)
+ {
+ _tdConnection.KeepConnection = true;
+ }
+ else
+ {
+ _tdConnectionOld.KeepConnection = true;
+ }
+
+ int runId = GetTestRunId(prevTest);
+
+ string stepsString = GetTestStepsDescFromQc(prevTest);
+
+ if (string.IsNullOrWhiteSpace(stepsString) && ConsoleWriter.ActiveTestRun.TestState != TestState.Error)
+ stepsString = GetTestRunLog(prevTest);
+
+ if (!string.IsNullOrWhiteSpace(stepsString))
+ ConsoleWriter.WriteLine(stepsString);
+
+ string linkStr = GetTestRunLink(runId);
+
+ if (linkStr == string.Empty)
+ {
+ Console.WriteLine(Resources.OldVersionOfQC);
+ }
+ else
+ {
+ ConsoleWriter.WriteLine("\n" + string.Format(Resources.AlmRunnerDisplayLink, "\n" + linkStr + "\n"));
+ }
+
+ ConsoleWriter.WriteLineWithTime(Resources.AlmRunnerTestCompleteCaption + " " + prevTest.Name +
+ ", " + Resources.AlmRunnerRunIdCaption + " " + runId
+ + "\n-------------------------------------------------------------------------------------------------------");
+ }
+
+ ///
+ /// Writes a summary of the test run after it's over
+ ///
+ private string GetTestInstancesString(ITestSet set)
+ {
+ var retVal = string.Empty;
+ try
+ {
+ TSTestFactory factory = set.TSTestFactory;
+ IList list = factory.NewList(string.Empty);
+
+ if (list == null)
+ return string.Empty;
+ retVal = string.Join(",", list.Cast().Select(t => t.ID as string));
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ return retVal;
+ }
+
+
+ ///
+ /// Update test run summary
+ ///
+ ///
+ ///
+ private void UpdateCounters(TestRunResults test, TestSuiteRunResults testSuite)
+ {
+ if (!test.TestState.In(TestState.Running, TestState.Waiting, TestState.Unknown))
+ ++testSuite.NumTests;
+
+ switch (test.TestState)
+ {
+ case TestState.Failed:
+ ++testSuite.NumFailures;
+ break;
+ case TestState.Error:
+ ++testSuite.NumErrors;
+ break;
+ case TestState.Warning:
+ ++testSuite.NumWarnings;
+ break;
+ }
+ }
+
+ ///
+ /// translate the qc states into a state enum
+ ///
+ ///
+ ///
+ private TestState GetTsStateFromQcState(TestExecStatus qcTestStatus)
+ {
+ if (TdConnection == null && TdConnectionOld == null)
+ {
+ return TestState.Failed;
+ }
+
+ if (qcTestStatus == null)
+ return TestState.Unknown;
+
+ switch (qcTestStatus.Status)
+ {
+ case "Waiting":
+ return TestState.Waiting;
+ case "Error":
+ return TestState.Error;
+ case "No Run":
+ return TestState.NoRun;
+ case "Running":
+ case "Connecting":
+ return TestState.Running;
+ case "Success":
+ case "Finished":
+ case "FinishedPassed":
+ {
+ if (qcTestStatus.Message.Contains("warning"))
+ {
+ return TestState.Warning;
+ }
+
+ return TestState.Passed;
+ }
+ case "FinishedFailed":
+ return TestState.Failed;
+ }
+ return TestState.Unknown;
+ }
+
+ // ------------------------- Logs -----------------------------
+
+ ///
+ /// Returns a description of the failure
+ ///
+ ///
+ ///
+ private string GenerateFailedLog(IRun pTest)
+ {
+ try
+ {
+ var sf = pTest.StepFactory as StepFactory;
+ ; if (sf == null)
+ return string.Empty;
+
+ var stepList = sf.NewList(string.Empty) as IList;
+ if (stepList == null)
+ return string.Empty;
+
+ var failedMsg = new StringBuilder();
+
+ //loop on each step in the steps
+ foreach (IStep s in stepList)
+ {
+ if (s.Status == "Failed")
+ failedMsg.AppendLine(s["ST_DESCRIPTION"]);
+ }
+ return failedMsg.ToString();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ return string.Empty;
+ }
+ }
+
+ ///
+ /// retrieves the run logs for the test when the steps are not reported to Qc (like in ST)
+ ///
+ ///
+ /// the test run log
+ private string GetTestRunLog(ITSTest currentTest)
+ {
+ const string testLog = "log\\vtd_user.log";
+
+ IRun lastRun = currentTest.LastRun as IRun;
+ string retVal = string.Empty;
+ if (lastRun != null)
+ {
+ try
+ {
+ var storage = lastRun.ExtendedStorage as IExtendedStorage;
+ if (storage != null)
+ {
+ bool wasFatalError;
+ List list;
+ var path = storage.LoadEx(testLog, true, out list, out wasFatalError);
+ string logPath = Path.Combine(path, testLog);
+
+ if (File.Exists(logPath))
+ {
+ retVal = File.ReadAllText(logPath).TrimEnd();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ retVal = string.Empty;
+ Console.WriteLine(ex.Message);
+ }
+ }
+ retVal = ConsoleWriter.FilterXmlProblematicChars(retVal);
+ return retVal;
+ }
+
+ public void Dispose(bool managed)
+ {
+ //Console.WriteLine("Dispose ALM connection");
+ if (Connected)
+ {
+ if (TdConnection != null)
+ {
+ _tdConnection.Disconnect();
+ Marshal.ReleaseComObject(_tdConnection);
+ }
+ else
+ {
+ _tdConnectionOld.Disconnect();
+ Marshal.ReleaseComObject(_tdConnectionOld);
+ }
+ }
+ }
+
+ public override void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ public class QCFailure
+ {
+ public string Name { get; set; }
+ public string Desc { get; set; }
+ }
+
+ public enum QcRunMode
+ {
+ RUN_LOCAL,
+ RUN_REMOTE,
+ RUN_PLANNED_HOST
+ }
+}
\ No newline at end of file
diff --git a/HpToolsLauncher/Runners/FileSystemTestsRunner.cs b/HpToolsLauncher/Runners/FileSystemTestsRunner.cs
index 337ab9f193..ea1361faf0 100644
--- a/HpToolsLauncher/Runners/FileSystemTestsRunner.cs
+++ b/HpToolsLauncher/Runners/FileSystemTestsRunner.cs
@@ -1,369 +1,761 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using HpToolsLauncher.Properties;
-using HpToolsLauncher.TestRunners;
-
-namespace HpToolsLauncher
-{
- public class FileSystemTestsRunner : RunnerBase, IDisposable
- {
- #region Members
-
- Dictionary _jenkinsEnvVariables;
- private List _tests;
- private static string _uftViewerPath;
- private int _errors, _fail;
- private bool _useUFTLicense;
- private TimeSpan _timeout = TimeSpan.MaxValue;
- private Stopwatch _stopwatch = null;
- private string _abortFilename = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\stop" + Launcher.UniqueTimeStamp + ".txt";
-
- //LoadRunner Arguments
- private int _pollingInterval;
- private TimeSpan _perScenarioTimeOutMinutes;
- private List _ignoreErrorStrings;
-
-
- //saves runners for cleaning up at the end.
- private Dictionary _colRunnersForCleanup = new Dictionary();
-
-
- public const string UftJUnitRportName = "uftRunnerRoot";
-
- private McConnectionInfo _mcConnection;
- private string _mobileInfoForAllGuiTests;
-
- #endregion
-
- ///
- /// creates instance of the runner given a source.
- ///
- ///
- ///
- ///
- ///
- public FileSystemTestsRunner(List sources,
- TimeSpan timeout,
- int ControllerPollingInterval,
- TimeSpan perScenarioTimeOutMinutes,
- List ignoreErrorStrings,
- Dictionary jenkinsEnvVariables,
- McConnectionInfo mcConnection,
- string mobileInfo,
- bool useUFTLicense = false
- )
- {
- _jenkinsEnvVariables = jenkinsEnvVariables;
- //search if we have any testing tools installed
- if (!Helper.IsTestingToolsInstalled(TestStorageType.FileSystem))
- {
- ConsoleWriter.WriteErrLine(string.Format(Resources.FileSystemTestsRunner_No_HP_testing_tool_is_installed_on, System.Environment.MachineName));
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
-
- _timeout = timeout;
- ConsoleWriter.WriteLine("FileSystemTestRunner timeout is " + _timeout );
- _stopwatch = Stopwatch.StartNew();
-
- _pollingInterval = ControllerPollingInterval;
- _perScenarioTimeOutMinutes = perScenarioTimeOutMinutes;
- _ignoreErrorStrings = ignoreErrorStrings;
-
-
- _useUFTLicense = useUFTLicense;
- _tests = new List();
-
- _mcConnection = mcConnection;
- _mobileInfoForAllGuiTests = mobileInfo;
-
- ConsoleWriter.WriteLine("Mc connection info is - " + _mcConnection.ToString());
-
- //go over all sources, and create a list of all tests
- foreach (string source in sources)
- {
- List testGroup = new List();
- try
- {
- //--handle directories which contain test subdirectories (recursively)
- if (Helper.IsDirectory(source))
- {
-
- var testsLocations = Helper.GetTestsLocations(source);
- foreach (var loc in testsLocations)
- {
- var test = new TestInfo(loc, loc, source);
- testGroup.Add(test);
- }
- }
- //--handle mtb files (which contain links to tests)
- else
- //file might be LoadRunner scenario or
- //mtb file (which contain links to tests)
- //other files are dropped
- {
- testGroup = new List();
- FileInfo fi = new FileInfo(source);
- if (fi.Extension == Helper.LoadRunnerFileExtention)
- testGroup.Add(new TestInfo(source, source, source));
- else if (fi.Extension == ".mtb")
- //if (source.TrimEnd().EndsWith(".mtb", StringComparison.CurrentCultureIgnoreCase))
- {
- MtbManager manager = new MtbManager();
- var paths = manager.Parse(source);
- foreach (var p in paths)
- {
- testGroup.Add(new TestInfo(p, p, source));
- }
- }
- else if (fi.Extension == ".mtbx")
- //if (source.TrimEnd().EndsWith(".mtb", StringComparison.CurrentCultureIgnoreCase))
- {
- testGroup = MtbxManager.Parse(source, _jenkinsEnvVariables, source);
- }
- }
- }
- catch (Exception)
- {
- testGroup = new List();
- }
-
- //--handle single test dir, add it with no group
- if (testGroup.Count == 1)
- {
- testGroup[0].TestGroup = "";
- }
-
- _tests.AddRange(testGroup);
- }
-
- if (_tests == null || _tests.Count == 0)
- {
- ConsoleWriter.WriteLine(Resources.FsRunnerNoValidTests);
- Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
- }
-
- ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerTestsFound, _tests.Count));
- _tests.ForEach(t => ConsoleWriter.WriteLine("" + t.TestName));
- ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator);
- }
-
-
-
-
- ///
- /// runs all tests given to this runner and returns a suite of run resutls
- ///
- /// The rest run results for each test
- public override TestSuiteRunResults Run()
- {
- //create a new Run Results object
- TestSuiteRunResults activeRunDesc = new TestSuiteRunResults();
-
- double totalTime = 0;
- try
- {
- var start = DateTime.Now;
- foreach (var test in _tests)
- {
- if (RunCancelled()) break;
-
- var testStart = DateTime.Now;
-
- string errorReason = string.Empty;
- TestRunResults runResult = null;
- try
- {
- runResult = RunHPToolsTest(test, ref errorReason);
- }
- catch (Exception ex)
- {
- runResult = new TestRunResults();
- runResult.TestState = TestState.Error;
- runResult.ErrorDesc = ex.Message;
- runResult.TestName = test.TestName;
- }
-
- //get the original source for this test, for grouping tests under test classes
- runResult.TestGroup = test.TestGroup;
-
- activeRunDesc.TestRuns.Add(runResult);
-
- //if fail was terminated before this step, continue
- if (runResult.TestState != TestState.Failed)
- {
- if (runResult.TestState != TestState.Error)
- {
- Helper.GetTestStateFromReport(runResult);
- }
- else
- {
- if (string.IsNullOrEmpty(runResult.ErrorDesc))
- {
- if (RunCancelled())
- {
- runResult.ErrorDesc = HpToolsLauncher.Properties.Resources.ExceptionUserCancelled;
- }
- else
- {
- runResult.ErrorDesc = HpToolsLauncher.Properties.Resources.ExceptionExternalProcess;
- }
- }
- runResult.ReportLocation = null;
- runResult.TestState = TestState.Error;
- }
- }
-
- if (runResult.TestState == TestState.Passed && runResult.HasWarnings)
- {
- runResult.TestState = TestState.Warning;
- ConsoleWriter.WriteLine(Resources.FsRunnerTestDoneWarnings);
- }
- else
- {
- ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerTestDone, runResult.TestState));
- }
-
- ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Test complete: " + runResult.TestPath + "\n-------------------------------------------------------------------------------------------------------");
-
- UpdateCounters(runResult.TestState);
- var testTotalTime = (DateTime.Now - testStart).TotalSeconds;
- }
- totalTime = (DateTime.Now - start).TotalSeconds;
- }
- finally
- {
- activeRunDesc.NumTests = _tests.Count;
- activeRunDesc.NumErrors = _errors;
- activeRunDesc.TotalRunTime = TimeSpan.FromSeconds(totalTime);
- activeRunDesc.NumFailures = _fail;
-
- foreach (IFileSysTestRunner cleanupRunner in _colRunnersForCleanup.Values)
- {
- cleanupRunner.CleanUp();
- }
- }
-
- return activeRunDesc;
- }
-
- ///
- /// checks if timeout has expired
- ///
- ///
- private bool CheckTimeout()
- {
- TimeSpan timeleft = _timeout - _stopwatch.Elapsed;
- return (timeleft > TimeSpan.Zero);
- }
-
- ///
- /// creates a correct type of runner and runs a single test.
- ///
- ///
- ///
- ///
- private TestRunResults RunHPToolsTest(TestInfo testinf, ref string errorReason)
- {
-
- var testPath = testinf.TestPath;
- var type = Helper.GetTestType(testPath);
- IFileSysTestRunner runner = null;
- switch (type)
- {
- case TestType.ST:
- runner = new ApiTestRunner(this, _timeout - _stopwatch.Elapsed);
- break;
- case TestType.QTP:
- runner = new GuiTestRunner(this, _useUFTLicense, _timeout - _stopwatch.Elapsed, _mcConnection, _mobileInfoForAllGuiTests);
- break;
- case TestType.LoadRunner:
- AppDomain.CurrentDomain.AssemblyResolve += Helper.HPToolsAssemblyResolver;
- runner = new PerformanceTestRunner(this, _timeout, _pollingInterval, _perScenarioTimeOutMinutes, _ignoreErrorStrings);
- break;
- }
-
-
- if (runner != null)
- {
- if (!_colRunnersForCleanup.ContainsKey(type))
- _colRunnersForCleanup.Add(type, runner);
-
- Stopwatch s = Stopwatch.StartNew();
-
- var results = runner.RunTest(testinf, ref errorReason, RunCancelled);
-
- results.Runtime = s.Elapsed;
- if (type == TestType.LoadRunner)
- AppDomain.CurrentDomain.AssemblyResolve -= Helper.HPToolsAssemblyResolver;
-
- return results;
- }
-
- //check for abortion
- if (System.IO.File.Exists(_abortFilename))
- {
-
- ConsoleWriter.WriteLine(Resources.GeneralStopAborted);
-
- //stop working
- Environment.Exit((int)Launcher.ExitCodeEnum.Aborted);
- }
-
- return new TestRunResults { ErrorDesc = "Unknown TestType", TestState = TestState.Error };
- }
-
-
- ///
- /// checks if run was cancelled/aborted
- ///
- ///
- public bool RunCancelled()
- {
- //if timeout has passed
- if (_stopwatch.Elapsed > _timeout && !_blnRunCancelled)
- {
- ConsoleWriter.WriteLine(Resources.GeneralTimedOut);
-
- Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted;
- _blnRunCancelled = true;
- }
-
- return _blnRunCancelled;
- }
-
- ///
- /// sums errors and failed tests
- ///
- ///
- private void UpdateCounters(TestState testState)
- {
- switch (testState)
- {
- case TestState.Error:
- _errors += 1;
- break;
- case TestState.Failed:
- _fail += 1;
- break;
- }
- }
-
-
- ///
- /// Opens the report viewer for the given report directory
- ///
- ///
- public static void OpenReport(string reportDirectory)
- {
- Helper.OpenReport(reportDirectory, ref _uftViewerPath);
- }
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using HpToolsLauncher.Properties;
+using HpToolsLauncher.TestRunners;
+using HpToolsLauncher.RTS;
+using System.Threading;
+using System.Linq;
+using HpToolsLauncher.Utils;
+
+namespace HpToolsLauncher
+{
+ public class FileSystemTestsRunner : RunnerBase, IDisposable
+ {
+ #region Members
+
+ private List _tests;
+ private static string _uftViewerPath;
+ private int _errors, _fail, _warnings;
+ private bool _useUFTLicense;
+ private bool _displayController;
+ private string _analysisTemplate;
+ private SummaryDataLogger _summaryDataLogger;
+ private List _scriptRTSSet;
+ private TimeSpan _timeout = TimeSpan.MaxValue;
+ private string _uftRunMode;
+ private Stopwatch _stopwatch = null;
+ private string _abortFilename = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\stop" + Launcher.UniqueTimeStamp + ".txt";
+ private string _encoding;
+
+ //LoadRunner Arguments
+ private int _pollingInterval;
+ private TimeSpan _perScenarioTimeOutMinutes;
+ private List _ignoreErrorStrings;
+
+ // parallel runner related information
+ private Dictionary> _parallelRunnerEnvironments;
+
+ //saves runners for cleaning up at the end.
+ private Dictionary _colRunnersForCleanup = new Dictionary();
+
+ private DigitalLab _digitalLab;
+ private bool _printInputParams;
+ private RunAsUser _uftRunAsUser;
+ private IFileSysTestRunner _runner = null;
+
+ private const string REPORT = "Report";
+ private const string REPORT1 = "Report1";
+ private const string SPACES = " ";
+
+ #endregion
+
+ private void InitCommonFields(bool printInputParams,
+ TimeSpan timeout,
+ string uftRunMode,
+ int controllerPollingInterval,
+ TimeSpan perScenarioTimeOutMinutes,
+ List ignoreErrorStrings,
+ DigitalLab digitalLab,
+ Dictionary> parallelRunnerEnvironments,
+ bool displayController,
+ string analysisTemplate,
+ SummaryDataLogger summaryDataLogger,
+ List scriptRtsSet,
+ string reportPath,
+ string xmlResultsFullFileName,
+ string encoding,
+ RunAsUser uftRunAsUser,
+ bool useUftLicense = false)
+ {
+ //search if we have any testing tools installed
+ if (!Helper.IsTestingToolsInstalled(TestStorageType.FileSystem))
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.FileSystemTestsRunner_No_HP_testing_tool_is_installed_on, Environment.MachineName));
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ _timeout = timeout;
+ ConsoleWriter.WriteLine("FileSystemTestRunner timeout is " + _timeout);
+ _stopwatch = Stopwatch.StartNew();
+
+ _pollingInterval = controllerPollingInterval;
+ _perScenarioTimeOutMinutes = perScenarioTimeOutMinutes;
+ _ignoreErrorStrings = ignoreErrorStrings;
+
+ _useUFTLicense = useUftLicense;
+ _displayController = displayController;
+ _analysisTemplate = analysisTemplate;
+ _summaryDataLogger = summaryDataLogger;
+ _scriptRTSSet = scriptRtsSet;
+ _printInputParams = printInputParams;
+
+ _digitalLab = digitalLab;
+
+ _parallelRunnerEnvironments = parallelRunnerEnvironments;
+ _xmlBuilder.XmlName = xmlResultsFullFileName;
+ _encoding = encoding;
+ _uftRunAsUser = uftRunAsUser;
+ _uftRunMode = uftRunMode;
+
+ if (_digitalLab.ConnectionInfo != null)
+ ConsoleWriter.WriteLine("Digital Lab connection info is - " + _digitalLab.ConnectionInfo.ToString());
+
+ if (reportPath != null)
+ {
+ ConsoleWriter.WriteLine("Results directory is: " + reportPath);
+ }
+ }
+
+ ///
+ /// creates instance of the runner given a source.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public FileSystemTestsRunner(List sources,
+ List @params,
+ bool printInputParams,
+ TimeSpan timeout,
+ string uftRunMode,
+ int controllerPollingInterval,
+ TimeSpan perScenarioTimeOutMinutes,
+ List ignoreErrMsgs,
+ Dictionary jenkinsEnvVars,
+ DigitalLab digitalLab,
+ Dictionary> parallelRunnerEnvs,
+ bool displayController,
+ string analysisTemplate,
+ SummaryDataLogger summaryDataLogger,
+ List scriptRtsSet,
+ string reportPath,
+ string xmlResultsFullFileName,
+ string encoding,
+ RunAsUser uftRunAsUser,
+ bool useUftLicense = false)
+ {
+ InitCommonFields(printInputParams, timeout, uftRunMode, controllerPollingInterval, perScenarioTimeOutMinutes, ignoreErrMsgs, digitalLab, parallelRunnerEnvs, displayController, analysisTemplate, summaryDataLogger, scriptRtsSet, reportPath, xmlResultsFullFileName, encoding, uftRunAsUser, useUftLicense);
+
+ _tests = GetListOfTestInfo(sources, @params, jenkinsEnvVars);
+
+ if (_tests == null || _tests.Count == 0)
+ {
+ ConsoleWriter.WriteLine(Resources.FsRunnerNoValidTests);
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ // if a custom path was provided,set the custom report path for all the valid tests(this will overwrite the default location)
+ if (reportPath != null)
+ {
+ _tests.ForEach(test => test.ReportPath = reportPath);
+ }
+
+ ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerTestsFound, _tests.Count));
+
+ foreach (var test in _tests)
+ {
+ ConsoleWriter.WriteLine(string.Empty + test.TestName);
+ if (parallelRunnerEnvs.ContainsKey(test.TestId))
+ {
+ parallelRunnerEnvs[test.TestId].ForEach(env => ConsoleWriter.WriteLine(SPACES + env));
+ }
+ }
+
+ ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator);
+ }
+
+ public FileSystemTestsRunner(List tests,
+ bool printInputParams,
+ TimeSpan timeout,
+ string uftRunMode,
+ int controllerPollingInterval,
+ TimeSpan perScenarioTimeOutMinutes,
+ List ignoreErrMsgs,
+ Dictionary jenkinsEnvVars,
+ DigitalLab digitalLab,
+ Dictionary> parallelRunnerEnvs,
+ bool displayController,
+ string analysisTemplate,
+ SummaryDataLogger summaryDataLogger,
+ List scriptRtsSet,
+ string reportPath,
+ string xmlResultsFullFileName,
+ string encoding,
+ RunAsUser uftRunAsUser,
+ bool useUftLicense = false)
+ {
+ InitCommonFields(printInputParams, timeout, uftRunMode, controllerPollingInterval, perScenarioTimeOutMinutes, ignoreErrMsgs, digitalLab, parallelRunnerEnvs, displayController, analysisTemplate, summaryDataLogger, scriptRtsSet, reportPath, xmlResultsFullFileName, encoding, uftRunAsUser, useUftLicense);
+
+ _tests = tests;
+ if (_tests == null || _tests.Count == 0)
+ {
+ ConsoleWriter.WriteLine(Resources.FsRunnerNoValidTests);
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerTestsFound, _tests.Count));
+
+ foreach (var test in _tests)
+ {
+ ConsoleWriter.WriteLine(string.Empty + test.TestName);
+ if (parallelRunnerEnvs.ContainsKey(test.TestId))
+ {
+ parallelRunnerEnvs[test.TestId].ForEach(env => ConsoleWriter.WriteLine(SPACES + env));
+ }
+ }
+
+ ConsoleWriter.WriteLine(Resources.GeneralDoubleSeperator);
+ }
+
+ public static TestInfo GetFirstTestInfo(TestData source, Dictionary jenkinsEnvVars)
+ {
+ var tests = GetListOfTestInfo(new List() { source }, jenkinsEnvVars: jenkinsEnvVars);
+ return tests.FirstOrDefault();
+ }
+
+ public static List GetListOfTestInfo(List sources, List @params = null, Dictionary jenkinsEnvVars = null)
+ {
+ List tests = new List();
+
+ int idx = 1;
+ //go over all sources, and create a list of all tests
+ foreach (TestData source in sources)
+ {
+ //this will contain all the tests found in the source
+ List testGroup = new List();
+ try
+ {
+ //--handle directories which contain test subdirectories (recursively)
+ if (Helper.IsDirectory(Helper.GetTestPathWithoutParams(source.Tests)))
+ {
+ string testPath = Helper.GetTestPathWithoutParams(source.Tests);
+ var testsLocations = Helper.GetTestsLocations(testPath);
+
+ foreach (var loc in testsLocations)
+ {
+ var test = new TestInfo(loc, loc, testPath, source.Id);
+
+ try
+ {
+ //we need to check for inline params and props params as well, for backward compatibility
+ SetInlineParams(source.Tests, ref test);
+ SetPropsParams(@params, idx, ref test);
+ }
+ catch (ArgumentException)
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.FsRunnerErrorParameterFormat, testPath));
+ }
+
+ testGroup.Add(test);
+ }
+ }
+ //--handle mtb files (which contain links to tests)
+ else
+ //file might be LoadRunner scenario or
+ //mtb file (which contain links to tests)
+ //other files are dropped
+ {
+ testGroup = new List();
+ FileInfo fi = new FileInfo(source.Tests);
+ if (fi.Extension == Helper.LoadRunnerFileExt)
+ testGroup.Add(new TestInfo(source.Tests, source.Tests, source.Tests, source.Id));
+ else if (fi.Extension == Helper.MtbFileExt)
+ {
+ MtbManager manager = new MtbManager();
+ var paths = manager.Parse(source.Tests);
+ foreach (var p in paths)
+ {
+ testGroup.Add(new TestInfo(p, p, source.Tests, source.Id));
+ }
+ }
+ else if (fi.Extension == Helper.MtbxFileExt)
+ {
+ testGroup = MtbxManager.Parse(source.Tests, jenkinsEnvVars, source.Tests);
+
+ // set the test Id for each test from the group
+ // this is important for parallel runner
+ foreach (var testInfo in testGroup)
+ {
+ testInfo.TestId = source.Id;
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ testGroup = new List();
+ }
+
+ //--handle single test dir, add it with no group
+ if (testGroup.Count == 1)
+ {
+ testGroup[0].TestGroup = "Test group";
+ }
+
+ //we add the found tests to the test list
+ tests.AddRange(testGroup);
+
+ ++idx;
+ }
+ return tests;
+ }
+
+ ///
+ /// runs all tests given to this runner and returns a suite of run results
+ ///
+ /// The rest run results for each test
+ public override TestSuiteRunResults Run()
+ {
+ //create a new Run Results object
+ TestSuiteRunResults activeRunDesc = new TestSuiteRunResults();
+ bool isNewTestSuite;
+ testsuite ts = _xmlBuilder.TestSuites.GetTestSuiteOrDefault(activeRunDesc.SuiteName, JunitXmlBuilder.ClassName, out isNewTestSuite);
+ ts.tests += _tests.Count;
+
+ // if we have at least one environment for parallel runner, then it must be enabled
+ var isParallelRunnerEnabled = _parallelRunnerEnvironments.Count > 0;
+ double totalTime = 0;
+ try
+ {
+ var start = DateTime.Now;
+
+ Dictionary indexList = new Dictionary();
+ foreach (var test in _tests)
+ {
+ indexList[test.TestPath] = 0;
+ }
+
+ Exception dcomEx = null;
+ bool isDcomVerified = false;
+ Dictionary rerunList = CreateDictionary(_tests);
+ Dictionary prevTestOutParams = null;
+
+ for (int x = 0; x < _tests.Count; x++)
+ {
+ var test = _tests[x];
+ if (indexList[test.TestPath] == 0)
+ {
+ indexList[test.TestPath] = 1;
+ }
+
+ if (RunCancelled()) break;
+
+ string errorReason = string.Empty;
+ TestRunResults runResult = null;
+ try
+ {
+ var type = Helper.GetTestType(test.TestPath);
+ if (isParallelRunnerEnabled && type == TestType.QTP)
+ {
+ type = TestType.ParallelRunner;
+ }
+
+ if (type == TestType.QTP)
+ {
+ if (!isDcomVerified)
+ {
+ try
+ {
+ Helper.ChangeDCOMSettingToInteractiveUser();
+ }
+ catch (Exception ex)
+ {
+ dcomEx = ex;
+ }
+ finally
+ {
+ isDcomVerified = true;
+ }
+ }
+
+ if (dcomEx != null)
+ throw dcomEx;
+ }
+
+ if (prevTestOutParams != null && prevTestOutParams.Count > 0)
+ {
+ foreach (var param in test.Params)
+ {
+ if (param.Source != null && prevTestOutParams.ContainsKey(param.Source))
+ {
+ param.Value = prevTestOutParams[param.Source];
+ }
+ }
+ prevTestOutParams = null;
+ }
+ Dictionary outParams = null;
+ runResult = RunHpToolsTest(test, type, ref errorReason, out outParams);
+ if (outParams != null && outParams.Count > 0)
+ prevTestOutParams = outParams;
+ else
+ prevTestOutParams = null;
+ }
+ catch (Exception ex)
+ {
+ runResult = new TestRunResults
+ {
+ TestState = TestState.Error,
+ ErrorDesc = ex.Message,
+ TestName = test.TestName,
+ TestPath = test.TestPath
+ };
+ }
+ runResult.TestInfo = test;
+ //get the original source for this test, for grouping tests under test classes
+ runResult.TestGroup = test.TestGroup;
+
+ activeRunDesc.TestRuns.Add(runResult);
+
+ //if fail was terminated before this step, continue
+ if (runResult.TestState != TestState.Failed)
+ {
+ if (runResult.TestState != TestState.Error)
+ {
+ Helper.GetTestStateFromReport(runResult);
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(runResult.ErrorDesc))
+ {
+ runResult.ErrorDesc = RunCancelled() ? Resources.ExceptionUserCancelled : Resources.ExceptionExternalProcess;
+ }
+ runResult.ReportLocation = null;
+ runResult.TestState = TestState.Error;
+ }
+ }
+
+ if (runResult.TestState == TestState.Passed && runResult.HasWarnings)
+ {
+ runResult.TestState = TestState.Warning;
+ ConsoleWriter.WriteLine(Resources.FsRunnerTestDoneWarnings);
+ }
+ else
+ {
+ ConsoleWriter.WriteLine(string.Format(Resources.FsRunnerTestDone, runResult.TestState));
+ }
+
+ UpdateCounters(runResult.TestState, ts);
+
+ //create test folders
+ if (rerunList[test.TestPath] > 0)
+ {
+ rerunList[test.TestPath]--;
+ if (Directory.Exists(Path.Combine(test.TestPath, REPORT1)))
+ {
+ indexList[test.TestPath]++;
+ }
+ }
+
+ if (runResult.TestType == TestType.ParallelRunner)
+ {
+ ConsoleWriter.WriteLine(string.Format("uftReportDir is: {0}", runResult.ReportLocation));
+ }
+ else
+ {
+ string uftReportDir = Path.Combine(test.TestPath, REPORT);
+ string uftReportDirNew = Path.Combine(test.TestPath, string.Format("Report{0}", indexList[test.TestPath]));
+ UpdateUftReportDir(uftReportDir, uftReportDirNew);
+ }
+ // Create or update the xml report. This function is called after each test execution in order to have a report available in case of job interruption
+ _xmlBuilder.CreateOrUpdatePartialXmlReport(ts, runResult, isNewTestSuite && x==0);
+ ConsoleWriter.WriteLineWithTime("Test complete: " + runResult.TestPath + "\n-------------------------------------------------------------------------------------------------------");
+ }
+
+ totalTime = (DateTime.Now - start).TotalSeconds;
+ }
+ finally
+ {
+ activeRunDesc.NumTests = _tests.Count;
+ activeRunDesc.NumErrors = _errors;
+ activeRunDesc.TotalRunTime = TimeSpan.FromSeconds(totalTime);
+ activeRunDesc.NumFailures = _fail;
+ activeRunDesc.NumWarnings = _warnings;
+
+ foreach (IFileSysTestRunner cleanupRunner in _colRunnersForCleanup.Values)
+ {
+ cleanupRunner.CleanUp();
+ }
+ }
+
+ return activeRunDesc;
+ }
+
+ private void UpdateUftReportDir(string uftReportDir, string uftReportDirNew)
+ {
+ //update report folder
+ if (Directory.Exists(uftReportDir))
+ {
+ ConsoleWriter.WriteLine(string.Format("uftReportDir is {0}", uftReportDirNew));
+ if (Directory.Exists(uftReportDirNew))
+ {
+ Helper.DeleteDirectory(uftReportDirNew);
+ }
+ TryMoveDir(uftReportDir, uftReportDirNew, 0);
+ }
+ }
+
+ private bool TryMoveDir(string srcDir, string destDir, int idxOfRetry)
+ {
+ try
+ {
+ Thread.Sleep(1500);
+ Directory.Move(srcDir, destDir);
+ }
+ catch(Exception ex)
+ {
+ if (idxOfRetry >= 5)
+ {
+ ConsoleWriter.WriteErrLineWithTime(string.Format("Failed to rename {0} after {1} retries.", srcDir, idxOfRetry));
+ ConsoleWriter.WriteLine(string.Format("{0}: {1}", ex.GetType().Name, ex.Message));
+ return false;
+ }
+ return TryMoveDir(srcDir, destDir, ++idxOfRetry);
+ }
+ return true;
+ }
+
+ public override void SafelyCancel()
+ {
+ base.SafelyCancel();
+ if (_runner != null)
+ {
+ _runner.SafelyCancel();
+ }
+ }
+
+ private Dictionary CreateDictionary(List validTests)
+ {
+ var rerunList = new Dictionary();
+ foreach (var item in validTests)
+ {
+ if (!rerunList.ContainsKey(item.TestPath))
+ {
+ rerunList.Add(item.TestPath, 1);
+ }
+ else
+ {
+ rerunList[item.TestPath]++;
+ }
+ }
+
+ return rerunList;
+ }
+
+ ///
+ /// Sets the test's inline parameters.
+ ///
+ ///
+ ///
+ ///
+ private static void SetInlineParams(string testPath, ref TestInfo test)
+ {
+ // the inline test path does not contain any parameter specification
+ if (testPath.IndexOf("\"") == -1) return;
+
+ // the inline test path does contain parameter specification
+ string strParams = testPath.Substring(testPath.IndexOf("\"", StringComparison.Ordinal)).Trim();
+ string[] @params = strParams.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+
+ if (@params == null || @params.Length == 0) return;
+
+ IList paramNames, paramValues;
+
+ if (!Helper.ValidateInlineParams(@params, out paramNames, out paramValues))
+ {
+ throw new ArgumentException();
+ }
+
+ string paramType;
+ long _unused;
+ for (int i = 0; i < paramNames.Count; ++i)
+ {
+ paramType = long.TryParse(paramValues[i], out _unused) ? "number" : "string";
+ test.Params.Add(new TestParameterInfo() { Name = paramNames[i], Type = paramType, Value = paramValues[i] });
+ }
+ }
+
+ ///
+ /// Sets the test's parameters from the props (CI args).
+ ///
+ private static void SetPropsParams(List @params, int idx, ref TestInfo test)
+ {
+ if (@params != null && @params.Count > 0)
+ {
+ // all the parameters that belong to this test
+ List testParams = @params.FindAll(elem => elem.TestIdx.Equals(idx));
+
+ foreach (TestParameter param in testParams)
+ {
+ test.Params.Add(new TestParameterInfo() { Name = param.ParamName, Type = param.ParamType, Value = param.ParamVal });
+ }
+ }
+
+ return;
+ }
+
+ ///
+ /// creates a correct type of runner and runs a single test.
+ ///
+ ///
+ ///
+ ///
+ private TestRunResults RunHpToolsTest(TestInfo testInfo, TestType type, ref string errorReason, out Dictionary outParams)
+ {
+ outParams = new Dictionary();
+ // if the current test is an api test ignore the parallel runner flag and just continue as usual
+ if (type == TestType.ST && _parallelRunnerEnvironments.Count > 0)
+ {
+ ConsoleWriter.WriteLine("ParallelRunner does not support API tests, treating as normal test.");
+ }
+
+ switch (type)
+ {
+ case TestType.ST:
+ _runner = new ApiTestRunner(this, _timeout - _stopwatch.Elapsed, _encoding, _printInputParams, _uftRunAsUser);
+ break;
+ case TestType.QTP:
+ _runner = new GuiTestRunner(this, _useUFTLicense, _timeout - _stopwatch.Elapsed, _uftRunMode, _digitalLab, _printInputParams, _uftRunAsUser);
+ break;
+ case TestType.LoadRunner:
+ AppDomain.CurrentDomain.AssemblyResolve += Helper.HPToolsAssemblyResolver;
+ _runner = new PerformanceTestRunner(this, _timeout, _pollingInterval, _perScenarioTimeOutMinutes, _ignoreErrorStrings, _displayController, _analysisTemplate, _summaryDataLogger, _scriptRTSSet);
+ break;
+ case TestType.ParallelRunner:
+ _runner = new ParallelTestRunner(this, _digitalLab.ConnectionInfo, _parallelRunnerEnvironments, _uftRunAsUser);
+ break;
+ default:
+ _runner = null;
+ break;
+ }
+
+ if (_runner != null)
+ {
+ if (!_colRunnersForCleanup.ContainsKey(type))
+ _colRunnersForCleanup.Add(type, _runner);
+
+ Stopwatch s = Stopwatch.StartNew();
+
+ var results = _runner.RunTest(testInfo, ref errorReason, RunCancelled, out outParams);
+ if (results.ErrorDesc != null && results.ErrorDesc.Equals(TestState.Error))
+ {
+ Environment.Exit((int)Launcher.ExitCodeEnum.Failed);
+ }
+
+ results.Runtime = s.Elapsed;
+ if (type == TestType.LoadRunner)
+ AppDomain.CurrentDomain.AssemblyResolve -= Helper.HPToolsAssemblyResolver;
+
+ return results;
+ }
+
+ //check for abortion
+ if (File.Exists(_abortFilename))
+ {
+ ConsoleWriter.WriteLine(Resources.GeneralStopAborted);
+ //stop working
+ Environment.Exit((int)Launcher.ExitCodeEnum.Aborted);
+ }
+
+ return new TestRunResults { ErrorDesc = "Unknown TestType", TestState = TestState.Error };
+ }
+
+ ///
+ /// checks if run was cancelled/aborted
+ ///
+ ///
+ public bool RunCancelled()
+ {
+ //if timeout has passed
+ if (_stopwatch.Elapsed > _timeout && !_isRunCancelled)
+ {
+ ConsoleWriter.WriteLine(Resources.SmallDoubleSeparator);
+ ConsoleWriter.WriteLine(Resources.GeneralTimedOut);
+ ConsoleWriter.WriteLine(Resources.SmallDoubleSeparator);
+
+ Launcher.ExitCode = Launcher.ExitCodeEnum.Aborted;
+ _isRunCancelled = true;
+ }
+
+ return _isRunCancelled;
+ }
+
+ ///
+ /// sums errors and failed tests
+ ///
+ ///
+ private void UpdateCounters(TestState testState, testsuite ts)
+ {
+ switch (testState)
+ {
+ case TestState.Error:
+ _errors++;
+ ts.errors++;
+ break;
+ case TestState.Failed:
+ _fail++;
+ ts.failures++;
+ break;
+ case TestState.Warning:
+ _warnings++;
+ break;
+ }
+ }
+
+
+ ///
+ /// Opens the report viewer for the given report directory
+ ///
+ ///
+ public static void OpenReport(string reportDirectory)
+ {
+ Helper.OpenReport(reportDirectory, ref _uftViewerPath);
+ }
+ }
+}
diff --git a/HpToolsLauncher/Runners/MBTRunner.cs b/HpToolsLauncher/Runners/MBTRunner.cs
new file mode 100644
index 0000000000..0553d17db8
--- /dev/null
+++ b/HpToolsLauncher/Runners/MBTRunner.cs
@@ -0,0 +1,336 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+
+using QTObjectModelLib;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace HpToolsLauncher
+{
+ public class MBTRunner : RunnerBase, IDisposable
+ {
+ private readonly object _lockObject = new object();
+ private string parentFolder;//folder in which we will create new tests
+ private string repoFolder;
+ private IEnumerable tests;
+
+ public MBTRunner(string parentFolder, string repoFolder, IEnumerable tests)
+ {
+ this.parentFolder = parentFolder;
+ this.repoFolder = repoFolder;
+ this.tests = tests;
+ }
+
+ public override TestSuiteRunResults Run()
+ {
+ var type = Type.GetTypeFromProgID("Quicktest.Application");
+
+ lock (_lockObject)
+ {
+ Application _qtpApplication = Activator.CreateInstance(type) as Application;
+ try
+ {
+ if (Directory.Exists(parentFolder))
+ {
+ Directory.Delete(parentFolder, true);
+ }
+ ConsoleWriter.WriteLine("Using parent folder : " + parentFolder);
+ }
+ catch (Exception e)
+ {
+ ConsoleWriter.WriteErrLine("Failed to delete parent folder : " + e.Message);
+ }
+
+ Directory.CreateDirectory(parentFolder);
+ DirectoryInfo parentDir = new DirectoryInfo(parentFolder);
+
+ try
+ {
+ if (_qtpApplication.Launched)
+ {
+ _qtpApplication.Quit();
+ }
+ }
+ catch (Exception e)
+ {
+ ConsoleWriter.WriteErrLine("Failed to close qtpApp : " + e.Message);
+ }
+
+
+
+ //START Test creation
+ //_qtpApplication.Launch();
+ //_qtpApplication.Visible = false;
+ foreach (var test in tests)
+ {
+ DateTime startTotal = DateTime.Now;
+ ConsoleWriter.WriteLine("Creation of " + test.Name + " *****************************");
+ LoadNeededAddins(_qtpApplication, test.UnderlyingTests);
+ try
+ {
+ DateTime startSub1 = DateTime.Now;
+ _qtpApplication.New();
+
+ try
+ {
+ //The test is set to record and run on any open Web application.
+ _qtpApplication.Test.Settings.Launchers["Web"].Active = false;
+ }
+ catch (Exception e)
+ {
+ ConsoleWriter.WriteLine("Failed to set .Launchers[Web].Active = false : " + e.Message);
+ }
+
+ ConsoleWriter.WriteLine(string.Format("_qtpApplication.New took {0:0.0} secs", DateTime.Now.Subtract(startSub1).TotalSeconds));
+ QTObjectModelLib.Action qtAction1 = _qtpApplication.Test.Actions[1];
+ qtAction1.Description = "unitIds=" + string.Join(",", test.UnitIds);
+
+ //https://myskillpoint.com/how-to-use-loadandrunaction-in-uft/#LoadAndRunAction_Having_Input-Output_Parameters
+ //LoadAndRunAction "E:\UFT_WorkSpace\TestScripts\SampleTest","Action1",0,"inputParam1","inputParam2",outParameterVal
+ //string actionContent = "LoadAndRunAction \"c:\\Temp\\GUITest2\\\",\"Action1\"";
+ string actionContent = File.Exists(test.Script) ? File.ReadAllText(test.Script) : test.Script;
+ qtAction1.ValidateScript(actionContent);
+ qtAction1.SetScript(actionContent);
+
+ DirectoryInfo fullDir = parentDir;
+ if (!string.IsNullOrEmpty(test.PackageName))
+ {
+ fullDir = fullDir.CreateSubdirectory(test.PackageName);
+ }
+
+ //Expects to receive params in CSV format, encoded base64
+ if (!string.IsNullOrEmpty(test.DatableParams))
+ {
+ string tempCsvFileName = Path.Combine(parentFolder, "temp.csv");
+ if (File.Exists(tempCsvFileName))
+ {
+ File.Delete(tempCsvFileName);
+ }
+
+ byte[] data = Convert.FromBase64String(test.DatableParams);
+ string decodedParams = Encoding.UTF8.GetString(data);
+
+ File.WriteAllText(tempCsvFileName, decodedParams);
+ _qtpApplication.Test.DataTable.Import(tempCsvFileName);
+ File.Delete(tempCsvFileName);
+ }
+
+ string fullPath = fullDir.CreateSubdirectory(test.Name).FullName;
+ _qtpApplication.Test.SaveAs(fullPath);
+ double sec = DateTime.Now.Subtract(startTotal).TotalSeconds;
+ ConsoleWriter.WriteLine(string.Format("MBT test was created in {0} in {1:0.0} secs", fullPath, sec));
+
+ }
+ catch (Exception e)
+ {
+ ConsoleWriter.WriteErrLine("Fail in MBTRunner : " + e.Message);
+ }
+ }
+ if (_qtpApplication.Launched)
+ {
+ _qtpApplication.Quit();
+ }
+ }
+
+ return null;
+ }
+
+ private string GetResourceFileNameAndAddToUftFoldersIfRequired(Application qtpApplication, string filePath)
+ {
+ //file path might be full or just file name;
+ string location = qtpApplication.Folders.Locate(filePath);
+ if (!string.IsNullOrEmpty(location))
+ {
+ ConsoleWriter.WriteLine(string.Format("Adding resources : {0} - done", filePath));
+ }
+ else
+ {
+ ConsoleWriter.WriteLine(string.Format("Adding resources : {0} - failed to find file in repository. Please check correctness of resource location.", filePath));
+ }
+ /*else
+ {
+ string[] allFiles = Directory.GetFiles(repoFolder, fileName, SearchOption.AllDirectories);
+ if (allFiles.Length == 0)
+ {
+ ConsoleWriter.WriteLine(string.Format("Adding resources : {0} - failed to find file in repository. Please check correctness of resource name.", fileName));
+ }
+ else if (allFiles.Length > 1)
+ {
+ //we found several possible locations
+ //if resource has full path, we can try to find it in found paths
+ //for example resource : c://aa/bb/repo/resourceName
+ //one of found paths is : c:/jenkins/repo/resourceName , after removing repo is will be /repo/resourceName
+ //so /repo/resourceName is last part of c://aa/bb/repo/resourceName
+ bool found = false;
+ if (Path.IsPathRooted(filePath))
+ {
+ foreach (string path in allFiles)
+ {
+ string pathInRepo = path.Replace(repoFolder,"");
+ if (filePath.EndsWith(pathInRepo))
+ {
+ string directoryPath = new FileInfo(path).Directory.FullName;
+ ConsoleWriter.WriteLine(string.Format("Adding resources : {0} - folder {1} is added to settings", fileName, directoryPath.Replace(repoFolder, "")));
+ qtpApplication.Folders.Add(directoryPath);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (string path in allFiles)
+ {
+ string directoryPath = new FileInfo(path).Directory.FullName;
+ sb.Append(directoryPath).Append("; ");
+ }
+ ConsoleWriter.WriteLine(string.Format("Adding resources : {0} - found more than 1 file in repo. Please define 'Folder location' manually in (Tools->Options->GUI Testing->Folders). Possible values : {1}", fileName, sb.ToString()));
+ }
+ }
+ else//found ==1
+ {
+ string directoryPath = new FileInfo(allFiles[0]).Directory.FullName;
+ ConsoleWriter.WriteLine(string.Format("Adding resources : {0} - folder {1} is added to settings", fileName, directoryPath.Replace(repoFolder,"")));
+ qtpApplication.Folders.Add(directoryPath);
+ }
+ }*/
+
+ return filePath;
+ }
+
+ private void LoadNeededAddins(Application _qtpApplication, IEnumerable fileNames)
+ {
+ try
+ {
+ HashSet addinsSet = new HashSet();
+ foreach (string fileName in fileNames)
+ {
+ try
+ {
+ DateTime start1 = DateTime.Now;
+ var testAddinsObj = _qtpApplication.GetAssociatedAddinsForTest(fileName);
+ ConsoleWriter.WriteLine(string.Format("GetAssociatedAddinsForTest took {0:0.0} secs", DateTime.Now.Subtract(start1).TotalSeconds));
+ object[] tempTestAddins = (object[])testAddinsObj;
+
+ foreach (string addin in tempTestAddins)
+ {
+ addinsSet.Add(addin);
+ }
+ }
+ catch (Exception testErr)
+ {
+ ConsoleWriter.WriteErrLine("Fail to LoadNeededAddins for : " + fileName + ", " + testErr.Message);
+ }
+ }
+
+ //if (_qtpApplication.Launched)
+ //{
+ //_qtpApplication.Quit();
+ //ConsoleWriter.WriteLine("LoadNeededAddins : _qtpApplication.Quit");
+ //}
+
+ object erroDescription = null;
+
+ string[] addinsArr = new string[addinsSet.Count];
+ addinsSet.CopyTo(addinsArr);
+ ConsoleWriter.WriteLine("Loading Addins : " + string.Join(",", addinsArr));
+ DateTime start2 = DateTime.Now;
+ _qtpApplication.SetActiveAddins(addinsArr, out erroDescription);
+ ConsoleWriter.WriteLine(string.Format("SetActiveAddins took {0:0.0} secs", DateTime.Now.Subtract(start2).TotalSeconds));
+ if (!string.IsNullOrEmpty((string)erroDescription))
+ {
+ ConsoleWriter.WriteErrLine("Fail to SetActiveAddins : " + erroDescription);
+ }
+ }
+ catch (Exception globalErr)
+ {
+ ConsoleWriter.WriteErrLine("Fail to LoadNeededAddins : " + globalErr.Message);
+ // Try anyway to run the test
+ }
+ }
+ }
+
+ public class RecoveryScenario
+ {
+ public string FileName { get; set; }
+ public string Name { get; set; }
+ public int Position { get; set; }
+
+ public static RecoveryScenario ParseFromString(string content)
+ {
+ RecoveryScenario rs = new RecoveryScenario();
+ string[] parts = content.Split(',');//expected 3 parts separated by , : location,name,position(default is -1)
+ if (parts.Length < 2)
+ {
+ ConsoleWriter.WriteErrLine("Fail to parse recovery scenario (need at least 2 parts, separated with ,): " + content);
+ return null;
+ }
+ rs.FileName = parts[0];
+ rs.Name = parts[1];
+ if (parts.Length >= 3)
+ {
+ try
+ {
+ rs.Position = int.Parse(parts[2]);
+ }
+ catch (Exception e)
+ {
+ ConsoleWriter.WriteErrLine("Fail to parse position of recovery scenario : " + content + " : " + e.Message);
+ rs.Position = -1;
+ }
+ }
+ else
+ {
+ rs.Position = -1;
+ }
+
+ return rs;
+ }
+ }
+
+ public class MBTTest
+ {
+ public string Name { get; set; }
+ public string Script { get; set; }
+ public string UnitIds { get; set; }
+ public List UnderlyingTests { get; set; }
+ public string PackageName { get; set; }
+ public string DatableParams { get; set; }
+ }
+
+
+}
diff --git a/HpToolsLauncher/Runners/RunnerBase.cs b/HpToolsLauncher/Runners/RunnerBase.cs
index 97814de306..229e960e81 100644
--- a/HpToolsLauncher/Runners/RunnerBase.cs
+++ b/HpToolsLauncher/Runners/RunnerBase.cs
@@ -1,30 +1,67 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-
-namespace HpToolsLauncher
-{
- public class RunnerBase: IAssetRunner
- {
-
- public void Dispose()
- {
- }
- protected bool _blnRunCancelled = false;
-
- public bool RunWasCancelled
- {
- get { return _blnRunCancelled; }
- set { _blnRunCancelled = value; }
- }
-
- public virtual TestSuiteRunResults Run()
- {
- throw new NotImplementedException();
- }
-
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+
+namespace HpToolsLauncher
+{
+ public class RunnerBase : IAssetRunner
+ {
+ public virtual void Dispose()
+ {
+ }
+ protected bool _isRunCancelled = false;
+ protected JunitXmlBuilder _xmlBuilder = new JunitXmlBuilder();
+
+ public bool RunWasCancelled
+ {
+ get { return _isRunCancelled; }
+ set { _isRunCancelled = value; }
+ }
+
+ public JunitXmlBuilder XmlBuilder
+ {
+ get { return _xmlBuilder; }
+ set { _xmlBuilder = value; }
+ }
+
+ public virtual TestSuiteRunResults Run()
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual void SafelyCancel()
+ {
+ _isRunCancelled = true;
+ }
+ }
+}
diff --git a/HpToolsLauncher/SummaryDataLogger.cs b/HpToolsLauncher/SummaryDataLogger.cs
new file mode 100644
index 0000000000..0f262f16c2
--- /dev/null
+++ b/HpToolsLauncher/SummaryDataLogger.cs
@@ -0,0 +1,160 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HP.LoadRunner.Interop.Wlrun;
+using System;
+using System.Text;
+
+namespace HpToolsLauncher.TestRunners
+{
+ public class SummaryDataLogger
+ {
+ private bool m_logVusersStates;
+ private bool m_logErrorCount;
+ private bool m_logTransactionStatistics;
+ private int m_pollingInterval;
+
+ public SummaryDataLogger(bool logVusersStates, bool logErrorCount, bool logTransactionStatistics, int pollingInterval)
+ {
+ m_logVusersStates = logVusersStates;
+ m_logErrorCount = logErrorCount;
+ m_logTransactionStatistics = logTransactionStatistics;
+ m_pollingInterval = pollingInterval;
+ }
+
+ public SummaryDataLogger() { }
+
+ public int GetPollingInterval()
+ {
+ return m_pollingInterval * 1000;
+ }
+
+ private enum VUSERS_STATE
+ {
+ Down = 1,
+ Pending = 2,
+ Init = 3,
+ Ready = 4,
+ Run = 5,
+ Rendez = 6,
+ Passed = 7,
+ Failed = 8,
+ Error = 9,
+ Exiting = 10,
+ Stopped = 11,
+ G_Exit = 12 //Gradual Exiting
+ }
+
+ private void LogVuserStates(LrScenario scenario)
+ {
+ StringBuilder headerBuilder = new StringBuilder(),
+ bodyBuilder = new StringBuilder();
+
+ foreach (var vuserState in Enum.GetValues(typeof(VUSERS_STATE)))
+ {
+ headerBuilder.Append(string.Format("{0, -10}", vuserState.ToString()));
+ }
+
+ foreach (var vuserState in Enum.GetValues(typeof(VUSERS_STATE)))
+ {
+ bodyBuilder.Append(string.Format("{0, -10}", scenario.GetVusersCount((int)vuserState)));
+ }
+
+ ConsoleWriter.WriteLine(headerBuilder.ToString());
+ ConsoleWriter.WriteLine(bodyBuilder.ToString());
+ }
+
+ private void LogErrorCount(LrScenario scenario)
+ {
+
+ int errorsCount = scenario.GetErrorsCount("");
+
+ ConsoleWriter.WriteLine("Error count: " + errorsCount);
+ }
+
+ private void LogScenarioDuration(LrScenario scenario)
+ {
+ int scenarioDuration = scenario.ScenarioDuration;
+ TimeSpan time = TimeSpan.FromSeconds(scenarioDuration);
+ string convertedTime = time.ToString(@"dd\:hh\:mm\:ss");
+
+ ConsoleWriter.WriteLine("Elapsed Time (D:H:M:S): " + convertedTime);
+ }
+
+ public void LogSummaryData(LrScenario scenario)
+ {
+ if (m_logVusersStates || m_logErrorCount || m_logTransactionStatistics)
+ {
+ LogScenarioDuration(scenario);
+
+ if (m_logVusersStates)
+ {
+ LogVuserStates(scenario);
+ }
+
+ if (m_logErrorCount)
+ {
+ LogErrorCount(scenario);
+ }
+
+ if (m_logTransactionStatistics)
+ {
+ LogTransactionStatistics(scenario);
+ }
+ }
+ }
+
+ public bool IsAnyDataLogged()
+ {
+ return (m_logVusersStates || m_logErrorCount || m_logTransactionStatistics);
+ }
+
+ private void LogTransactionStatistics(LrScenario scenario)
+ {
+ int passed = 0, failed = 0;
+ double hitsPerSecond = 0;
+ scenario.GetTransactionStatistics(ref passed, ref failed, ref hitsPerSecond);
+
+ ConsoleWriter.WriteLine("Passed transactions: " + passed);
+ ConsoleWriter.WriteLine("Failed transactions: " + failed);
+ ConsoleWriter.WriteLine("Hits per second: " + Math.Round(hitsPerSecond, 2));
+ }
+
+ public void LogTransactionDetails(LrScenario scenario)
+ {
+ string transactionDetails;
+ scenario.GetTransactionStatisticsDetails(out transactionDetails);
+
+ ConsoleWriter.WriteLine("Transaction details: " + transactionDetails);
+ }
+ }
+}
diff --git a/HpToolsLauncher/TestData.cs b/HpToolsLauncher/TestData.cs
new file mode 100644
index 0000000000..45bc0fa9b4
--- /dev/null
+++ b/HpToolsLauncher/TestData.cs
@@ -0,0 +1,52 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+namespace HpToolsLauncher
+{
+ public class TestData
+ {
+ public TestData(string tests, string id)
+ {
+ this.Tests = tests;
+ this.Id = id;
+ }
+
+ public string Tests { get; set; }
+ public string Id { get; set; }
+
+ public override string ToString()
+ {
+ return Id + ": " + Tests;
+ }
+
+ }
+}
diff --git a/HpToolsLauncher/TestInfo.cs b/HpToolsLauncher/TestInfo.cs
index 1bbf03b72f..1d27baba2a 100644
--- a/HpToolsLauncher/TestInfo.cs
+++ b/HpToolsLauncher/TestInfo.cs
@@ -1,164 +1,264 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Xml.Linq;
-using System.Xml.Schema;
-
-namespace HpToolsLauncher
-{
- public class TestInfo
- {
- public TestInfo(string testPath)
- {
- TestPath = testPath;
- }
- public string GenerateAPITestXmlForTest()
- {
- Dictionary paramDict = new Dictionary();
- foreach (var param in ParameterList)
- {
- paramDict.Add(param.Name.ToLower(), param);
- }
- string paramXmlFileName = Path.Combine(TestPath, "TestInputParameters.xml");
- XDocument doc = XDocument.Load(paramXmlFileName);
- string schemaStr = doc.Descendants("Schema").First().Elements().First().ToString();
- XElement xArgs = doc.Descendants("Arguments").FirstOrDefault();
- if (xArgs!=null)
- foreach (XElement arg in xArgs.Elements())
- {
- string paramName = arg.Name.ToString().ToLower();
- if (paramDict.ContainsKey(paramName))
- {
- var param = paramDict[paramName];
- arg.Value = NormalizeParamValue(param);
- }
- }
- string argumentSectionStr = doc.Descendants("Values").First().Elements().First().ToString();
- try
- {
- XDocument doc1 = XDocument.Parse(argumentSectionStr);
- XmlSchema schema = XmlSchema.Read(new MemoryStream(Encoding.ASCII.GetBytes(schemaStr), false), null);
-
- XmlSchemaSet schemas = new XmlSchemaSet();
- schemas.Add(schema);
-
- string validationMessages = "";
- doc1.Validate(schemas, (o, e) =>
- {
- validationMessages += e.Message + Environment.NewLine;
- });
-
- if (!string.IsNullOrWhiteSpace(validationMessages))
- ConsoleWriter.WriteLine("parameter schema validation errors: \n" + validationMessages);
- }
- catch (Exception ex)
- {
- ConsoleWriter.WriteErrLine("An error occured while creating ST parameter file, check the validity of TestInputParameters.xml in your test directory and of your mtbx file");
- }
- return doc.ToString();
- }
-
-
- private string NormalizeParamValue(TestParameterInfo param)
- {
- switch (param.Type.ToLower())
- {
- case "datetime":
- case "date":
- string retStr = "";
- try
- {
- retStr = ((DateTime)param.ParseValue()).ToString("yyyy-MM-ddTHH:mm:ss");
- }
- catch
- {
- ConsoleWriter.WriteErrLine("incorrect dateTime value format in parameter: " + param.Name);
- }
- return retStr;
- default:
- return param.Value;
- }
- }
-
- private string NormalizeParamType(string pType)
- {
- switch (pType.ToLower())
- {
- case "datetime":
- case "date":
- return "dateTime";
-
- case "any":
- case "string":
- case "password":
- return "string";
-
- case "int":
- case "integer":
- case "number":
- return "integer";
- case "bool":
- case "boolean":
- return "boolean";
- default:
- return pType.ToLower();
- }
- }
-
- public TestInfo(string testPath, string testName)
- {
- TestPath = testPath;
- TestName = testName;
- }
-
- public TestInfo(string testPath, string testName, string testGroup)
- {
- _testPath = testPath;
- TestGroup = testGroup;
- _testName = testName;
- }
-
-
- List _paramList = new List();
- string _testName;
- string _testGroup;
-
- public string TestGroup
- {
- get { return _testGroup; }
- set { _testGroup = value.TrimEnd("\\/".ToCharArray()).Replace(".", "_"); }
- }
-
- public string TestName
- {
- get { return _testName; }
- set { _testName = value; }
- }
- string _testPath;
-
- public string TestPath
- {
- get { return _testPath; }
- set { _testPath = value; }
- }
- public List ParameterList
- {
- get { return _paramList; }
- set { _paramList = value; }
- }
-
-
- internal Dictionary GetParameterDictionaryForQTP()
- {
- Dictionary retval = new Dictionary();
- foreach (var param in _paramList)
- {
- object val = param.ParseValue();
- retval.Add(param.Name, val);
- }
- return retval;
- }
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.TestRunners;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using HpToolsLauncher.Properties;
+using HpToolsLauncher.Utils;
+
+namespace HpToolsLauncher
+{
+ public class TestInfo
+ {
+ private const string TEST_INPUT_PARAMETERS_XML = "TestInputParameters.xml";
+ private const string SCHEMA = "Schema";
+ private const string XS = "xs";
+ private const string ARGUMENTS = "Arguments";
+ private const string ELEMENT = "element";
+ private const string NAME = "name";
+ private const string TYPE = "type";
+ private const string DATETIME = "datetime";
+ private const string DATE = "date";
+ private const string BOOLEAN = "boolean";
+ private const string YYYY_MM_ddTHH_mm_ss = "yyyy-MM-ddTHH:mm:ss";
+ private const string VALUES = "Values";
+ private const string COLON = ":";
+ private const char DOT = '.';
+ private const char UNDERSCORE = '_';
+ private readonly char[] _slashes = "\\/".ToCharArray();
+
+ public TestInfo(string testPath)
+ {
+ TestPath = testPath;
+ }
+
+ public string GenerateAPITestXmlForTest(Dictionary paramDict, bool printInputParams)
+ {
+ string paramXmlFileName = Path.Combine(TestPath, TEST_INPUT_PARAMETERS_XML);
+ XDocument doc = XDocument.Load(paramXmlFileName);
+ var schemaTmp = doc.Descendants(SCHEMA).First().Elements().First();
+ var paramNs = schemaTmp.GetNamespaceOfPrefix(XS);
+ string schemaStr = schemaTmp.ToString();
+ XElement xArgs = doc.Descendants(ARGUMENTS).FirstOrDefault();
+
+ // parameter specifications according to schema
+ var xParams = doc.Descendants(paramNs + ELEMENT)
+ .Where(node => ARGUMENTS == (string)node.Attribute(NAME))
+ .Descendants(paramNs + ELEMENT).ToList();
+
+ if (xArgs != null && xParams.Count != 0)
+ foreach (XElement arg in xArgs.Elements())
+ {
+ string paramName = arg.Name.ToString();
+
+ if (!paramDict.ContainsKey(paramName))
+ {
+ continue;
+ }
+
+ var param = paramDict[paramName];
+
+ // spec belonging to this parameter
+ var paramSpec = xParams.Find(elem => paramName == (string)elem.Attribute(NAME));
+ // its type
+ string paramType;
+ if (paramSpec != null)
+ {
+ var typeSpec = paramSpec.Attribute(TYPE);
+
+ if (typeSpec != null)
+ {
+ var tmpVal = typeSpec.Value;
+ var startIdx = tmpVal.IndexOf(COLON, StringComparison.Ordinal);
+ paramType = typeSpec.Value.Substring(startIdx != 0 ? startIdx + 1 : startIdx);
+ }
+ else continue;
+ }
+ else continue; // no spec found for given parameter, skipping
+
+ // verify its type according to the spec
+ if (!ApiTestRunner.VerifyParameterValueType(param, paramType))
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.GeneralParameterTypeMismatchWith2Types, paramName, paramType, param.GetType()));
+ }
+ else
+ {
+ arg.Value = NormalizeParamValue(paramName, param, paramType);
+ if (printInputParams)
+ ConsoleWriter.WriteLine(string.Format(Resources.GeneralParameterUsage, paramName, paramType.ToLower().In(DATETIME, DATE) ? ((DateTime)param).ToShortDateString() : param));
+ }
+ }
+
+ string argumentSectionStr = doc.Descendants(VALUES).First().Elements().First().ToString();
+ try
+ {
+ XDocument doc1 = XDocument.Parse(argumentSectionStr);
+ XmlSchema schema = XmlSchema.Read(new MemoryStream(Encoding.ASCII.GetBytes(schemaStr), false), null);
+
+ XmlSchemaSet schemas = new XmlSchemaSet();
+ schemas.Add(schema);
+
+ string validationMessages = string.Empty;
+ doc1.Validate(schemas, (o, e) =>
+ {
+ validationMessages += e.Message + Environment.NewLine;
+ });
+
+ if (!string.IsNullOrWhiteSpace(validationMessages))
+ {
+ ConsoleWriter.WriteErrLine("Parameter schema validation errors, falling back to default parameter definitions: \n" + validationMessages);
+ return string.Empty;
+ }
+ }
+ catch
+ {
+ ConsoleWriter.WriteErrLine("An error occured while creating ST parameter file, check the validity of TestInputParameters.xml in your test directory and of your mtbx file");
+ }
+
+ return doc.ToString();
+ }
+
+ private string NormalizeParamValue(string name, object param, string type)
+ {
+ switch (type.ToLower())
+ {
+ case DATETIME:
+ case DATE:
+ try
+ {
+ return ((DateTime)param).ToString(YYYY_MM_ddTHH_mm_ss);
+ }
+ catch
+ {
+ ConsoleWriter.WriteErrLine("Incorrect dateTime value format in parameter: " + name);
+ return string.Empty;
+ }
+ case BOOLEAN:
+ return param.ToString().ToLower();
+ default:
+ return param.ToString();
+ }
+ }
+
+ public TestInfo(string testPath, string testName) : this(testPath)
+ {
+ TestName = testName;
+ }
+
+ public TestInfo(string testPath, string testName, string testGroup): this(testPath, testName)
+ {
+ TestGroup = testGroup;
+ }
+
+ public TestInfo(string testPath, string testName, string testGroup, string testId) : this(testPath, testName, testGroup)
+ {
+ TestId = testId;
+ }
+
+ public TestInfo(string testId, TestInfo test)
+ {
+ TestId = testId;
+ TestName = test.TestName;
+ TestPath = test.TestPath;
+ TestGroup = test.TestGroup;
+ _params = test.Params;
+ ReportPath = test.ReportPath;
+ DataTablePath = test.DataTablePath;
+ IterationInfo = test.IterationInfo;
+ }
+
+ private List _params = new List();
+ string _testName;
+ string _testGroup;
+ string _dataTablePath;
+ IterationInfo _iterationInfo;
+
+ public string TestGroup
+ {
+ get { return _testGroup; }
+ set { _testGroup = value.TrimEnd(_slashes).Replace(DOT, UNDERSCORE); }
+ }
+
+ public string TestName
+ {
+ get { return _testName; }
+ set { _testName = value; }
+ }
+ string _testPath;
+
+ public string TestPath
+ {
+ get { return _testPath; }
+ set { _testPath = value; }
+ }
+
+ // the path where the report will be saved
+ public string ReportPath { get; set; }
+
+ public string TestId { get; set; }
+
+ public List Params
+ {
+ get { return _params; }
+ set { _params = value; }
+ }
+
+ public string DataTablePath
+ {
+ get { return _dataTablePath; }
+ set { _dataTablePath = value; }
+ }
+
+ public IterationInfo IterationInfo
+ {
+ get { return _iterationInfo; }
+ set { _iterationInfo = value; }
+ }
+
+ internal Dictionary GetParameterDictionaryForQTP()
+ {
+ Dictionary retval = new Dictionary();
+ foreach (var param in _params)
+ {
+ object val = param.ParseValue();
+ retval.Add(param.Name, val);
+ }
+ return retval;
+ }
+ }
+}
diff --git a/HpToolsLauncher/TestParameter.cs b/HpToolsLauncher/TestParameter.cs
new file mode 100644
index 0000000000..6908f1b4f4
--- /dev/null
+++ b/HpToolsLauncher/TestParameter.cs
@@ -0,0 +1,50 @@
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+namespace HpToolsLauncher
+{
+ public class TestParameter
+ {
+ public TestParameter(int TestIdx, string ParamName, string ParamVal, string ParamType) {
+ this.TestIdx = TestIdx;
+ this.ParamName = ParamName;
+ this.ParamVal = ParamVal;
+ this.ParamType = ParamType;
+ }
+
+ public int TestIdx { get; set; }
+ public string ParamName { get; set; }
+ public string ParamVal { get; set; }
+ public string ParamType { get; set; }
+
+ }
+}
diff --git a/HpToolsLauncher/TestParameterInfo.cs b/HpToolsLauncher/TestParameterInfo.cs
index 295a2cadf2..8f18d24929 100644
--- a/HpToolsLauncher/TestParameterInfo.cs
+++ b/HpToolsLauncher/TestParameterInfo.cs
@@ -1,161 +1,199 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace HpToolsLauncher
-{
- public class TestParameterInfo
- {
- string _name;
-
- public string Name
- {
- get { return _name; }
- set { _name = value; }
- }
- string _value;
-
- public string Value
- {
- get { return _value; }
- set { _value = value; }
- }
- string _type;
-
- public string Type
- {
- get { return _type; }
- set { _type = value; }
- }
-
-
- ///
- /// parses the value string and returns an object of the specified type.
- ///
- ///
- public object ParseValue()
- {
- object val = null;
- bool ok = false;
- switch (this.Type.ToLower())
- {
- case "int":
-
- int v;
- ok = int.TryParse(this.Value, out v);
- if (ok)
- {
- val = v;
- }
- break;
- case "number":
- case "password":
- case "string":
- case "any":
- val = this.Value;
- break;
- case "float":
- float v1;
- ok = float.TryParse(this.Value, out v1);
- if (ok)
- {
- val = v1;
- }
-
- break;
- case "double":
-
- double v2;
- ok = double.TryParse(this.Value, out v2);
- if (ok)
- {
- val = v2;
- }
- break;
- case "datetime":
- case "date":
- DateTime v3;
- ok = DateTime.TryParseExact(this.Value,
- new string[] {
- "yyyy-MM-ddTHH:mm:ss",
- "dd/MM/yyyy HH:mm:ss.fff",
- "dd/M/yyyy HH:mm:ss.fff",
- "d/MM/yyyy HH:mm:ss.fff",
- "dd/MM/yyyy hh:mm:ss.fff tt" ,
- "d/MM/yyyy hh:mm:ss.fff tt" ,
- "dd/M/yyyy hh:mm:ss.fff tt" ,
- "d/M/yyyy hh:mm:ss.fff tt" ,
- "dd-MM-yyyy HH:mm:ss.fff",
- "dd.MM.yyyy HH:mm:ss.fff",
- "dd.MM.yyyy hh:mm:ss.fff tt" ,
- "dd/MM/yyyy HH:mm:ss",
- "dd-MM-yyyy HH:mm:ss",
- "d/MM/yyyy HH:mm:ss",
- "d/MM/yyyy hh:mm:ss tt",
- "d-MM-yyyy HH:mm:ss",
- "d.MM.yyyy HH:mm:ss",
- "d.MM.yyyy hh:mm:ss tt" ,
- "dd/MM/yyyy",
- "dd-MM-yyyy",
- "dd.MM.yyyy",
- "d/MM/yyyy" ,
- "d-MM-yyyy" ,
- "d.MM.yyyy" ,
- "M/d/yyyy HH:mm:ss.fff",
- "M.d.yyyy hh:mm:ss.fff tt",
- "M.d.yyyy HH:mm:ss.fff",
- "M/d/yyyy hh:mm:ss.fff t",
- "MM/dd/yyyy hh:mm:ss.fff tt",
- "MM/d/yyyy hh:mm:ss.fff tt",
- "MM/dd/yyyy HH:mm:ss",
- "MM.dd.yyyy HH:mm:ss",
- "M/dd/yyyy HH:mm:ss.fff",
- "M/dd/yyyy hh:mm:ss.fff tt",
- "M.dd.yyyy HH:mm:ss.fff",
- "M.dd.yyyy hh:mm:ss.fff tt",
- "MM/dd/yyyy",
- "MM.dd.yyyy",
- "M/dd/yyyy",
- "M.dd.yyyy"
- },
- null,
- System.Globalization.DateTimeStyles.None,
- out v3);
-
- //ok = DateTime.TryParse(param.Value, out v3);
- if (ok)
- {
- val = v3;
- }
- break;
-
- case "long":
- long v4;
- ok = long.TryParse(this.Value, out v4);
- if (ok)
- {
- val = v4;
- }
- break;
- case "boolean":
- bool v5;
- ok = bool.TryParse(this.Value, out v5);
- if (ok)
- {
- val = v5;
- }
- break;
- case "decimal":
- decimal v6;
- ok = decimal.TryParse(this.Value, out v6);
- if (ok)
- {
- val = v6;
- }
- break;
- }
- return val;
- }
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using System;
+
+namespace HpToolsLauncher
+{
+ public class TestParameterInfo
+ {
+ string _name;
+
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+ string _value;
+
+ public string Value
+ {
+ get { return _value; }
+ set { _value = value; }
+ }
+ string _type;
+
+ public string Type
+ {
+ get { return _type; }
+ set { _type = value; }
+ }
+
+ public string Source { get; set; }
+
+
+ ///
+ /// parses the value string and returns an object of the specified type.
+ ///
+ ///
+ public object ParseValue()
+ {
+ object val = null;
+ bool ok = false;
+ switch (_type.ToLower())
+ {
+ case "int":
+ int v;
+ ok = int.TryParse(_value, out v);
+ if (ok)
+ {
+ val = v;
+ }
+ break;
+ case "number":
+ case "password":
+ case "string":
+ case "any":
+ val = _value;
+ break;
+ case "float":
+ float v1;
+ ok = float.TryParse(_value, out v1);
+ if (ok)
+ {
+ val = v1;
+ }
+
+ break;
+ case "double":
+ double v2;
+ ok = double.TryParse(_value, out v2);
+ if (ok)
+ {
+ val = v2;
+ }
+ break;
+ case "datetime":
+ case "date":
+ DateTime v3;
+ ok = DateTime.TryParseExact(_value,
+ new string[] {
+ "yyyy-MM-ddTHH:mm:ss",
+ "dd/MM/yyyy HH:mm:ss.fff",
+ "dd/M/yyyy HH:mm:ss.fff",
+ "d/MM/yyyy HH:mm:ss.fff",
+ "dd/MM/yyyy hh:mm:ss.fff tt" ,
+ "d/MM/yyyy hh:mm:ss.fff tt" ,
+ "dd/M/yyyy hh:mm:ss.fff tt" ,
+ "d/M/yyyy hh:mm:ss.fff tt" ,
+ "dd-MM-yyyy HH:mm:ss.fff",
+ "dd.MM.yyyy HH:mm:ss.fff",
+ "dd.MM.yyyy hh:mm:ss.fff tt" ,
+ "dd/MM/yyyy HH:mm:ss",
+ "dd-MM-yyyy HH:mm:ss",
+ "dd/MM/yyyy hh:mm:ss tt",
+ "dd/M/yyyy hh:mm:ss tt",
+ "d/M/yyyy hh:mm:ss tt",
+ "d/MM/yyyy HH:mm:ss",
+ "d/MM/yyyy hh:mm:ss tt",
+ "d-MM-yyyy HH:mm:ss",
+ "d.MM.yyyy HH:mm:ss",
+ "d.MM.yyyy hh:mm:ss tt" ,
+ "dd/MM/yyyy",
+ "dd-MM-yyyy",
+ "dd.MM.yyyy",
+ "d/MM/yyyy" ,
+ "d-MM-yyyy" ,
+ "d.MM.yyyy" ,
+ "M/d/yyyy HH:mm:ss.fff",
+ "M.d.yyyy hh:mm:ss.fff tt",
+ "M.d.yyyy hh:mm:ss tt",
+ "M.d.yyyy HH:mm:ss.fff",
+ "M/d/yyyy hh:mm:ss.fff t",
+ "MM/dd/yyyy hh:mm:ss.fff tt",
+ "MM/d/yyyy hh:mm:ss.fff tt",
+ "MM/dd/yyyy hh:mm:ss tt",
+ "MM/d/yyyy hh:mm:ss tt",
+ "MM/dd/yyyy HH:mm:ss",
+ "MM.dd.yyyy HH:mm:ss",
+ "M/dd/yyyy HH:mm:ss.fff",
+ "M/dd/yyyy hh:mm:ss.fff tt",
+ "M/dd/yyyy hh:mm:ss tt",
+ "M.dd.yyyy HH:mm:ss.fff",
+ "M.dd.yyyy hh:mm:ss.fff tt",
+ "M.dd.yyyy hh:mm:ss tt",
+ "MM/dd/yyyy",
+ "MM.dd.yyyy",
+ "M/dd/yyyy",
+ "M.dd.yyyy"
+ },
+ null,
+ System.Globalization.DateTimeStyles.None,
+ out v3);
+
+ //ok = DateTime.TryParse(param.Value, out v3);
+ if (ok)
+ {
+ val = v3;
+ }
+ break;
+
+ case "long":
+ long v4;
+ ok = long.TryParse(_value, out v4);
+ if (ok)
+ {
+ val = v4;
+ }
+ break;
+ case "bool":
+ case "boolean":
+ bool v5;
+ ok = bool.TryParse(_value, out v5);
+ if (ok)
+ {
+ val = v5;
+ }
+ break;
+ case "decimal":
+ decimal v6;
+ ok = decimal.TryParse(_value, out v6);
+ if (ok)
+ {
+ val = v6;
+ }
+ break;
+ }
+ return val;
+ }
+ }
+}
diff --git a/HpToolsLauncher/TestRunResults.cs b/HpToolsLauncher/TestRunResults.cs
index 9fb5dbc7c2..71c5639f0a 100644
--- a/HpToolsLauncher/TestRunResults.cs
+++ b/HpToolsLauncher/TestRunResults.cs
@@ -1,52 +1,83 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-
-namespace HpToolsLauncher
-{
- public class TestRunResults
- {
- public TestRunResults()
- {
- FatalErrors = -1;
- }
-
- private TestState m_enmTestState = TestState.Unknown;
- private TestState m_enmPrevTestState = TestState.Unknown;
- private bool m_hasWarnings = false;
-
- public bool HasWarnings
- {
- get { return m_hasWarnings; }
- set { m_hasWarnings = value; }
- }
-
- public string TestPath { get; set; }
- public string TestName { get; set; }
- public string TestGroup { get; set; }
- public string ErrorDesc { get; set; }
- public string FailureDesc { get; set; }
- public string ConsoleOut { get; set; }
- public string ConsoleErr { get; set; }
- public TimeSpan Runtime { get; set; }
- public string TestType { get; set; }
- public string ReportLocation { get; set; }
- public int FatalErrors { get; set; }
- public TestState TestState
- {
- get { return m_enmTestState; }
- set { m_enmTestState = value; }
- }
-
- public TestState PrevTestState
- {
- get { return m_enmPrevTestState; }
- set { m_enmPrevTestState = value; }
- }
-
- public int PrevRunId { get; set; }
- }
-}
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+
+using HpToolsLauncher.Utils;
+using System;
+
+namespace HpToolsLauncher
+{
+ public class TestRunResults
+ {
+ public TestRunResults()
+ {
+ FatalErrors = -1;
+ }
+
+ private TestState m_enmTestState = TestState.Unknown;
+ private TestState m_enmPrevTestState = TestState.Unknown;
+ private bool m_hasWarnings = false;
+
+ public bool HasWarnings
+ {
+ get { return m_hasWarnings; }
+ set { m_hasWarnings = value; }
+ }
+
+ public string TestPath { get; set; }
+ public string TestName { get; set; }
+ public string TestGroup { get; set; }
+ public string ErrorDesc { get; set; }
+ public string FailureDesc { get; set; }
+ public string ConsoleOut { get; set; }
+ public string ConsoleErr { get; set; }
+ public TimeSpan Runtime { get; set; }
+ public TestType TestType { get; set; }
+ public string ReportLocation { get; set; }
+ public int FatalErrors { get; set; }
+ public TestState TestState
+ {
+ get { return m_enmTestState; }
+ set { m_enmTestState = value; }
+ }
+
+ public TestState PrevTestState
+ {
+ get { return m_enmPrevTestState; }
+ set { m_enmPrevTestState = value; }
+ }
+
+ public int PrevRunId { get; set; }
+
+ public TestInfo TestInfo { get; set; }
+ }
+}
diff --git a/HpToolsLauncher/TestRunners/ApiTestRunner.cs b/HpToolsLauncher/TestRunners/ApiTestRunner.cs
index 86e84b52fc..b4b6bb931f 100644
--- a/HpToolsLauncher/TestRunners/ApiTestRunner.cs
+++ b/HpToolsLauncher/TestRunners/ApiTestRunner.cs
@@ -1,310 +1,410 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using HpToolsLauncher.Properties;
-
-namespace HpToolsLauncher
-{
- public class ApiTestRunner : IFileSysTestRunner
- {
- public const string STRunnerName = "ServiceTestExecuter.exe";
- public const string STRunnerTestArg = @"-test";
- public const string STRunnerReportArg = @"-report";
- public const string STRunnerInputParamsArg = @"-inParams";
- private const int PollingTimeMs = 500;
- private bool _stCanRun;
- private string _stExecuterPath = Directory.GetCurrentDirectory();
- private readonly IAssetRunner _runner;
- private TimeSpan _timeout = TimeSpan.MaxValue;
- private Stopwatch _stopwatch = null;
- private RunCancelledDelegate _runCancelled;
-
- ///
- /// constructor
- ///
- /// parent runner
- /// the global timout
- public ApiTestRunner(IAssetRunner runner, TimeSpan timeout)
- {
- _stopwatch = Stopwatch.StartNew();
- _timeout = timeout;
- _stCanRun = TrySetSTRunner();
- _runner = runner;
- }
-
- ///
- /// Search ServiceTestExecuter.exe in the current running process directory,
- /// and if not found, in the installation folder (taken from registry)
- ///
- ///
- public bool TrySetSTRunner()
- {
- if (File.Exists(STRunnerName))
- return true;
- _stExecuterPath = Helper.GetSTInstallPath();
- if ((!String.IsNullOrEmpty(_stExecuterPath)))
- {
- _stExecuterPath += "bin";
- return true;
- }
- _stCanRun = false;
- return false;
- }
-
-
- ///
- /// runs the given test
- ///
- ///
- ///
- /// cancellation delegate, holds the function that checks cancellation
- ///
- public TestRunResults RunTest(TestInfo testinf, ref string errorReason, RunCancelledDelegate runCancelled)
- {
-
- TestRunResults runDesc = new TestRunResults();
- ConsoleWriter.ActiveTestRun = runDesc;
- ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Running: " + testinf.TestPath);
-
- runDesc.ReportLocation = Helper.CreateTempDir();
- runDesc.ErrorDesc = errorReason;
- runDesc.TestPath = testinf.TestPath;
- runDesc.TestState = TestState.Unknown;
- if (!Helper.IsServiceTestInstalled())
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = string.Format(Resources.LauncherStNotInstalled, System.Environment.MachineName);
- ConsoleWriter.WriteErrLine(runDesc.ErrorDesc);
- Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed;
- return runDesc;
- }
-
- _runCancelled = runCancelled;
- if (!_stCanRun)
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = Resources.STExecuterNotFound;
- return runDesc;
- }
- string fileName = Path.Combine(_stExecuterPath, STRunnerName);
-
- if (!File.Exists(fileName))
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = Resources.STExecuterNotFound;
- ConsoleWriter.WriteErrLine(Resources.STExecuterNotFound);
- return runDesc;
- }
-
- //write the input parameter xml file for the API test
- string paramFileName = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 10);
- string tempPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestParams");
- Directory.CreateDirectory(tempPath);
- string paramsFilePath = Path.Combine(tempPath, "params" + paramFileName + ".xml");
- string paramFileContent = testinf.GenerateAPITestXmlForTest();
-
- string argumentString = "";
- if (!string.IsNullOrWhiteSpace(paramFileContent))
- {
- File.WriteAllText(paramsFilePath, paramFileContent);
- argumentString = String.Format("{0} \"{1}\" {2} \"{3}\" {4} \"{5}\"", STRunnerTestArg, testinf.TestPath, STRunnerReportArg, runDesc.ReportLocation, STRunnerInputParamsArg, paramsFilePath);
- }
- else
- {
- argumentString = String.Format("{0} \"{1}\" {2} \"{3}\"", STRunnerTestArg, testinf.TestPath, STRunnerReportArg, runDesc.ReportLocation);
- }
-
- Stopwatch s = Stopwatch.StartNew();
- runDesc.TestState = TestState.Running;
-
- if (!ExecuteProcess(fileName,
- argumentString,
- ref errorReason))
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = errorReason;
- }
- else
- {
- runDesc.ReportLocation = Path.Combine(runDesc.ReportLocation, "Report");
- if (!File.Exists(Path.Combine(runDesc.ReportLocation, "Results.xml")) && !File.Exists(Path.Combine(runDesc.ReportLocation, "run_results.html")))
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = "No Results.xml or run_results.html file found";
- }
- }
- //File.Delete(paramsFilePath);
- runDesc.Runtime = s.Elapsed;
- return runDesc;
- }
-
- ///
- /// performs global cleanup code for this type of runner
- ///
- public void CleanUp()
- {
- }
-
- #region Process
-
- ///
- /// executes the run of the test by using the Init and RunProcss routines
- ///
- ///
- ///
- ///
- ///
- private bool ExecuteProcess(string fileName, string arguments, ref string failureReason)
- {
- Process proc = null;
- try
- {
- using (proc = new Process())
- {
- InitProcess(proc, fileName, arguments, true);
- RunProcess(proc, true);
-
- //it could be that the process already existed
- //before we could handle the cancel request
- if (_runCancelled())
- {
- failureReason = "Process was stopped since job has timed out!";
- ConsoleWriter.WriteLine(failureReason);
-
- if (!proc.HasExited)
- {
-
- proc.OutputDataReceived -= OnOutputDataReceived;
- proc.ErrorDataReceived -= OnErrorDataReceived;
- proc.Kill();
- return false;
- }
- }
- if (proc.ExitCode != 0)
- {
- failureReason = "The Api test runner's exit code was: " + proc.ExitCode;
- ConsoleWriter.WriteLine(failureReason);
- return false;
- }
- }
- }
- catch (Exception e)
- {
- failureReason = e.Message;
- return false;
- }
- finally
- {
- if (proc != null)
- {
- proc.Close();
- }
- }
-
- return true;
- }
-
- ///
- /// initializes the ServiceTestExecuter process
- ///
- ///
- ///
- ///
- ///
- private void InitProcess(Process proc, string fileName, string arguments, bool enableRedirection)
- {
- var processStartInfo = new ProcessStartInfo
- {
- FileName = fileName,
- Arguments = arguments,
- WorkingDirectory = Directory.GetCurrentDirectory()
- };
-
- if (!enableRedirection) return;
-
- processStartInfo.ErrorDialog = false;
- processStartInfo.UseShellExecute = false;
- processStartInfo.RedirectStandardOutput = true;
- processStartInfo.RedirectStandardError = true;
-
- proc.StartInfo = processStartInfo;
-
- proc.EnableRaisingEvents = true;
- proc.StartInfo.CreateNoWindow = true;
-
- proc.OutputDataReceived += OnOutputDataReceived;
- proc.ErrorDataReceived += OnErrorDataReceived;
- }
-
- ///
- /// runs the ServiceTestExecuter process after initialization
- ///
- ///
- ///
- private void RunProcess(Process proc, bool enableRedirection)
- {
- proc.Start();
- if (enableRedirection)
- {
- proc.BeginOutputReadLine();
- proc.BeginErrorReadLine();
- }
- proc.WaitForExit(PollingTimeMs);
- while (!_runCancelled() && !proc.HasExited)
- {
- proc.WaitForExit(PollingTimeMs);
- }
- }
-
- ///
- /// callback function for spawnd process errors
- ///
- ///
- ///
- private void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
- {
- var p = sender as Process;
-
- if (p == null) return;
- try
- {
- if (!p.HasExited || p.ExitCode == 0) return;
- }
- catch { return; }
- string format = String.Format("{0} {1}: ", DateTime.Now.ToShortDateString(),
- DateTime.Now.ToLongTimeString());
- string errorData = e.Data;
-
- if (String.IsNullOrEmpty(errorData))
- {
- errorData = String.Format("External process has exited with code {0}", p.ExitCode);
-
- }
-
- ConsoleWriter.WriteErrLine(errorData);
- }
-
- ///
- /// callback function for spawnd process output
- ///
- ///
- ///
- private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
- {
- if (!String.IsNullOrEmpty(e.Data))
- {
- string data = e.Data;
- ConsoleWriter.WriteLine(data);
- }
- }
-
- #endregion
-
- }
+/*
+ * Certain versions of software accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company.
+ * This software was acquired by Micro Focus on September 1, 2017, and is now offered by OpenText.
+ * Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.
+ * __________________________________________________________________
+ * MIT License
+ *
+ * Copyright 2012-2023 Open Text
+ *
+ * The only warranties for products and services of Open Text and
+ * its affiliates and licensors ("Open Text") are as may be set forth
+ * in the express warranty statements accompanying such products and services.
+ * Nothing herein should be construed as constituting an additional warranty.
+ * Open Text shall not be liable for technical or editorial errors or
+ * omissions contained herein. The information contained herein is subject
+ * to change without notice.
+ *
+ * Except as specifically indicated otherwise, this document contains
+ * confidential information and a valid license is required for possession,
+ * use or copying. If this work is provided to the U.S. Government,
+ * consistent with FAR 12.211 and 12.212, Commercial Computer Software,
+ * Computer Software Documentation, and Technical Data for Commercial Items are
+ * licensed to the U.S. Government under vendor's standard commercial license.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ___________________________________________________________________
+ */
+
+using HpToolsLauncher.Properties;
+using HpToolsLauncher.Utils;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+
+namespace HpToolsLauncher
+{
+ public class ApiTestRunner : IFileSysTestRunner
+ {
+ public const string STRunnerName = "ServiceTestExecuter.exe";
+ public const string STRunnerTestArg = @"-test";
+ public const string STRunnerReportArg = @"-report";
+ public const string STRunnerInputParamsArg = @"-inParams";
+ public const string STRunnerEncodingArg = @"-encoding";
+ private const int PollingTimeMs = 500;
+ private bool _stCanRun;
+ private string _stExecuterPath = Directory.GetCurrentDirectory();
+ private readonly IAssetRunner _runner;
+ private TimeSpan _timeout = TimeSpan.MaxValue;
+ private Stopwatch _stopwatch = null;
+ private RunCancelledDelegate _runCancelled;
+ private string _encoding;
+ private RunAsUser _uftRunAsUser;
+ private bool _printInputParams;
+
+ ///
+ /// constructor
+ ///
+ /// parent runner
+ /// the global timout
+ public ApiTestRunner(IAssetRunner runner, TimeSpan timeout, string encoding, bool printInputParams, RunAsUser uftRunAsUser)
+ {
+ _stopwatch = Stopwatch.StartNew();
+ _timeout = timeout;
+ _stCanRun = TrySetSTRunner();
+ _runner = runner;
+ _encoding = encoding;
+ _printInputParams = printInputParams;
+ _uftRunAsUser = uftRunAsUser;
+ }
+
+ ///
+ /// Search ServiceTestExecuter.exe in the current running process directory,
+ /// and if not found, in the installation folder (taken from registry)
+ ///
+ ///
+ public bool TrySetSTRunner()
+ {
+ if (File.Exists(STRunnerName))
+ return true;
+ _stExecuterPath = Helper.GetSTInstallPath();
+ if (!string.IsNullOrEmpty(_stExecuterPath))
+ {
+ _stExecuterPath += "bin";
+ return true;
+ }
+ _stCanRun = false;
+ return false;
+ }
+
+ ///
+ /// runs the given test
+ ///
+ ///
+ ///
+ /// cancellation delegate, holds the function that checks cancellation
+ ///
+ public TestRunResults RunTest(TestInfo testinf, ref string errorReason, RunCancelledDelegate runCancelled, out Dictionary outParams)
+ {
+ outParams = new Dictionary();
+ TestRunResults runDesc = new TestRunResults { TestType = TestType.ST };
+ ConsoleWriter.ActiveTestRun = runDesc;
+ ConsoleWriter.WriteLineWithTime("Running: " + testinf.TestPath);
+
+ runDesc.TestPath = testinf.TestPath;
+
+ // default report location is the test path
+ runDesc.ReportLocation = testinf.TestPath;
+
+ // check if the report path has been defined
+ if (!string.IsNullOrEmpty(testinf.ReportPath))
+ {
+ if (!Helper.TrySetTestReportPath(runDesc, testinf, ref errorReason))
+ {
+ return runDesc;
+ }
+ }
+
+ runDesc.ErrorDesc = errorReason;
+ runDesc.TestState = TestState.Unknown;
+ if (!Helper.IsServiceTestInstalled())
+ {
+ runDesc.TestState = TestState.Error;
+ runDesc.ErrorDesc = string.Format(Resources.LauncherStNotInstalled, System.Environment.MachineName);
+ ConsoleWriter.WriteErrLine(runDesc.ErrorDesc);
+ Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed;
+ return runDesc;
+ }
+
+ _runCancelled = runCancelled;
+ if (!_stCanRun)
+ {
+ runDesc.TestState = TestState.Error;
+ runDesc.ErrorDesc = Resources.STExecuterNotFound;
+ return runDesc;
+ }
+ string fileName = Path.Combine(_stExecuterPath, STRunnerName);
+
+ if (!File.Exists(fileName))
+ {
+ runDesc.TestState = TestState.Error;
+ runDesc.ErrorDesc = Resources.STExecuterNotFound;
+ ConsoleWriter.WriteErrLine(Resources.STExecuterNotFound);
+ return runDesc;
+ }
+
+ //write the input parameter xml file for the API test
+ string paramFileName = Guid.NewGuid().ToString().Replace("-", string.Empty).Substring(0, 10);
+ string tempPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestParams");
+ Directory.CreateDirectory(tempPath);
+ string paramsFilePath = Path.Combine(tempPath, "params" + paramFileName + ".xml");
+
+ Dictionary paramDict;
+ try
+ {
+ paramDict = testinf.GetParameterDictionaryForQTP();
+ }
+ catch (ArgumentException)
+ {
+ ConsoleWriter.WriteErrLine(string.Format(Resources.FsDuplicateParamNames));
+ throw;
+ }
+
+ string paramFileContent = testinf.GenerateAPITestXmlForTest(paramDict, _printInputParams);
+
+ string argumentString;
+ if (!string.IsNullOrWhiteSpace(paramFileContent))
+ {
+ File.WriteAllText(paramsFilePath, paramFileContent);
+ argumentString = string.Format("{0} \"{1}\" {2} \"{3}\" {4} \"{5}\" {6} {7}", STRunnerTestArg, testinf.TestPath, STRunnerReportArg, runDesc.ReportLocation, STRunnerInputParamsArg, paramsFilePath, string.IsNullOrWhiteSpace(_encoding) ? string.Empty : STRunnerEncodingArg, _encoding);
+ }
+ else
+ {
+ argumentString = string.Format("{0} \"{1}\" {2} \"{3}\" {4} {5}", STRunnerTestArg, testinf.TestPath, STRunnerReportArg, runDesc.ReportLocation, string.IsNullOrWhiteSpace(_encoding) ? string.Empty : STRunnerEncodingArg, _encoding);
+ }
+
+ Stopwatch s = Stopwatch.StartNew();
+ runDesc.TestState = TestState.Running;
+
+ if (!ExecuteProcess(fileName, argumentString, ref errorReason))
+ {
+ runDesc.TestState = TestState.Error;
+ runDesc.ErrorDesc = errorReason;
+ }
+ else
+ {
+ runDesc.ReportLocation = Path.Combine(runDesc.ReportLocation, "Report");
+ if (!File.Exists(Path.Combine(runDesc.ReportLocation, "Results.xml")) && !File.Exists(Path.Combine(runDesc.ReportLocation, "run_results.html")))
+ {
+ runDesc.TestState = TestState.Error;
+ runDesc.ErrorDesc = "No Results.xml or run_results.html file found";
+ }
+ }
+ //File.Delete(paramsFilePath);
+ runDesc.Runtime = s.Elapsed;
+ return runDesc;
+ }
+
+ ///
+ /// performs global cleanup code for this type of runner
+ ///
+ public void CleanUp()
+ {
+ }
+
+ public void SafelyCancel()
+ {
+ }
+
+ #region Process
+
+ ///
+ /// executes the run of the test by using the Init and RunProcss routines
+ ///
+ ///
+ ///
+ ///
+ ///
+ private bool ExecuteProcess(string fileName, string arguments, ref string failureReason)
+ {
+ Process proc = null;
+ try
+ {
+ using (proc = new Process())
+ {
+ InitProcess(proc, fileName, arguments, true);
+ RunProcess(proc, true);
+
+ //it could be that the process already exited before we could handle the cancel request
+ if (_runCancelled())
+ {
+ ConsoleWriter.WriteLine(Resources.GeneralTimeoutExpired);
+
+ if (!proc.HasExited)
+ {
+ proc.OutputDataReceived -= OnOutputDataReceived;
+ proc.ErrorDataReceived -= OnErrorDataReceived;
+ proc.Kill();
+ return false;
+ }
+ }
+ if (proc.ExitCode != 0)
+ {
+ failureReason = "The Api test runner's exit code was: " + proc.ExitCode;
+ ConsoleWriter.WriteLine(failureReason);
+ return false;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ failureReason = e.Message;
+ return false;
+ }
+ finally
+ {
+ if (proc != null)
+ {
+ proc.Close();
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// initializes the ServiceTestExecuter process
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void InitProcess(Process proc, string fileName, string arguments, bool enableRedirection)
+ {
+ var procStartInfo = new ProcessStartInfo
+ {
+ FileName = fileName,
+ Arguments = arguments,
+ WorkingDirectory = Directory.GetCurrentDirectory()
+ };
+ if (_uftRunAsUser != null)
+ {
+ procStartInfo.UserName = _uftRunAsUser.Username;
+ procStartInfo.Password = _uftRunAsUser.Password;
+ }
+
+ Console.WriteLine("{0} {1}", STRunnerName, arguments);
+
+ if (!enableRedirection) return;
+
+ procStartInfo.ErrorDialog = false;
+ procStartInfo.UseShellExecute = false;
+ procStartInfo.RedirectStandardOutput = true;
+ procStartInfo.RedirectStandardError = true;
+
+ proc.StartInfo = procStartInfo;
+
+ proc.EnableRaisingEvents = true;
+ proc.StartInfo.CreateNoWindow = true;
+
+ proc.OutputDataReceived += OnOutputDataReceived;
+ proc.ErrorDataReceived += OnErrorDataReceived;
+ }
+
+ ///
+ /// runs the ServiceTestExecuter process after initialization
+ ///
+ ///
+ ///
+ private void RunProcess(Process proc, bool enableRedirection)
+ {
+ proc.Start();
+ if (enableRedirection)
+ {
+ proc.BeginOutputReadLine();
+ proc.BeginErrorReadLine();
+ }
+ proc.WaitForExit(PollingTimeMs);
+ while (!_runCancelled() && !proc.HasExited)
+ {
+ proc.WaitForExit(PollingTimeMs);
+ }
+ }
+
+ ///
+ /// callback function for spawnd process errors
+ ///
+ ///
+ ///
+ private void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
+ {
+ var p = sender as Process;
+
+ if (p == null) return;
+ try
+ {
+ if (!p.HasExited || p.ExitCode == 0) return;
+ }
+ catch { return; }
+
+ string errorData = e.Data;
+
+ if (string.IsNullOrEmpty(errorData))
+ {
+ errorData = string.Format("External process has exited with code {0}", p.ExitCode);
+ }
+
+ ConsoleWriter.WriteErrLine(errorData);
+ }
+
+ ///
+ /// callback function for spawnd process output
+ ///
+ ///
+ ///
+ private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
+ {
+ if (!string.IsNullOrEmpty(e.Data))
+ {
+ string data = e.Data;
+ ConsoleWriter.WriteLine(data);
+ }
+ }
+
+ #endregion
+
+ public static bool VerifyParameterValueType(object paramValue, string type)
+ {
+ bool legal = false;
+
+ switch (type)
+ {
+ case "boolean":
+ legal = paramValue is bool;
+ break;
+
+ case "dateTime":
+ legal = paramValue is DateTime;
+ break;
+
+ case "int":
+ case "long":
+ legal = ((paramValue is int) || (paramValue is long));
+ break;
+
+ case "float":
+ case "double":
+ case "decimal":
+ legal = ((paramValue is decimal) || (paramValue is float) || (paramValue is double));
+ break;
+
+ case "string":
+ legal = paramValue is string;
+ break;
+
+ default:
+ legal = false;
+ break;
+ }
+
+ return legal;
+ }
+
+ }
}
\ No newline at end of file
diff --git a/HpToolsLauncher/TestRunners/GuiTestRunner.cs b/HpToolsLauncher/TestRunners/GuiTestRunner.cs
index e8560581fc..bbd41326bb 100644
--- a/HpToolsLauncher/TestRunners/GuiTestRunner.cs
+++ b/HpToolsLauncher/TestRunners/GuiTestRunner.cs
@@ -1,743 +1,964 @@
-// (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Linq;
-using System.IO;
-using System.Xml;
-using QTObjectModelLib;
-using Resources = HpToolsLauncher.Properties.Resources;
-using System.Threading;
-using System.Diagnostics;
-using System.Collections.Generic;
-using Microsoft.Win32;
-
-namespace HpToolsLauncher
-{
- public class GuiTestRunner : IFileSysTestRunner
- {
- // Setting keys for mobile
- private const string MOBILE_HOST_ADDRESS = "ALM_MobileHostAddress";
- private const string MOBILE_HOST_PORT = "MobileHostPort";
- private const string MOBILE_USER = "ALM_MobileUserName";
- private const string MOBILE_PASSWORD = "ALM_MobilePassword";
- private const string MOBILE_USE_SSL = "MobileUseSSL";
- private const string MOBILE_USE_PROXY= "MobileProxySetting_UseProxy";
- private const string MOBILE_PROXY_SETTING_ADDRESS = "MobileProxySetting_Address";
- private const string MOBILE_PROXY_SETTING_PORT = "MobileProxySetting_Port";
- private const string MOBILE_PROXY_SETTING_AUTHENTICATION = "MobileProxySetting_Authentication";
- private const string MOBILE_PROXY_SETTING_USERNAME = "MobileProxySetting_UserName";
- private const string MOBILE_PROXY_SETTING_PASSWORD = "MobileProxySetting_Password";
- private const string MOBILE_INFO = "mobileinfo";
-
- private readonly IAssetRunner _runNotifier;
- private readonly object _lockObject = new object();
- private TimeSpan _timeLeftUntilTimeout = TimeSpan.MaxValue;
- private Stopwatch _stopwatch = null;
- private Application _qtpApplication;
- private ParameterDefinitions _qtpParamDefs;
- private Parameters _qtpParameters;
- private bool _useUFTLicense;
- private RunCancelledDelegate _runCancelled;
- private McConnectionInfo _mcConnection;
- private string _mobileInfo;
- ///
- /// constructor
- ///
- ///
- ///
- ///
- public GuiTestRunner(IAssetRunner runNotifier, bool useUftLicense, TimeSpan timeLeftUntilTimeout, McConnectionInfo mcConnectionInfo, string mobileInfo)
- {
- _timeLeftUntilTimeout = timeLeftUntilTimeout;
- _stopwatch = Stopwatch.StartNew();
- _runNotifier = runNotifier;
- _useUFTLicense = useUftLicense;
- _mcConnection = mcConnectionInfo;
- _mobileInfo = mobileInfo;
- }
-
- #region QTP
-
- ///
- /// runs the given test and returns resutls
- ///
- ///
- ///
- ///
- ///
- public TestRunResults RunTest(TestInfo testinf, ref string errorReason, RunCancelledDelegate runCanclled)
- {
- var testPath = testinf.TestPath;
- TestRunResults runDesc = new TestRunResults();
- ConsoleWriter.ActiveTestRun = runDesc;
- ConsoleWriter.WriteLine(DateTime.Now.ToString(Launcher.DateFormat) + " Running: " + testPath);
- runDesc.ReportLocation = testPath;
-
-
- runDesc.TestPath = testPath;
- runDesc.TestState = TestState.Unknown;
-
- _runCancelled = runCanclled;
-
- if (!Helper.IsQtpInstalled())
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = string.Format(Resources.GeneralQtpNotInstalled, System.Environment.MachineName);
- ConsoleWriter.WriteErrLine(runDesc.ErrorDesc);
- Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed;
- return runDesc;
- }
-
- string reason = string.Empty;
- if (!Helper.CanUftProcessStart(out reason))
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = reason;
- ConsoleWriter.WriteErrLine(runDesc.ErrorDesc);
- Environment.ExitCode = (int)Launcher.ExitCodeEnum.Failed;
- return runDesc;
- }
-
- try
- {
- ChangeDCOMSettingToInteractiveUser();
- var type = Type.GetTypeFromProgID("Quicktest.Application");
-
- lock (_lockObject)
- {
- _qtpApplication = Activator.CreateInstance(type) as Application;
-
- Version qtpVersion = Version.Parse(_qtpApplication.Version);
- if (qtpVersion.Equals(new Version(11, 0)))
- {
- runDesc.ReportLocation = Path.Combine(testPath, "Report");
- if (Directory.Exists(runDesc.ReportLocation))
- {
- Directory.Delete(runDesc.ReportLocation, true);
- Directory.CreateDirectory(runDesc.ReportLocation);
- }
- }
-
-
- // Check for required Addins
- LoadNeededAddins(testPath);
-
- // set Mc connection and other mobile info into rack if neccesary
- #region Mc connection and other mobile info
-
- // Mc Address, username and password
- if (!string.IsNullOrEmpty(_mcConnection.MobileHostAddress))
- {
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_HOST_ADDRESS, _mcConnection.MobileHostAddress);
- if (!string.IsNullOrEmpty(_mcConnection.MobileHostPort))
- {
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_HOST_PORT, _mcConnection.MobileHostPort);
- }
- }
-
- if (!string.IsNullOrEmpty(_mcConnection.MobileUserName))
- {
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_USER, _mcConnection.MobileUserName);
- }
-
- if (!string.IsNullOrEmpty(_mcConnection.MobilePassword))
- {
- string encriptedMcPassword = WinUserNativeMethods.ProtectBSTRToBase64(_mcConnection.MobilePassword);
- if (encriptedMcPassword == null)
- {
- ConsoleWriter.WriteLine("ProtectBSTRToBase64 fail for mcPassword");
- throw new Exception("ProtectBSTRToBase64 fail for mcPassword");
- }
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_PASSWORD, encriptedMcPassword);
- }
-
- // ssl and proxy info
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_USE_SSL, _mcConnection.MobileUseSSL);
-
- if (_mcConnection.MobileUseProxy == 1)
- {
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_USE_PROXY, _mcConnection.MobileUseProxy);
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_ADDRESS, _mcConnection.MobileProxySetting_Address);
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_PORT, _mcConnection.MobileProxySetting_Port);
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_AUTHENTICATION, _mcConnection.MobileProxySetting_Authentication);
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_USERNAME, _mcConnection.MobileProxySetting_UserName);
- string encriptedMcProxyPassword = WinUserNativeMethods.ProtectBSTRToBase64(_mcConnection.MobileProxySetting_Password);
- if (encriptedMcProxyPassword == null)
- {
- ConsoleWriter.WriteLine("ProtectBSTRToBase64 fail for mc proxy Password");
- throw new Exception("ProtectBSTRToBase64 fail for mc proxy Password");
- }
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_PROXY_SETTING_PASSWORD, encriptedMcProxyPassword);
- }
-
- // Mc info (device, app, launch and terminate data)
- if (!string.IsNullOrEmpty(_mobileInfo))
- {
- _qtpApplication.TDPierToTulip.SetTestOptionsVal(MOBILE_INFO, _mobileInfo);
- }
-
- #endregion
-
-
- if (!_qtpApplication.Launched)
- {
- if (_runCancelled())
- {
- QTPTestCleanup();
- KillQtp();
- runDesc.TestState = TestState.Error;
- return runDesc;
- }
- // Launch application after set Addins
- _qtpApplication.Launch();
- _qtpApplication.Visible = false;
-
- }
- }
- }
- catch (Exception e)
- {
- errorReason = Resources.QtpNotLaunchedError;
- runDesc.TestState = TestState.Error;
- runDesc.ReportLocation = "";
- runDesc.ErrorDesc = e.Message;
- return runDesc;
- }
-
- if (_qtpApplication.Test != null && _qtpApplication.Test.Modified)
- {
- var message = Resources.QtpNotLaunchedError;
- errorReason = message;
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = errorReason;
- return runDesc;
- }
-
- _qtpApplication.UseLicenseOfType(_useUFTLicense
- ? tagUnifiedLicenseType.qtUnifiedFunctionalTesting
- : tagUnifiedLicenseType.qtNonUnified);
-
- if (!HandleInputParameters(testPath, ref errorReason, testinf.GetParameterDictionaryForQTP()))
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = errorReason;
- return runDesc;
- }
-
- GuiTestRunResult guiTestRunResult = ExecuteQTPRun(runDesc);
- runDesc.ReportLocation = guiTestRunResult.ReportPath;
-
- if (!guiTestRunResult.IsSuccess)
- {
- runDesc.TestState = TestState.Error;
- return runDesc;
- }
-
- if (!HandleOutputArguments(ref errorReason))
- {
- runDesc.TestState = TestState.Error;
- runDesc.ErrorDesc = errorReason;
- return runDesc;
- }
-
- QTPTestCleanup();
-
-
- return runDesc;
- }
-
- ///
- /// performs global cleanup code for this type of runner
- ///
- public void CleanUp()
- {
- try
- {
- //if we don't have a qtp instance, create one
- if (_qtpApplication == null)
- {
- var type = Type.GetTypeFromProgID("Quicktest.Application");
- _qtpApplication = Activator.CreateInstance(type) as Application;
- }
-
- //if the app is running, close it.
- if (_qtpApplication.Launched)
- _qtpApplication.Quit();
- }
- catch
- {
- //nothing to do. (cleanup code should not throw exceptions, and there is no need to log this as an error in the test)
- }
- }
-
- static HashSet _colLoadedAddinNames = null;
- ///